skillcaddy 0.27.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 (99) hide show
  1. package/CHANGELOG.md +497 -0
  2. package/CONTEXT.md +149 -0
  3. package/LICENSE +21 -0
  4. package/README.md +499 -0
  5. package/README_CN.md +482 -0
  6. package/collection-metadata/github/mattpocock.json +16 -0
  7. package/lib/canonicalJson.js +11 -0
  8. package/lib/claudeStore.js +135 -0
  9. package/lib/collectionEnablement.js +115 -0
  10. package/lib/collectionSetup.js +199 -0
  11. package/lib/enablePlan.js +116 -0
  12. package/lib/enablementScope.js +8 -0
  13. package/lib/hermesStore.js +21 -0
  14. package/lib/libraryImage.js +1785 -0
  15. package/lib/managerInstall.js +109 -0
  16. package/lib/managerSourceWorkflow.js +234 -0
  17. package/lib/projectActions.js +24 -0
  18. package/lib/projectPath.js +51 -0
  19. package/lib/roots.js +99 -0
  20. package/lib/skillLinkStore.js +68 -0
  21. package/lib/skillMetadata.js +191 -0
  22. package/lib/skillStore.js +541 -0
  23. package/lib/sourceAcquisition.js +475 -0
  24. package/lib/sourceAcquisitionAdapter.js +47 -0
  25. package/lib/sourceAcquisitionError.js +18 -0
  26. package/lib/sourceAcquisitionPolicy.js +139 -0
  27. package/lib/sourceArchive.js +363 -0
  28. package/lib/sourceArchiveWorkspace.js +36 -0
  29. package/lib/sourceGit.js +95 -0
  30. package/lib/sourceGitAcquisitionAdapter.js +145 -0
  31. package/lib/sourceGitBatchUpdate.js +168 -0
  32. package/lib/sourceGitRepair.js +227 -0
  33. package/lib/sourceGitStaging.js +139 -0
  34. package/lib/sourceGitUpgradeAdapter.js +583 -0
  35. package/lib/sourceGitUrl.js +170 -0
  36. package/lib/sourceHttp.js +302 -0
  37. package/lib/sourceLocal.js +200 -0
  38. package/lib/sourceLocalAcquisitionAdapter.js +107 -0
  39. package/lib/sourceManager.js +242 -0
  40. package/lib/sourceMigration.js +172 -0
  41. package/lib/sourceMigrationIssue.js +6 -0
  42. package/lib/sourcePath.js +6 -0
  43. package/lib/sourcePolicy.js +53 -0
  44. package/lib/sourceRecord.js +295 -0
  45. package/lib/sourceRegistry.js +155 -0
  46. package/lib/sourceRemoteArchiveAcquisitionAdapter.js +147 -0
  47. package/lib/sourceRemoteFileAcquisitionAdapter.js +95 -0
  48. package/lib/sourceRemoteFilePolicy.js +62 -0
  49. package/lib/sourceRemoteFileWorkspace.js +55 -0
  50. package/lib/sourceSkillDiscovery.js +117 -0
  51. package/lib/sourceTree.js +185 -0
  52. package/lib/sourceUpgrade.js +596 -0
  53. package/lib/sourceUpgradeAdapter.js +41 -0
  54. package/lib/sourceUpgradePolicy.js +170 -0
  55. package/lib/sourceUpgradeTransaction.js +202 -0
  56. package/lib/sourceValidation.js +120 -0
  57. package/lib/sourceWorkspace.js +37 -0
  58. package/lib/specGate.js +235 -0
  59. package/lib/tuiActions.js +169 -0
  60. package/lib/tuiInstall.js +133 -0
  61. package/lib/tuiLayout.js +94 -0
  62. package/lib/version.js +17 -0
  63. package/lib/webManager.js +370 -0
  64. package/package.json +74 -0
  65. package/public/agentsUi.js +138 -0
  66. package/public/app.js +1431 -0
  67. package/public/claude.css +2 -0
  68. package/public/claudeUi.js +119 -0
  69. package/public/emptyState.js +12 -0
  70. package/public/enabled.css +303 -0
  71. package/public/favicon.svg +5 -0
  72. package/public/index.html +199 -0
  73. package/public/skillcaddy_CN.png +0 -0
  74. package/public/skillcaddy_EN.png +0 -0
  75. package/public/styles.css +1611 -0
  76. package/scripts/cli.js +647 -0
  77. package/scripts/cron-sync-update-git.sh +128 -0
  78. package/scripts/pull-github.sh +22 -0
  79. package/scripts/source.js +638 -0
  80. package/scripts/tui.js +1058 -0
  81. package/server.js +196 -0
  82. package/skills/skillcaddy-manager/SKILL.md +93 -0
  83. package/skills/skillcaddy-manager/agents/openai.yaml +7 -0
  84. package/skills/skillcaddy-manager/references/METADATA.md +75 -0
  85. package/skills/skillcaddy-manager/references/OPERATIONS.md +315 -0
  86. package/skills/skillcaddy-manager/references/RECOMMENDATION_GUIDE.md +51 -0
  87. package/skills/skillcaddy-manager/references/featured-skills.json +564 -0
  88. package/skills/skillcaddy-manager/references/skill-platforms.json +48 -0
  89. package/skills/skillcaddy-manager/scripts/check-conflicts.cjs +117 -0
  90. package/skills/skillcaddy-manager/scripts/check-global-skills.cjs +169 -0
  91. package/skills/skillcaddy-manager/scripts/translate-skill-notes.cjs +297 -0
  92. package/skills/skillcaddy-manager/scripts/version-manager.cjs +146 -0
  93. package/skills/skillcaddy-manager/scripts/view-recommendations.cjs +279 -0
  94. package/skills/skillcaddy-manager/skillcaddy.json +9 -0
  95. package/skills/spec-pipeline/spec-direction-gate/SKILL.md +119 -0
  96. package/skills/spec-pipeline/spec-direction-gate/check-approval.py +110 -0
  97. package/skills/spec-pipeline/spec-draft-intake/SKILL.md +116 -0
  98. package/skills/spec-pipeline/spec-role-contract/SKILL.md +113 -0
  99. package/skills/spec-pipeline/spec-role-contract/check-roles.py +108 -0
