@ssheleg/make-skill 0.6.6 → 0.7.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.
- package/CHANGELOG.md +69 -0
- package/README.md +17 -5
- package/bin/make-skill.js +8 -17
- package/cursor/rules/make-skill.mdc +41 -4
- package/package.json +2 -2
- package/plugins/make-skill/.claude-plugin/plugin.json +3 -2
- package/plugins/make-skill/skills/make-skill/SKILL.md +182 -223
- package/plugins/make-skill/skills/make-skill/references/claude-code-plugin.md +280 -0
- package/plugins/make-skill/skills/make-skill/references/distribution.md +52 -0
- package/templates/README.md +10 -0
- package/templates/SKILL.template.md +6 -0
- package/templates/marketplace.template.json +27 -0
- package/templates/plugin.template.json +16 -0
- package/plugins/make-skill/commands/make-skill.md +0 -19
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
# Claude Code plugin reference — the Anthropic layer
|
|
2
|
+
|
|
3
|
+
**Load this when:** building, retrofitting, or auditing anything that ships as a
|
|
4
|
+
**Claude Code plugin or marketplace** — writing `plugin.json` / `marketplace.json`,
|
|
5
|
+
adding agents / hooks / MCP / LSP / monitors to a plugin, or resolving a
|
|
6
|
+
`claude plugin validate` failure.
|
|
7
|
+
|
|
8
|
+
Upstream (read against these, not from memory — the schema grows every release):
|
|
9
|
+
- Plugins reference — <https://code.claude.com/docs/en/plugins-reference>
|
|
10
|
+
- Marketplaces — <https://code.claude.com/docs/en/plugin-marketplaces>
|
|
11
|
+
- Skills — <https://code.claude.com/docs/en/skills>
|
|
12
|
+
|
|
13
|
+
*Read from the docs on 2026-07-30 against Claude Code 2.1.212. Re-read before
|
|
14
|
+
trusting a version-gated field in a new quarter.*
|
|
15
|
+
|
|
16
|
+
The [Agent Skills spec](https://agentskills.io/specification) (see
|
|
17
|
+
`references/agent-skills-spec.md`) is the portable floor. **This file is the
|
|
18
|
+
host layer on top of it**: everything here is Claude-Code-specific and is
|
|
19
|
+
ignored by other agents — so nothing here may be load-bearing for a skill that
|
|
20
|
+
must also run on Cursor, Codex, or the skills CLI.
|
|
21
|
+
|
|
22
|
+
## The gate: `claude plugin validate`
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
claude plugin validate ./plugins/<name> --strict # the plugin manifest
|
|
26
|
+
claude plugin validate . --strict # the marketplace manifest
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Both must exit 0. Rules that decide the outcome:
|
|
30
|
+
|
|
31
|
+
- Unrecognized top-level fields are **warnings**, not errors — the plugin still
|
|
32
|
+
loads. `--strict` turns them into failures, which is what you want in CI:
|
|
33
|
+
a field from another ecosystem, or one typo'd by two characters, is caught
|
|
34
|
+
before publish.
|
|
35
|
+
- Wrong **types** always fail (`keywords` as a string, not an array).
|
|
36
|
+
- It runs offline and needs no auth, so it belongs in CI:
|
|
37
|
+
`npm i -g @anthropic-ai/claude-code && claude plugin validate … --strict`.
|
|
38
|
+
|
|
39
|
+
## `plugin.json` — `.claude-plugin/plugin.json`
|
|
40
|
+
|
|
41
|
+
The manifest is optional (components auto-discover, name falls back to the
|
|
42
|
+
directory). Ship one anyway: without it there is no version, no metadata, and
|
|
43
|
+
nothing to validate. **`name` is the only required field.**
|
|
44
|
+
|
|
45
|
+
| Field | Type | Notes |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| `$schema` | string | `https://json.schemastore.org/claude-code-plugin-manifest.json` — editor autocomplete; ignored at load |
|
|
48
|
+
| `name` | string | **required**, kebab-case, no spaces; namespaces every component (`plugin-dev:agent-creator`). A marketplace entry listing it under another name wins for `enabledPlugins` and `/plugin` |
|
|
49
|
+
| `displayName` | string | UI label, may contain spaces/case; never used for lookup (CC ≥ 2.1.143) |
|
|
50
|
+
| `version` | string | semver. **Set it and you must bump it** — CC uses the version as the cache key, so new commits under an unchanged version never reach users. Omit it entirely and the git SHA is the version (every commit ships) |
|
|
51
|
+
| `description`, `author{name,email,url}`, `homepage`, `repository`, `license`, `keywords[]` | | metadata |
|
|
52
|
+
| `defaultEnabled` | boolean | `false` = installs disabled until the user opts in (CC ≥ 2.1.154). The marketplace entry's copy wins over this one; an existing `enabledPlugins` entry wins over both |
|
|
53
|
+
| `skills` | string\|array | extra skill dirs — **adds to** the default `skills/` scan |
|
|
54
|
+
| `commands`, `agents`, `workflows`, `outputStyles` | string\|array | **replace** the default folder. To keep it, list it: `["./commands/", "./extras/"]` |
|
|
55
|
+
| `hooks`, `mcpServers`, `lspServers` | string\|array\|object | path(s) or inline config; own merge rules |
|
|
56
|
+
| `experimental.themes`, `experimental.monitors` | string\|array | still moving; top level warns today, will be required under `experimental` |
|
|
57
|
+
| `userConfig` | object | values prompted at enable time — `type` (`string`/`number`/`boolean`/`directory`/`file`), `title`, `description` required; `sensitive`, `required`, `default`, `multiple`, `min`/`max` optional |
|
|
58
|
+
| `channels` | array | message channels; each `server` must match a key in `mcpServers` |
|
|
59
|
+
| `dependencies` | array | `["helper-lib", {"name":"secrets-vault","version":"~2.1.0"}]` |
|
|
60
|
+
|
|
61
|
+
All component paths are **relative to the plugin root and start with `./`**.
|
|
62
|
+
|
|
63
|
+
`${user_config.KEY}` substitutes in MCP/LSP configs and hook commands, and in
|
|
64
|
+
skill/agent content for non-sensitive values — but **not** in shell-form hook
|
|
65
|
+
commands, monitor commands, or MCP `headersHelper` (a shell would execute
|
|
66
|
+
whatever the value contains); those read `CLAUDE_PLUGIN_OPTION_<KEY>` from the
|
|
67
|
+
environment instead. Sensitive values go to the OS keychain (~2 KB shared
|
|
68
|
+
budget), never to `settings.json`.
|
|
69
|
+
|
|
70
|
+
## `marketplace.json` — `.claude-plugin/marketplace.json`
|
|
71
|
+
|
|
72
|
+
| Field | Required | Notes |
|
|
73
|
+
|---|---|---|
|
|
74
|
+
| `name` | yes | kebab-case, public (`/plugin install x@<name>`). One marketplace per name per user — a second add **replaces** the first |
|
|
75
|
+
| `owner` | yes | `{name}` required, `email`/`url` optional |
|
|
76
|
+
| `plugins[]` | yes | entries, below |
|
|
77
|
+
| `$schema` | no | `https://json.schemastore.org/claude-code-marketplace.json` |
|
|
78
|
+
| `description`, `version` | no | also accepted under `metadata` for backward compatibility |
|
|
79
|
+
| `metadata.pluginRoot` | no | prefix for relative sources (`"./plugins"` → `"source": "formatter"`) |
|
|
80
|
+
| `allowCrossMarketplaceDependenciesOn` | no | marketplaces this one's plugins may depend on; anything else is blocked at install |
|
|
81
|
+
| `renames` | no | old plugin name → new name, or `null` if removed; migrates existing users (CC ≥ 2.1.193) |
|
|
82
|
+
|
|
83
|
+
**There is no top-level `homepage`, `repository`, or `license`.** Those are
|
|
84
|
+
plugin-entry fields; at marketplace level they are unrecognized and `--strict`
|
|
85
|
+
fails on them. Put the project URL in `owner.url`.
|
|
86
|
+
|
|
87
|
+
**Reserved marketplace names** (third-party use blocked, re-checked on every
|
|
88
|
+
load, so a name can become reserved under a live marketplace):
|
|
89
|
+
`claude-code-marketplace`, `claude-code-plugins`, `claude-plugins-official`,
|
|
90
|
+
`claude-plugins-community`, `claude-community`, `anthropic-marketplace`,
|
|
91
|
+
`anthropic-plugins`, `agent-skills`, `anthropic-agent-skills`,
|
|
92
|
+
`knowledge-work-plugins`, `life-sciences`, `claude-for-legal`,
|
|
93
|
+
`claude-for-financial-services`, `financial-services-plugins`,
|
|
94
|
+
`first-party-plugins`, `healthcare` — plus anything that impersonates them
|
|
95
|
+
(`official-claude-plugins`, `anthropic-plugins-v2`).
|
|
96
|
+
|
|
97
|
+
### Plugin entries
|
|
98
|
+
|
|
99
|
+
Required: `name` and `source`. Any plugin-manifest field is allowed, plus the
|
|
100
|
+
marketplace-only `source`, `category`, `tags`, `strict`, `relevance`,
|
|
101
|
+
`defaultEnabled`.
|
|
102
|
+
|
|
103
|
+
| Source | Shape |
|
|
104
|
+
|---|---|
|
|
105
|
+
| relative path | `"./plugins/my-plugin"` — must start with `./`, resolved from the marketplace **root**, not `.claude-plugin/` |
|
|
106
|
+
| `github` | `{"source":"github","repo":"owner/repo","ref?":"main","sha?":"…"}` |
|
|
107
|
+
| `url` | `{"source":"url","url":"https://….git","ref?":…,"sha?":…}` |
|
|
108
|
+
| `git-subdir` | `{"source":"git-subdir","url":"…","path":"packages/x","ref?":…,"sha?":…}` — sparse clone |
|
|
109
|
+
| `npm` | `{"source":"npm","package":"@scope/pkg","version?":…,"registry?":…}` — version resolves to `unknown`, so no update detection |
|
|
110
|
+
|
|
111
|
+
`sha` beats `ref` when both are set. **Marketplace source ≠ plugin source**: the
|
|
112
|
+
first says where `marketplace.json` lives (supports `ref` only), the second where
|
|
113
|
+
each plugin comes from (`ref` and `sha`).
|
|
114
|
+
|
|
115
|
+
`strict` (default `true`): `plugin.json` is the authority and the entry may add
|
|
116
|
+
to it. `strict: false` makes the entry the entire definition — and a
|
|
117
|
+
`plugin.json` that also declares components is then a load error.
|
|
118
|
+
|
|
119
|
+
Version resolution order: `plugin.json` → marketplace entry → git SHA →
|
|
120
|
+
`unknown`.
|
|
121
|
+
|
|
122
|
+
## Component locations
|
|
123
|
+
|
|
124
|
+
| Component | Default location |
|
|
125
|
+
|---|---|
|
|
126
|
+
| manifest | `.claude-plugin/plugin.json` |
|
|
127
|
+
| skills | `skills/<name>/SKILL.md` |
|
|
128
|
+
| commands | `commands/*.md` (flat skills; prefer `skills/` for new plugins) |
|
|
129
|
+
| agents | `agents/*.md` |
|
|
130
|
+
| workflows | `workflows/*.js` |
|
|
131
|
+
| output styles | `output-styles/*.md` |
|
|
132
|
+
| hooks | `hooks/hooks.json` |
|
|
133
|
+
| MCP | `.mcp.json` |
|
|
134
|
+
| LSP | `.lsp.json` |
|
|
135
|
+
| monitors | `monitors/monitors.json` |
|
|
136
|
+
| executables | `bin/` — on the Bash tool's PATH while enabled |
|
|
137
|
+
| defaults | `settings.json` (only `agent` and `subagentStatusLine` keys) |
|
|
138
|
+
|
|
139
|
+
**Only `plugin.json` goes inside `.claude-plugin/`.** Every component directory
|
|
140
|
+
sits at the plugin root; components buried in `.claude-plugin/` load as nothing
|
|
141
|
+
and the plugin still "works", which is why this one costs an afternoon.
|
|
142
|
+
|
|
143
|
+
A plugin-root `CLAUDE.md` is **not** loaded as context. Ship instructions as a
|
|
144
|
+
skill.
|
|
145
|
+
|
|
146
|
+
A plugin root `SKILL.md` with no `skills/` dir and no `skills` field loads as a
|
|
147
|
+
single-skill plugin (CC ≥ 2.1.142) — set frontmatter `name`, or the invocation
|
|
148
|
+
name becomes the install directory, which for marketplace installs is a version
|
|
149
|
+
string that changes on every update.
|
|
150
|
+
|
|
151
|
+
## Skill frontmatter — host extensions
|
|
152
|
+
|
|
153
|
+
Portable floor (`name`, `description`, `license`, `compatibility`, `metadata`,
|
|
154
|
+
`allowed-tools`) is in `references/agent-skills-spec.md`. Claude Code also reads:
|
|
155
|
+
|
|
156
|
+
| Field | Effect |
|
|
157
|
+
|---|---|
|
|
158
|
+
| `when_to_use` | extra trigger text appended to `description` in the listing |
|
|
159
|
+
| `argument-hint`, `arguments` | autocomplete hint; named `$name` substitutions |
|
|
160
|
+
| `disable-model-invocation` | `true` = only the user can fire it (`/name`) |
|
|
161
|
+
| `user-invocable` | `false` = hidden from the `/` menu |
|
|
162
|
+
| `disallowed-tools` | tools removed while the skill is active |
|
|
163
|
+
| `model`, `effort` | override for the turn that invoked the skill |
|
|
164
|
+
| `context: fork`, `agent`, `background` | run the skill in a subagent |
|
|
165
|
+
| `hooks` | hooks scoped to this skill's lifecycle |
|
|
166
|
+
| `paths` | globs that gate automatic activation |
|
|
167
|
+
| `shell` | `bash` (default) or `powershell` for inline `` !`cmd` `` |
|
|
168
|
+
|
|
169
|
+
Booleans accept `yes/no/on/off/1/0` in any case as of CC 2.1.218 — earlier
|
|
170
|
+
versions read only `true`/`false`, so write `true`/`false`.
|
|
171
|
+
|
|
172
|
+
Listing budget: `description` + `when_to_use` is truncated at **1,536 chars** in
|
|
173
|
+
the skill listing; the spec's own `description` cap of 1024 is the tighter rule
|
|
174
|
+
and stays the one to hold.
|
|
175
|
+
|
|
176
|
+
Command name: a plugin skill is `/<plugin>:<skill-dir>`, and frontmatter `name`
|
|
177
|
+
replaces the last segment (`name: fancy` → `/my-plugin:fancy`). Personal and
|
|
178
|
+
project skills take the command name from the directory; `name` is only a label
|
|
179
|
+
there.
|
|
180
|
+
|
|
181
|
+
## Agents, hooks, MCP inside a plugin
|
|
182
|
+
|
|
183
|
+
- **Agents** (`agents/*.md`) support `name`, `description`, `model`, `effort`,
|
|
184
|
+
`maxTurns`, `tools`, `disallowedTools`, `skills`, `memory`, `background`,
|
|
185
|
+
`isolation` (only value: `"worktree"`). `hooks`, `mcpServers`, and
|
|
186
|
+
`permissionMode` are **rejected** for plugin-shipped agents. They appear as
|
|
187
|
+
`<plugin>:<agent>`.
|
|
188
|
+
- **Hooks** use the standard event set (`SessionStart`, `PreToolUse`,
|
|
189
|
+
`PostToolUse`, `UserPromptSubmit`, `Stop`, `SessionEnd`, …) and types
|
|
190
|
+
`command`, `http`, `mcp_tool`, `prompt`, `agent`. Event names are
|
|
191
|
+
case-sensitive; scripts need `chmod +x` and a shebang.
|
|
192
|
+
- A hook targeting the plugin's **own** MCP server must use scoped names:
|
|
193
|
+
matcher/`if` take `mcp__plugin_<plugin>_<server>__<tool>`, and an `mcp_tool`
|
|
194
|
+
hook's `server` takes `plugin:<plugin>:<server>`. A matcher on the bare server
|
|
195
|
+
key never fires.
|
|
196
|
+
|
|
197
|
+
## Path variables
|
|
198
|
+
|
|
199
|
+
| Variable | Resolves to |
|
|
200
|
+
|---|---|
|
|
201
|
+
| `${CLAUDE_PLUGIN_ROOT}` | the plugin's install directory — **changes on every update**, never store state there |
|
|
202
|
+
| `${CLAUDE_PLUGIN_DATA}` | `~/.claude/plugins/data/<id>/`, survives updates; for `node_modules`, venvs, caches |
|
|
203
|
+
| `${CLAUDE_PROJECT_DIR}` | project root |
|
|
204
|
+
| `${CLAUDE_SKILL_DIR}` | the skill's own directory (skill content and `allowed-tools` Bash rules) |
|
|
205
|
+
|
|
206
|
+
They substitute in skill/agent content, hook and monitor commands, MCP
|
|
207
|
+
`command`/`args`/`env` (or `url`/`headers`/`headersHelper`), and LSP
|
|
208
|
+
`command`/`args`/`env`/`workspaceFolder`. In shell-form commands, quote them:
|
|
209
|
+
`"${CLAUDE_PLUGIN_ROOT}"/scripts/x.sh`.
|
|
210
|
+
|
|
211
|
+
**Portability:** all four are Claude Code inventions. A skill that must also run
|
|
212
|
+
on other agents references bundled files by **relative path** and treats the
|
|
213
|
+
variables as an optimization, not the contract.
|
|
214
|
+
|
|
215
|
+
## Caching, symlinks, path traversal
|
|
216
|
+
|
|
217
|
+
Marketplace plugins are copied into `~/.claude/plugins/cache` per version;
|
|
218
|
+
orphaned versions are cleaned up ~14 days later. Consequences:
|
|
219
|
+
|
|
220
|
+
- `../shared-utils` — anything outside the plugin root — **does not exist after
|
|
221
|
+
install**. It was never copied.
|
|
222
|
+
- Symlinks inside the plugin dir are preserved; symlinks to elsewhere in the
|
|
223
|
+
same marketplace are **dereferenced** (content copied); symlinks outside the
|
|
224
|
+
marketplace are skipped. This is why a meta-plugin can link sibling skills —
|
|
225
|
+
and why the same trick still breaks on non-Claude agents, which install only
|
|
226
|
+
the skill folder.
|
|
227
|
+
|
|
228
|
+
## Skills-directory plugins
|
|
229
|
+
|
|
230
|
+
A folder under a skills directory with `.claude-plugin/plugin.json` loads next
|
|
231
|
+
session as `<name>@skills-dir` — no marketplace, no install, discovered in
|
|
232
|
+
place. Scaffold with `claude plugin init <name> [--with skills agents hooks mcp
|
|
233
|
+
lsp output-style channel]`.
|
|
234
|
+
|
|
235
|
+
`~/.claude/skills/` → personal, every project. `<cwd>/.claude/skills/` →
|
|
236
|
+
project-scope, loads only after the workspace trust dialog, MCP servers still
|
|
237
|
+
need per-server approval, monitors don't load at all. Project-scope
|
|
238
|
+
`@skills-dir` plugins do **not** walk up to the repo root — launch Claude from
|
|
239
|
+
the repository root or run `/reload-plugins`.
|
|
240
|
+
|
|
241
|
+
`SKILL.md` edits apply live; `hooks/`, `.mcp.json`, `agents/`, `output-styles/`
|
|
242
|
+
need `/reload-plugins`. Disable with `claude plugin disable <name>@skills-dir`.
|
|
243
|
+
|
|
244
|
+
## CLI
|
|
245
|
+
|
|
246
|
+
| Command | Use |
|
|
247
|
+
|---|---|
|
|
248
|
+
| `claude plugin validate <path> [--strict]` | the conformance gate, offline |
|
|
249
|
+
| `claude plugin init <name> [--with …]` | scaffold a `@skills-dir` plugin |
|
|
250
|
+
| `claude plugin install <name>@<marketplace> [-s user\|project\|local] [--config k=v]` | install |
|
|
251
|
+
| `claude plugin update <name>@<marketplace>` | update — the **full `name@marketplace` form is mandatory** |
|
|
252
|
+
| `claude plugin enable\|disable <name>@<marketplace>` | toggle without uninstalling |
|
|
253
|
+
| `claude plugin uninstall <name>@<marketplace> [--keep-data] [--prune]` | remove (deletes the data dir unless `--keep-data`) |
|
|
254
|
+
| `claude plugin list [--json]` | installed plugins, versions, source, state |
|
|
255
|
+
| `claude plugin details <name>` | component inventory + **always-on vs on-invoke token cost** — run it before claiming a plugin is cheap |
|
|
256
|
+
| `claude plugin tag [path] [--push]` | cut the release tag for dependency resolution |
|
|
257
|
+
| `claude plugin marketplace add\|update\|remove\|list <repo>` | manage catalogues |
|
|
258
|
+
|
|
259
|
+
`claude --debug` prints plugin loading, manifest errors, and component
|
|
260
|
+
registration — the first stop when a component silently doesn't appear.
|
|
261
|
+
|
|
262
|
+
## Conformance checklist
|
|
263
|
+
|
|
264
|
+
- [ ] `claude plugin validate ./plugins/<name> --strict` → exit 0
|
|
265
|
+
- [ ] `claude plugin validate . --strict` → exit 0 (marketplace)
|
|
266
|
+
- [ ] `$schema` set in both manifests
|
|
267
|
+
- [ ] `name` kebab-case and identical in `plugin.json`, the marketplace entry,
|
|
268
|
+
and the plugin directory
|
|
269
|
+
- [ ] `version` present and bumped this release (or deliberately absent for
|
|
270
|
+
SHA-based iteration)
|
|
271
|
+
- [ ] marketplace `name` not on the reserved list
|
|
272
|
+
- [ ] every component path relative and starting with `./`
|
|
273
|
+
- [ ] only `plugin.json` inside `.claude-plugin/`; `skills/`, `commands/`,
|
|
274
|
+
`agents/`, `hooks/` at the plugin root
|
|
275
|
+
- [ ] no path escapes the plugin root (`../`), no symlink leaves the marketplace
|
|
276
|
+
- [ ] scripts referenced through `${CLAUDE_PLUGIN_ROOT}`, state through
|
|
277
|
+
`${CLAUDE_PLUGIN_DATA}`, and both treated as Claude-only conveniences
|
|
278
|
+
- [ ] plugin agents free of `hooks` / `mcpServers` / `permissionMode`
|
|
279
|
+
- [ ] `claude plugin details <name>` token cost is one you would pay in every
|
|
280
|
+
session
|
|
@@ -102,6 +102,58 @@ package's own repo, `npx` resolves the local package and reports a false
|
|
|
102
102
|
- **`npx` inside the package's own repo** resolves the local package → a false
|
|
103
103
|
`command not found`. Always e2e-test from another cwd.
|
|
104
104
|
|
|
105
|
+
### Installer implementation traps (read while WRITING the CLI)
|
|
106
|
+
|
|
107
|
+
- **Piped stdin + readline:** sequential `rl.question()` drops buffered lines.
|
|
108
|
+
Use ONE persistent-listener prompter for the whole flow (super-ux
|
|
109
|
+
`makePrompter`), with a non-TTY fallback for every prompt (`1,3` / `all` / `q`).
|
|
110
|
+
- **Interactive pickers:** raw-mode multiselect only when
|
|
111
|
+
`stdin.isTTY && stdout.isTTY`; restore `setRawMode(false)` on every exit path.
|
|
112
|
+
Delegate agent-matrix pickers to `npx skills add` instead of rebuilding one.
|
|
113
|
+
- **ANSI escapes:** write `\x1b[…` literals in source, never raw ESC bytes — an
|
|
114
|
+
editor or a copy-paste eats the invisible one.
|
|
115
|
+
- **Python drift:** system `python3` may be 3.9, so a validator using `str |
|
|
116
|
+
None` annotations needs `from __future__ import annotations`. CI's `3.x` is
|
|
117
|
+
newer and won't catch it; the user's local run will.
|
|
118
|
+
|
|
119
|
+
## First publish — the 11-step sequence
|
|
120
|
+
|
|
121
|
+
Run it end-to-end in one session. The only human step is npm 2FA, and step 9
|
|
122
|
+
removes even that for every release after this one.
|
|
123
|
+
|
|
124
|
+
1. **Preflight before code:** `npm view <name>` (E404 = free — but read the
|
|
125
|
+
name-similarity trap above); `gh auth status` (may lie — try the operation
|
|
126
|
+
anyway); `npm whoami` (401 → plan the 2FA human step, keep building).
|
|
127
|
+
2. Build per the SKILL.md layout; `git init -b main`; conventional commits; set
|
|
128
|
+
the local git identity if `git config user.email` is empty.
|
|
129
|
+
3. House validator + functional tests + BOTH `claude plugin validate … --strict`
|
|
130
|
+
runs green BEFORE publishing.
|
|
131
|
+
4. **GitHub:** `gh repo create <owner>/<name> --public --source . --push`, then
|
|
132
|
+
`gh repo edit <owner>/<name> --homepage "https://www.npmjs.com/package/<name>"`.
|
|
133
|
+
5. **Badges day one:** npm (shields.io), CI
|
|
134
|
+
(`actions/workflows/validate.yml/badge.svg`), license.
|
|
135
|
+
6. **CI:** poll `gh run list --repo <owner>/<name> --limit 1` until
|
|
136
|
+
`completed success`. Red = fix now, not later.
|
|
137
|
+
7. **npm:** `npm publish --dry-run` (eye the tarball) → `npm publish`. On
|
|
138
|
+
EOTP/2FA hand the user exactly one command (`cd <repo> && npm publish`), wait,
|
|
139
|
+
then verify `npm view <name> version` and e2e `npx <name>@<ver> --help`
|
|
140
|
+
**from a non-repo cwd**.
|
|
141
|
+
8. **Install for the user:** `claude plugin marketplace add <owner>/<name>` +
|
|
142
|
+
`claude plugin install <name>@<name>`; verify
|
|
143
|
+
`npx --yes skills add <owner>/<name> --list` finds the skills.
|
|
144
|
+
9. **Arm CI publishing so this is the last manual publish.** Ship the release
|
|
145
|
+
workflow, then hand over two commands — `gh secret set NPM_TOKEN --repo
|
|
146
|
+
<owner>/<name>` (a GRANULAR AUTOMATION token; the user pastes it, never you)
|
|
147
|
+
and `gh variable set PUBLISH_NPMJS --body true --repo <owner>/<name>`. Secret
|
|
148
|
+
first: arming the variable with no token queues a red run on the next tag.
|
|
149
|
+
10. **Done = five verified facts:** repo + CI green; npm resolvable via npx;
|
|
150
|
+
plugin installed; skills-CLI discovery works; the next tag publishes without
|
|
151
|
+
a human.
|
|
152
|
+
11. **If it belongs to a family** (`sshlg-skills`): bump its `version` pin in the
|
|
153
|
+
umbrella's `skills.json`, release the umbrella, verify with
|
|
154
|
+
`npx --yes sshlg-skills@latest list` — until that lands, the launcher
|
|
155
|
+
advertises the OLD version and `update` installs it (§5 below).
|
|
156
|
+
|
|
105
157
|
## 4. Cursor
|
|
106
158
|
|
|
107
159
|
Two routes, no overlap:
|
package/templates/README.md
CHANGED
|
@@ -6,6 +6,16 @@ is absent; never overwrite existing files.
|
|
|
6
6
|
| Template | Seeds | Used by |
|
|
7
7
|
|---|---|---|
|
|
8
8
|
| `SKILL.template.md` | a new `skills/<name>/SKILL.md` — spec-legal front-matter (required + optional fields, limits stated inline) and section stubs incl. References and Gotchas | Create / Promote |
|
|
9
|
+
| `plugin.template.json` | `plugins/<name>/.claude-plugin/plugin.json` | Create (distributable) / Promote |
|
|
10
|
+
| `marketplace.template.json` | `.claude-plugin/marketplace.json` at the repo root | Create (distributable) / Promote |
|
|
11
|
+
|
|
12
|
+
The two JSON skeletons carry only fields Claude Code recognizes, so
|
|
13
|
+
`claude plugin validate <path> --strict` passes on the seeded repo. Replace every
|
|
14
|
+
`<placeholder>`, keep the `$schema` lines (editor autocomplete), and keep all
|
|
15
|
+
four versions in sync. Marketplace level takes `name`, `owner`, `plugins`,
|
|
16
|
+
`$schema`, `description`, `version`, `metadata`,
|
|
17
|
+
`allowCrossMarketplaceDependenciesOn`, `renames` and nothing else —
|
|
18
|
+
`homepage`/`repository`/`license` belong to the plugin entry.
|
|
9
19
|
|
|
10
20
|
**Never name a skeleton `SKILL.md`.** The skills CLI discovers every `SKILL.md` in
|
|
11
21
|
a repo tree and installs it as a real skill — a placeholder would land in every
|
|
@@ -8,6 +8,12 @@ description: Use when <concrete triggering conditions and symptoms>. Add trigger
|
|
|
8
8
|
# author: <you>
|
|
9
9
|
# version: "0.1.0" # quote it, or YAML makes it a float
|
|
10
10
|
# allowed-tools: Bash(git:*) Read # space-separated string, experimental
|
|
11
|
+
#
|
|
12
|
+
# Claude Code host extensions — legal here, IGNORED by every other agent, so
|
|
13
|
+
# never let portable behavior depend on one:
|
|
14
|
+
# when_to_use / argument-hint / arguments / disable-model-invocation /
|
|
15
|
+
# user-invocable / disallowed-tools / model / effort / context: fork / agent /
|
|
16
|
+
# background / hooks / paths / shell
|
|
11
17
|
---
|
|
12
18
|
|
|
13
19
|
# <Skill Name>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/claude-code-marketplace.json",
|
|
3
|
+
"name": "<marketplace-name>",
|
|
4
|
+
"owner": {
|
|
5
|
+
"name": "<you>",
|
|
6
|
+
"url": "https://github.com/<owner>/<repo>"
|
|
7
|
+
},
|
|
8
|
+
"description": "<what this catalogue distributes>",
|
|
9
|
+
"plugins": [
|
|
10
|
+
{
|
|
11
|
+
"name": "<plugin-name>",
|
|
12
|
+
"source": "./plugins/<plugin-name>",
|
|
13
|
+
"description": "<what the plugin gives an agent>",
|
|
14
|
+
"version": "0.1.0",
|
|
15
|
+
"author": {
|
|
16
|
+
"name": "<you>"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/<owner>/<repo>",
|
|
19
|
+
"repository": "https://github.com/<owner>/<repo>",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"keywords": [
|
|
22
|
+
"<topic>"
|
|
23
|
+
],
|
|
24
|
+
"category": "development"
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
|
3
|
+
"name": "<plugin-name>",
|
|
4
|
+
"description": "<what the plugin gives an agent, in one sentence>",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "<you>"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/<owner>/<repo>",
|
|
10
|
+
"repository": "https://github.com/<owner>/<repo>",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"keywords": [
|
|
13
|
+
"<topic>",
|
|
14
|
+
"claude-code"
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Create, retrofit, audit, or publish an agent skill / Claude Code plugin the proven ssheleg way — Agent Skills spec conformance, marketplace layout, version sync, validator + CI, multi-channel distribution, MCP / A2A rules.
|
|
3
|
-
argument-hint: "<what to build/retrofit/audit, or a skill path>"
|
|
4
|
-
---
|
|
5
|
-
Use the `make-skill` skill for the task below. First **detect the workflow** from
|
|
6
|
-
the task and any path in `$ARGUMENTS`, announce it, then follow the skill exactly:
|
|
7
|
-
|
|
8
|
-
- new skill only for this user's agents → **Create (personal)**
|
|
9
|
-
- new skill others install → **Create (distributable)** → First publish end-to-end
|
|
10
|
-
- existing skill/repo below the standard, or "does this match the spec?" →
|
|
11
|
-
**Retrofit** (audit → fix → release)
|
|
12
|
-
- a personal skill that should become installable → **Promote**
|
|
13
|
-
|
|
14
|
-
Task: $ARGUMENTS
|
|
15
|
-
|
|
16
|
-
If `$ARGUMENTS` is empty, **detect instead of asking**: inspect the current
|
|
17
|
-
directory — a `SKILL.md`, `.claude-plugin/`, or `plugins/*/skills/*/` present →
|
|
18
|
-
run the Retrofit audit and report the gap table plus exactly ONE next action.
|
|
19
|
-
Only when there is nothing to detect, ask in one line what to create.
|