From 985a62b6b41da4c5a665fe0790128d5229893603 Mon Sep 17 00:00:00 2001 From: Marco Walz Date: Fri, 24 Jul 2026 00:37:44 +0200 Subject: [PATCH 1/4] Add self-configuring ICP skills onboarding to generated projects The generated AGENTS.md now walks the user through choosing how the project uses ICP skills (autosync / pinned / registry) and then rewrites itself into a terse, mode-specific block. Adds AGENT_SKILLS.md documenting the modes, update policies, fallbacks, commit-vs-ignore, and how to switch. Gitignores the skill caches (.claude/skills/, .agents/skills/) across all subtemplates. Co-Authored-By: Claude Opus 4.8 (1M context) --- AGENT_SKILLS.md | 120 +++++++++++++++++++++++++++++++++ _shared/write-agent-files.rhai | 111 ++++++++++++++++++++++++------ bitcoin-starter/.gitignore | 5 ++ hello-world/.gitignore | 5 ++ motoko/.gitignore | 5 ++ proxy/.gitignore | 5 ++ rust/.gitignore | 5 ++ static-website/.gitignore | 5 ++ 8 files changed, 242 insertions(+), 19 deletions(-) create mode 100644 AGENT_SKILLS.md diff --git a/AGENT_SKILLS.md b/AGENT_SKILLS.md new file mode 100644 index 0000000..f8926c7 --- /dev/null +++ b/AGENT_SKILLS.md @@ -0,0 +1,120 @@ +# How ICP skills are managed in generated projects + +Every project scaffolded from these templates ships an `AGENTS.md` (and a +`CLAUDE.md` that points to it) with a **self-configuring skills section**. This +document explains what that section does, the choices it offers, and why it is +written the way it is — so a future reader of a project's `AGENTS.md` can tell +where the content came from and why. + +For the broader, tool-agnostic picture of how agents consume ICP skills, see the +developer-docs guide: . + +## What ICP skills are + +ICP skills are tested, frequently-updated instruction files (correct dependency +versions, compiler flags, API signatures, and documented pitfalls) published at +. ICP evolves quickly, so pre-training +knowledge is outdated by definition. The rule agents follow is: **when a skill +and general knowledge disagree, the skill is correct.** + +## The self-configuring `AGENTS.md` + +The skills section of a fresh `AGENTS.md` is delimited by markers: + +``` + + +... + +``` + +While `state:` is `onboarding-needed`, the first agent session runs a one-time +setup: it asks you to choose how this project should use skills, performs the +setup, and then **rewrites everything between the two markers** with a small, +mode-specific block — deleting the onboarding instructions. From then on every +session reads that terse block and behaves accordingly, without asking again. +Only the text between the markers is ever rewritten; anything you add elsewhere +in `AGENTS.md` is left untouched. + +## The three modes + +| Mode | Who it's for | Preconditions | How skills are obtained | +|------|--------------|---------------|-------------------------| +| **autosync** | Claude Code users who want zero-maintenance, always-current skills | bash, `curl`, `jq`, Claude Code | A `SessionStart` hook (`.claude/sync-ic-skills.sh`) mirrors the latest skills into `.claude/skills/` every session | +| **pinned** | Any agent/harness; teams wanting reproducible, version-locked skills | Node / `npx` | `npx skills add dfinity/icskills` records a `skills-lock.json`; skills restored/refreshed via the CLI | +| **registry** | Anyone; zero install; the safe default | Network access | Skills fetched fresh from the registry on demand each session | + +`registry` is the **recommended default** and the fallback (see below) because it +installs nothing, works with any agent, and is fully reversible. + +### Pinned update policy + +When `pinned` is chosen, you also pick how new sessions keep skills current: + +- **auto** — each session runs `npx skills update` silently. +- **confirm** — each session asks you first, then runs `npx skills update`. +- **off** — never auto-updates; you update manually when you want. + +## The two fallbacks (and why they differ) + +If skills aren't present when a session needs them, the recovery path depends on +the mode — because each mode stores skills differently: + +- **autosync → fetch from the registry.** There is no lock file in this mode; the + hook is the source of truth. If the hook hasn't run yet (or `jq` is missing), + the agent fetches skills on demand from + . +- **pinned → `npx skills experimental_install`.** This mode commits a + `skills-lock.json`, so the exact locked versions are restored deterministically + from it. + +## What's committed vs. git-ignored + +Skill files are treated as a **managed cache**, not source. The generated +`.gitignore` ignores: + +``` +.claude/skills/ +.agents/skills/ +``` + +Committed instead is the small metadata that makes the cache reproducible: + +- **pinned** commits `skills-lock.json` (repo root). Teammates restore the exact + versions with `npx skills experimental_install`. +- **autosync** commits the hook and script (`.claude/settings.json`, + `.claude/sync-ic-skills.sh`) — *not* the skills themselves, which the hook + repopulates each session. + +This avoids committing frequently-changing generated files (no surprise diffs, no +cross-platform symlink issues from `npx skills`), while keeping every mode fully +recoverable. + +## Non-interactive sessions, and "just start" + +The onboarding never blocks your actual work. If a session can't ask you +(non-interactive/CI) or you'd rather just start coding, the agent uses `registry` +for that session only and **does not modify `AGENTS.md`** — leaving the choice +open so a later interactive session can still make it. A choice is persisted only +when you actively make one. + +## Changing your mind later + +To switch modes, reset the marker to re-trigger onboarding: replace the block +between `ic-skills:managed:start` / `end` with a single line: + +``` + +``` + +The next session will walk you through the choice again. (You can also just edit +the configured block by hand if you know the target mode.) + +## A note on reliability + +The self-rewrite is deliberately simple (clear markers, copy-one-block-verbatim) +so a wide range of agents can perform it. It has been validated across simulated +Claude Code / Cursor / Aider sessions. A less capable model could still mis-edit +the block; because `registry` is side-effect-free and every mode is recoverable, +the failure modes are benign (an extra prompt, or one session on general +knowledge) rather than destructive. diff --git a/_shared/write-agent-files.rhai b/_shared/write-agent-files.rhai index 69c947f..2a91cb8 100644 --- a/_shared/write-agent-files.rhai +++ b/_shared/write-agent-files.rhai @@ -1,22 +1,95 @@ -let agents_md = `# AI Agent Instructions - -This is an Internet Computer (ICP) project built with icp-cli. - -Documentation: https://cli.internetcomputer.org/llms.txt - -## Skills - -Tested implementation patterns for ICP development are available as agent skills. -Fetch the skills index and remember each skill's name and description: -https://skills.internetcomputer.org/.well-known/skills/index.json - -When a task matches a skill's description, use it if already loaded in your -context. Otherwise, fetch its content on-demand from the registry: -https://skills.internetcomputer.org/.well-known/skills/{name}/{file} - -Skills contain correct dependency versions, configuration formats, and common pitfalls that prevent build failures. -Always prefer skill guidance over general documentation when both cover the same topic. -`; +// Writes AGENTS.md + CLAUDE.md into every generated icp-cli project (post-hook, +// shared by all sub-templates). AGENTS.md is emitted as an array of double-quoted +// lines joined with "\n": its content has many backticks (markdown code spans) that +// would terminate a Rhai backtick string, and no double quotes, so this needs zero +// escaping. Canonical source and rationale: AGENT_SKILLS.md at the repo root. +let agents_lines = [ + "# AI Agent Instructions", + "", + "This is an Internet Computer (ICP) project built with icp-cli.", + "Documentation: https://cli.internetcomputer.org/llms.txt", + "", + "## Skills", + "", + "", + "", + "", + "ICP evolves quickly. Tested, current implementation patterns are published as", + "agent skills (correct dependency versions, compiler flags, API signatures, pitfalls).", + "Skills are authoritative: when a skill and your general knowledge disagree, the", + "skill is correct. How these options work and why:", + "https://github.com/dfinity/icp-cli-templates/blob/main/AGENT_SKILLS.md", + "", + "This project has not chosen how to use skills yet. Handle setup as follows, and", + "NEVER block the user's actual request on it:", + "", + "- If you CANNOT ask the user (non-interactive session), or the user would rather", + " just start: use `registry` for THIS session only (fetch skills on demand — see", + " the registry block below), do NOT modify this file, and continue with their", + " request. A later session can still choose.", + "", + "- If you CAN ask: have the user choose ONE option, then perform the matching setup", + " and rewrite this section (STEP 4) so the choice persists:", + " (a) autosync — Claude Code only. Skills auto-update every session.", + " (b) pinned — any agent (needs Node/npx). Skills version-locked via", + " skills-lock.json, restored on demand.", + " (c) registry — no install, works anywhere with network. Fetch skills fresh", + " each session. (Recommended default if the user is unsure.)", + " If they chose (b) pinned, also ask whether new sessions should update skills", + " automatically, only after confirming, or never.", + "", + "Setup commands:", + " (a) autosync — fetch and follow:", + " https://skills.internetcomputer.org/.well-known/skills/autosync-ic-skills/SKILL.md", + " (b) pinned — run: npx skills add dfinity/icskills", + " (c) registry — nothing to install.", + "", + "STEP 4 (only after the user has actively CHOSEN an option) — keep the two", + " `ic-skills:managed:` marker lines exactly as they are, and replace EVERYTHING", + " between them (these instructions included) with the one block below whose", + " `` comment matches the choice. Copy it verbatim; for pinned,", + " pick the block matching the update answer. Do NOT do this if you fell back to", + " registry without the user choosing.", + "", + ">>> Blocks to choose from (write exactly one, between the markers):", + "", + "", + "ICP skills auto-update each session via a SessionStart hook (`.claude/sync-ic-skills.sh`)", + "and live in your agent skills directory — you don't need to run anything to refresh them.", + "Skills are authoritative — prefer them over general knowledge for all ICP work.", + "If they are not present (hook hasn't run, or `jq` is missing), fetch them on demand per", + "https://skills.internetcomputer.org/llms.txt instead.", + "How skills are managed here, and why: https://github.com/dfinity/icp-cli-templates/blob/main/AGENT_SKILLS.md", + "", + "", + "ICP skills are version-locked in this repo (skills-lock.json) and live in your agent", + "skills directory. Skills are authoritative — prefer them over general knowledge for all", + "ICP work. At the start of each session, run `npx skills update` to refresh them.", + "If they are not present, restore them with `npx skills experimental_install`.", + "How skills are managed here, and why: https://github.com/dfinity/icp-cli-templates/blob/main/AGENT_SKILLS.md", + "", + "", + "ICP skills are version-locked in this repo (skills-lock.json) and live in your agent", + "skills directory. Skills are authoritative — prefer them over general knowledge for all", + "ICP work. At the start of each session, ask the user, and run `npx skills update` if they", + "agree. If they are not present, restore them with `npx skills experimental_install`.", + "How skills are managed here, and why: https://github.com/dfinity/icp-cli-templates/blob/main/AGENT_SKILLS.md", + "", + "", + "ICP skills are version-locked in this repo (skills-lock.json) and live in your agent", + "skills directory. Skills are authoritative — prefer them over general knowledge for all", + "ICP work. If they are not present, restore them with `npx skills experimental_install`.", + "How skills are managed here, and why: https://github.com/dfinity/icp-cli-templates/blob/main/AGENT_SKILLS.md", + "", + "", + "Before writing ICP code, fetch https://skills.internetcomputer.org/llms.txt and follow it:", + "fetch the skills index, then the relevant SKILL.md. Skills are authoritative — prefer them", + "over general knowledge.", + "How skills are managed here, and why: https://github.com/dfinity/icp-cli-templates/blob/main/AGENT_SKILLS.md", + "", +]; +let agents_md = ""; +for line in agents_lines { agents_md += line + "\n"; } file::write("AGENTS.md", agents_md); file::write("CLAUDE.md", "Read and follow the instructions in [AGENTS.md](AGENTS.md).\n"); diff --git a/bitcoin-starter/.gitignore b/bitcoin-starter/.gitignore index 02bf150..5ff312d 100644 --- a/bitcoin-starter/.gitignore +++ b/bitcoin-starter/.gitignore @@ -17,3 +17,8 @@ target/ .icp/cache/ # Do NOT ignore .icp/data/ — it stores mainnet canister ID mappings. # See: https://github.com/dfinity/icp-cli/blob/main/docs/concepts/project-model.md#whats-safe-to-delete + +# Agent skill caches — managed by the autosync hook or `npx skills`, restored +# from skills-lock.json. Not source; safe to delete. +.claude/skills/ +.agents/skills/ diff --git a/hello-world/.gitignore b/hello-world/.gitignore index f8d9d7a..c5deb2e 100644 --- a/hello-world/.gitignore +++ b/hello-world/.gitignore @@ -14,3 +14,8 @@ .icp/cache/ # Do NOT ignore .icp/data/ — it stores mainnet canister ID mappings. # See: https://github.com/dfinity/icp-cli/blob/main/docs/concepts/project-model.md#whats-safe-to-delete + +# Agent skill caches — managed by the autosync hook or `npx skills`, restored +# from skills-lock.json. Not source; safe to delete. +.claude/skills/ +.agents/skills/ diff --git a/motoko/.gitignore b/motoko/.gitignore index 611b208..1d02899 100644 --- a/motoko/.gitignore +++ b/motoko/.gitignore @@ -18,3 +18,8 @@ .icp/cache/ # Do NOT ignore .icp/data/ — it stores mainnet canister ID mappings. # See: https://github.com/dfinity/icp-cli/blob/main/docs/concepts/project-model.md#whats-safe-to-delete + +# Agent skill caches — managed by the autosync hook or `npx skills`, restored +# from skills-lock.json. Not source; safe to delete. +.claude/skills/ +.agents/skills/ diff --git a/proxy/.gitignore b/proxy/.gitignore index ab65e15..985ee72 100644 --- a/proxy/.gitignore +++ b/proxy/.gitignore @@ -2,3 +2,8 @@ .icp/cache/ # Do NOT ignore .icp/data/ — it stores mainnet canister ID mappings. # See: https://github.com/dfinity/icp-cli/blob/main/docs/concepts/project-model.md#whats-safe-to-delete + +# Agent skill caches — managed by the autosync hook or `npx skills`, restored +# from skills-lock.json. Not source; safe to delete. +.claude/skills/ +.agents/skills/ diff --git a/rust/.gitignore b/rust/.gitignore index 02bf150..5ff312d 100644 --- a/rust/.gitignore +++ b/rust/.gitignore @@ -17,3 +17,8 @@ target/ .icp/cache/ # Do NOT ignore .icp/data/ — it stores mainnet canister ID mappings. # See: https://github.com/dfinity/icp-cli/blob/main/docs/concepts/project-model.md#whats-safe-to-delete + +# Agent skill caches — managed by the autosync hook or `npx skills`, restored +# from skills-lock.json. Not source; safe to delete. +.claude/skills/ +.agents/skills/ diff --git a/static-website/.gitignore b/static-website/.gitignore index 1d639f0..b3209cb 100644 --- a/static-website/.gitignore +++ b/static-website/.gitignore @@ -27,3 +27,8 @@ dist-ssr .icp/cache/ # Do NOT ignore .icp/data/ — it stores mainnet canister ID mappings. # See: https://github.com/dfinity/icp-cli/blob/main/docs/concepts/project-model.md#whats-safe-to-delete + +# Agent skill caches — managed by the autosync hook or `npx skills`, restored +# from skills-lock.json. Not source; safe to delete. +.claude/skills/ +.agents/skills/ From 2cb121e2f8ade23ca90ee38718947ae3ff98e954 Mon Sep 17 00:00:00 2001 From: Marco Walz Date: Fri, 24 Jul 2026 01:28:15 +0200 Subject: [PATCH 2/4] Rename registry mode to on-demand; decouple its block from llms.txt Renames the third skills mode from 'registry' to 'on-demand' (all three modes use the registry, so the behavioural name is clearer). The on-demand configured block now references the fetch mechanics (index + SKILL.md) directly instead of 'follow llms.txt', so an already-configured project never re-enters onboarding once llms.txt itself becomes a choice-flow. Co-Authored-By: Claude Opus 4.8 (1M context) --- AGENT_SKILLS.md | 8 ++++---- _shared/write-agent-files.rhai | 28 +++++++++++++++------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/AGENT_SKILLS.md b/AGENT_SKILLS.md index f8926c7..b6a61e4 100644 --- a/AGENT_SKILLS.md +++ b/AGENT_SKILLS.md @@ -42,9 +42,9 @@ in `AGENTS.md` is left untouched. |------|--------------|---------------|-------------------------| | **autosync** | Claude Code users who want zero-maintenance, always-current skills | bash, `curl`, `jq`, Claude Code | A `SessionStart` hook (`.claude/sync-ic-skills.sh`) mirrors the latest skills into `.claude/skills/` every session | | **pinned** | Any agent/harness; teams wanting reproducible, version-locked skills | Node / `npx` | `npx skills add dfinity/icskills` records a `skills-lock.json`; skills restored/refreshed via the CLI | -| **registry** | Anyone; zero install; the safe default | Network access | Skills fetched fresh from the registry on demand each session | +| **on-demand** | Anyone; zero install; the safe default | Network access | Skills fetched fresh from the registry on demand each session | -`registry` is the **recommended default** and the fallback (see below) because it +`on-demand` is the **recommended default** and the fallback (see below) because it installs nothing, works with any agent, and is fully reversible. ### Pinned update policy @@ -93,7 +93,7 @@ recoverable. ## Non-interactive sessions, and "just start" The onboarding never blocks your actual work. If a session can't ask you -(non-interactive/CI) or you'd rather just start coding, the agent uses `registry` +(non-interactive/CI) or you'd rather just start coding, the agent uses `on-demand` for that session only and **does not modify `AGENTS.md`** — leaving the choice open so a later interactive session can still make it. A choice is persisted only when you actively make one. @@ -115,6 +115,6 @@ the configured block by hand if you know the target mode.) The self-rewrite is deliberately simple (clear markers, copy-one-block-verbatim) so a wide range of agents can perform it. It has been validated across simulated Claude Code / Cursor / Aider sessions. A less capable model could still mis-edit -the block; because `registry` is side-effect-free and every mode is recoverable, +the block; because `on-demand` is side-effect-free and every mode is recoverable, the failure modes are benign (an extra prompt, or one session on general knowledge) rather than destructive. diff --git a/_shared/write-agent-files.rhai b/_shared/write-agent-files.rhai index 2a91cb8..74e7c8f 100644 --- a/_shared/write-agent-files.rhai +++ b/_shared/write-agent-files.rhai @@ -25,32 +25,32 @@ let agents_lines = [ "NEVER block the user's actual request on it:", "", "- If you CANNOT ask the user (non-interactive session), or the user would rather", - " just start: use `registry` for THIS session only (fetch skills on demand — see", - " the registry block below), do NOT modify this file, and continue with their", + " just start: use `on-demand` for THIS session only (fetch skills on demand — see", + " the on-demand block below), do NOT modify this file, and continue with their", " request. A later session can still choose.", "", "- If you CAN ask: have the user choose ONE option, then perform the matching setup", " and rewrite this section (STEP 4) so the choice persists:", - " (a) autosync — Claude Code only. Skills auto-update every session.", - " (b) pinned — any agent (needs Node/npx). Skills version-locked via", + " (a) autosync — Claude Code only. Skills auto-update every session.", + " (b) pinned — any agent (needs Node/npx). Skills version-locked via", " skills-lock.json, restored on demand.", - " (c) registry — no install, works anywhere with network. Fetch skills fresh", + " (c) on-demand — no install, works anywhere with network. Fetch skills fresh", " each session. (Recommended default if the user is unsure.)", " If they chose (b) pinned, also ask whether new sessions should update skills", " automatically, only after confirming, or never.", "", "Setup commands:", - " (a) autosync — fetch and follow:", + " (a) autosync — fetch and follow:", " https://skills.internetcomputer.org/.well-known/skills/autosync-ic-skills/SKILL.md", - " (b) pinned — run: npx skills add dfinity/icskills", - " (c) registry — nothing to install.", + " (b) pinned — run: npx skills add dfinity/icskills", + " (c) on-demand — nothing to install.", "", "STEP 4 (only after the user has actively CHOSEN an option) — keep the two", " `ic-skills:managed:` marker lines exactly as they are, and replace EVERYTHING", " between them (these instructions included) with the one block below whose", " `` comment matches the choice. Copy it verbatim; for pinned,", " pick the block matching the update answer. Do NOT do this if you fell back to", - " registry without the user choosing.", + " on-demand without the user choosing.", "", ">>> Blocks to choose from (write exactly one, between the markers):", "", @@ -82,10 +82,12 @@ let agents_lines = [ "ICP work. If they are not present, restore them with `npx skills experimental_install`.", "How skills are managed here, and why: https://github.com/dfinity/icp-cli-templates/blob/main/AGENT_SKILLS.md", "", - "", - "Before writing ICP code, fetch https://skills.internetcomputer.org/llms.txt and follow it:", - "fetch the skills index, then the relevant SKILL.md. Skills are authoritative — prefer them", - "over general knowledge.", + "", + "Before writing ICP code, fetch the skills index", + "https://skills.internetcomputer.org/.well-known/skills/index.json and then the", + "matching skill's SKILL.md", + "(https://skills.internetcomputer.org/.well-known/skills/{name}/SKILL.md).", + "Skills are authoritative — prefer them over general knowledge.", "How skills are managed here, and why: https://github.com/dfinity/icp-cli-templates/blob/main/AGENT_SKILLS.md", "", ]; From d97a4f89b17a7e44cf44e53a6043d95bd2a48438 Mon Sep 17 00:00:00 2001 From: Marco Walz Date: Fri, 24 Jul 2026 14:23:31 +0200 Subject: [PATCH 3/4] Refine pinned update policy; leave .gitignore to the maintainer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - pinned update policy is now 'manual' or 'ask-first' (drop silent 'auto', which a prompt cannot enforce and which failed silently in testing). 'ask-first' offers 'npx skills update' before the first task and never blocks — it skips in non-interactive/CI sessions and keeps the locked versions. - on-demand now fetches the index once per session (remembering names/URLs) rather than re-fetching per task. - Stop pre-shipping skill-cache .gitignore entries; committing vs ignoring .claude/skills is a maintainer decision, now documented in AGENT_SKILLS.md. Co-Authored-By: Claude Opus 4.8 (1M context) --- AGENT_SKILLS.md | 49 +++++++++++++++++++--------------- _shared/write-agent-files.rhai | 33 +++++++++++------------ bitcoin-starter/.gitignore | 5 ---- hello-world/.gitignore | 5 ---- motoko/.gitignore | 5 ---- proxy/.gitignore | 5 ---- rust/.gitignore | 5 ---- static-website/.gitignore | 5 ---- 8 files changed, 42 insertions(+), 70 deletions(-) diff --git a/AGENT_SKILLS.md b/AGENT_SKILLS.md index b6a61e4..e2c581a 100644 --- a/AGENT_SKILLS.md +++ b/AGENT_SKILLS.md @@ -49,11 +49,19 @@ installs nothing, works with any agent, and is fully reversible. ### Pinned update policy -When `pinned` is chosen, you also pick how new sessions keep skills current: +Pinned means "use the version-locked skills" — that is the safe default, so the two +policies only differ in how updates are offered (there is deliberately no silent +auto-update, which a prompt cannot enforce reliably): -- **auto** — each session runs `npx skills update` silently. -- **confirm** — each session asks you first, then runs `npx skills update`. -- **off** — never auto-updates; you update manually when you want. +- **manual** — skills change only when the user runs `npx skills update`. +- **ask-first** — before the first task of a session, the agent offers to run + `npx skills update`. If the user declines, or the session is non-interactive + (e.g. CI), it keeps the locked versions and continues — it never blocks the task. + +Either way, if the skills are missing they are restored from `skills-lock.json` +with `npx skills experimental_install`. For always-latest without asking, use +`autosync` (Claude Code) or `on-demand` instead — pinned is about control, not +freshness. ## The two fallbacks (and why they differ) @@ -68,27 +76,24 @@ the mode — because each mode stores skills differently: `skills-lock.json`, so the exact locked versions are restored deterministically from it. -## What's committed vs. git-ignored - -Skill files are treated as a **managed cache**, not source. The generated -`.gitignore` ignores: - -``` -.claude/skills/ -.agents/skills/ -``` +## Version control — the maintainer's call -Committed instead is the small metadata that makes the cache reproducible: +The templates do **not** touch `.gitignore`; how the skill directories +(`.claude/skills/`, `.agents/skills/`) are tracked is your decision: -- **pinned** commits `skills-lock.json` (repo root). Teammates restore the exact - versions with `npx skills experimental_install`. -- **autosync** commits the hook and script (`.claude/settings.json`, - `.claude/sync-ic-skills.sh`) — *not* the skills themselves, which the hook - repopulates each session. +- **Commit them** — reproducible, offline, and reviewable; a natural fit for + `pinned`. Trade-off: with `autosync`, refreshed skills show up as changes to + commit, and `npx skills` may use symlinks that are awkward across platforms. +- **Git-ignore them** — treat them as a managed cache (like `node_modules`); a + natural fit for `autosync` (no churn). They are repopulated by the hook, by + `npx skills experimental_install` (pinned), or by on-demand fetch. +- **Leave it to your harness's default** — also fine; just note that untracked + skill files will otherwise show up in `git status`. -This avoids committing frequently-changing generated files (no surprise diffs, no -cross-platform symlink issues from `npx skills`), while keeping every mode fully -recoverable. +Whichever you choose, keep the small reproducibility metadata committed: +`skills-lock.json` for `pinned`, and the hook + `.claude/sync-ic-skills.sh` for +`autosync`. That way every mode stays fully recoverable regardless of the +`.gitignore` decision. ## Non-interactive sessions, and "just start" diff --git a/_shared/write-agent-files.rhai b/_shared/write-agent-files.rhai index 74e7c8f..6402b94 100644 --- a/_shared/write-agent-files.rhai +++ b/_shared/write-agent-files.rhai @@ -36,8 +36,9 @@ let agents_lines = [ " skills-lock.json, restored on demand.", " (c) on-demand — no install, works anywhere with network. Fetch skills fresh", " each session. (Recommended default if the user is unsure.)", - " If they chose (b) pinned, also ask whether new sessions should update skills", - " automatically, only after confirming, or never.", + " If they chose (b) pinned, also ask how updates should happen: only when the user", + " runs `npx skills update` themselves (manual), or offer to update at the start of", + " each session (ask-first).", "", "Setup commands:", " (a) autosync — fetch and follow:", @@ -62,31 +63,27 @@ let agents_lines = [ "https://skills.internetcomputer.org/llms.txt instead.", "How skills are managed here, and why: https://github.com/dfinity/icp-cli-templates/blob/main/AGENT_SKILLS.md", "", - "", + "", "ICP skills are version-locked in this repo (skills-lock.json) and live in your agent", "skills directory. Skills are authoritative — prefer them over general knowledge for all", - "ICP work. At the start of each session, run `npx skills update` to refresh them.", - "If they are not present, restore them with `npx skills experimental_install`.", + "ICP work. Update only when the user runs `npx skills update`. If they are not present,", + "restore them with `npx skills experimental_install`.", "How skills are managed here, and why: https://github.com/dfinity/icp-cli-templates/blob/main/AGENT_SKILLS.md", "", - "", + "", "ICP skills are version-locked in this repo (skills-lock.json) and live in your agent", "skills directory. Skills are authoritative — prefer them over general knowledge for all", - "ICP work. At the start of each session, ask the user, and run `npx skills update` if they", - "agree. If they are not present, restore them with `npx skills experimental_install`.", - "How skills are managed here, and why: https://github.com/dfinity/icp-cli-templates/blob/main/AGENT_SKILLS.md", - "", - "", - "ICP skills are version-locked in this repo (skills-lock.json) and live in your agent", - "skills directory. Skills are authoritative — prefer them over general knowledge for all", - "ICP work. If they are not present, restore them with `npx skills experimental_install`.", + "ICP work. Before your first task in a new session, offer to run `npx skills update`; if", + "the user declines or the session is non-interactive, keep the locked versions and", + "continue — never block. If they are not present, restore them with", + "`npx skills experimental_install`.", "How skills are managed here, and why: https://github.com/dfinity/icp-cli-templates/blob/main/AGENT_SKILLS.md", "", "", - "Before writing ICP code, fetch the skills index", - "https://skills.internetcomputer.org/.well-known/skills/index.json and then the", - "matching skill's SKILL.md", - "(https://skills.internetcomputer.org/.well-known/skills/{name}/SKILL.md).", + "Fetch the skills index once per session and keep each skill's name, description, and", + "SKILL.md URL: https://skills.internetcomputer.org/.well-known/skills/index.json", + "Before writing ICP code for a task, fetch the matching skill's SKILL.md", + "(https://skills.internetcomputer.org/.well-known/skills/{name}/SKILL.md) and follow it.", "Skills are authoritative — prefer them over general knowledge.", "How skills are managed here, and why: https://github.com/dfinity/icp-cli-templates/blob/main/AGENT_SKILLS.md", "", diff --git a/bitcoin-starter/.gitignore b/bitcoin-starter/.gitignore index 5ff312d..02bf150 100644 --- a/bitcoin-starter/.gitignore +++ b/bitcoin-starter/.gitignore @@ -17,8 +17,3 @@ target/ .icp/cache/ # Do NOT ignore .icp/data/ — it stores mainnet canister ID mappings. # See: https://github.com/dfinity/icp-cli/blob/main/docs/concepts/project-model.md#whats-safe-to-delete - -# Agent skill caches — managed by the autosync hook or `npx skills`, restored -# from skills-lock.json. Not source; safe to delete. -.claude/skills/ -.agents/skills/ diff --git a/hello-world/.gitignore b/hello-world/.gitignore index c5deb2e..f8d9d7a 100644 --- a/hello-world/.gitignore +++ b/hello-world/.gitignore @@ -14,8 +14,3 @@ .icp/cache/ # Do NOT ignore .icp/data/ — it stores mainnet canister ID mappings. # See: https://github.com/dfinity/icp-cli/blob/main/docs/concepts/project-model.md#whats-safe-to-delete - -# Agent skill caches — managed by the autosync hook or `npx skills`, restored -# from skills-lock.json. Not source; safe to delete. -.claude/skills/ -.agents/skills/ diff --git a/motoko/.gitignore b/motoko/.gitignore index 1d02899..611b208 100644 --- a/motoko/.gitignore +++ b/motoko/.gitignore @@ -18,8 +18,3 @@ .icp/cache/ # Do NOT ignore .icp/data/ — it stores mainnet canister ID mappings. # See: https://github.com/dfinity/icp-cli/blob/main/docs/concepts/project-model.md#whats-safe-to-delete - -# Agent skill caches — managed by the autosync hook or `npx skills`, restored -# from skills-lock.json. Not source; safe to delete. -.claude/skills/ -.agents/skills/ diff --git a/proxy/.gitignore b/proxy/.gitignore index 985ee72..ab65e15 100644 --- a/proxy/.gitignore +++ b/proxy/.gitignore @@ -2,8 +2,3 @@ .icp/cache/ # Do NOT ignore .icp/data/ — it stores mainnet canister ID mappings. # See: https://github.com/dfinity/icp-cli/blob/main/docs/concepts/project-model.md#whats-safe-to-delete - -# Agent skill caches — managed by the autosync hook or `npx skills`, restored -# from skills-lock.json. Not source; safe to delete. -.claude/skills/ -.agents/skills/ diff --git a/rust/.gitignore b/rust/.gitignore index 5ff312d..02bf150 100644 --- a/rust/.gitignore +++ b/rust/.gitignore @@ -17,8 +17,3 @@ target/ .icp/cache/ # Do NOT ignore .icp/data/ — it stores mainnet canister ID mappings. # See: https://github.com/dfinity/icp-cli/blob/main/docs/concepts/project-model.md#whats-safe-to-delete - -# Agent skill caches — managed by the autosync hook or `npx skills`, restored -# from skills-lock.json. Not source; safe to delete. -.claude/skills/ -.agents/skills/ diff --git a/static-website/.gitignore b/static-website/.gitignore index b3209cb..1d639f0 100644 --- a/static-website/.gitignore +++ b/static-website/.gitignore @@ -27,8 +27,3 @@ dist-ssr .icp/cache/ # Do NOT ignore .icp/data/ — it stores mainnet canister ID mappings. # See: https://github.com/dfinity/icp-cli/blob/main/docs/concepts/project-model.md#whats-safe-to-delete - -# Agent skill caches — managed by the autosync hook or `npx skills`, restored -# from skills-lock.json. Not source; safe to delete. -.claude/skills/ -.agents/skills/ From 6013749b8e483d1efbb9dce907f2c0fbce38949d Mon Sep 17 00:00:00 2001 From: Marco Walz Date: Thu, 30 Jul 2026 13:56:53 +0200 Subject: [PATCH 4/4] agent-skills: pinned update flow also discovers new/renamed skills MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit npx skills update only refreshes and prunes skills already in the lock — it does not discover newly published skills (vercel-labs/skills#591), and its stale-skill prune can silently no-op for shorthand sources like dfinity/icskills (vercel-labs/skills#1376). Update the pinned-mode guidance in AGENT_SKILLS.md and the generated AGENTS.md markers (write-agent-files.rhai) so an update is treated as refresh + discover: also run 'npx skills add dfinity/icskills --list' and offer to add any not-yet-installed skills (never --all), and remove a renamed skill's stale copy with 'npx skills remove ' if it lingers. --- AGENT_SKILLS.md | 10 ++++++++++ _shared/write-agent-files.rhai | 18 ++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/AGENT_SKILLS.md b/AGENT_SKILLS.md index e2c581a..8366ce4 100644 --- a/AGENT_SKILLS.md +++ b/AGENT_SKILLS.md @@ -58,6 +58,16 @@ auto-update, which a prompt cannot enforce reliably): `npx skills update`. If the user declines, or the session is non-interactive (e.g. CI), it keeps the locked versions and continues — it never blocks the task. +**An update is refresh + discover.** `npx skills update` only refreshes and prunes +skills already in `skills-lock.json` — it does **not** pull in skills added to the +repo since you pinned ([vercel-labs/skills#591](https://github.com/vercel-labs/skills/issues/591)), +and its stale-skill prune can silently no-op for shorthand sources like +`dfinity/icskills` ([vercel-labs/skills#1376](https://github.com/vercel-labs/skills/issues/1376)). +So whichever policy you pick, an update should also run +`npx skills add dfinity/icskills --list` and offer to add any skills not yet installed +— never `--all`, since pinning is curated. A **renamed** skill surfaces there under its +new name; if `update` left the old name behind, drop it with `npx skills remove `. + Either way, if the skills are missing they are restored from `skills-lock.json` with `npx skills experimental_install`. For always-latest without asking, use `autosync` (Claude Code) or `on-demand` instead — pinned is about control, not diff --git a/_shared/write-agent-files.rhai b/_shared/write-agent-files.rhai index 6402b94..11eae87 100644 --- a/_shared/write-agent-files.rhai +++ b/_shared/write-agent-files.rhai @@ -38,7 +38,9 @@ let agents_lines = [ " each session. (Recommended default if the user is unsure.)", " If they chose (b) pinned, also ask how updates should happen: only when the user", " runs `npx skills update` themselves (manual), or offer to update at the start of", - " each session (ask-first).", + " each session (ask-first). Either way, an update is refresh + discover: `npx skills", + " update` only refreshes/prunes already-pinned skills, so also run `npx skills add", + " dfinity/icskills --list` and offer to add any not yet installed (never --all).", "", "Setup commands:", " (a) autosync — fetch and follow:", @@ -66,16 +68,20 @@ let agents_lines = [ "", "ICP skills are version-locked in this repo (skills-lock.json) and live in your agent", "skills directory. Skills are authoritative — prefer them over general knowledge for all", - "ICP work. Update only when the user runs `npx skills update`. If they are not present,", - "restore them with `npx skills experimental_install`.", + "ICP work. Update only when the user runs `npx skills update` — when they do, also check", + "for newly added skills with `npx skills add dfinity/icskills --list` and offer to add any", + "that are missing (remove a renamed skill's old copy with `npx skills remove ` if", + "it lingers). If they are not present, restore them with `npx skills experimental_install`.", "How skills are managed here, and why: https://github.com/dfinity/icp-cli-templates/blob/main/AGENT_SKILLS.md", "", "", "ICP skills are version-locked in this repo (skills-lock.json) and live in your agent", "skills directory. Skills are authoritative — prefer them over general knowledge for all", - "ICP work. Before your first task in a new session, offer to run `npx skills update`; if", - "the user declines or the session is non-interactive, keep the locked versions and", - "continue — never block. If they are not present, restore them with", + "ICP work. Before your first task in a new session, offer to run `npx skills update`, then", + "check for newly added skills with `npx skills add dfinity/icskills --list` and offer to add", + "any not yet installed (remove a renamed skill's old copy with `npx skills remove `", + "if it lingers); if the user declines or the session is non-interactive, keep the locked", + "versions and continue — never block. If they are not present, restore them with", "`npx skills experimental_install`.", "How skills are managed here, and why: https://github.com/dfinity/icp-cli-templates/blob/main/AGENT_SKILLS.md", "",