agentic-skill-mill 1.0.10 → 1.0.11

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.
@@ -1,555 +0,0 @@
1
- ---
2
- managed_by: agentic-skill-mill
3
- trigger: manual
4
- description: "\"Build, augment, and maintain skill projects that follow the skill-system-template architecture. Covers adding CLI commands, creating fragments, composing skills, renaming projects, and turning research into actionable tooling. Use when the user mentions: add a command, new skill, new fragment, augment the CLI, build a utility, add a tool, rename the project, forge a component, or wants to extend an existing skill project.\""
5
- ---
6
-
7
- # Agentic Skill Mill
8
-
9
- Forge and refine skill projects that follow the skill-system-template architecture: fragment-composed skills compiled to multiple IDE targets, paired with a TypeScript companion CLI (`skillmill`) that provides structured commands for agents and humans. Prefer `npx --yes agentic-skill-mill@latest <command>` when the utility is not globally installed. Remote users can install everything via `bash <(curl -fsSL https://agenticskillmill.com/install.sh) --all`.
10
-
11
- ---
12
-
13
- ## Architecture
14
-
15
- The skill-system-template architecture has two halves that meet at the agent:
16
-
17
- ```
18
- Skills (what to do) CLI Companion (tools to do it with)
19
- skill/skills/*.md src/cli/commands/*.ts
20
- skill/fragments/*.md src/core/*.ts
21
- | |
22
- v v
23
- compiled/ (7 IDE formats) dist/ (npm -> npx or global CLI)
24
- | |
25
- +---------> Agent <----------+
26
- ^
27
- |
28
- Distribution: npm publish + agenticskillmill.com
29
- .github/workflows/release.yml (build, test, version, publish)
30
- .github/workflows/deploy-pages.yml (site/ -> GitHub Pages)
31
- site/install.sh (curl-friendly bootstrap)
32
- ```
33
-
34
- **Skills** are step-by-step runbooks in markdown with YAML frontmatter. They tell the agent *what* to do. Skills reference the CLI by name so the agent can invoke structured commands.
35
-
36
- **Fragments** are shared knowledge blocks included by multiple skills via include markers (`\{\{include:path\}\}`). Edit a fragment once, recompile, and every skill that includes it gets the update. Fragments have no frontmatter.
37
-
38
- **The compiler** (`skill/build/compile.mjs`) resolves includes, applies IDE-specific frontmatter transforms, and writes to `compiled/` with one subdirectory per target. It validates naming rules, checks for unresolved includes, and cross-validates manifest declarations against actual includes in source files.
39
-
40
- **The CLI companion** is a TypeScript package with:
41
- - `src/core/` — Pure logic modules with typed interfaces
42
- - `src/cli/commands/` — Thin command wrappers that delegate to core modules
43
- - `src/cli/index.ts` — Commander.js entry point wiring all commands
44
- - `src/cli/output-formatter.ts` — JSON, table, and key-value formatters
45
- - `src/errors/types.ts` — Typed error hierarchy (AppError, NotFoundError, etc.)
46
- - `src/cache/cache-manager.ts` — Two-tier cache (memory + disk) with TTL
47
-
48
- **Local installers:** Every project ships `install.sh` (bash) and `install.ps1` (PowerShell). Both support the same flags and produce identical installed state.
49
-
50
- **The local installer** (`install-local.sh`) builds the CLI, compiles skills, and copies compiled outputs to IDE-specific directories (~/.claude/skills, ~/.cursor/rules, etc.) with marker-based stale file cleanup. The bootstrap installer is hosted at `https://agenticskillmill.com/install.sh` (source: `site/install.sh`) and is also bundled in the npm package as `install.sh`. It installs the npm utility first, then delegates to `install-local.sh --skills-only`. Local installer functions use `set -e` for fail-fast behavior. Any function that uses an early-exit guard (`[[ -d ... ]] || return`, `[[ -z ... ]] && return`) **must** use `return 0`, never bare `return`. Bare `return` inherits the exit code of the last command, which for a failed conditional test is 1 -- and `set -e` treats that as a script-terminating failure with no error message.
51
-
52
- ### Key files to modify when augmenting a project
53
-
54
- | What | File(s) |
55
- |------|---------|
56
- | Add a CLI command | `src/core/<name>.ts`, `src/cli/commands/<name>.ts`, `src/cli/index.ts`, `src/index.ts` |
57
- | Add a fragment | `skill/fragments/<category>/<name>.md`, `skill/build/manifest.json`, skill source |
58
- | Add a skill | `skill/skills/<name>/<name>.md`, `skill/build/manifest.json`, `install-local.sh` SKILLS array |
59
- | Change installer behavior | `install.sh` and `install.ps1` (repo root), then copy bootstraps to `site/` |
60
- | Update the landing page | `site/index.html`, `site/style.css` |
61
- | Change CI secrets or workflow | `.github/workflows/release.yml` or `deploy-pages.yml`, repo settings |
62
- | Rename the project | See the rename workflow |
63
-
64
- ---
65
-
66
- ## Distribution and CI
67
-
68
- ### Distribution model
69
-
70
- The project is published to npmjs as a public package and hosted at `https://agenticskillmill.com`.
71
-
72
- **Remote install (no clone):** Every project hosts `site/install.sh` and `site/install.ps1` bootstrap scripts served via GitHub Pages. Non-npm projects use a clone-to-temp pattern instead of `npm install -g`.
73
-
74
- There are multiple ways users consume it:
75
-
76
- | Method | Command | Who uses it |
77
- |--------|---------|-------------|
78
- | Remote install (bash) | `bash <(curl -fsSL https://<domain>/install.sh)` | End users on Linux/macOS |
79
- | Remote install (PowerShell) | `irm https://<domain>/install.ps1 \| iex` | End users on Windows |
80
- | npx (no install) | `npx --yes agentic-skill-mill@latest <command>` | Users running CLI commands without global install |
81
- | Local development | `git clone` then `bash install-local.sh --all` | Contributors working on the project itself |
82
-
83
- ### Two installer scripts
84
-
85
- **`install-local.sh`** is the full local installer. It runs from a cloned repo and handles:
86
- - `npm install` + `npm run build` + `npm run compile`
87
- - `npm link` to make `skillmill` available globally
88
- - Copies compiled skill outputs to IDE-specific directories (~/.claude/skills, ~/.cursor/rules, etc.)
89
- - Supports `--skills-only` (skip build, just copy), `--uninstall`, `--compile-only`, and per-tool flags (`--cursor`, `--claude`, etc.)
90
- - Auto-detects installed tools when no flags are provided
91
-
92
- **`install.sh`** is the remote bootstrap installer. It is hosted at `https://agenticskillmill.com/install.sh` (source: `site/install.sh`) and bundled in the npm package. It:
93
- 1. Runs `npm install -g agentic-skill-mill@latest`
94
- 2. Locates `install-local.sh` inside the globally installed package
95
- 3. Delegates to `install-local.sh --skills-only` with the user's flags
96
-
97
- Both scripts respect environment overrides `SKILLMILL_PACKAGE_NAME` and `SKILLMILL_PACKAGE_VERSION`.
98
-
99
- ### npm package contents
100
-
101
- The `files` array in `package.json` controls what ships to npm:
102
-
103
- | Entry | Purpose |
104
- |-------|---------|
105
- | `dist` | Compiled TypeScript CLI and library |
106
- | `compiled` | Pre-compiled skill outputs for all 7 IDE targets |
107
- | `skill` | Skill sources, fragments, compiler, and manifest |
108
- | `README.md` | Package documentation |
109
- | `install.sh` | Bootstrap installer (bundled for remote delegation) |
110
- | `install-local.sh` | Full local installer (used by bootstrap in --skills-only mode) |
111
-
112
- The `bin` field maps `skillmill` to `dist/cli/index.js`, so `npx agentic-skill-mill` and global install both expose the `skillmill` command.
113
-
114
- ### GitHub Actions workflows
115
-
116
- **Release to npm** (`.github/workflows/release.yml`):
117
- - Triggers on push to `main` or `workflow_dispatch`
118
- - Skips runs caused by its own release commits (loop guard via `chore(release):` in commit message)
119
- - Steps: `npm ci` -> `npm run build` -> `npm run test -- --passWithNoTests` -> `npm run compile` -> `npm run compile:validate` -> version bump -> `git push --follow-tags` -> `npm publish --access public`
120
- - Version bump finds the next available patch tag to avoid collisions with existing tags
121
- - Required secrets: `AGENT_TOKEN` (PAT with repo scope for push), `AGENT_NPM_TOKEN` (npm automation token for publish)
122
-
123
- **Deploy GitHub Pages** (`.github/workflows/deploy-pages.yml`):
124
- - Triggers on push to `main` when files in `site/` change, or `workflow_dispatch`
125
- - Uploads `site/` directory as the Pages artifact
126
- - Deploys to the `github-pages` environment at `agenticskillmill.com`
127
-
128
- ### The `site/` directory
129
-
130
- Static site served via GitHub Pages at `https://agenticskillmill.com`:
131
-
132
- | File | Purpose |
133
- |------|---------|
134
- | `site/CNAME` | Custom domain binding |
135
- | `site/index.html` | Landing page with architecture, CLI commands, and install instructions |
136
- | `site/style.css` | Site styles |
137
- | `site/install.sh` | Bootstrap installer served at `https://agenticskillmill.com/install.sh` |
138
- | `site/install.ps1` | PowerShell bootstrap installer served at `https://agenticskillmill.com/install.ps1` |
139
-
140
- When updating the bootstrap installer logic, edit `install.sh` and `install.ps1` at the repo root and copy them to `site/install.sh` and `site/install.ps1` to keep both in sync. The release workflow publishes the repo-root copies to npm; the Pages workflow serves the site copies to the domain.
141
-
142
- ### Modifying distribution touchpoints
143
-
144
- | Change | Files to update |
145
- |--------|----------------|
146
- | Add a new skill | `install-local.sh` SKILLS array, `skill/build/manifest.json` |
147
- | Change package name | `package.json` name + bin, `install.sh` default, `site/install.sh` default, `install-local.sh` PROJECT_NAME + CLI_BIN_NAME + MANAGED_MARKER, `site/index.html`, README |
148
- | Change bootstrap behavior | `install.sh` and `install.ps1` (repo root), then copy to `site/install.sh` and `site/install.ps1` |
149
- | Add a GitHub Actions secret | Repo settings, document in README |
150
- | Update domain | `site/CNAME`, README, skill source, architecture fragment |
151
-
152
- ---
153
-
154
- ## Workflow
155
-
156
- ### Step 1: Understand the Goal
157
-
158
- Ask or infer:
159
-
160
- | Question | Why It Matters |
161
- |----------|---------------|
162
- | What is the user trying to add or change? | Scopes the work: new command, new skill, new fragment, rename, or full project |
163
- | Is there research or a requirements document? | Source material drives which CLI commands to build |
164
- | What's the existing project state? | Read manifest.json, package.json, and src/cli/index.ts to understand what's already built |
165
- | Does this need a new skill, a new fragment, or just a new CLI command? | Different paths require different steps |
166
-
167
- ### Step 2: Read the Project State
168
-
169
- Before making changes, read these files to understand the current structure:
170
-
171
- 1. `skill/build/manifest.json` — what skills and fragments exist
172
- 2. `src/cli/index.ts` — what CLI commands are wired
173
- 3. `src/index.ts` — what's exported
174
- 4. `package.json` — package name, bin name, dependencies
175
-
176
- ### Step 3: If Adding CLI Commands from Research
177
-
178
- ### Extracting CLI utilities from research
179
-
180
- When research documents, field observations, or domain expertise suggest actionable tooling, follow this process to turn insights into CLI commands:
181
-
182
- **Step 1: Read the research and tag actionable items**
183
-
184
- Scan the source material for:
185
- - Checklists that could be generated dynamically (checklist generator command)
186
- - Calculations that depend on user inputs (calculator command)
187
- - Validation rules that can be checked programmatically (validator command)
188
- - Structured data that can be extracted from existing files (extractor command)
189
- - Schedules or plans that follow a formula (planner command)
190
- - Analysis that can be automated against a codebase or artifact (scanner command)
191
-
192
- **Step 2: Group by command**
193
-
194
- Each command should do one thing well. If two items from the research share the same input and output shape, they belong in one command. If they have different inputs, they're separate commands.
195
-
196
- | Research insight | CLI command type | Example |
197
- |-----------------|-----------------|---------|
198
- | "Audiences retain 3+/-1 points" | Validator | Check that outlines have 2-4 key sections |
199
- | "Budget 130 WPM for speaking" | Calculator | Compute per-section word counts from time budgets |
200
- | "Spaced retrieval beats rereading" | Planner | Generate rehearsal schedule from event date |
201
- | "Audio quality affects credibility" | Checklist | Pre-flight checklist with audio test item |
202
- | "Entry points tell the story structure" | Scanner | Analyze repo for entry points and connectivity |
203
-
204
- **Step 3: Define the interface before writing code**
205
-
206
- For each command, write the TypeScript interface first:
207
- - What does the user provide? (Options interface)
208
- - What does the command return? (Result interface)
209
- - What warnings can it produce? (`warnings: string[]` in Result)
210
-
211
- **Step 4: Implement bottom-up**
212
-
213
- 1. Core module in `src/core/` (pure logic, no CLI concerns)
214
- 2. Command wrapper in `src/cli/commands/` (thin delegate)
215
- 3. Wire into `src/cli/index.ts` (with --json support)
216
- 4. Export from `src/index.ts` (for library consumers)
217
- 5. Build and verify: `npm run build && node dist/cli/index.js <command> --help`
218
-
219
- **Step 5: Embed the research rationale**
220
-
221
- When a command produces items (checklist entries, warnings, schedule sessions), include a `rationale` or `description` field that cites the research principle. This teaches the user *why*, not just *what*.
222
-
223
- ### Step 4: Implement Core Modules
224
-
225
- Every CLI command starts as a **core module** in `src/core/`. Core modules contain pure domain logic with no CLI concerns (no chalk, no console.log, no process.exit). This separation lets the logic be consumed as a library, tested independently, and composed by multiple commands.
226
-
227
- ### Structure of a core module
228
-
229
- ```typescript
230
- // src/core/<name>.ts
231
-
232
- /** Input options -- everything the caller needs to provide */
233
- export interface <Name>Options {
234
- requiredParam: string;
235
- optionalParam?: number;
236
- }
237
-
238
- /** Output result -- everything the caller gets back */
239
- export interface <Name>Result {
240
- data: SomeType[];
241
- warnings: string[];
242
- }
243
-
244
- /** Pure function: options in, result out. No side effects on stdout. */
245
- export function <name>(options: <Name>Options): <Name>Result {
246
- return { data: [], warnings: [] };
247
- }
248
- ```
249
-
250
- ### Rules
251
-
252
- - **Export typed interfaces** for both input and output so consumers get autocomplete and type safety
253
- - **Return structured data**, never print to stdout -- the CLI wrapper decides how to format
254
- - **Include a `warnings` array** in results when the function can detect non-fatal issues
255
- - **Use `async` only when needed** (file I/O, network) -- synchronous logic stays synchronous
256
- - **Throw typed errors** from `src/errors/types.ts` for unrecoverable failures
257
- - **Keep modules focused** -- one concept per file. A pace calculator doesn't also validate outlines
258
- - **Accept paths and options, not raw CLI strings** -- parsing belongs in the command wrapper
259
-
260
- ### Shared parsers
261
-
262
- When two or more commands need to parse the same input format, extract a shared parser module. The parser returns a structured type that both consumers work with.
263
-
264
- ### Step 5: Implement CLI Command Wrappers
265
-
266
- ### Command wrapper pattern
267
-
268
- Each CLI command lives in `src/cli/commands/<name>.ts` as a thin wrapper:
269
-
270
- ```typescript
271
- // src/cli/commands/<name>.ts
272
- import { doThing, type ThingOptions, type ThingResult } from '../../core/<name>.js';
273
-
274
- export interface ThingCommandOptions extends ThingOptions {
275
- json: boolean;
276
- }
277
-
278
- export async function thingCommand(
279
- options: ThingCommandOptions,
280
- ): Promise<ThingResult> {
281
- return doThing({
282
- param: options.param,
283
- });
284
- }
285
- ```
286
-
287
- **Rules for command wrappers:**
288
- - Import from core module using `.js` extension (ESM resolution)
289
- - Extend the core options interface with `json: boolean`
290
- - Delegate immediately to the core function -- no business logic in the wrapper
291
- - Return the core result type -- formatting happens in `index.ts`
292
-
293
- ### Wiring into the CLI entry point
294
-
295
- Add the command in `src/cli/index.ts`:
296
-
297
- ```typescript
298
- import { thingCommand } from './commands/<name>.js';
299
-
300
- program
301
- .command('<name>')
302
- .description('One-line description of what this does')
303
- .argument('<required>', 'Description of required positional arg') // if needed
304
- .requiredOption('--param <value>', 'Required option description') // if needed
305
- .option('--json', 'Output as JSON', false)
306
- .option('--optional <value>', 'Optional flag', 'default')
307
- .action(async (positionalArg, options) => {
308
- try {
309
- const result = await thingCommand({
310
- param: positionalArg,
311
- json: options.json,
312
- });
313
-
314
- if (options.json) {
315
- console.log(JSON.stringify(result, null, 2));
316
- } else {
317
- // Human-readable output using chalk
318
- console.log();
319
- console.log(chalk.bold('Title'));
320
- for (const item of result.data) {
321
- console.log(` ${item}`);
322
- }
323
- console.log();
324
- }
325
- } catch (error) {
326
- handleError(error);
327
- }
328
- });
329
- ```
330
-
331
- **Rules for CLI wiring:**
332
- - Every command supports `--json` for structured agent consumption
333
- - Human-readable output uses chalk for color and formatting
334
- - Errors funnel through the shared `handleError()` function
335
- - Use `.argument()` for required positional args, `.requiredOption()` for mandatory flags
336
- - Parse string options to their real types (parseInt, parseFloat) in the action handler
337
- - Comma-separated list options get `.split(',').map(s => s.trim())` in the action handler
338
-
339
- ### Updating exports
340
-
341
- After adding a new core module, export its public API from `src/index.ts`:
342
-
343
- ```typescript
344
- export { doThing } from './core/<name>.js';
345
- export type { ThingOptions, ThingResult } from './core/<name>.js';
346
- ```
347
-
348
- This allows the package to be consumed as a library, not just a CLI.
349
-
350
- ### Step 6: If Adding or Modifying Fragments
351
-
352
- ### Designing fragments
353
-
354
- Fragments are reusable knowledge blocks stored in `skill/fragments/<category>/`. They are included in skill sources via include markers (`\{\{include:path\}\}`) and resolved at compile time.
355
-
356
- **When to create a fragment:**
357
- - The knowledge applies to 2+ skills (or likely will in the future)
358
- - The content is self-contained and makes sense without its parent skill
359
- - Updating the knowledge in one place should propagate everywhere
360
-
361
- **When NOT to create a fragment:**
362
- - The content is specific to exactly one skill and unlikely to be reused
363
- - The content requires context from the surrounding skill to make sense
364
- - The content is a single sentence or table row (too small to justify the indirection)
365
-
366
- ### Fragment categories
367
-
368
- | Category | What goes here | Examples |
369
- |----------|---------------|---------|
370
- | `common/` | Rules and formats shared across all skills | Output format, guidelines, anti-patterns |
371
- | `domain/` | Deep domain knowledge specific to the project's subject area | Pacing tables, narrative patterns, voice guides |
372
- | `meta/` | Knowledge about the skill system itself | Architecture, patterns, workflows |
373
-
374
- ### Creating a fragment
375
-
376
- 1. **Create the file** at `skill/fragments/<category>/<name>.md`
377
- - No YAML frontmatter -- fragments are pure content
378
- - Write in the same imperative style as the parent skill
379
- - Use markdown headers starting at `###` (they'll be nested inside the skill's `##` sections)
380
-
381
- 2. **Include it in the skill source** with an include marker: `\{\{include:<category>/<name>.md\}\}`
382
-
383
- 3. **Declare it in manifest.json** under the skill's `fragments` array -- the compiler cross-validates these declarations against actual includes and errors on mismatches
384
-
385
- ### Fragment rules
386
-
387
- - **One level of includes only.** Fragments cannot include other fragments. This is enforced by the compiler.
388
- - **No frontmatter.** Fragments are content blocks, not standalone documents.
389
- - **Match the parent skill's voice.** If the skill uses imperative mood ("Do X"), the fragment should too.
390
- - **Fragments are inlined verbatim.** The compiler replaces include markers with the fragment content, trimming trailing whitespace. No wrapping, no indentation changes.
391
- - **Keep fragments focused.** A fragment about pacing shouldn't also cover narrative patterns. If they're separate concepts, they're separate fragments.
392
-
393
- ### Step 7: If Adding a New Skill
394
-
395
- Create the skill source at `skill/skills/<name>/<name>.md` with this structure:
396
-
397
- ```markdown
398
- ---
399
- name: <skill-name>
400
- description: "One sentence explaining what this skill does and when to invoke it."
401
- ---
402
-
403
- # Skill Title
404
-
405
- Brief description of what this skill produces.
406
-
407
- ---
408
-
409
- ## Section Name
410
-
411
- \{\{include:<category>/<fragment>.md\}\}
412
-
413
- ---
414
-
415
- ## Another Section
416
-
417
- Direct content or more includes.
418
- ```
419
-
420
- Then register it:
421
-
422
- 1. Add the skill entry to `skill/build/manifest.json` with its source path and fragment dependencies
423
- 2. Add the skill name to the `SKILLS` array in `install-local.sh`
424
- 3. Compile: `npm run compile`
425
-
426
- ### Step 8: If Renaming the Project
427
-
428
- ### Renaming a skill project
429
-
430
- When the project, skill, or CLI needs a new name, update all touchpoints in one pass to avoid stale references. The rename affects three identity layers:
431
-
432
- | Layer | Old example | New example |
433
- |-------|-------------|-------------|
434
- | npm package name | `presentation-creator` | `tech-demo-director` |
435
- | CLI binary name | `presentation-util` | `demo-director` |
436
- | Skill name + managed marker | `presentation-creator` | `tech-demo-director` |
437
-
438
- ### Rename checklist (in order)
439
-
440
- 1. **Skill source directory and file**
441
- ```bash
442
- mv skill/skills/<old>/ skill/skills/<new>/
443
- mv skill/skills/<new>/<old>.md skill/skills/<new>/<new>.md
444
- ```
445
-
446
- 2. **Skill source frontmatter** -- update `name:` and H1 title in the renamed .md
447
-
448
- 3. **Manifest** (`skill/build/manifest.json`) -- rename the skill key and `source` path
449
-
450
- 4. **Compiler marker** (`skill/build/compile.mjs`) -- update the `MANAGED_BY` constant
451
-
452
- 5. **Local installer** (`install-local.sh`) -- update `PROJECT_NAME`, `CLI_BIN_NAME`, `MANAGED_MARKER`, `SKILLS` array
453
-
454
- 6. **Bootstrap installer** (`install.sh`) -- update the default `PACKAGE_NAME`, then copy to `site/install.sh`
455
-
456
- 7. **Package metadata** (`package.json`) -- update `name`, `bin` key, and `description`
457
-
458
- 8. **CLI metadata** (`src/cli/index.ts`) -- update `.name()` and `.description()` calls
459
-
460
- 9. **README** -- update title, CLI references, project layout, npx examples, install URLs
461
-
462
- 10. **Landing page** (`site/index.html`) -- update title, CLI references, install commands, GitHub link
463
-
464
- 11. **GitHub Actions secrets** -- if the npm package name changed, verify `AGENT_NPM_TOKEN` still works for the new package scope
465
-
466
- 12. **Any docs** referencing the old name (translation-map, lessons-learned, etc.)
467
-
468
- 13. **Regenerate everything:**
469
- ```bash
470
- rm -rf compiled
471
- npm install # regenerates package-lock.json
472
- npm run build # rebuilds TypeScript CLI
473
- npm run compile # regenerates compiled/ under new paths
474
- ```
475
-
476
- ### Verification
477
-
478
- After renaming, run this sweep to confirm no stale references remain:
479
-
480
- ```bash
481
- grep -r "<old-name>" --include="*.md" --include="*.json" --include="*.mjs" --include="*.ts" --include="*.sh" --include="*.html" --include="*.yml" .
482
- ```
483
-
484
- The grep should return zero results (excluding node_modules and dist).
485
-
486
- ### Step 9: Build, Compile, and Verify
487
-
488
- After any change, run the full verification sequence:
489
-
490
- ```bash
491
- npm run build # TypeScript CLI compiles cleanly
492
- npm run compile # Skills compile to all 7 IDE targets
493
- npm run compile:validate # Cross-validates manifest vs source includes
494
- npx --yes agentic-skill-mill@latest --help # CLI command surface works via npx
495
- ```
496
-
497
- If adding a new CLI command, also verify it runs:
498
-
499
- ```bash
500
- npx --yes agentic-skill-mill@latest <command> --help # Options are correct
501
- npx --yes agentic-skill-mill@latest <command> <args> # Human output works
502
- npx --yes agentic-skill-mill@latest <command> --json # JSON output works
503
- ```
504
-
505
- ### Step 10: Commit
506
-
507
- Use conventional commit format with a detailed body:
508
-
509
- - `feat:` for new commands, skills, or fragments
510
- - `refactor:` for renames or restructuring
511
- - `fix:` for bug fixes
512
-
513
- The commit body should list every file category changed (core modules, CLI wrappers, fragments, manifest, etc.) and what was done in each.
514
-
515
- ### Cross-Artifact Skill Signature
516
-
517
- When updating or creating a skill, embed a deterministic signature in each externally searchable artifact so operators can query everything produced by that specific skill across systems.
518
-
519
- Derive the signature per skill name:
520
-
521
- - Compute `sha256("<skill-name>")`
522
- - Use the first 8 lowercase hex characters
523
- - Format as `skill-sig: <sig8>`
524
-
525
- For a given skill name, the value is permanently static across all versions.
526
-
527
- Example:
528
-
529
- - `sha256("3pp-skill")` -> `ad61853a...`
530
- - signature value: `skill-sig: ad61853a`
531
-
532
- ### Artifact Embedding Rules
533
-
534
- - **Commit message body**: append a git trailer after a blank line: `Skill-Sig: <sig8>`
535
- - **PR markdown doc**: append `<sub>skill-sig: <sig8></sub>` after the `## Notes` section
536
- - **GUS HTML details**: append `<p style="font-size:0.8em;color:#888">skill-sig: <sig8></p>` before closing `</body></html>`
537
-
538
- ### Searchability Targets
539
-
540
- - Git: `git log --grep="skill-sig: <sig8>"`
541
- - GitHub: search for `"skill-sig: <sig8>"`
542
- - GUS SOQL: `WHERE Details__c LIKE '%skill-sig: <sig8>%'`
543
-
544
- ---
545
-
546
- ## Anti-Patterns
547
-
548
- - **Business logic in CLI wrappers.** Command wrappers delegate; they don't compute.
549
- - **Console output in core modules.** Core modules return data; they don't print.
550
- - **Fragments that include fragments.** Only one level of includes is supported.
551
- - **Undeclared fragments.** Every include marker in a skill source must be declared in manifest.json. The compiler errors on mismatches.
552
- - **Stale compiled outputs.** Always recompile after changing skills or fragments. Run `npm run compile:validate` to detect staleness.
553
- - **Partial renames.** When renaming, update every touchpoint in one pass (see rename workflow). A grep sweep with zero results confirms completeness.
554
- - **Missing --json support.** Every CLI command must support `--json` for structured agent consumption. Agents cannot parse chalk-colored terminal output.
555
- - **Bare `return` in `set -e` scripts.** In `install-local.sh`, never write `[[ condition ]] || return` or `grep ... || return`. Bare `return` inherits the exit code of the failed test (1), which `set -e` treats as fatal -- killing the script silently. Always use `return 0` for early-exit guards: `[[ -d "$dir" ]] || return 0`, `[[ -z "$var" ]] && return 0`.