package/README.md ADDED
@@ -0,0 +1,499 @@
1
+ # Skillcaddy
2
+
3
+ [English](README.md) · [中文](README_CN.md)
4
+
5
+ Local AI skills central library + scoped symlink enablement. One library directory holds every skill source; symlink what you need into a project, the shared user-level Agents directory, or Hermes on demand.
6
+
7
+ ![](public/skillcaddy_EN.png)
8
+
9
+ ## Why Skillcaddy?
10
+
11
+ If you use Claude Code, Codex, OpenCode, or Pi across multiple projects, you eventually hit one of these:
12
+
13
+ - The same skill lives in three repos, slightly drifted each time
14
+ - A new project means copying skills over and wondering which version is current
15
+ - An upstream skill gets updated but your local copy is weeks behind
16
+ - A Claude-Code-only entry needs to coexist with the agents-side list
17
+ - An archived skill slips back in because no one gated it
18
+
19
+ Skillcaddy fixes this with one library directory as the source of truth and explicit project/global/Hermes symlink scopes as the delivery mechanism.
20
+
21
+ - **One source of truth** — one library directory aggregates `official / github / personal / archived`; the bundled `skills/` come with the program
22
+ - **Install-independent library** — the library lives at `~/.skillcaddy/library`, so reinstalling or upgrading Skillcaddy never touches your skills
23
+ - **Zero project pollution** — enable by symlink into `.agents/skills/`; never copy
24
+ - **Project or global scope** — project links stay local; global links go only to `~/.agents/skills/`
25
+ - **Independent Hermes scope** — `official`/`github`/`personal` skills explicitly link to `~/.hermes/skills/`; it ignores `HERMES_HOME` and never changes project/global scopes
26
+ - **Multi-Agent by default** — one symlink reaches Claude Code, Codex, OpenCode, Pi via their standard paths
27
+ - **Independent enable / disable** — agents-side and Claude-Code-side are tracked separately
28
+ - **Safe by default** — disable only removes the symlink; `archived/` requires explicit naming
29
+ - **Contribute-friendly** — new skills land under `skills/<name>/` with `SKILL.md` + `agents/openai.yaml` and ship with the repo
30
+
31
+ Whether you're a solo dev with half a dozen repos, a small team standardizing on shared skills, or an author publishing reusable ones — the contract is the same: skills belong to your library, not to any one project.
32
+
33
+ ## Installation
34
+
35
+ ```bash
36
+ npx skillcaddy # one-shot run, nothing to install
37
+ npm install -g skillcaddy # persistent global command
38
+ brew install skillcaddy # macOS / Linuxbrew
39
+ ```
40
+
41
+ Or use the shell installer:
42
+
43
+ ```bash
44
+ curl -fsSL https://raw.githubusercontent.com/chenweil/skillcaddy/main/scripts/install.sh | bash
45
+ ```
46
+
47
+ Or run it from source:
48
+
49
+ ```bash
50
+ git clone https://github.com/chenweil/skillcaddy.git
51
+ cd skillcaddy
52
+ npm install
53
+ npm start
54
+ ```
55
+
56
+ Requires Node.js >= 20. The web manager uses the fixed default URL `http://127.0.0.1:4173`. Fill in the target project path on the page, and enable/disable skills. If that port is temporarily occupied, start with `PORT=<other-port> npm start`.
57
+
58
+ ### Where the library lives
59
+
60
+ Skillcaddy separates the **code root** (the program: `package.json`, `server.js`, the bundled `skills/`) from the **library root** (your skills: `official / github / personal / archived`, the source registry, and skill metadata).
61
+
62
+ - A **clone** keeps the library inside the clone, exactly as before.
63
+ - A **packaged install** (`npx`, `npm i -g`, `brew`) keeps the library in `~/.skillcaddy/library`, so reinstalling or upgrading the program never touches your skills.
64
+ - `SKILLCADDY_ROOT` or `--root <dir>` points Skillcaddy at any other library directory; the same variable is already used by `scripts/pull-github.sh`.
65
+
66
+ Both roots are reported by `skillcaddy -a`, and the library root is printed by the TUI summary.
67
+
68
+ ### Bundled spec-pipeline skills
69
+
70
+ This repository ships three skills under `skills/spec-pipeline/` that implement the direction-confirmation gate described in [`docs/research/0037`](docs/research/0037-spec-doc-pipeline-gaps-improvement-plan.md). They are tracked in git, so a clone has the content — but the project enablement links are not, by design: ADR 0011 Decision 4 keeps project enablements out of the library image (`lib/libraryImage.js` carries only `global` and `hermes` triples). Recreate the links once per checkout:
71
+
72
+ ```bash
73
+ npm run enable:spec-pipeline
74
+ # preview without touching anything
75
+ npm run enable:spec-pipeline -- --dry-run
76
+ ```
77
+
78
+ Then check that every spec in this repository satisfies the gate:
79
+
80
+ ```bash
81
+ npm run check:specs
82
+ ```
83
+
84
+ Both commands are idempotent. `check:specs` is also part of `npm test`; a repository with no `specs/` directory passes, and `--strict` inverts that.
85
+
86
+ The Web library keeps project, global, and Hermes enablement independent. Enabling a skill globally does not disable its project action: you can still add the same skill to the current project when that project needs its own setup, Claude Code synchronization, or explicit project-level precedence. Collection actions show separate project/global/Hermes progress; text search expands matching collections, while source and tag filters keep collections collapsed for compact browsing. The enabled panel presents project Agents and Claude Code as side-by-side channel slots, with full-width global and Hermes slots below; a shared enabled-skill search finds a name or source without scrolling long lists.
87
+
88
+ ### Global CLI / TUI command
89
+
90
+ A packaged install already provides the `skillcaddy` command. When you work from a clone, link that clone's command globally instead (local `npm link`):
91
+
92
+ ```bash
93
+ npm run install:cli
94
+ npm run check:cli
95
+ ```
96
+
97
+ The installed `skillcaddy` command provides both the CLI and TUI. The older `install:tui` / `check:tui` names remain as compatibility aliases. You can also run `npm run tui -- install cli` from the clone, or choose `11. 安装/检查全局 CLI + TUI 命令` inside the TUI.
98
+
99
+ After linking the local CLI/TUI command once, the same entry point can manage the Web server and inspect or update skills from any project:
100
+
101
+ ```bash
102
+ skillcaddy start [projectPath] # start the Web manager
103
+ skillcaddy stop # stop Skillcaddy-owned Web only
104
+ skillcaddy restart [projectPath] # restart the Web manager
105
+ skillcaddy -v # show the version
106
+ skillcaddy -h # show help
107
+ skillcaddy -u [projectPath] # safely update registered Git skill sources
108
+ skillcaddy -a [projectPath] # report project state, advice, and recommendations
109
+ skillcaddy enable <skill-id> --project <dir> [--alias <name>]
110
+ skillcaddy enable <skill-id> --global [--alias <name>]
111
+ skillcaddy enable <skill-id> --hermes [--alias <name>]
112
+ skillcaddy disable <alias> --project <dir>
113
+ skillcaddy disable <alias> --global
114
+ skillcaddy disable <alias> --hermes
115
+ ```
116
+
117
+ `-a` is read-only and never creates source folders, installs, enables, or writes metadata. `-u` reuses the existing fast-forward-only Git source update flow and requires an explicit current project path; global links are checked in the same update. `start` reuses a Web process that is already running; `stop` and `restart` act only on a process whose Skillcaddy ownership can be verified, so an external service on the port is not killed. `--root` selects the library root and applies to every command, including the Web lifecycle; the Web process always runs the code root that provides the executable. Running `skillcaddy` without arguments still opens the TUI.
118
+
119
+ On platforms without a process-ownership probe, Web stop/restart fail closed rather than guessing which process to terminate.
120
+
121
+ If you do not want to link the global command yet, the repository-local entry supports the same commands:
122
+
123
+ ```bash
124
+ npm run tui -- start --no-open
125
+ npm run tui -- stop
126
+ npm run tui -- -a /path/to/project
127
+ ```
128
+
129
+ ### Terminal UI (TUI)
130
+
131
+ For the interactive terminal manager, run:
132
+
133
+ ```bash
134
+ npm run tui -- /path/to/project
135
+ # or with explicit root
136
+ npm run tui -- --root ~/.skillcaddy/library /path/to/project
137
+ ```
138
+
139
+ To use the cloned library from any project, link its CLI/TUI command once:
140
+
141
+ ```bash
142
+ npm run install:cli
143
+ npm run check:cli
144
+
145
+ cd /path/to/another-project
146
+ skillcaddy
147
+ ```
148
+
149
+ `install:cli` uses local `npm link`: it links this clone instead of downloading a package. The global `skillcaddy` command remains linked to this clone, which stays the central library and can be updated with `git pull`. Running `skillcaddy` without an argument manages the current directory; `skillcaddy /path/to/project` selects another project. The installer refuses to replace a global `skillcaddy` package linked to another clone.
150
+
151
+ The TUI provides a full keyboard-driven interface without needing a browser:
152
+
153
+ - **View enabled skills** — Agents and Claude Code columns side by side
154
+ - **Browse/search skill library** — Keyword search, source filter, library drill-down
155
+ - **Enable skill** — Creates symlink in `.agents/skills/` and auto-syncs Claude Code
156
+ - **Enable globally** — Adds an explicit shared link under `~/.agents/skills/` without requiring a project
157
+ - **Clear enabled skill** — Removes project symlink only; source stays safe
158
+ - **Manage global skills** — Option 13 inspects, enables, and safely removes links owned by this central library under `~/.agents/skills/`
159
+ - **Manage Hermes skills** — Option 14 explicitly inspects, enables, and safely removes eligible links under `~/.hermes/skills/`
160
+ - **Sync Claude Code** — One-click sync `.claude/skills/` with `.agents/skills/`
161
+ - **Edit metadata** — Inline note, tags, auto-enable toggle per skill
162
+ - **View diagnostics** — Advice on duplicates, broken links, source drift
163
+ - **Track collection setup** — Distinguish enabled links from project-ready configuration and guide interactive setup
164
+ - **Resolve duplicate names** — Enable a selected source skill under a suggested or custom project alias without renaming the source
165
+ - **Refresh project** — Reload state, switch project path
166
+ - **Update GitHub sources** — Batch fast-forward pull `github/` repos
167
+ - **Batch Chinese notes** — Interactive flow (option 10) to fill missing Chinese `note` fields for skills that only have an English description
168
+ - **Install/check the global command** — Option 11 installs the CLI + TUI command from this clone
169
+ - **Acquire remote sources** — Option 12 adds complete HTTPS/SSH/SCP Git repositories, public HTTP(S) ZIP files, or stable direct HTTP(S) `/SKILL.md` files to the central library
170
+
171
+ Library browsing now shows skills in a compact paginated table (`n`/`p` to page through, `a` to bulk-enable). The skill introduction prefers the metadata `note` over the raw English `description` when both exist.
172
+
173
+ Menu navigation uses number keys (1-14) for actions, `/keyword` for search, `b` to go back, `q` to quit. Ideal for quick terminal workflows or headless environments.
174
+
175
+ To make the bundled `skillcaddy-manager` skill available to AI agents from any project, install its global entry once:
176
+
177
+ ```bash
178
+ npm run install:manager
179
+ npm run check:manager
180
+ ```
181
+
182
+ This creates a managed symlink at `~/.agents/skills/skillcaddy-manager` pointing back to `skills/skillcaddy-manager`. It will not overwrite an existing file, directory, or symlink that points somewhere else.
183
+
184
+ You can also pass the project path through the URL:
185
+
186
+ ```text
187
+ http://127.0.0.1:4173/?projectPath=<encoded-project-path>
188
+ ```
189
+
190
+ The page loads that project immediately, keeps recently used project paths in browser-local history, and lets you bulk-enable all available skills from a library with the library-level `+` button. The enabled panel groups project Agents, Claude Code, global Agents, and Hermes into explicit channel slots and provides one shared search across their enabled entries. If a library was enabled by mistake, use the library-level `×` button to clean that library from both Agents and Claude Code.
191
+
192
+ ## Skill metadata
193
+
194
+ `SKILL.md` remains the Agent-facing contract. Human-facing notes and categorization are stored by Skillcaddy under `.skillcaddy/metadata/.../skillcaddy.json` so external source repositories stay clean:
195
+
196
+ ```json
197
+ {
198
+ "note": "Useful before and after code changes to keep execution disciplined.",
199
+ "tags": ["Developer Tools", "Quality", "Workflow"],
200
+ "autoEnable": true
201
+ }
202
+ ```
203
+
204
+ Runtime scans and the web UI read metadata only from the local sidecar store. Tags appear as filter tabs and badge pills; notes are shown on each skill card. Set `autoEnable` to `false` to exclude a deprecated or risky skill from library-level bulk enable while still allowing single-skill manual enable. This keeps upstream source repositories clean while still making a large local skill library easier to browse.
205
+
206
+ Since v0.15.0, normal runtime scans ignore legacy `<skill-dir>/skillcaddy.json` files. The migration command explicitly discovers them, remains available through v0.15.x, and is removed in v0.16.0. Preview and apply the migration with:
207
+
208
+ ```bash
209
+ npm run migrate:metadata
210
+ npm run migrate:metadata -- --yes
211
+ ```
212
+
213
+ The apply command writes equivalent sidecar metadata and retains the legacy file for rollback. Runtime behavior changes only after the sidecar is written.
214
+
215
+ ## Collection setup lifecycle
216
+
217
+ Some collections require a one-time, per-project setup after their skills are enabled. Skillcaddy keeps these contracts outside third-party clones under `collection-metadata/<source>/<collection>.json`. `/api/state` reports each configured collection as `missing`, `partial`, `ready`, or `invalid`. Global enablement never runs or requests project setup.
218
+
219
+ Library-level enablement uses an explicit `scope` (`project`, `global`, or `hermes`) with `POST /api/enable-plan` and `POST /api/enable-collection` to apply the shared plan. Project scope includes declared setup guidance; global scope only creates `~/.agents/skills` links; Hermes scope accepts `official`, `github`, and `personal` skills and creates direct links under `~/.hermes/skills/`. One lifecycle classifies every candidate as enabled, unchanged, skipped, or failed. Enabling links remains allowed, but an incomplete project collection is shown as pending rather than ready. Interactive setup is never run silently, and collection metadata cannot provide executable shell commands.
220
+
221
+ ## Platform compatibility
222
+
223
+ | Platform | Status | Notes |
224
+ |----------|--------|-------|
225
+ | macOS | ✅ Fully supported | Native directory symlinks |
226
+ | Linux | ✅ Fully supported | Native directory symlinks |
227
+ | Windows | ⚠️ Extra setup required | See below |
228
+
229
+ ### Windows prerequisites
230
+
231
+ Skillcaddy creates directory symlinks via Node's `fs.symlink(..., 'dir')`. On Windows this call requires one of the following or it throws `EPERM`:
232
+
233
+ 1. **Enable Developer Mode (recommended)**
234
+ - Settings → Privacy & Security → For developers → **Developer Mode**
235
+ - Applies to Windows 10 Creators Update (1703) and above
236
+ 2. **Run as Administrator**
237
+ - Run `npm start` in an elevated terminal
238
+
239
+ ### Known Windows limitations
240
+
241
+ - `readlink` may return the target with a `\\?\` prefix or backslashes, which can affect the duplicate-alias-target detection (`existingTarget !== resolvedSkillPath` check in `enableSkill`).
242
+ - NTFS is case-insensitive by default, but the code compares aliases case-sensitively. Usually fine in practice, but aliases that differ only in case are treated as two different skills.
243
+ - No Windows-specific path normalization, junction fallback, or copy-downgrade.
244
+
245
+ ### Planned compatibility improvements (not implemented)
246
+
247
+ To make Skillcaddy work out of the box on Windows, the following strategies will be introduced later — but **none are implemented in the current version**:
248
+
249
+ - **Platform branch**: when `process.platform === 'win32'` is detected, prefer junction (`fs.symlink(target, path, 'junction')`); junctions don't require Developer Mode.
250
+ - **Failure fallback**: catch `EPERM` and recursively copy skill contents into `.agents/skills/`, and modify `disableSkill` to remove the real directory.
251
+ - **Path normalization**: `resolveLinkTarget` strips the `\\?\` prefix, normalizes separators, and compares case-insensitively on Windows.
252
+ - **README Windows section**: add PowerShell commands, disk-format requirements (NTFS), and a junction-vs-symlink trade-off note.
253
+
254
+ ## Architecture
255
+
256
+ ![Skillcaddy target architecture](docs/assets/skillcaddy-arch.svg)
257
+
258
+ **Core design**:
259
+ - `.agents/skills` is the cross-Agent standard path; every Agent recognizes it.
260
+ - `.claude/skills` is Claude-Code-specific, but uses secondary symlinks pointing back into `.agents/skills`.
261
+ - Skillcaddy's global scope manages only `~/.agents/skills/`; the global Claude directory is scanned by agents, not written by this manager.
262
+ - Enable once, share across multiple Agents; disable only removes the symlink, source files stay safe.
263
+
264
+ ## Directory layout
265
+
266
+ ```text
267
+ skillcaddy/ # code root
268
+ ├── lib/ # Manager code
269
+ ├── public/ # Web UI
270
+ ├── scripts/ # Entry points and maintenance scripts (e.g. pull-github.sh)
271
+ ├── skills/ # Repo-bundled skills (ships with the program; currently hosts skillcaddy-manager)
272
+ ├── collection-metadata/ # Collection setup contracts
273
+ ├── server.js
274
+ └── test/
275
+
276
+ ~/.skillcaddy/library/ # library root (packaged installs)
277
+ ├── official/ # Official / upstream skills
278
+ ├── github/ # Skills cloned from GitHub
279
+ ├── personal/ # Personal original skills
280
+ ├── archived/ # Retired skills
281
+ └── .skillcaddy/ # Source registry + skill metadata sidecars
282
+ ```
283
+
284
+ The four external skill source directories (`official / github / personal / archived`) are added to `.gitignore`. Use the managed source commands below instead of choosing a destination manually. `skills/` is the repo-bundled source, shipped with this project, and is **not** in `.gitignore`.
285
+
286
+ ## Managed source acquisition
287
+
288
+ The first release is exposed through repository-local npm commands:
289
+
290
+ ```bash
291
+ # Read-only inventory and inspection
292
+ npm run source -- list
293
+
294
+ # Move the central library, including offline sources and user enablements
295
+ npm run source -- image export /path/to/library.tar.gz
296
+ npm run source -- image import /path/to/library.tar.gz --dry-run
297
+ npm run source -- image import /path/to/library.tar.gz --yes
298
+ npm run source -- inspect github/example/toolbox
299
+
300
+ # Preview, then acquire a Git repo, public HTTP(S) ZIP, direct SKILL.md,
301
+ # local ZIP, or local directory
302
+ npm run source -- add <input>
303
+ npm run source -- add <input> --yes
304
+
305
+ # Direct SKILL.md requires an explicit name and installs under official/<name>/
306
+ npm run source -- add https://example.com/SKILL.md --name example --yes
307
+
308
+ # Replace one registered source; Archive/Local updates require a new input,
309
+ # while Git/Remote file updates may reuse their registered origin
310
+ npm run source -- update <source-id> [input] --project /path/to/project
311
+ npm run source -- update <source-id> [input] --allow-breaking --yes --project /path/to/project
312
+
313
+ # Update all registered Git sources through the same safety path
314
+ npm run source -- update-git --project /path/to/project
315
+ # Show the affected skill paths in the update summary
316
+ npm run source -- update-git --verbose --project /path/to/project
317
+ ```
318
+
319
+ `add` and `update` are separate operations. An identical repeated add is a successful no-op, while an identity or destination collision stops without authorizing replacement. Use `--name` or `--namespace` to resolve Archive/Local naming collisions. Remote files require `--name` and reject `--namespace`; use `update` only for a source identity already present in the source registry. A Remote-file update may omit input to reuse the registered origin or supply a new stable URL to migrate that origin.
320
+
321
+ CLI exit categories are stable: `0` success or identical no-op, `1` general acquisition/update failure, `2` invalid usage, `3` unresolved identity or collision, and `4` missing authorization for a breaking replacement.
322
+
323
+ Acquisition changes only the central library. It never creates project links, executes acquired code, runs setup, or invokes runtime preflight. Enablement uses an already acquired skill through the existing Web, TUI, or project-link API. For an explicit combined request, acquire first, rescan state, resolve the one requested skill by full ID, and enable only that selection.
324
+
325
+ Unknown setup readiness produces no generic warning or gate. A declared setup contract may add a non-blocking reminder after enablement. The publisher skill's runtime preflight remains responsible for proprietary credentials and setup, such as an IMA API key.
326
+
327
+ ### Adopt an existing library
328
+
329
+ Migration preserves physical source paths and project links. Preview it first:
330
+
331
+ ```bash
332
+ npm run source -- migrate
333
+ npm run source -- migrate --yes
334
+ ```
335
+
336
+ Library image export requires registered bucket contents and intact non-Git integrity baselines. When the library root is a git repository, the export additionally requires a clean, pushed working tree; when it is a plain directory, that repository-state check is skipped. Library images contain complete nested Git repositories and user enablements; project enablements and `skillcaddy-manager` are excluded. Import never replaces differing source bytes or existing aliases. A partial source submission reports committed, uncommitted, and unattempted sources; rerun the same library image to resume. See [the implementation contract](docs/LIBRARY_IMAGE_SPEC.md) and [verification notes](docs/LIBRARY_IMAGE_IMPLEMENTATION.md).
337
+
338
+ The apply command writes only sidecar records under `.skillcaddy/sources/`; ambiguous sources remain unresolved rather than guessed. For extra recovery protection, copy that registry directory before applying. Restoring that copy restores the previous registry state without moving central-library content. Failed add and update operations clean up or roll back automatically; after any interruption, run `npm run source -- list` and `npm run source -- inspect <source-id>` before retrying.
339
+
340
+ The first release supports complete Git repositories, public HTTP(S) ZIP files, stable direct HTTP(S) `/SKILL.md` files, local ZIP files, and local directories through the CLI. TUI option 12 also acquires complete HTTPS/SSH/SCP Git repositories, public HTTP(S) ZIP files, and stable direct HTTP(S) `/SKILL.md` files into the central library only; it does not create project links, run setup, or invoke runtime preflight. Web source acquisition, replacement, and removal remain out of scope, as do TUI source replacement and removal, automatic latest-version selection, and non-ZIP archives. The global `skillcaddy` command exposes Web lifecycle, read-only analysis, and registered-Git update entry points while retaining the existing source-management boundaries. Skillcaddy is distributed as an npm package and a Homebrew formula, but the program and the library remain separate: installing the program never moves, rewrites, or deletes the library. A Remote file acquires only one `SKILL.md`; skills with companion files must use a ZIP, Local, or complete Git source.
341
+
342
+ Bundled with this repo (only when contributing to Skillcaddy itself):
343
+
344
+ ```text
345
+ skills/<skill-name>/
346
+ ├── SKILL.md
347
+ └── agents/
348
+ └── openai.yaml # Codex / OpenCode metadata (optional)
349
+ ```
350
+
351
+ Skills under `skills/` are tagged during scan as `source: 'local'`, `id: 'local/<name>'` — behavior is identical to other sources and they can be enabled into any project's `.agents/skills/`.
352
+
353
+ On startup the manager scans every source directory (`official / github / personal / archived / skills`); no service restart is needed to see new skills in the UI.
354
+
355
+ ## Updating Git sources
356
+
357
+ Update every registered Git source through the unified fast-forward-only safety path. Dirty working trees are skipped, and breaking updates that affect a known project or global link are blocked:
358
+
359
+ ```bash
360
+ npm run source -- update-git --project /path/to/project
361
+ ```
362
+
363
+ `--project` is required so project links are checked; global `~/.agents/skills/`
364
+ links are always scanned as well. A breaking update reports project, global, and Hermes
365
+ links separately. `--allow-breaking` authorizes the source replacement but
366
+ leaves affected links in place, where they may become broken.
367
+
368
+ Successful Git updates print a temporary summary containing the commit range and
369
+ the number of added, edited, and deleted skills. Use `--verbose` to list those
370
+ skill paths. The summary is command output only; it does not write descriptions,
371
+ commit messages, or diff content into the source registry or the central skill
372
+ library.
373
+
374
+ The installed global command supports the same detail mode:
375
+
376
+ ```bash
377
+ skillcaddy -u --verbose /path/to/project
378
+ ```
379
+
380
+ If a registered Git checkout was advanced manually with `git pull`, repair only
381
+ the sidecar registry with an explicit adoption plan:
382
+
383
+ ```bash
384
+ npm run source -- repair github/<owner>/<repo> --project /path/to/project
385
+ npm run source -- repair github/<owner>/<repo> --project /path/to/project --yes
386
+ ```
387
+
388
+ Repair does not pull, overwrite, stash, or reset the checkout. It only adopts a
389
+ clean checkout that is on the registered ref, matches its configured remote,
390
+ has advanced by fast-forward, and passes source validation. Breaking project
391
+ links still require `--allow-breaking`; dirty checkouts are left untouched and
392
+ reported as reminders.
393
+
394
+ ## Skills bundled with this project
395
+
396
+ ### skillcaddy-manager
397
+
398
+ Lets an Agent (especially Codex) know how to use Skillcaddy itself correctly:
399
+
400
+ - List currently available skills (source / collection / alias / path)
401
+ - Enable / disable a single skill, or batch-operate on a whole source / collection
402
+ - Sync Claude Code entry points
403
+ - Update GitHub-source local clones
404
+ - Health check (broken links, alias conflicts, archived mis-enabled)
405
+ - Detect conflicts and require user confirmation
406
+
407
+ **Safety rules**: operate only on explicit project, global `.agents/skills`, or Hermes `~/.hermes/skills` scopes; never delete central source files; never take over ordinary or foreign entries; Hermes accepts only `official`/`github`/`personal` sources; never touch `archived/` unless explicitly named; always produce a dry-run summary before any state change.
408
+
409
+ **Invocation**: `agents/openai.yaml` sets `allow_implicit_invocation: true`, so the Agent auto-loads it when seeing a relevant request.
410
+
411
+ ## Enable / Disable
412
+
413
+ **Enable**: creates a symlink in the selected scope pointing back into the central library. Project scope also best-effort syncs Claude Code; global scope writes only `~/.agents/`; Hermes scope writes only `~/.hermes/` for eligible sources.
414
+
415
+ ```text
416
+ <project>/.agents/skills/<alias> -> <skillcaddy>/<source>/<skill>
417
+ ```
418
+
419
+ ```text
420
+ ~/.agents/skills/<alias> -> <skillcaddy>/<source>/<skill>
421
+ ```
422
+
423
+ **Sync Claude**: creates a `.claude/skills/` entry point for Claude Code, where each skill symlinks into `.agents/skills/`.
424
+
425
+ ```text
426
+ <project>/.claude/skills/<alias> -> ../../.agents/skills/<alias>
427
+ ```
428
+
429
+ **Disable**: removes the selected-scope symlink. The source file is left untouched. Global cleanup removes only links whose target is proven to belong to the current Skillcaddy library; foreign links and ordinary directories remain read-only.
430
+
431
+ **Why two layers of symlinks?**
432
+ - `.agents/skills` is the Agent Skills standard; Codex / OpenCode / Pi all recognize it.
433
+ - `.claude/skills` lets Claude Code use them too, with independent enable/disable.
434
+ - Global enablement is Agents-only by design; it never writes `~/.claude/skills`.
435
+ - Enable once, share across Agents; disable doesn't touch the source files — safe and reversible.
436
+
437
+ ## Recommendation System
438
+
439
+ Skillcaddy includes a built-in recommendation system to help users discover and choose appropriate skills.
440
+
441
+ ### Quick View
442
+
443
+ ```bash
444
+ node skills/skillcaddy-manager/scripts/view-recommendations.cjs onboarding
445
+ node skills/skillcaddy-manager/scripts/view-recommendations.cjs scenario new-project
446
+ ```
447
+
448
+ ### Recommendation Principles
449
+
450
+ - **Analyze first**: Inspect the current library and project context before recommending
451
+ - **Platform first**: Empty libraries should start with discovery platforms, not a fixed starter library
452
+ - **Scenario split**: mattpocock + lencx is for clear development workflows, not the blank default
453
+ - **Overlap review**: Compare collection names, capability lists, and descriptions before enabling similar libraries
454
+ - **Global detection**: Detect global skills directories and suggest unified management
455
+
456
+ ### Empty-Library Default
457
+
458
+ When the library is empty, the default recommendation is:
459
+
460
+ 1. Discovery platforms: `skillsmp`, `skills.sh`
461
+ 2. Then classify the use case: development, writing, research, design
462
+ 3. Only after that, choose a starter library
463
+
464
+ ### Development Starter
465
+
466
+ **Development workflow golden combo:**
467
+
468
+ 1. **mattpocock/skills** (workflow suite)
469
+ - Setup: guided `setup-matt-pocock-skills` project configuration with readiness tracking
470
+ - Includes: TDD, domain modeling, debugging, implementation, grilling
471
+
472
+ 2. **lencx/skills** (project control)
473
+ - coding-protocol: Prevent AI from making unintended changes
474
+ - keel: Architecture governance
475
+
476
+ ### Utility Scripts
477
+
478
+ ```bash
479
+ node skills/skillcaddy-manager/scripts/check-conflicts.cjs <collection-id> --against <installed-id,installed-id>
480
+ node skills/skillcaddy-manager/scripts/check-global-skills.cjs
481
+ node skills/skillcaddy-manager/scripts/version-manager.cjs check
482
+ ```
483
+
484
+ See [the Skillcaddy manager recommendation branch](skills/skillcaddy-manager/references/RECOMMENDATION_GUIDE.md) for detailed documentation.
485
+
486
+
487
+ ## Tests
488
+
489
+ ```bash
490
+ npm test
491
+ ```
492
+
493
+ ## Link
494
+
495
+ Inspired by the author of this WeChat Official Account: [Thought Prototype](https://mp.weixin.qq.com/s/HOj99MT5F4ecSAFkvJfVvQ)
496
+
497
+ [Linux Do](https://linux.do/)
498
+ [浅谈 AI 编程](https://mp.weixin.qq.com/s/f-NIkyxIuA8vjAUDp1bh5w)
499
+ [深度思考:架构腐朽 & Loop Engineering](https://mp.weixin.qq.com/s/wINKSDQCroWBvf29h567zA)