@ssheleg/make-skill 0.8.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/CHANGELOG.md +114 -3
  2. package/README.md +49 -15
  3. package/SECURITY.md +24 -8
  4. package/cursor/rules/make-skill.mdc +29 -0
  5. package/package.json +2 -3
  6. package/plugins/make-skill/.claude-plugin/plugin.json +1 -1
  7. package/plugins/make-skill/agents/skill-auditor.md +46 -0
  8. package/plugins/make-skill/commands/skill-audit.md +31 -0
  9. package/plugins/make-skill/hooks/hooks.json +19 -0
  10. package/plugins/make-skill/hooks/skill-md-audit.sh +43 -0
  11. package/plugins/make-skill/skills/make-skill/SKILL.md +101 -87
  12. package/plugins/make-skill/skills/make-skill/assets/agent.template.md +33 -0
  13. package/plugins/make-skill/skills/make-skill/assets/command.template.md +32 -0
  14. package/plugins/make-skill/skills/make-skill/assets/hooks.template.json +32 -0
  15. package/{templates → plugins/make-skill/skills/make-skill/assets}/marketplace.template.json +1 -0
  16. package/{templates → plugins/make-skill/skills/make-skill/assets}/plugin.template.json +1 -0
  17. package/plugins/make-skill/skills/make-skill/references/authoring.md +7 -0
  18. package/plugins/make-skill/skills/make-skill/references/claude-code-plugin.md +2 -2
  19. package/plugins/make-skill/skills/make-skill/references/distribution.md +19 -6
  20. package/plugins/make-skill/skills/make-skill/references/host-capabilities.md +218 -0
  21. package/plugins/make-skill/skills/make-skill/references/retrofit.md +114 -0
  22. package/plugins/make-skill/skills/make-skill/scripts/audit_skill.py +378 -0
  23. package/templates/README.md +0 -31
  24. /package/{templates → plugins/make-skill/skills/make-skill/assets}/SKILL.template.md +0 -0
