@celsoft/coordinator 0.0.0 → 0.1.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 +11 -0
- package/README.md +107 -0
- package/THIRD_PARTY_NOTICES.md +2005 -0
- package/agents/console.md +20 -0
- package/agents/free.md +110 -0
- package/build/0-JP6XL6LB.js +17 -0
- package/build/1-A52YZWNS.js +17 -0
- package/build/2-CLH2NM6F.js +32 -0
- package/build/3-4N467IB6.js +45 -0
- package/build/4-WL5H4LUW.js +29 -0
- package/build/_layout.svelte-KPUSX7LQ.js +27 -0
- package/build/_page.svelte-22H56UR6.js +7972 -0
- package/build/_page.svelte-CVWUNRQC.js +135 -0
- package/build/_page.svelte-LTZXBHMT.js +57 -0
- package/build/_server.ts-3KVBYN6P.js +20 -0
- package/build/_server.ts-3POPKVEM.js +47 -0
- package/build/_server.ts-5735T2V5.js +31 -0
- package/build/_server.ts-5VXGNWV2.js +38 -0
- package/build/_server.ts-645KP7WP.js +42 -0
- package/build/_server.ts-A3AA24Z2.js +28 -0
- package/build/_server.ts-CITUOEM6.js +58 -0
- package/build/_server.ts-I7HMTPOA.js +25 -0
- package/build/_server.ts-M5BQ4LLX.js +30 -0
- package/build/_server.ts-OB4O27HF.js +683 -0
- package/build/_server.ts-OJT7HE7M.js +15 -0
- package/build/_server.ts-OYGWVLZM.js +12 -0
- package/build/_server.ts-T75UVMQP.js +38 -0
- package/build/_server.ts-WYZYNHUZ.js +28 -0
- package/build/_server.ts-Z26EB47B.js +486 -0
- package/build/chunk-4CIG53L5.js +33 -0
- package/build/chunk-BJTJS3XY.js +338 -0
- package/build/chunk-F2CNWJZM.js +14 -0
- package/build/chunk-HGYE3UTU.js +416 -0
- package/build/chunk-KAYW2W7H.js +1311 -0
- package/build/chunk-LFP3UPCM.js +10 -0
- package/build/chunk-M44JEFEH.js +62 -0
- package/build/chunk-MC5AGLMY.js +39 -0
- package/build/chunk-NCZ77J5E.js +19798 -0
- package/build/chunk-NVNLDPUJ.js +2122 -0
- package/build/chunk-PDCON4KS.js +494 -0
- package/build/chunk-Q4OQNY5M.js +25 -0
- package/build/chunk-QCUOR2U5.js +75 -0
- package/build/chunk-R6RYZZWA.js +46 -0
- package/build/chunk-SOJTASZC.js +51 -0
- package/build/chunk-SU26PJVX.js +410 -0
- package/build/chunk-U5BSBG4R.js +506 -0
- package/build/chunk-UEKOZGRO.js +37 -0
- package/build/chunk-W6EFUWJ2.js +9 -0
- package/build/chunk-WOPREK6Q.js +117 -0
- package/build/chunk-WWJ3F4QS.js +127 -0
- package/build/chunk-ZGZJEEE3.js +1091 -0
- package/build/client/_app/immutable/assets/0.BGa5ZNDM.css +1 -0
- package/build/client/_app/immutable/chunks/BUrrLYDt.js +2 -0
- package/build/client/_app/immutable/chunks/BgFr_EyZ.js +4 -0
- package/build/client/_app/immutable/chunks/Bjy-W4x2.js +82 -0
- package/build/client/_app/immutable/chunks/C8qZab0y.js +56 -0
- package/build/client/_app/immutable/chunks/C90fLsA5.js +4 -0
- package/build/client/_app/immutable/chunks/CRzLMJPS.js +1 -0
- package/build/client/_app/immutable/chunks/DLT1iIlz.js +2 -0
- package/build/client/_app/immutable/chunks/pIrVVOVY.js +2 -0
- package/build/client/_app/immutable/entry/app.0DERehLW.js +3 -0
- package/build/client/_app/immutable/entry/payload.DSmR2FwN.js +2 -0
- package/build/client/_app/immutable/entry/start.B7srFiqh.js +3 -0
- package/build/client/_app/immutable/nodes/0.aD9vJoxR.js +2 -0
- package/build/client/_app/immutable/nodes/1.Br4FL91i.js +2 -0
- package/build/client/_app/immutable/nodes/2.vl6OYfu3.js +8 -0
- package/build/client/_app/immutable/nodes/3.VYqJOLAF.js +2 -0
- package/build/client/_app/immutable/nodes/4.jF9UVlFN.js +2 -0
- package/build/client/_app/version.json +1 -0
- package/build/client/apple-touch-icon.png +0 -0
- package/build/client/favicon.ico +0 -0
- package/build/client/favicon.svg +48 -0
- package/build/client/icon-192.png +0 -0
- package/build/client/icon-512.png +0 -0
- package/build/client/icon-maskable-512.png +0 -0
- package/build/client/icon.svg +44 -0
- package/build/client/manifest.webmanifest +15 -0
- package/build/error.svelte-JXZDY65F.js +51 -0
- package/build/handler.js +716 -0
- package/build/hooks.server-34IMHRKC.js +43 -0
- package/build/instance-NP3FJIWW.js +2967 -0
- package/client/client.mjs +28 -0
- package/client/hooks.mjs +7 -0
- package/client/register.mjs +5 -0
- package/dist/cli.js +62826 -0
- package/dist/port.js +36691 -0
- package/package.json +20 -1
- package/skills/agents/.claude-plugin/plugin.json +5 -0
- package/skills/agents/hooks/hooks.json +1 -0
- package/skills/agents/hooks/register.ts +57 -0
- package/skills/agents/skills/bus-work/SKILL.md +66 -0
- package/skills/agents/skills/plan/SKILL.md +98 -0
- package/skills/console/.claude-plugin/plugin.json +5 -0
- package/skills/console/hooks/hooks.json +1 -0
- package/skills/console/hooks/register.ts +10 -0
- package/skills/console/skills/bus/SKILL.md +61 -0
- package/skills/default/.claude-plugin/plugin.json +5 -0
- package/skills/default/skills/git-workflow/SKILL.md +294 -0
- package/skills/default/skills/git-workflow/mise-tasks/_lib.sh +107 -0
- package/skills/default/skills/git-workflow/mise-tasks/clone +36 -0
- package/skills/default/skills/git-workflow/mise-tasks/repo-list +8 -0
- package/skills/default/skills/git-workflow/mise-tasks/unpushed +26 -0
- package/skills/default/skills/git-workflow/mise-tasks/worktree-add +60 -0
- package/skills/default/skills/github/SKILL.md +208 -0
- package/skills/default/skills/github/scripts/gh-org +196 -0
- package/skills/default/skills/plan-page/SKILL.md +300 -0
- package/skills/default/skills/plan-page/assets/index.html +854 -0
- package/skills/default/skills/plan-page/scripts/inline +46 -0
- package/skills/default/skills/plan-page/scripts/stage +26 -0
- package/skills/default/skills/secrets/SKILL.md +134 -0
- package/skills/default/skills/secrets/scripts/secrets-check +87 -0
- package/skills/default/skills/writing-style/SKILL.md +45 -0
- package/skills/extra/.claude-plugin/plugin.json +5 -0
- package/skills/extra/skills/artifacts/SKILL.md +52 -0
- package/skills/extra/skills/github-actions/SKILL.md +78 -0
- package/skills/extra/skills/github-actions/scan +32 -0
- package/skills/extra/skills/markdown-review/SKILL.md +70 -0
- package/skills/extra/skills/markdown-review/assets/index.html +201 -0
- package/skills/extra/skills/markdown-review/scripts/stage +36 -0
- package/skills/extra/skills/mise-usage/SKILL.md +155 -0
- package/skills/extra/skills/plugin-authoring/SKILL.md +317 -0
- package/skills/extra/skills/project-conventions/SKILL.md +64 -0
- package/skills/extra/skills/questions/SKILL.md +156 -0
- package/skills/extra/skills/questions/assets/index.html +376 -0
- package/skills/extra/skills/questions/scripts/stage +26 -0
- package/skills/extra/skills/serve/SKILL.md +165 -0
- package/skills/extra/skills/serve/scripts/serve +268 -0
- package/skills/extra/skills/serve/scripts/server.py +345 -0
- package/skills/extra/skills/skill-dependencies/SKILL.md +65 -0
- package/skills/extra/skills/skill-maintenance/SKILL.md +101 -0
- package/skills/extra/skills/ticketing/SKILL.md +125 -0
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: plugin-authoring
|
|
3
|
+
description: "MUST READ before creating or restructuring a skill collection, a Claude Code plugin, or a marketplace; before adding a skill to one; or when deciding whether a rule belongs in your own collection or upstream in a base one. Covers the two distribution models (portable skills collection vs Claude Code plugin) and how to choose, portability rules, structure, naming, the base-layer/modifier model, the two authoring disciplines (no preflighting the happy path, shell in bundled scripts), local development, and version bumps. For the format of an individual SKILL.md file, read `skill-maintenance`."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Skill collection, plugin, and marketplace authoring
|
|
7
|
+
|
|
8
|
+
These are the conventions for packaging skills for distribution. They live in a **skill**,
|
|
9
|
+
not a repo's `CLAUDE.md`, on purpose: a `CLAUDE.md` is only visible inside its own repo, so
|
|
10
|
+
conventions kept there get restated (and then drift) in every other repo. A skill is visible
|
|
11
|
+
everywhere it is installed.
|
|
12
|
+
|
|
13
|
+
Companion: **`skill-maintenance`** owns the format and lifecycle of an individual
|
|
14
|
+
`SKILL.md`. This skill owns everything around it.
|
|
15
|
+
|
|
16
|
+
## Pick a distribution model first
|
|
17
|
+
|
|
18
|
+
| | **Skills collection** (default) | **Claude Code plugin** |
|
|
19
|
+
| --- | --- | --- |
|
|
20
|
+
| Layout | `skills/<skill>/SKILL.md` at repo root | `plugins/<plugin>/skills/<skill>/SKILL.md` |
|
|
21
|
+
| Install | `npx skills add <owner>/<repo> -g` | `/plugin install <plugin>@<marketplace>` |
|
|
22
|
+
| Reaches | Claude Code, Cursor, Codex, and 70+ others | Claude Code only |
|
|
23
|
+
| Carries | skills | skills, commands, agents, hooks, MCP servers |
|
|
24
|
+
| Versioning | none; installs current `HEAD` | semver in `plugin.json`, version-keyed cache |
|
|
25
|
+
| Org push | none; each person installs | managed scope via server settings |
|
|
26
|
+
|
|
27
|
+
**Default to a skills collection.** Choose a plugin only when you need something a
|
|
28
|
+
`SKILL.md` cannot carry (commands, agents, hooks, an MCP server) or you need managed-scope
|
|
29
|
+
org rollout. Everything from [Naming](#naming) onward applies to both.
|
|
30
|
+
|
|
31
|
+
A repo can be both: put `skills/` at the root and add `.claude-plugin/` alongside it with a
|
|
32
|
+
plugin whose `source` is `./`. One layout, both install paths, no conditionals.
|
|
33
|
+
|
|
34
|
+
### The bootstrap plugin pattern
|
|
35
|
+
|
|
36
|
+
Use this when an org must push skills to everyone automatically **and** some of those people
|
|
37
|
+
want the skills in other agents too.
|
|
38
|
+
|
|
39
|
+
**What this is not for.** A managed-scope plugin *can* be updated: members pick up a new
|
|
40
|
+
version through `/plugin` in Claude Code. Do not reach for this pattern because you believe
|
|
41
|
+
managed delivery is frozen; it is not. (`claude plugin update` does refuse at managed scope,
|
|
42
|
+
erroring *"not installed at scope user"*, which is easy to misread as a hard limit. `/plugin`
|
|
43
|
+
is the control.)
|
|
44
|
+
|
|
45
|
+
**What it is for:** a plugin reaches Claude Code and nothing else. When part of your audience
|
|
46
|
+
works across Cursor, Codex, or anything else reading the Agent Skills spec, that half needs a
|
|
47
|
+
portable collection. So ship a small plugin that installs the collection and hands off.
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
.claude-plugin/marketplace.json # catalogs one plugin
|
|
51
|
+
plugin/ # pushed by managed settings
|
|
52
|
+
skills/<trigger-skill>/ # installs the collection, then hands off
|
|
53
|
+
skills/ # the portable half; updates by pushing
|
|
54
|
+
<prefix>-<topic>/
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Split by **who needs portability**, not by topic. Content that only ever runs in Claude Code
|
|
58
|
+
can live in the plugin; anything an engineer might want in another agent belongs in the
|
|
59
|
+
collection.
|
|
60
|
+
|
|
61
|
+
Rules:
|
|
62
|
+
|
|
63
|
+
1. **The bootstrap names no individual skill** beyond one fixed probe per collection, pins no
|
|
64
|
+
version, and holds no list. Installing is `--skill '*'`.
|
|
65
|
+
2. **Keep the plugin half small.** Everything in `skills/` updates by pushing; the plugin half
|
|
66
|
+
needs a version bump and a `/plugin` update on each member's machine.
|
|
67
|
+
3. **Mark every plugin skill `metadata.internal: true`**, or the skills CLI will also install
|
|
68
|
+
it flat, colliding on its bare name and duplicating the copy the plugin provides.
|
|
69
|
+
4. **Probe for a SKILL, never for a plugin.** A plugin can be present while providing
|
|
70
|
+
pre-rename names, so "the plugin is installed" proves nothing about what is usable.
|
|
71
|
+
5. **Probe the plugin cache too**, so a legitimately plugin-provided skill suppresses the flat
|
|
72
|
+
install rather than producing a second copy.
|
|
73
|
+
6. **No transition-era cleanup in the plugin.** Migration notes belong in a doc you can edit.
|
|
74
|
+
|
|
75
|
+
**Changing an executable file in the plugin** makes the admin console flag the marketplace
|
|
76
|
+
with *"Review it before members use it"*. That is advisory: it offers only a read-only
|
|
77
|
+
**View files**, there is no approve button, and nothing needs clearing.
|
|
78
|
+
|
|
79
|
+
If the collection is in a **private** repo, order matters: install the public base layer
|
|
80
|
+
first, verify git can read the private one (`git ls-remote`), and only then install it.
|
|
81
|
+
Signal "not authenticated yet" with a distinct exit code so the caller can route through the
|
|
82
|
+
GitHub setup skill and resume.
|
|
83
|
+
|
|
84
|
+
## Portability rules (both models)
|
|
85
|
+
|
|
86
|
+
A skill that assumes Claude Code silently breaks everywhere else. These are not style
|
|
87
|
+
preferences:
|
|
88
|
+
|
|
89
|
+
1. **Strict YAML frontmatter.** Claude Code's parser is lenient; every other agent's is not,
|
|
90
|
+
and an unparseable skill is *silently skipped*. Quote any description containing `: `.
|
|
91
|
+
See `skill-maintenance` for the rule and the check.
|
|
92
|
+
2. **Cross-reference by the skill's full directory name.** Write
|
|
93
|
+
`` the `secrets` skill ``, never `toolkit:secrets`: that `<plugin>:<skill>`
|
|
94
|
+
form is a Claude Code plugin namespace and means nothing to any other agent. The
|
|
95
|
+
reference is prose the model resolves, not a link.
|
|
96
|
+
3. **No `${CLAUDE_PLUGIN_ROOT}`.** Reference bundled scripts relative to the skill: "run this
|
|
97
|
+
skill's `scripts/zsh-fragment`".
|
|
98
|
+
4. **`name` must equal the directory name.** Installers install by directory.
|
|
99
|
+
5. **Claude-only features must degrade.** `context: fork` and hooks are Claude Code only;
|
|
100
|
+
`allowed-tools` is portable.
|
|
101
|
+
|
|
102
|
+
## Structure (plugin model)
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
.claude-plugin/
|
|
106
|
+
marketplace.json # catalog: names the marketplace, lists plugins by relative path
|
|
107
|
+
plugins/
|
|
108
|
+
<plugin>/
|
|
109
|
+
.claude-plugin/
|
|
110
|
+
plugin.json # this plugin's manifest
|
|
111
|
+
skills/
|
|
112
|
+
<skill>/
|
|
113
|
+
SKILL.md
|
|
114
|
+
scripts/ # bundled executables, run in place
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
1. **Manifests only in `.claude-plugin/`.** *Only* `marketplace.json` and `plugin.json` go
|
|
118
|
+
there. Everything else (`skills/`, `commands/`, `agents/`, `hooks/`, `.mcp.json`) sits at
|
|
119
|
+
the plugin root and is auto-discovered.
|
|
120
|
+
2. **`source` paths are repo-relative** (`./plugins/toolkit`). Relative sources are what let
|
|
121
|
+
one manifest serve both a local-path install and a hosted one.
|
|
122
|
+
3. **Validate before publishing:** `claude plugin validate <plugin-or-marketplace-path>`.
|
|
123
|
+
|
|
124
|
+
**Contracts to keep in sync.** Each of these names appears in more than one place, and all
|
|
125
|
+
copies must agree:
|
|
126
|
+
|
|
127
|
+
| Name | Appears in |
|
|
128
|
+
| --- | --- |
|
|
129
|
+
| Marketplace name | `marketplace.json`, every `<plugin>@<marketplace>` reference, install commands |
|
|
130
|
+
| Plugin name | its `plugin.json`, its `marketplace.json` entry, install/uninstall commands |
|
|
131
|
+
| Relative source | `marketplace.json`, and must resolve from the marketplace root |
|
|
132
|
+
|
|
133
|
+
## Naming
|
|
134
|
+
|
|
135
|
+
- **Namespace the plugin.** A plugin name carries its owner or org as a prefix. That prefix
|
|
136
|
+
is the collision-avoidance mechanism, so never publish a bare, unprefixed plugin name.
|
|
137
|
+
- **Split plugins by audience, not by topic.** Who installs it is the axis; a topic is a
|
|
138
|
+
skill inside a plugin, not a plugin of its own. Add a new plugin only when a distinct
|
|
139
|
+
group needs a distinct install set.
|
|
140
|
+
- **In a collection, prefix every skill directory with the collection's name**
|
|
141
|
+
(`<prefix>-deploy`, `<prefix>-git-workflow`). A flat install shares one global namespace
|
|
142
|
+
across every collection the user has, and installing a same-named skill from anywhere
|
|
143
|
+
else **silently overwrites** the existing one: no warning, no prompt, and `skills list`
|
|
144
|
+
records no provenance to trace it afterwards. The prefix is the whole defence.
|
|
145
|
+
- **In a plugin, the plugin supplies the namespace.** Skills are invoked as
|
|
146
|
+
`/<plugin>:<skill>`, so name a skill for what it covers (`git`, `deploy`) rather than
|
|
147
|
+
repeating the plugin. Split into topic-qualified names (`git-commit`, `git-clone`) only
|
|
148
|
+
when a skill actually splits.
|
|
149
|
+
- **Name a modifier after the skill it modifies**, so the pairing is obvious at a glance.
|
|
150
|
+
|
|
151
|
+
## Layered marketplaces: base layers and modifiers
|
|
152
|
+
|
|
153
|
+
A marketplace often sits **on top of** another one: a company marketplace over a personal
|
|
154
|
+
toolkit, a team's over the company's. When it does, name the base layer explicitly and
|
|
155
|
+
follow these rules.
|
|
156
|
+
|
|
157
|
+
**The base layer wins every conflict.** If a base skill and an overlay skill disagree, the
|
|
158
|
+
base is right and the overlay is the bug. An overlay that quietly contradicts its base is
|
|
159
|
+
worse than no overlay, because both look authoritative.
|
|
160
|
+
|
|
161
|
+
**Never fork a base skill.** A copy drifts, and then the two contradict each other while
|
|
162
|
+
each looks maintained. Two legitimate options only:
|
|
163
|
+
|
|
164
|
+
- The behavior is **generic** (it would be just as correct anywhere else): it belongs in the
|
|
165
|
+
base layer. Contribute it upstream.
|
|
166
|
+
- The behavior is **specific** to your context: keep it, as a modifier.
|
|
167
|
+
|
|
168
|
+
**Apply the rule/fact test.** This is the question that decides where something goes:
|
|
169
|
+
|
|
170
|
+
- A **rule** is how work gets done: commit conventions, install methods, safety
|
|
171
|
+
requirements, file layouts. Rules are almost always generic. They belong upstream, even
|
|
172
|
+
when you discovered the need for them locally.
|
|
173
|
+
- A **fact** is a value that is true of your context and false elsewhere: an org name, an
|
|
174
|
+
email domain, an account, a vault, a repo list, a provisioning step.
|
|
175
|
+
|
|
176
|
+
An overlay marketplace should trend toward **facts only**. If yours is accumulating rules,
|
|
177
|
+
they are candidates for upstream, not for local special-casing.
|
|
178
|
+
|
|
179
|
+
**A modifier is a modifier, not a replacement.** It names its base skill, defers to it for
|
|
180
|
+
the procedure, and states only what changes. Restating the base procedure *is* forking it.
|
|
181
|
+
|
|
182
|
+
```markdown
|
|
183
|
+
---
|
|
184
|
+
name: <topic>
|
|
185
|
+
description: <Context>-specific <topic> rules. Read AFTER <base>:<skill>, which owns the
|
|
186
|
+
procedure; this only adds the deltas. <when to load>
|
|
187
|
+
paths:
|
|
188
|
+
- "**/<Org>/**"
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
# <Topic> deltas
|
|
192
|
+
|
|
193
|
+
**Base skill: `<base>:<skill>`.** Follow it for the full procedure. This file records only
|
|
194
|
+
where things differ. If the two conflict, the base wins and this file is the bug.
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**Scope repo-specific guidance with `paths`.** It is a supported frontmatter field taking a
|
|
198
|
+
list of globs; the skill auto-loads only when the work touches a matching path. Use it for
|
|
199
|
+
guidance that is **repo-scoped** (project conventions, per-repo layouts). Do **not** use it
|
|
200
|
+
on **machine-scoped** setup skills (onboarding, installing a CLI, signing into an account):
|
|
201
|
+
those run once, often from a home directory with no repo in sight, and a glob would stop
|
|
202
|
+
them loading exactly when needed. Gate those on their `description`.
|
|
203
|
+
|
|
204
|
+
**Install the base layer first.** If an overlay's skills defer to a base, nothing else is
|
|
205
|
+
meaningful until the base is installed. An onboarding flow should install it as its first
|
|
206
|
+
real action.
|
|
207
|
+
|
|
208
|
+
## Setup versus day-to-day: do not preflight the happy path
|
|
209
|
+
|
|
210
|
+
**Prerequisites are handled during setup. Day-to-day operations assume setup is done and
|
|
211
|
+
just run the command.** A skill must not gate everyday work behind a
|
|
212
|
+
verify/preflight/connectivity check "before every command": that friction is the thing to
|
|
213
|
+
avoid.
|
|
214
|
+
|
|
215
|
+
- **Setup flows** own installs, logins, connectivity, and the idempotent repairs for them.
|
|
216
|
+
- **Day-to-day usage** just runs the command. A new shell has already sourced the profile,
|
|
217
|
+
so the tool is on `PATH`. No pre-check.
|
|
218
|
+
- **On failure, then diagnose.** Only when a command actually fails (not found, not
|
|
219
|
+
authenticated, session unavailable) run the skill's `doctor` and repair, then retry. Frame
|
|
220
|
+
a diagnosis script as the failure path, never the default path.
|
|
221
|
+
- **The one exception is a silent-correctness guard with no failure signal**, such as
|
|
222
|
+
checking commit identity before committing, where a wrong value does not error. Keep those
|
|
223
|
+
only when the check is instant and nothing else catches the mistake.
|
|
224
|
+
|
|
225
|
+
So a skill's `description` should trigger it for *setup* or *on failure*, not "before every
|
|
226
|
+
`X` command".
|
|
227
|
+
|
|
228
|
+
## Shell goes in bundled scripts, not in SKILL.md
|
|
229
|
+
|
|
230
|
+
Keep complex shell **out** of the markdown. Anything beyond a trivial one-liner (preflights,
|
|
231
|
+
installs, config writes, verification, key generation) lives as an executable in the skill's
|
|
232
|
+
`scripts/` directory, and the `SKILL.md` tells the model to run it by name. A named script
|
|
233
|
+
keeps the permission prompt a clean "run `scripts/<name>`", makes the logic reviewable and
|
|
234
|
+
testable, and stops the model re-emitting variable ad-hoc bash that trips approval
|
|
235
|
+
classifiers.
|
|
236
|
+
|
|
237
|
+
- **Shape:** `skills/<skill>/scripts/<name>`, no extension, `#!/usr/bin/env bash`,
|
|
238
|
+
`set -euo pipefail`, `chmod +x`.
|
|
239
|
+
- **Invocation:** refer to it as "this skill's `scripts/<name>`" and let the model resolve
|
|
240
|
+
the path. Do not hardcode a path that breaks either plugin mode or local dev.
|
|
241
|
+
- **Idempotent:** check before installing or writing, and skip work already done, so
|
|
242
|
+
re-running a skill is always safe. Report `NOCHANGE` when there was nothing to do.
|
|
243
|
+
- **Read-only diagnosis:** a `doctor` script prints one `KEY: VALUE` fact per line so the
|
|
244
|
+
caller can branch without parsing prose, and changes nothing.
|
|
245
|
+
- **Protected-path writes** (`~/.zshrc`, `~/.ssh/config`) still go in a script, but keep the
|
|
246
|
+
"announce the write before running it" prose in the `SKILL.md` so the approval prompt is
|
|
247
|
+
expected rather than surprising. Do not try to engineer around a denial: in auto-accept
|
|
248
|
+
mode a classifier stands in for the absent human, and that denial is the guardrail working.
|
|
249
|
+
- **Trivial contextual one-liners** (a single `git config`, `op --version`) stay inline. Do
|
|
250
|
+
not over-script.
|
|
251
|
+
- **Target bash 3.2.** macOS still ships it, so no `mapfile`, no associative arrays, no
|
|
252
|
+
`${var^^}`. A script that only runs under bash 4 fails on the most common target.
|
|
253
|
+
- **Scripts run in place.** Do not install a skill's internal scripts to `~/.local/bin`: a
|
|
254
|
+
plugin-owned script that also sits on `PATH` has two owners, and the `PATH` copy goes stale
|
|
255
|
+
the moment the plugin updates. The exception is a genuinely **user-facing command**, one a
|
|
256
|
+
person types in a terminal, since a version-keyed plugin cache path is not typeable. Such a
|
|
257
|
+
command is then owned by the plugin, so a dotfile manager must not manage it too.
|
|
258
|
+
|
|
259
|
+
## Local development
|
|
260
|
+
|
|
261
|
+
For a **skills collection**, install straight from the working copy: a local path source
|
|
262
|
+
needs no commit, push, or version bump:
|
|
263
|
+
|
|
264
|
+
```
|
|
265
|
+
npx skills add "$PWD" --skill '*' -g -y
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
The symlink approach below also works, and is what to use inside the collection's own repo.
|
|
269
|
+
|
|
270
|
+
For a **plugin**, skills under `plugins/` are only discovered once the plugin is installed from a marketplace,
|
|
271
|
+
which would mean publishing on every edit. Instead, symlink each skill into `.claude/skills/`
|
|
272
|
+
so Claude Code discovers it straight from the working tree:
|
|
273
|
+
|
|
274
|
+
```
|
|
275
|
+
.claude/skills/<skill> -> ../../plugins/<plugin>/skills/<skill>
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Use **relative** link targets so a fresh clone stays valid, keep the directory **gitignored
|
|
279
|
+
and generated** (never hand-edited or committed), and rebuild it with a script that scans
|
|
280
|
+
`plugins/*/skills/*` (or `skills/*` in a collection). Locally these resolve to the bare
|
|
281
|
+
`/<skill>` command; a plugin's installed form is `/<plugin>:<skill>`, and the two coexist
|
|
282
|
+
without collision.
|
|
283
|
+
|
|
284
|
+
This tests a skill's **content**, the same `SKILL.md` the plugin ships. It does **not**
|
|
285
|
+
exercise the namespaced command, plugin-bundled hooks or MCP, or the install flow. For those,
|
|
286
|
+
test the plugin somewhere it is not force-enabled by managed settings.
|
|
287
|
+
|
|
288
|
+
> A `--plugin-dir` dev copy cannot override a plugin that managed settings force-enable; the
|
|
289
|
+
> CLI errors instead. Project-skill discovery is a separate mechanism and is unaffected. The
|
|
290
|
+
> exception is the managed setting `strictPluginOnlyCustomization`, which blocks user and
|
|
291
|
+
> project skills entirely; where it is set, local dev needs a skills-directory plugin or an
|
|
292
|
+
> admin exception.
|
|
293
|
+
|
|
294
|
+
## Bump the version on every change (plugin model only)
|
|
295
|
+
|
|
296
|
+
**Bump the plugin's `version` in `plugin.json` in the same commit as the change.** The plugin
|
|
297
|
+
cache is version-keyed, so `claude plugin update` is a no-op when the version has not moved:
|
|
298
|
+
an unbumped change simply never reaches anyone. Patch for fixes and docs, minor for a new or
|
|
299
|
+
removed skill.
|
|
300
|
+
|
|
301
|
+
A **skills collection has no version and no cache:** an install resolves current `HEAD`, so
|
|
302
|
+
there is nothing to bump and no way for an edit to go stale.
|
|
303
|
+
|
|
304
|
+
## Adding a skill
|
|
305
|
+
|
|
306
|
+
**Step 0 is a gate.** If you are working in an overlay marketplace, check the base layer
|
|
307
|
+
first: list its skills and read any that touch the same topic. If it already covers this,
|
|
308
|
+
use its skill. If it *should* cover this because the behavior is generic, contribute it
|
|
309
|
+
upstream. Only a genuine context-specific delta continues.
|
|
310
|
+
|
|
311
|
+
1. Create the `SKILL.md` (see `skill-maintenance`): `skills/<skill>/SKILL.md` in a
|
|
312
|
+
collection, `plugins/<plugin>/skills/<skill>/SKILL.md` in a plugin.
|
|
313
|
+
2. Add `paths` if the guidance is repo-scoped; omit it for machine-scoped setup.
|
|
314
|
+
3. Regenerate the local-dev symlinks.
|
|
315
|
+
4. Verify it parses for a strict reader: `npx -y skills add "$PWD" --list`.
|
|
316
|
+
5. Plugin model only: bump the plugin version, then `claude plugin validate` the plugin and
|
|
317
|
+
the marketplace.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: project-conventions
|
|
3
|
+
verified: 2026-10-31
|
|
4
|
+
description: "MUST READ whenever a new project or repo is created or scaffolded, and whenever the user asks for a project to follow good code conventions. Ensures the project has a CLAUDE.md and that it carries the standard conventions section, creating the file if missing and merging into it if present."
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Project Conventions
|
|
8
|
+
|
|
9
|
+
This skill makes sure a project's `CLAUDE.md` exists and carries the standard
|
|
10
|
+
[conventions](#the-conventions), so every later session in that project follows them.
|
|
11
|
+
|
|
12
|
+
## When to apply
|
|
13
|
+
|
|
14
|
+
- **New project.** Right after creating or scaffolding a repo or project directory, before
|
|
15
|
+
the first commit.
|
|
16
|
+
- **On request.** The user asks for a project to follow good conventions, best practices,
|
|
17
|
+
or "our conventions".
|
|
18
|
+
|
|
19
|
+
Do it without asking: the user wants the file in place, not a discussion of it.
|
|
20
|
+
|
|
21
|
+
## Apply it
|
|
22
|
+
|
|
23
|
+
1. **Find the project root.** The git toplevel if there is one, else the directory just
|
|
24
|
+
created.
|
|
25
|
+
2. **No `CLAUDE.md`.** Create it with a `# CLAUDE.md` heading, one line saying what the
|
|
26
|
+
project is (from the conversation, or the directory name if there is nothing else), then
|
|
27
|
+
the conventions section below verbatim.
|
|
28
|
+
3. **`CLAUDE.md` exists.** Read it first. Then:
|
|
29
|
+
- No `## Code conventions` section: append the section below.
|
|
30
|
+
- Section present: add only the bullets it is missing. Never reword, reorder, or delete
|
|
31
|
+
what is already there, since the repo may have deliberately diverged.
|
|
32
|
+
- A rule in the file contradicts one below: keep the file's rule and tell the user about
|
|
33
|
+
the conflict in one line.
|
|
34
|
+
4. **Commit.** Follow the `git-workflow` skill. In a new project, fold `CLAUDE.md`
|
|
35
|
+
into the first commit rather than a separate one.
|
|
36
|
+
|
|
37
|
+
Re-running this skill on a project that already has every convention changes nothing.
|
|
38
|
+
|
|
39
|
+
## The conventions
|
|
40
|
+
|
|
41
|
+
Copy this section into the project's `CLAUDE.md`:
|
|
42
|
+
|
|
43
|
+
```markdown
|
|
44
|
+
## Code conventions
|
|
45
|
+
|
|
46
|
+
- **Design:** design and change code as deep modules: small interfaces hiding a lot of
|
|
47
|
+
behavior, each with one responsibility, no logic written twice.
|
|
48
|
+
- **Commits:** commit each finished change as you go, without asking; push only after
|
|
49
|
+
showing every unpushed commit and getting approval, per the `git-workflow` skill.
|
|
50
|
+
- **Tools:** pin every tool version in this project's `mise.toml` and run tools through
|
|
51
|
+
mise, following the `mise-usage` skill. Install nothing globally (`brew`,
|
|
52
|
+
`npm -g`, `pip --user`, `uv tool`, `go install`) unless mise cannot provide the tool, and
|
|
53
|
+
then say why.
|
|
54
|
+
- **Tasks:** write automation as mise file tasks under `mise-tasks/`, never as tasks in
|
|
55
|
+
`mise.toml` and never as standalone shell scripts unless a mise task cannot do the job.
|
|
56
|
+
Group related tasks into folders, so `mise-tasks/db/migrate` runs as `mise run db:migrate`.
|
|
57
|
+
- **Running things:** at the start of a session run `mise tasks` to learn every task, and
|
|
58
|
+
use a task over the equivalent raw command whenever one exists. Never run `mise exec`;
|
|
59
|
+
when a command needs the mise environment
|
|
60
|
+
(tools, env vars, `.env`), write a mise task for it and run that.
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The `Commits` line is the opt-in the `git-workflow` skill looks for. Keep its
|
|
64
|
+
wording exact.
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: questions
|
|
3
|
+
description: "MUST READ whenever you and the user are working toward a decision about one specific topic and there are many things to consider: several questions, concerns, findings, options or tradeoffs you would otherwise list in chat. A single question stays in chat. Not for planning. Publishes the items to a Claude artifact where the user weighs each one's pros and cons, then approves or comments, reads the answers back, and removes each item once it is settled and recorded."
|
|
4
|
+
verified: 2026-10-28
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Questions
|
|
8
|
+
|
|
9
|
+
When you are working toward a decision about one specific topic and have many things for the
|
|
10
|
+
user to consider, put them on a page instead of listing them in chat:
|
|
11
|
+
|
|
12
|
+
- **Use it for:** several questions, concerns, findings, options or tradeoffs that each need the
|
|
13
|
+
user's call, including the ones you turn up while answering something else.
|
|
14
|
+
- **Not for one question:** a single question stays in chat.
|
|
15
|
+
- **Not for planning:** plans follow their own process.
|
|
16
|
+
|
|
17
|
+
Each item is a panel with its proposal, a Pros and a Cons section, an Approve checkbox, and a
|
|
18
|
+
comment box to change it or ask about it. One page per topic, kept for as long as the topic has
|
|
19
|
+
open items.
|
|
20
|
+
|
|
21
|
+
The page is a Claude artifact made of two files:
|
|
22
|
+
|
|
23
|
+
1. **`index.html`:** this skill's `assets/index.html`, a renderer that never changes.
|
|
24
|
+
2. **`questions.json`:** the open items, which you write and rewrite.
|
|
25
|
+
|
|
26
|
+
Answers live in the artifact's database, collection `responses`, one document per item id:
|
|
27
|
+
`{ approved, comment, updatedAt }`.
|
|
28
|
+
|
|
29
|
+
## questions.json
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"title": "Auth Decisions",
|
|
34
|
+
"problem": "Sessions expire mid-task, and people lose unsaved work.",
|
|
35
|
+
"intro": "Tick to approve as written; comment to change it or ask.",
|
|
36
|
+
"groups": [
|
|
37
|
+
{
|
|
38
|
+
"title": "Sessions",
|
|
39
|
+
"note": "Optional text under the group heading.",
|
|
40
|
+
"items": [
|
|
41
|
+
{
|
|
42
|
+
"id": "session-length",
|
|
43
|
+
"title": "Sessions last 30 days",
|
|
44
|
+
"proposal": "Keep a session for `30` days, renewed on use.",
|
|
45
|
+
"why": "Why this question is being asked at all: the problem or event that raised it.",
|
|
46
|
+
"versus": "What it is weighed against: today's behavior, or the option it competes with.",
|
|
47
|
+
"pros": ["Each point one short sentence."],
|
|
48
|
+
"cons": ["An empty list shows None."],
|
|
49
|
+
"reply": "Optional: which comment this item came from, and your answer."
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
- **`problem`:** required; the one problem the whole page exists to solve, in the user's terms,
|
|
58
|
+
shown above every item. Keep it current: when settling shrinks or changes what is left, rewrite
|
|
59
|
+
it to the problem the remaining items still solve, so the user never loses the plot.
|
|
60
|
+
- **`id`:** kebab-case, unique, and never reused for a different question, since answers are
|
|
61
|
+
keyed by it.
|
|
62
|
+
- **Text:** plain text, plus `` `code` `` and `**bold**`; nothing else is rendered.
|
|
63
|
+
- **One concern per item:** break the topic into every separate question, concern, finding or
|
|
64
|
+
option, and give each its own item with its own proposal. Never fold several concerns into
|
|
65
|
+
one item as its pros and cons.
|
|
66
|
+
- **One decision per item:** a proposal the user can approve with one tick. Split anything
|
|
67
|
+
that needs two answers.
|
|
68
|
+
- **Why it came up:** every item has `why`, saying which part of `problem` it solves, and the
|
|
69
|
+
finding or request that raised it, so the user never wonders why it is being considered. It sits
|
|
70
|
+
above the proposal. An item that solves no part of `problem` belongs on another page, or nowhere.
|
|
71
|
+
- **A concrete example:** every `why` walks through one short, specific scenario drawn from the
|
|
72
|
+
topic itself, showing what happens without the proposal, so the user can catch up without
|
|
73
|
+
knowing the details. Explain any term the user may not know in plain words inside it, never
|
|
74
|
+
by name alone.
|
|
75
|
+
- **Compared with something:** every item has `versus`, naming what it is weighed against: how
|
|
76
|
+
things work today, or the option it competes with.
|
|
77
|
+
- **Pros and cons are differences:** each one says how the proposal is better or worse than
|
|
78
|
+
`versus`, never something true of both. A different concern is a different item, not a con.
|
|
79
|
+
- **Real cons only:** a con is a lasting cost or risk of the outcome. One-time work to build it
|
|
80
|
+
is not a con, and neither is a command the user only meets in an error message that names it.
|
|
81
|
+
- **Alternatives:** `versus` is the main alternative, so the user knows what approving rules out.
|
|
82
|
+
- **Suggestions in chat too:** when the user suggests another way while a page is open, add it
|
|
83
|
+
as a new item to weigh instead of acting on it.
|
|
84
|
+
- **Settled items:** removed, never marked done. A page left with no open items is deleted;
|
|
85
|
+
see [Settle](#settle).
|
|
86
|
+
|
|
87
|
+
## Publish
|
|
88
|
+
|
|
89
|
+
1. **Stage:** run this skill's `scripts/stage <out-dir>`, with `<out-dir>` a folder for this
|
|
90
|
+
topic in the session's scratch directory, such as `<scratch>/questions/<topic>`. It prints:
|
|
91
|
+
```
|
|
92
|
+
PAGE: <out-dir>/index.html
|
|
93
|
+
QUESTIONS: <out-dir>/questions.json
|
|
94
|
+
```
|
|
95
|
+
2. **Write** the items into `questions.json`.
|
|
96
|
+
3. **Publish** with the Artifact tool:
|
|
97
|
+
- `file_path`: the `PAGE` path.
|
|
98
|
+
- `files`: `{"questions.json": "<QUESTIONS path>"}`.
|
|
99
|
+
- `capabilities`: `{"db": {}, "comments": {}}`, on the first publish only.
|
|
100
|
+
- `icon`: `checklist`, on the first publish only.
|
|
101
|
+
4. **Link:** give the user the artifact link.
|
|
102
|
+
|
|
103
|
+
## Read answers
|
|
104
|
+
|
|
105
|
+
The page has a **Done, tell Claude** button. It posts a comment on the page and sends it to
|
|
106
|
+
this session, which wakes you while the publish's watch has comment auto-replies armed.
|
|
107
|
+
|
|
108
|
+
1. **Woken by "Done answering":** list the `responses` collection with the `ArtifactData`
|
|
109
|
+
tool, ignoring documents whose id is no longer in `questions.json`, then settle them.
|
|
110
|
+
2. **Close the loop:** reply in that comment's thread with one line on what changed, then
|
|
111
|
+
resolve it with `ArtifactComments`.
|
|
112
|
+
3. **No button:** it hides when no session can receive it; the user then tells you in chat.
|
|
113
|
+
|
|
114
|
+
## Settle
|
|
115
|
+
|
|
116
|
+
For each item with an answer:
|
|
117
|
+
|
|
118
|
+
1. **Approved, no comment:** record the decision where the topic's decisions live (a design
|
|
119
|
+
doc, a plan, the code), then remove the item.
|
|
120
|
+
2. **Approved, with a comment:** the comment refines the approval, never voids it. Record the
|
|
121
|
+
decision as the proposal changed by the comment, then remove the item. Only when the
|
|
122
|
+
comment raises something still to be answered (a question, a choice it leaves open) add a
|
|
123
|
+
new item for just that, with a `reply` saying which approval it came from.
|
|
124
|
+
3. **Commented, not approved:** the commented item never stays. Remove it, and roll the comment into new
|
|
125
|
+
items with new ids; carry forward whatever part of the original is still live, such as its
|
|
126
|
+
proposal becoming the `versus` of a new item.
|
|
127
|
+
- **A change:** a new item with the revised proposal.
|
|
128
|
+
- **A question:** a new item whose `reply` answers it, with the proposal revised if the
|
|
129
|
+
answer changes it.
|
|
130
|
+
- **A suggestion** ("why not this", "let's do it like that"): never just adopt it; a new item
|
|
131
|
+
proposing it, with its own alternative, pros and cons.
|
|
132
|
+
- **Settled by the comment:** record it, and add nothing.
|
|
133
|
+
- **`reply`:** on each new item, say in one sentence which comment it came from and what changed.
|
|
134
|
+
4. **Removed items:** delete their `responses` documents in one `batch`.
|
|
135
|
+
5. **Republish:** publish again with the same `file_path` and the `questions.json` entry in
|
|
136
|
+
`files`.
|
|
137
|
+
6. **Nothing left open:** instead of republishing an empty page, close the loop on the "Done
|
|
138
|
+
answering" thread first, then stop watching the artifact (`ArtifactComments`, `action:
|
|
139
|
+
"watch"`, `on: false`) and delete it (`Artifact`, `action: "delete"`). Tell the user the page
|
|
140
|
+
is gone and where its decisions were recorded.
|
|
141
|
+
|
|
142
|
+
Never remove an item before its decision is recorded somewhere lasting; the page is for open
|
|
143
|
+
items only.
|
|
144
|
+
|
|
145
|
+
## Later sessions
|
|
146
|
+
|
|
147
|
+
The scratch folder is gone. Read the artifact with `action: "read"` and fetch
|
|
148
|
+
`questions.json` with `action: "read"` and `path: "questions.json"`, run `scripts/stage` into a
|
|
149
|
+
fresh folder, put the fetched `questions.json` there, then publish with the artifact's `url`.
|
|
150
|
+
|
|
151
|
+
## Comments on the page
|
|
152
|
+
|
|
153
|
+
The comment box on each item is the answer field, not a notes system; the artifact's
|
|
154
|
+
built-in comments still work for anything else. See the `artifacts` skill.
|
|
155
|
+
|
|
156
|
+
Change the renderer only in this skill's `assets/index.html`.
|