From 84c784580474d20bb66056fd4bd04f05226caccb Mon Sep 17 00:00:00 2001 From: JorisJonkers Agent Date: Mon, 13 Jul 2026 10:11:06 +0000 Subject: [PATCH] skills: install grill-me for both CLIs, pinned to a reviewed ref Install the third-party grill-me skill (mattpocock/skills) for both Claude and Codex everywhere the kit installs skills. The step lives in install.sh.tpl, so it is baked into the runtime-home render for runners and runs on workstation installs (install-agents.sh delegates to install.sh). The skill executes inside agent context, so it is pinned to a reviewed upstream ref (mattpocock/skills#v1.1.0, commit d574778f) and the skills CLI is version-pinned (skills@1.5.16); bumping either is a renovate/review event. The install is idempotent (the skills CLI converges on re-run) and loud-skips with a doctor warning when npx or the network is unavailable rather than failing the whole install, matching the MCP fleet fallback posture. The skills CLI's Claude agent name is claude-code (not claude); the Claude branch passes claude-code while the installer keeps its own INSTALL_CLAUDE gating and CLAUDE_HOME/SKILLS_DIR variable names. Registers grill-me in manifest.yaml (skill entry + provenance pin) and adds a render-agent-kit.py --doctor check so --check/--doctor cover it. Records the pin in skills-source.lock, THIRD_PARTY_NOTICES.md, and renovate.json. --- THIRD_PARTY_NOTICES.md | 4 ++- installer/install.sh | 51 ++++++++++++++++++++++++++++ manifest.yaml | 35 ++++++++++++++++++-- render-agent-kit.py | 53 ++++++++++++++++++++++++++++++ renovate.json | 22 +++++++++++++ skills-source.lock | 9 ++++- templates/installer/install.sh.tpl | 51 ++++++++++++++++++++++++++++ 7 files changed, 221 insertions(+), 4 deletions(-) diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index 87a394d..3a8532c 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -28,7 +28,9 @@ sources: - Project: Skills - Repository: https://github.com/mattpocock/skills -- Source ref: main +- Pinned tag: v1.1.0 +- Resolved source commit: d574778f94cf620fcc8ce741584093bc650a61d3 +- Installed skills: grill-me (via `skills` CLI, pinned; installed by install.sh) - License: MIT - Copyright notice: Copyright (c) 2026 Matt Pocock diff --git a/installer/install.sh b/installer/install.sh index e24dcbd..1231c3c 100644 --- a/installer/install.sh +++ b/installer/install.sh @@ -174,6 +174,7 @@ claude_managed_paths=( "${SKILLS_DIR}/kb-first/SKILL.md" "${SKILLS_DIR}/token-economy/SKILL.md" "${SKILLS_DIR}/agent-session-bootstrap/SKILL.md" + "${SKILLS_DIR}/grill-me/SKILL.md" "${SKILLS_DIR}/council/SKILL.md" "${SKILLS_DIR}/council/council.mjs" "${SKILLS_DIR}/council/council.toml" @@ -237,6 +238,7 @@ codex_managed_paths=( "${CODEX_SKILLS_DIR}/kb-first/SKILL.md" "${CODEX_SKILLS_DIR}/token-economy/SKILL.md" "${CODEX_SKILLS_DIR}/agent-session-bootstrap/SKILL.md" + "${CODEX_SKILLS_DIR}/grill-me/SKILL.md" "${CODEX_SKILLS_DIR}/council/SKILL.md" "${CODEX_SKILLS_DIR}/council/council.mjs" "${CODEX_SKILLS_DIR}/council/council.toml" @@ -4041,6 +4043,55 @@ install_council() { if [ "${INSTALL_CLAUDE}" = 1 ]; then install_council "${SKILLS_DIR}" "${COUNCIL_SKILL_claude}"; fi if [ "${INSTALL_CODEX}" = 1 ]; then install_council "${CODEX_SKILLS_DIR}" "${COUNCIL_SKILL_codex}"; fi +# ----------------------------------------------------------------- +# Third-party skill: grill-me (mattpocock/skills). Installed for both +# CLIs via the `skills` CLI, pinned to a reviewed ref so bumping the +# pin is a normal renovate/review event (org supply-chain posture). +# The skill content executes inside agent context, so the ref is never +# floating. Loud-skip philosophy: if npx or the network is unavailable +# the step logs a warning and continues rather than failing the whole +# install (same fallback posture as the MCP fleet registration). The +# `skills` CLI is itself idempotent, so re-runs and upgrades converge +# without duplicating the skill. +# ----------------------------------------------------------------- +# Pin — reviewed 2026-07-13; see skills-source.lock and manifest.yaml +# provenance.skills. mattpocock/skills v1.1.0 = commit +# d574778f94cf620fcc8ce741584093bc650a61d3. Bump via renovate/review. +readonly GRILL_ME_SOURCE='mattpocock/skills#v1.1.0' +readonly GRILL_ME_SKILL='grill-me' +readonly SKILLS_CLI='skills@1.5.16' + +install_grill_me() { + # ${agent} is the `skills` CLI agent name (its registry keys are + # "claude-code" and "codex", not "claude"); ${home} is the installer's + # resolved client home for that agent. + local agent="$1" home="$2" + if [ "${DRY_RUN}" = 1 ]; then + log "would install ${GRILL_ME_SKILL} for ${agent} from ${GRILL_ME_SOURCE} via npx ${SKILLS_CLI}" + return 0 + fi + if ! command -v npx >/dev/null 2>&1; then + log "WARNING: npx is not on PATH; skipping ${GRILL_ME_SKILL} for ${agent} (install Node >=22 and re-run)" + return 0 + fi + # The `skills` CLI resolves its home from CLAUDE_CONFIG_DIR / CODEX_HOME, + # so exporting the installer-resolved home lands grill-me next to the + # kit's own skills for both user and project scope. + if CLAUDE_CONFIG_DIR="${home}" CODEX_HOME="${home}" \ + npx --yes "${SKILLS_CLI}" add "${GRILL_ME_SOURCE}" \ + --skill="${GRILL_ME_SKILL}" --agent "${agent}" --yes --global; then + log "installed ${GRILL_ME_SKILL} for ${agent} from ${GRILL_ME_SOURCE}" + else + log "WARNING: ${GRILL_ME_SKILL} install for ${agent} failed (npx/network unavailable?); continuing" + fi +} + +# The `skills` CLI expects "claude-code" (not "claude") as the Claude agent +# name; the installer's own INSTALL_CLAUDE gating and ${CLAUDE_HOME}/${SKILLS_DIR} +# variable names are unchanged. +if [ "${INSTALL_CLAUDE}" = 1 ]; then install_grill_me claude-code "${CLAUDE_HOME}"; fi +if [ "${INSTALL_CODEX}" = 1 ]; then install_grill_me codex "${CODEX_HOME}"; fi + # ----------------------------------------------------------------- # Path allowlist (gitignore-style). Hooks below skip any tool input # whose target matches a pattern here. Defaults exclude paths that diff --git a/manifest.yaml b/manifest.yaml index 30a66e4..0187e83 100644 --- a/manifest.yaml +++ b/manifest.yaml @@ -19,6 +19,18 @@ provenance: upstream_commit: "9313aaeb6573333c636c7ac55439dddc256c29e1" source_lock: spec-kit-source.lock third_party_notices: THIRD_PARTY_NOTICES.md + skills: + # grill-me is installed for both CLIs by the served install.sh via the + # `skills` CLI (`npx skills add mattpocock/skills# --skill=grill-me`), + # pinned to a reviewed ref. The upstream_commit is the immutable pin; + # bumping it is a renovate/review event. + upstream_repository: https://github.com/mattpocock/skills + upstream_tag: v1.1.0 + upstream_commit: "d574778f94cf620fcc8ce741584093bc650a61d3" + skills_cli_version: 1.5.16 + installed_skills: [grill-me] + source_lock: skills-source.lock + third_party_notices: THIRD_PARTY_NOTICES.md renderer: script_path: render-agent-kit.py @@ -403,6 +415,25 @@ skills: - agent: claude path: .claude/skills/fleet-change/SKILL.md sha256: da427baa764c7d17667f9faa0b2bdbb467c9a34acaeb1a4df2523d16bdb4e0c5 + - name: grill-me + # Third-party skill from mattpocock/skills, installed for both CLIs by the + # served install.sh via `npx skills add`. It has no repo file target, so it + # is pinned by upstream ref+commit (its immutable sha) under provenance + # rather than a repo-file sha256. Bumping the pin is a renovate/review event. + supported_agents: [codex, claude] + provenance: + source: skills-cli:mattpocock/skills + upstream_repository: https://github.com/mattpocock/skills + upstream_tag: v1.1.0 + upstream_commit: "d574778f94cf620fcc8ce741584093bc650a61d3" + skill_path: skills/productivity/grill-me/SKILL.md + skills_cli_version: 1.5.16 + source_lock: skills-source.lock + third_party_notices: THIRD_PARTY_NOTICES.md + installer: + source_path: installer/install.sh + target_path: "${CLAUDE_HOME}/skills/grill-me/SKILL.md" + codex_target_path: "${CODEX_HOME}/skills/grill-me/SKILL.md" - name: kb-first supported_agents: [codex, claude] targets: @@ -878,11 +909,11 @@ agent_runner_runtime: installer: path: installer/install.sh - sha256: 89f2d200077f0f44b386d4fa93f9a46a183a1fe605663f52034e9bc55f2ff395 + sha256: 01265e25aee91eed3bf78560b7e23871d84e7f44954538fbdf38bb273c5ee4e0 supported_agents: [codex, claude] served_artifacts: - path: installer/install.sh - sha256: 89f2d200077f0f44b386d4fa93f9a46a183a1fe605663f52034e9bc55f2ff395 + sha256: 01265e25aee91eed3bf78560b7e23871d84e7f44954538fbdf38bb273c5ee4e0 mode: "0644" - path: installer/install-agents.sh sha256: c2b20ca13df242056eb4b6591abdc830d5685a17ec7a7cde23c2886189fd14f4 diff --git a/render-agent-kit.py b/render-agent-kit.py index 7956367..468befb 100755 --- a/render-agent-kit.py +++ b/render-agent-kit.py @@ -496,6 +496,58 @@ def installer_artifact_check() -> DoctorCheck: ) +THIRD_PARTY_SKILLS_SOURCE = "mattpocock/skills" +THIRD_PARTY_SKILLS_PIN = "v1.1.0" + + +def grill_me_check() -> DoctorCheck: + """Confirm the grill-me third-party skill is wired into both served + installers with a pinned (non-floating) ref, and report whether npx is + available. A missing npx is a warn, not a fail: the installer loud-skips + grill-me and continues rather than hard-failing (same fallback posture as + the MCP fleet).""" + marker = "install_grill_me" + pinned_source = f"{THIRD_PARTY_SKILLS_SOURCE}#{THIRD_PARTY_SKILLS_PIN}" + for relative in SERVED_INSTALLERS: + installer = REPOSITORY_ROOT / relative + if not installer.is_file(): + return DoctorCheck(name="grill-me", status="fail", detail=f"missing {relative}") + body = installer.read_text(errors="replace") + # install-agents.sh delegates the base install (which carries grill-me); + # only install.sh must embed the pinned invocation directly. + if relative.name == "install.sh": + if marker not in body: + return DoctorCheck( + name="grill-me", + status="fail", + detail=f"{relative} does not install grill-me", + ) + if pinned_source not in body: + return DoctorCheck( + name="grill-me", + status="fail", + detail=f"{relative} does not pin {THIRD_PARTY_SKILLS_SOURCE} to a reviewed ref", + ) + if f"{THIRD_PARTY_SKILLS_SOURCE}#'" in body or f"{THIRD_PARTY_SKILLS_SOURCE}'" in body: + return DoctorCheck( + name="grill-me", + status="fail", + detail=f"{relative} uses a floating {THIRD_PARTY_SKILLS_SOURCE} ref", + ) + + if shutil.which("npx") is None: + return DoctorCheck( + name="grill-me", + status="warn", + detail=f"wired + pinned to {pinned_source}; npx not on PATH so the installer will loud-skip grill-me", + ) + return DoctorCheck( + name="grill-me", + status="ok", + detail=f"wired into both installers, pinned to {pinned_source}; npx available", + ) + + def kb_reachability_check(require_live_kb: bool, timeout_seconds: float) -> DoctorCheck: kb_url = os.environ.get("KB_URL", "").rstrip("/") token = os.environ.get("KB_BEARER_TOKEN", "") @@ -610,6 +662,7 @@ def doctor(args: argparse.Namespace) -> int: checks.append(manifest_check()) checks.append(parity_check()) checks.append(installer_artifact_check()) + checks.append(grill_me_check()) checks.append(kb_reachability_check(require_live_kb=args.require_live_kb, timeout_seconds=args.kb_timeout_seconds)) print("agent kit doctor") diff --git a/renovate.json b/renovate.json index c49ea81..1ce0aca 100644 --- a/renovate.json +++ b/renovate.json @@ -32,6 +32,28 @@ ], "datasourceTemplate": "git-refs" }, + { + "customType": "regex", + "description": "Update the pinned grill-me skill ref (mattpocock/skills) in the skills source lock.", + "managerFilePatterns": ["/^skills-source\\.lock$/"], + "matchStrings": [ + "pinned_tag: (?\\S+)\\s+pinned_commit: (?[a-f0-9]{7,40})" + ], + "depNameTemplate": "mattpocock/skills", + "datasourceTemplate": "github-releases", + "versioningTemplate": "semver" + }, + { + "customType": "regex", + "description": "Update the pinned `skills` CLI version used to install grill-me.", + "managerFilePatterns": ["/^skills-source\\.lock$/"], + "matchStrings": [ + "skills_cli_version: (?\\S+)" + ], + "depNameTemplate": "skills", + "datasourceTemplate": "npm", + "versioningTemplate": "npm" + }, { "customType": "regex", "description": "Update Spec Kit source lock release pins.", diff --git a/skills-source.lock b/skills-source.lock index 92fd168..f733a43 100644 --- a/skills-source.lock +++ b/skills-source.lock @@ -1,6 +1,6 @@ # Skills Source Lock -verified_at: 2026-07-03 +verified_at: 2026-07-13 ## Sources @@ -8,6 +8,13 @@ verified_at: 2026-07-03 status: included license: MIT license_notice: Copyright (c) 2026 Matt Pocock + # Installed for both CLIs by the served install.sh via the `skills` CLI, + # pinned to a reviewed ref (never floating). The commit is the immutable pin. + installed_via: "npx skills@1.5.16 add mattpocock/skills#v1.1.0 --skill=grill-me" + pinned_tag: v1.1.0 + pinned_commit: d574778f94cf620fcc8ce741584093bc650a61d3 + skills_cli_version: 1.5.16 + installed_skills: [grill-me] - upstream_repository: https://github.com/obra/superpowers status: included license: MIT diff --git a/templates/installer/install.sh.tpl b/templates/installer/install.sh.tpl index 722c82e..9a275b7 100644 --- a/templates/installer/install.sh.tpl +++ b/templates/installer/install.sh.tpl @@ -166,6 +166,7 @@ claude_managed_paths=( "${SKILLS_DIR}/kb-first/SKILL.md" "${SKILLS_DIR}/token-economy/SKILL.md" "${SKILLS_DIR}/agent-session-bootstrap/SKILL.md" + "${SKILLS_DIR}/grill-me/SKILL.md" # @agent-kit-council-managed claude "${ALLOWLIST}" ) @@ -180,6 +181,7 @@ codex_managed_paths=( "${CODEX_SKILLS_DIR}/kb-first/SKILL.md" "${CODEX_SKILLS_DIR}/token-economy/SKILL.md" "${CODEX_SKILLS_DIR}/agent-session-bootstrap/SKILL.md" + "${CODEX_SKILLS_DIR}/grill-me/SKILL.md" # @agent-kit-council-managed codex "${CODEX_ALLOWLIST}" "${CODEX_HOOKS_CONFIG}" @@ -280,6 +282,55 @@ fi # ----------------------------------------------------------------- # @agent-kit-council-bundle +# ----------------------------------------------------------------- +# Third-party skill: grill-me (mattpocock/skills). Installed for both +# CLIs via the `skills` CLI, pinned to a reviewed ref so bumping the +# pin is a normal renovate/review event (org supply-chain posture). +# The skill content executes inside agent context, so the ref is never +# floating. Loud-skip philosophy: if npx or the network is unavailable +# the step logs a warning and continues rather than failing the whole +# install (same fallback posture as the MCP fleet registration). The +# `skills` CLI is itself idempotent, so re-runs and upgrades converge +# without duplicating the skill. +# ----------------------------------------------------------------- +# Pin — reviewed 2026-07-13; see skills-source.lock and manifest.yaml +# provenance.skills. mattpocock/skills v1.1.0 = commit +# d574778f94cf620fcc8ce741584093bc650a61d3. Bump via renovate/review. +readonly GRILL_ME_SOURCE='mattpocock/skills#v1.1.0' +readonly GRILL_ME_SKILL='grill-me' +readonly SKILLS_CLI='skills@1.5.16' + +install_grill_me() { + # ${agent} is the `skills` CLI agent name (its registry keys are + # "claude-code" and "codex", not "claude"); ${home} is the installer's + # resolved client home for that agent. + local agent="$1" home="$2" + if [ "${DRY_RUN}" = 1 ]; then + log "would install ${GRILL_ME_SKILL} for ${agent} from ${GRILL_ME_SOURCE} via npx ${SKILLS_CLI}" + return 0 + fi + if ! command -v npx >/dev/null 2>&1; then + log "WARNING: npx is not on PATH; skipping ${GRILL_ME_SKILL} for ${agent} (install Node >=22 and re-run)" + return 0 + fi + # The `skills` CLI resolves its home from CLAUDE_CONFIG_DIR / CODEX_HOME, + # so exporting the installer-resolved home lands grill-me next to the + # kit's own skills for both user and project scope. + if CLAUDE_CONFIG_DIR="${home}" CODEX_HOME="${home}" \ + npx --yes "${SKILLS_CLI}" add "${GRILL_ME_SOURCE}" \ + --skill="${GRILL_ME_SKILL}" --agent "${agent}" --yes --global; then + log "installed ${GRILL_ME_SKILL} for ${agent} from ${GRILL_ME_SOURCE}" + else + log "WARNING: ${GRILL_ME_SKILL} install for ${agent} failed (npx/network unavailable?); continuing" + fi +} + +# The `skills` CLI expects "claude-code" (not "claude") as the Claude agent +# name; the installer's own INSTALL_CLAUDE gating and ${CLAUDE_HOME}/${SKILLS_DIR} +# variable names are unchanged. +if [ "${INSTALL_CLAUDE}" = 1 ]; then install_grill_me claude-code "${CLAUDE_HOME}"; fi +if [ "${INSTALL_CODEX}" = 1 ]; then install_grill_me codex "${CODEX_HOME}"; fi + # ----------------------------------------------------------------- # Path allowlist (gitignore-style). Hooks below skip any tool input # whose target matches a pattern here. Defaults exclude paths that