@@ -0,0 +1,218 @@
1
+ # Host capabilities — hooks, agents, commands, and what happens without them
2
+
3
+ **Load this when:** deciding whether a skill should ship a hook, a subagent, a
4
+ command, an MCP server or a script — or when writing the degradation clauses that
5
+ keep it working where those do not exist.
6
+
7
+ Sources: [Claude Code hooks reference](https://code.claude.com/docs/en/hooks) and
8
+ the [plugins reference](https://code.claude.com/docs/en/plugins-reference)
9
+ (*read 2026-08-03, Claude Code 2.1.212*), plus `references/claude-code-plugin.md`
10
+ for the manifest side.
11
+
12
+ ## Contents
13
+
14
+ - The rule: accelerator, never precondition
15
+ - What to reach for, and what it costs
16
+ - Hooks — events, handlers, matchers, exit codes
17
+ - Writing a hook that is invisible when idle
18
+ - Subagents
19
+ - Commands
20
+ - Scripts
21
+ - MCP servers and other plugins as dependencies
22
+ - The three degradation cases, written out
23
+ - Checklist
24
+
25
+ ## The rule: accelerator, never precondition
26
+
27
+ Everything on this page exists only inside Claude Code. A skill that *needs* one
28
+ of them is broken on Cursor, Codex, the skills CLI, the Claude API and claude.ai
29
+ — which is most of where skills run. So:
30
+
31
+ > **Every host capability is an accelerator with a stated fallback. The skill
32
+ > must complete its job without it, more slowly and with less polish.**
33
+
34
+ "Stated" is the operative word: the fallback goes in the skill body, in the words
35
+ the agent will read at the moment the capability is missing. A fallback you know
36
+ but did not write is not a fallback.
37
+
38
+ ## What to reach for, and what it costs
39
+
40
+ | Capability | Buys you | Costs | Reach for it when |
41
+ |---|---|---|---|
42
+ | `scripts/` | determinism, and output instead of code in context | none until run | the agent re-derives the same logic every run |
43
+ | `hooks/` | enforcement at the moment of the action | runs on the user's machine, every matching tool call | a rule matters more than an instruction can guarantee |
44
+ | `agents/` | a job done in a separate context window | ~100 always-on tokens per agent | the work would otherwise crowd out the main thread |
45
+ | `commands/` | a user-typed entry point with arguments | ~50–100 always-on tokens | a human, not the model, decides when it runs |
46
+ | `mcpServers` | live capability (network, credentials, a process) | a server to install, auth to hold | instructions cannot do it — see `references/mcp.md` |
47
+ | `lspServers`, `monitors`, `themes`, `outputStyles`, `workflows` | narrow, real, and rarely what a skill wants | always-on where they load | you can name the user who asked for it |
48
+ | `userConfig` | values prompted at enable time | a prompt in everyone's install | the skill genuinely cannot guess (a path, a workspace id) |
49
+
50
+ Everything in that table is Claude-Code-only. `scripts/` is the exception that
51
+ travels: it lives inside the skill directory, so every channel ships it.
52
+
53
+ ## Hooks — events, handlers, matchers, exit codes
54
+
55
+ Plugin hooks live in `hooks/hooks.json` at the plugin root (auto-discovered; a
56
+ manifest key is only needed for a custom path). Shape:
57
+
58
+ ```json
59
+ { "hooks": { "PostToolUse": [ { "matcher": "Write|Edit",
60
+ "hooks": [ { "type": "command", "shell": "bash",
61
+ "command": "\"${CLAUDE_PLUGIN_ROOT}/hooks/check.sh\"",
62
+ "timeout": 20 } ] } ] } }
63
+ ```
64
+
65
+ **Events worth a skill's attention** (the full set is larger):
66
+
67
+ | Event | Fires | Blocks? | Use for |
68
+ |---|---|---|---|
69
+ | `SessionStart` | session begins/resumes (`startup\|resume\|clear\|compact\|fork`) | no | seeding state, `additionalContext` |
70
+ | `UserPromptSubmit` | before the model sees the prompt | yes | injecting context, refusing a prompt |
71
+ | `PreToolUse` | before a tool runs | yes — `permissionDecision: deny` | guarding a destructive action |
72
+ | `PostToolUse` | after a tool succeeds | no | validating what was just written |
73
+ | `Stop` / `SubagentStop` | a turn or subagent finishes | yes | completion gates |
74
+ | `SessionEnd` | session ends | no | cleanup (1.5s shared budget) |
75
+
76
+ **Handler types:** `command` (a script — the portable one), `http`, `mcp_tool`,
77
+ `prompt`, `agent`. `command` takes `shell` (`bash`/`powershell`) in shell form,
78
+ or `args` for exec form with no shell tokenization.
79
+
80
+ **Matchers** are exact strings or `A|B` lists; anything with other characters is
81
+ an unanchored regex. Tool names are what you match (`Bash`, `Write`,
82
+ `mcp__server__tool`). A plugin's OWN MCP server is matched as
83
+ `mcp__plugin_<plugin>_<server>__<tool>`, and an `mcp_tool` hook names the server
84
+ as `plugin:<plugin>:<server>` — the bare key never fires. Narrow further with
85
+ `if`, a permission rule: `"if": "Bash(git commit *)"`.
86
+
87
+ **Exit codes are the contract:**
88
+
89
+ | Exit | Meaning |
90
+ |---|---|
91
+ | `0` | success; stdout is parsed as JSON for structured output |
92
+ | `2` | blocking error; **stderr goes to the model**, stdout is ignored |
93
+ | other | non-blocking error; the action proceeds, the transcript shows a hook error |
94
+
95
+ Structured output on exit 0: `systemMessage` (shown to the user),
96
+ `additionalContext` (injected for the model), `decision: "block"` with `reason`,
97
+ `permissionDecision` for `PreToolUse`, `suppressOutput`, `continue: false`.
98
+
99
+ **Environment:** `${CLAUDE_PLUGIN_ROOT}`, `${CLAUDE_PLUGIN_DATA}`,
100
+ `${CLAUDE_PROJECT_DIR}` substitute in the command and are exported. Quote them —
101
+ a space in the install path otherwise splits the command.
102
+
103
+ ## Writing a hook that is invisible when idle
104
+
105
+ A plugin installed globally fires its hooks in every project. Two rules keep that
106
+ from being a nuisance, and both belong in the `description` field of
107
+ `hooks.json`, where a reviewer reads them:
108
+
109
+ 1. **Exit 0 with no output the moment the event is not yours.** Wrong tool, wrong
110
+ path, no project marker file → `exit 0` before doing any work. This is why
111
+ `agent-sync`'s hooks open by checking for `.claude/agent-sync.json`.
112
+ 2. **Degrade instead of erroring.** No interpreter, missing script, unparsable
113
+ input → `exit 0` silently. A hook that reports its own absence as a failure
114
+ trains the user to disable hooks.
115
+
116
+ Block (`exit 2`) only where blocking is the point, and only on `PreToolUse` or
117
+ another event that actually blocks. On `PostToolUse` the write already happened;
118
+ advice via `systemMessage` is worth more than a veto that costs a turn.
119
+
120
+ Ship the script with a shebang and `chmod +x`, and keep it dependency-free —
121
+ `jq` is not installed everywhere, and a hook is a bad place to discover that.
122
+
123
+ ## Subagents
124
+
125
+ `agents/*.md` with `name` and `description`; optional `model`, `effort`,
126
+ `maxTurns`, `tools`, `disallowedTools`, `skills`, `memory`, `background`,
127
+ `isolation: "worktree"`. **`hooks`, `mcpServers` and `permissionMode` are
128
+ rejected** for plugin-shipped agents. They appear as `<plugin>:<agent>`.
129
+
130
+ A subagent earns its always-on cost when the work is *voluminous and separable* —
131
+ an audit across twenty skills, a survey, a long verification — because its output
132
+ is a summary while its reading stays in its own context. It does not earn it when
133
+ the main thread needs the intermediate detail anyway.
134
+
135
+ Fallback: on any other host there are no subagents. The skill body must describe
136
+ the same procedure inline, so a Cursor session does the work in one context.
137
+
138
+ ## Commands
139
+
140
+ `commands/*.md`, frontmatter `description` plus a **quoted** `argument-hint`;
141
+ body receives `$ARGUMENTS`. Two rules cost a debugging round each:
142
+
143
+ - **Never name a command after a skill in the same plugin.** Commands are skills
144
+ now: both claim `/<name>`, the skill wins, the command is unreachable always-on
145
+ cost visible only in `claude plugin details`.
146
+ - **Quote `argument-hint`.** Bare `[a | b]` is a YAML flow sequence; a comma
147
+ inside it drops the entire frontmatter block, leaving a command with no
148
+ description and no warning.
149
+
150
+ Fallback: elsewhere there is no `/command`. The skill's own description must
151
+ carry the trigger phrases that reach the same behavior in plain language.
152
+
153
+ ## Scripts
154
+
155
+ The one accelerator that travels. Keep it inside the skill directory
156
+ (`scripts/`), stdlib-only, and invoke it by a path the agent can actually
157
+ resolve:
158
+
159
+ ```bash
160
+ python3 "${CLAUDE_PLUGIN_ROOT}/skills/<skill>/scripts/x.py" <target> # Claude Code
161
+ python3 ~/.agents/skills/<skill>/scripts/x.py <target> # skills CLI
162
+ python3 ~/.claude/skills/<skill>/scripts/x.py <target> # plain install
163
+ ```
164
+
165
+ **The absolute path differs per channel**, so the instruction that survives is
166
+ "run the script from the skill directory you just read this file from", with
167
+ `${CLAUDE_PLUGIN_ROOT}` offered as the Claude Code convenience. State the
168
+ no-interpreter fallback too: the manual procedure, in the reference that the
169
+ script implements.
170
+
171
+ ## MCP servers and other plugins as dependencies
172
+
173
+ A skill may *use* an MCP server or a sibling skill; it may not *require* one
174
+ silently. Declare it in frontmatter `compatibility`, and write the branch:
175
+
176
+ - **Server present** → name the tool by discovery, never a hardcoded string
177
+ (`references/mcp.md`).
178
+ - **Server absent** → say so once, name what is degraded, and continue with the
179
+ manual path. Never loop on 401s; interactive auth is a human step.
180
+ - **Sibling skill absent** (`super-ux`, `agent-sync`, …) → the dependent stage
181
+ still runs, with its quality reduced and that reduction stated. A pipeline that
182
+ refuses to start because an optional companion is missing is a broken pipeline.
183
+
184
+ Claude Code's manifest `dependencies` field can express a hard requirement
185
+ between plugins. Use it only when the skill genuinely cannot function — and know
186
+ that it means nothing on any other host.
187
+
188
+ ## The three degradation cases, written out
189
+
190
+ Put these in the skill body, in this shape:
191
+
192
+ ```markdown
193
+ ## Degradation
194
+
195
+ - **Not Claude Code** (Cursor, Codex, skills CLI, API): hooks, subagents and
196
+ `/commands` do not exist. Run <procedure> inline; the bundled `scripts/` still
197
+ work wherever `python3` does.
198
+ - **Recommended plugin absent** (<name>): <what is lost>. Continue with
199
+ <manual path>, and say once that the result is <weaker in this way>.
200
+ - **Tool or interpreter absent** (`python3`, `gh`, `npm`, an MCP server): state
201
+ it once, fall back to <the by-hand procedure>, never retry in a loop.
202
+ ```
203
+
204
+ Three lines, one per axis. They are what a reader checks before installing, and
205
+ what the agent reads at the exact moment something is missing.
206
+
207
+ ## Checklist
208
+
209
+ - [ ] Every host capability the skill ships has a written fallback in the body
210
+ - [ ] `hooks.json` `description` says when the hooks no-op
211
+ - [ ] Hook scripts exit 0 silently on "not mine" and on a missing interpreter
212
+ - [ ] `PostToolUse` advises (`systemMessage`), `PreToolUse` blocks — not the reverse
213
+ - [ ] Hook commands quote `"${CLAUDE_PLUGIN_ROOT}"` and set a `timeout`
214
+ - [ ] Hook scripts are executable, have a shebang, and need no `jq`
215
+ - [ ] No command named after a skill; every `argument-hint` quoted
216
+ - [ ] Plugin agents carry no `hooks` / `mcpServers` / `permissionMode`
217
+ - [ ] Scripts are stdlib-only, inside the skill dir, invoked by a resolvable path
218
+ - [ ] MCP and sibling-skill dependencies declared in `compatibility` with a branch
@@ -0,0 +1,114 @@
1
+ # Retrofit — the audit procedure
2
+
3
+ **Load this when:** auditing an existing skill, plugin or repo against this
4
+ standard — including the no-argument `/make-skill` path, where a `SKILL.md`,
5
+ `.claude-plugin/` or `plugins/*/skills/*/` in the current directory means Retrofit.
6
+
7
+ ## Contents
8
+
9
+ - Run the script first
10
+ - How to report (the only acceptable verdict format)
11
+ - The 14-item audit checklist
12
+ - Personal skills — the short form
13
+ - After the audit
14
+
15
+ ## Run the script first
16
+
17
+ The mechanical half is deterministic — do not reason your way through it:
18
+
19
+ ```bash
20
+ python3 "${CLAUDE_PLUGIN_ROOT}/skills/make-skill/scripts/audit_skill.py" <skill-dir> --house
21
+ ```
22
+
23
+ `${CLAUDE_PLUGIN_ROOT}` is Claude Code's. On any other host the script sits at
24
+ `scripts/audit_skill.py` inside the make-skill directory you are reading this
25
+ from (`~/.agents/skills/make-skill/`, `~/.claude/skills/make-skill/`). No
26
+ `python3` at all? Check items 1 and 9 below by hand against
27
+ `references/agent-skills-spec.md` — the script implements that checklist and
28
+ nothing more. Either way, the judgement items are yours.
29
+
30
+ ## How to report
31
+
32
+ Audit first, fix second, in the same session. One verdict per item:
33
+
34
+ | Verdict | Requires |
35
+ |---|---|
36
+ | **PASS** | the check was actually run — a command's output or a `file:line` |
37
+ | **GAP** | what is wrong, the evidence, and the fix that closes it |
38
+
39
+ "Looks fine" is not a verdict. Neither is a PASS on a check that was reasoned
40
+ about rather than executed: `python3 test/validate.py`, `claude plugin validate
41
+ … --strict`, `npx skills add <repo> --list` all produce output, and the output is
42
+ the evidence. Report the gap table before changing anything, then fix.
43
+
44
+ ## The 14-item audit checklist
45
+
46
+ 1. **Spec floor** (`references/agent-skills-spec.md`): `name` charset + ≤64 +
47
+ equal to the directory + no `anthropic`/`claude` + no angle brackets;
48
+ `description` ≤1024, starts "Use when…", third person, English AND Russian
49
+ triggers, says what it does and when; no front-matter key outside spec ∪ host
50
+ extensions; body <500 lines and <5000 tokens; every `references/`,
51
+ `scripts/`, `assets/` file one level deep, linked from the body with a stated
52
+ load trigger, and a `## Contents` list past 100 lines. A skill can pass every
53
+ house rule and still be invalid upstream.
54
+ 2. **Anthropic floor** if it ships as a plugin
55
+ (`references/claude-code-plugin.md`): `claude plugin validate <plugin dir>
56
+ --strict` and `claude plugin validate . --strict` both exit 0; `$schema` and
57
+ `displayName` in the manifest and in the marketplace entry; components at the
58
+ plugin root, never inside `.claude-plugin/`; `claude plugin details <name>`
59
+ token cost worth paying every session.
60
+ 3. **Surface honesty** (`references/surfaces.md`): every runtime need — network,
61
+ packages, MCP server — declared in `compatibility`; no script assuming an
62
+ install the target surface forbids. A `pip install` in a workflow step is a
63
+ Claude Code skill claiming to be portable.
64
+ 4. **One job.** Two concerns → two skills plus a shared contract, and the
65
+ contract lives INSIDE each skill directory. Verify by installing through the
66
+ skills CLI and listing what actually arrived, not by reading the repo.
67
+ 5. **Entry point** exists and is idempotent: inspect state → repair what is
68
+ missing → status report → exactly ONE suggested next action, detected rather
69
+ than asked. Check the invocation for the channel it ships on (`/<skill>` from
70
+ a skills dir, `/<plugin>:<skill>` as a plugin).
71
+ 6. **Layout and manifests**: matches the tree in `references/distribution.md`;
72
+ version sync ×4 (×5 when `SKILL.md` carries `metadata.version`).
73
+ 7. **Validator**: present, green, and able to fail — run the negative test. CI
74
+ present, last run `success`, with `claude plugin validate --strict` as its own
75
+ job so an upstream outage cannot mask a house failure.
76
+ 8. **Evaluations** exist in `test/evals/` (`references/authoring.md`): ≥3
77
+ behavioral scenarios, a trigger set whose negatives are near-misses, both
78
+ classes on both sides of the train/validation split, coexistence checked
79
+ against the skills already installed, and a re-run on every model the skill
80
+ claims support for.
81
+ 9. **README**: badges (npm/CI/license), install + update matrix, English-first
82
+ prose, and the bundled `references/` listed so a reader sees what ships.
83
+ 10. **Distribution live-checks** (`references/distribution.md`): `npx --yes
84
+ skills add <repo> --list` lists ONLY real skills; `npx <name>` works from a
85
+ non-repo cwd if it is published; `.mdc` rules valid and free of relative
86
+ links.
87
+ 11. **Repo meta**: homepage, description and topics set on the forge; LICENSE
88
+ present and declared in the front matter and the marketplace entry;
89
+ CHANGELOG current; public repos also carry CONTRIBUTING.md and SECURITY.md.
90
+ 12. **Gotcha compliance**: the list in `SKILL.md`, plus the installer traps in
91
+ `references/distribution.md` when the repo ships a CLI or a validator.
92
+ 13. **Protocol dependencies** if it touches MCP or A2A (`references/mcp.md`,
93
+ `references/a2a.md`): dependency and protocol version in `compatibility`,
94
+ discovery instead of hardcoded tool names, the untrusted-output rule stated,
95
+ interactive auth handled as a human step rather than a retry loop.
96
+ 14. **Host capabilities and their fallbacks**
97
+ (`references/host-capabilities.md`) if it ships a hook, subagent, command or
98
+ MCP server: the degradation contract written in the body for all three axes
99
+ (not Claude Code / recommended plugin absent / tool absent); hooks that
100
+ exit 0 silently when the event is not theirs; `PostToolUse` advising rather
101
+ than blocking; commands quoted and never named after a skill; plugin agents
102
+ free of `hooks`, `mcpServers` and `permissionMode`.
103
+
104
+ ## Personal skills — the short form
105
+
106
+ A skill in `~/.claude/skills/<name>/` has no repo, no manifests, no CI and no
107
+ distribution, so items 1, 4 and 5 are the whole audit. Do not invent a release
108
+ process for a file that loads next session.
109
+
110
+ ## After the audit
111
+
112
+ Report the gap table, fix everything fixable now, bump a minor or patch version,
113
+ and run the release checklist in `references/distribution.md`. A retrofit that
114
+ ends in a list of things someone should do later is a report, not a retrofit.