mustard-claude 3.0.2 → 3.0.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mustard-claude",
3
- "version": "3.0.2",
3
+ "version": "3.0.3",
4
4
  "description": "Framework-agnostic CLI for Claude Code project setup",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,76 @@
1
+ <!-- mustard:generated at:2026-03-25T00:00:00.000Z role:general -->
2
+ # Guards: Templates
3
+
4
+ > DO/DON'T rules for the Mustard templates subproject.
5
+
6
+ ## Hook Development
7
+
8
+ | Rule | Type |
9
+ |------|------|
10
+ | DO read all stdin before processing (`on('end', ...)`) | DO |
11
+ | DO fail-open: `catch → stderr + exit(0)` | DO |
12
+ | DO normalize Windows paths (`\` to `/`) before pattern matching | DO |
13
+ | DO use `process.exit(0)` for approve (silent exit) | DO |
14
+ | DO write JSON to stdout for block/deny/context responses | DO |
15
+ | DON'T use any npm dependencies — only Node.js built-ins | DON'T |
16
+ | DON'T throw unhandled exceptions — always wrap in try/catch | DON'T |
17
+ | DON'T block on parse errors — treat as approve | DON'T |
18
+ | DON'T use `console.log` for debugging — use `process.stderr.write` | DON'T |
19
+
20
+ ## Hook Response Protocol
21
+
22
+ | Rule | Type |
23
+ |------|------|
24
+ | DO use `permissionDecision: 'block'` or `'deny'` for PreToolUse hooks | DO |
25
+ | DO use `decision: 'approve'` or `'block'` for PostToolUse hooks | DO |
26
+ | DO include `hookEventName` matching the hook's lifecycle event | DO |
27
+ | DON'T mix PreToolUse and PostToolUse response formats | DON'T |
28
+
29
+ ## Settings & Wiring
30
+
31
+ | Rule | Type |
32
+ |------|------|
33
+ | DO register every new hook in `settings.json` under the correct lifecycle event | DO |
34
+ | DO set a `timeout` for every hook registration (3-15 seconds) | DO |
35
+ | DO use `$CLAUDE_PROJECT_DIR` in hook command paths | DO |
36
+ | DON'T add hooks without a `matcher` — every hook must declare what it matches | DON'T |
37
+
38
+ ## Commands (SKILL.md)
39
+
40
+ | Rule | Type |
41
+ |------|------|
42
+ | DO end every command SKILL.md with `ULTRATHINK` | DO |
43
+ | DO include `## Trigger` with exact invocation syntax | DO |
44
+ | DO include `## Rules` section with explicit constraints | DO |
45
+ | DON'T create commands that implement code directly — delegate via Task | DON'T |
46
+
47
+ ## Scripts
48
+
49
+ | Rule | Type |
50
+ |------|------|
51
+ | DO use `execSync` with `stdio: ['pipe','pipe','pipe']` and `windowsHide: true` | DO |
52
+ | DO set timeouts on all `execSync` calls | DO |
53
+ | DO handle missing files/dirs gracefully (try/catch around fs ops) | DO |
54
+ | DON'T import external packages — all scripts must be self-contained | DON'T |
55
+
56
+ ## Skills (SKILL.md)
57
+
58
+ | Rule | Type |
59
+ |------|------|
60
+ | DO include YAML frontmatter with `name` and `description` | DO |
61
+ | DO write "pushy" descriptions with casual trigger phrases | DO |
62
+ | DO add `<!-- mustard:generated -->` after the closing `---` | DO |
63
+ | DO keep SKILL.md under 500 lines (ideally under 200) | DO |
64
+ | DON'T put `<!-- mustard:generated -->` before the opening `---` | DON'T |
65
+ | DON'T use generic descriptions — be specific about what and when | DON'T |
66
+
67
+ ## Generated Files
68
+
69
+ | Rule | Type |
70
+ |------|------|
71
+ | DO start every generated file with `<!-- mustard:generated at:{ISO} role:{role} -->` | DO |
72
+ | DO include H1 title + blockquote description | DO |
73
+ | DO keep under 200 lines per file | DO |
74
+ | DO reference real files with `Ref: path/file.ext` | DO |
75
+ | DON'T include generic information — only data traced from real code | DON'T |
76
+ | DON'T overwrite files without `<!-- mustard:generated` header (manual files) | DON'T |
@@ -0,0 +1,22 @@
1
+ # Notes: Templates (General)
2
+
3
+ > Manual notes for the Mustard templates subproject. Never overwritten by /scan.
4
+
5
+ ## Mandatory Patterns
6
+
7
+ - All hooks read JSON from stdin and write JSON to stdout
8
+ - All hooks fail-open (exit 0 on error) except when explicitly blocking
9
+ - All generated files start with `<!-- mustard:generated -->` header
10
+ - Skills use YAML frontmatter with `name` and `description` fields
11
+
12
+ ## Known Pitfalls
13
+
14
+ - Hook stdin must be fully consumed before processing (`on('end', ...)`)
15
+ - Windows path separators must be normalized (`\` to `/`) in file-guard and guard-verify
16
+ - CLAUDE_PROJECT_DIR env var may not be set in all contexts — always fallback to cwd
17
+
18
+ ## Observations
19
+
20
+ - Templates are copied verbatim to target projects by `mustard init`/`mustard update`
21
+ - The `settings.json` defines the full hook wiring — any new hook must be registered there
22
+ - Skills in `skills/` are foundation skills (stack-agnostic); subproject-specific skills go in `{sub}/.claude/skills/`
@@ -0,0 +1,173 @@
1
+ <!-- mustard:generated at:2026-03-25T00:00:00.000Z role:general -->
2
+ # Patterns: Templates
3
+
4
+ > Recurring code patterns across hooks, scripts, and commands.
5
+
6
+ ## P1. Hook Stdin/Stdout Protocol
7
+
8
+ All hooks read JSON from stdin, process, and either exit silently (approve) or write JSON to stdout (block/deny/context).
9
+
10
+ ```js
11
+ let input = '';
12
+ process.stdin.setEncoding('utf8');
13
+ process.stdin.on('data', chunk => input += chunk);
14
+ process.stdin.on('end', () => {
15
+ const data = JSON.parse(input);
16
+ // ... process
17
+ process.exit(0); // approve (silent)
18
+ });
19
+ ```
20
+
21
+ Ref: `hooks/bash-safety.js`, `hooks/file-guard.js`, `hooks/enforce-registry.js`
22
+
23
+ ## P2. PreToolUse Block Response
24
+
25
+ Hooks that block return a specific JSON structure with `permissionDecision`:
26
+
27
+ ```js
28
+ console.log(JSON.stringify({
29
+ hookSpecificOutput: {
30
+ hookEventName: 'PreToolUse',
31
+ permissionDecision: 'block', // or 'deny'
32
+ permissionDecisionReason: 'Reason message'
33
+ }
34
+ }));
35
+ ```
36
+
37
+ Ref: `hooks/enforce-registry.js` (line 100-109), `hooks/bash-safety.js` (line 44-49)
38
+
39
+ ## P3. PostToolUse Approve/Block Response
40
+
41
+ PostToolUse hooks use `decision` field (not `permissionDecision`):
42
+
43
+ ```js
44
+ process.stdout.write(JSON.stringify({ decision: 'approve' }));
45
+ // or
46
+ process.stdout.write(JSON.stringify({ decision: 'block', reason: '...' }));
47
+ ```
48
+
49
+ Ref: `hooks/guard-verify.js` (line 60-95)
50
+
51
+ ## P4. Fail-Open Error Handling
52
+
53
+ Every hook wraps the main logic in try/catch and exits 0 on error — never blocking due to hook bugs:
54
+
55
+ ```js
56
+ } catch (err) {
57
+ process.stderr.write(`[hook-name] Error: ${err.message}\n`);
58
+ process.exit(0); // fail-open
59
+ }
60
+ ```
61
+
62
+ Ref: `hooks/bash-safety.js` (line 56-59), `hooks/file-guard.js` (line 57-60)
63
+
64
+ ## P5. Regex-Based Dangerous Command Detection
65
+
66
+ `bash-safety.js` uses an array of `{ re, msg }` objects tested sequentially against the command string:
67
+
68
+ ```js
69
+ const DANGEROUS = [
70
+ { re: /\brm\s+(-\w*r\w*f|...)\b/i, msg: 'Recursive force delete blocked' },
71
+ // ...
72
+ ];
73
+ for (const { re, msg } of DANGEROUS) {
74
+ if (re.test(cmd)) { /* deny */ }
75
+ }
76
+ ```
77
+
78
+ Ref: `hooks/bash-safety.js` (line 14-28)
79
+
80
+ ## P6. File Pattern Blocking
81
+
82
+ `file-guard.js` blocks access to sensitive files using regex patterns tested against both full path and basename:
83
+
84
+ ```js
85
+ const BLOCKED_PATTERNS = [/credentials/i, /\.pem$/i, /\.key$/i, ...];
86
+ for (const pattern of BLOCKED_PATTERNS) {
87
+ if (pattern.test(normalized) || pattern.test(basename)) { /* deny */ }
88
+ }
89
+ ```
90
+
91
+ Ref: `hooks/file-guard.js` (line 16-25)
92
+
93
+ ## P7. Role Detection via Scoring
94
+
95
+ `sync-detect.js` assigns numeric weights (HIGH=10, MEDIUM=5, LOW=3) to file/dep signals, accumulating scores per role. Highest score wins:
96
+
97
+ | Weight | Signal Type | Example |
98
+ |--------|------------|---------|
99
+ | HIGH (10) | Config files | `.csproj` with Sdk.Web, `next.config.*` |
100
+ | MEDIUM (5) | Package deps | `react` in package.json, `express` |
101
+ | LOW (3) | Directories | `Controllers/`, `app/` + `components/` |
102
+
103
+ Ref: `scripts/sync-detect.js` (line 210-327)
104
+
105
+ ## P8. SHA-256 Source Hashing for Incremental Scan
106
+
107
+ `sync-detect.js` computes deterministic hashes by sorting files and updating hash with both path and content:
108
+
109
+ ```js
110
+ const hash = crypto.createHash('sha256');
111
+ for (const file of files.sort()) {
112
+ hash.update(file); // path (rename-sensitive)
113
+ hash.update(content); // content
114
+ }
115
+ return hash.digest('hex');
116
+ ```
117
+
118
+ Ref: `scripts/sync-detect.js` (line 643-659)
119
+
120
+ ## P9. FIFO Queue with Type-Match Preference (Subagent Tracker)
121
+
122
+ Subagent tracker uses a queue to correlate Task tool calls with SubagentStart events. PreToolUse captures description; SubagentStart consumes by type-match first, FIFO fallback:
123
+
124
+ ```js
125
+ const typeIdx = queue.findIndex(q => q.type === agentType);
126
+ if (typeIdx >= 0) { /* consume type-matched entry */ }
127
+ else { /* FIFO: consume first */ }
128
+ ```
129
+
130
+ Ref: `hooks/subagent-tracker.js` (line 80-95)
131
+
132
+ ## P10. ANSI Statusline with Git Cache
133
+
134
+ `statusline.js` caches git status in a temp file with 5s TTL to avoid repeated `git` calls:
135
+
136
+ ```js
137
+ const GIT_CACHE_FILE = path.join(os.tmpdir(), 'claude-statusline-git.json');
138
+ const GIT_CACHE_TTL = 5000;
139
+ ```
140
+
141
+ Ref: `scripts/statusline.js` (line 17-18, 296-326)
142
+
143
+ ## P11. Command SKILL.md Structure
144
+
145
+ All slash commands follow the same structure: H1 title, trigger section, description, procedure/action, rules, and `ULTRATHINK` footer:
146
+
147
+ ```markdown
148
+ # /command-name - Title
149
+ ## Trigger
150
+ `/command-name <args>`
151
+ ## Description / ## Procedure / ## Action
152
+ ...
153
+ ## Rules
154
+ ...
155
+ ULTRATHINK
156
+ ```
157
+
158
+ Ref: `commands/mustard/feature/SKILL.md`, `commands/mustard/bugfix/SKILL.md`
159
+
160
+ ## P12. Foundation Skill YAML Frontmatter
161
+
162
+ Foundation skills use YAML frontmatter with `name`, `description`, and optional `disable-model-invocation`:
163
+
164
+ ```yaml
165
+ ---
166
+ name: skill-name
167
+ description: "What it does. When to use it."
168
+ disable-model-invocation: true
169
+ ---
170
+ <!-- mustard:generated -->
171
+ ```
172
+
173
+ Ref: `skills/commit-workflow/SKILL.md`, `skills/pipeline-execution/SKILL.md`
@@ -0,0 +1,91 @@
1
+ <!-- mustard:generated at:2026-03-25T00:00:00.000Z role:general -->
2
+ # Recipes: Templates
3
+
4
+ > Implementation recipes for common tasks in the templates subproject.
5
+
6
+ ## Recipe: New Hook
7
+
8
+ ### Steps
9
+ 1. Create `hooks/{hook-name}.js` following stdin/stdout protocol → `patterns.md` P1
10
+ 2. Implement logic with fail-open error handling → `patterns.md` P4
11
+ 3. Choose response format: PreToolUse (`permissionDecision`) or PostToolUse (`decision`) → `patterns.md` P2, P3
12
+ 4. Register in `settings.json` under correct lifecycle event with matcher and timeout
13
+ 5. Add test cases in `hooks/__tests__/hooks.test.js`
14
+ 6. Run tests: `node --test hooks/__tests__/hooks.test.js`
15
+
16
+ ### Reference module: bash-safety.js (PreToolUse) | guard-verify.js (PostToolUse)
17
+ ### Reference files: `hooks/bash-safety.js`, `hooks/guard-verify.js`, `settings.json`, `hooks/__tests__/hooks.test.js`
18
+
19
+ ### Task splits
20
+ - **HookImpl** (steps 1-3): Patterns: `patterns.md` P1-P4 | Depends on: none
21
+ - **HookWiring** (steps 4-6): Patterns: `guards.md` Settings | Depends on: HookImpl
22
+
23
+ ### File hierarchy
24
+ | Level | Component | Depends on |
25
+ |-------|-----------|-----------|
26
+ | 1 | `hooks/{name}.js` | -- |
27
+ | 2 | `settings.json` (registration) | hooks/{name}.js |
28
+ | 3 | `hooks/__tests__/hooks.test.js` | hooks/{name}.js |
29
+ | 4 | test run | all |
30
+
31
+ ## Recipe: New Slash Command
32
+
33
+ ### Steps
34
+ 1. Create `commands/mustard/{command-name}/SKILL.md` with trigger, description, procedure, rules → `patterns.md` P11
35
+ 2. Include `ULTRATHINK` at the end
36
+ 3. Verify command follows delegation pattern (no direct code implementation)
37
+
38
+ ### Reference module: feature/SKILL.md (complex) | status/SKILL.md (simple)
39
+ ### Reference files: `commands/mustard/feature/SKILL.md`, `commands/mustard/status/SKILL.md`
40
+
41
+ ### Task splits
42
+ - **CommandDef** (steps 1-3): Patterns: `patterns.md` P11 | Depends on: none
43
+
44
+ ### File hierarchy
45
+ | Level | Component | Depends on |
46
+ |-------|-----------|-----------|
47
+ | 1 | `commands/mustard/{name}/SKILL.md` | -- |
48
+
49
+ ## Recipe: New Foundation Skill
50
+
51
+ ### Steps
52
+ 1. Create `skills/{skill-name}/SKILL.md` with YAML frontmatter → `patterns.md` P12
53
+ 2. Write pushy description with casual trigger phrases → `guards.md` Skills
54
+ 3. Add `<!-- mustard:generated -->` after closing `---`
55
+ 4. Create `skills/{skill-name}/references/examples.md` with real code examples
56
+ 5. Keep SKILL.md under 500 lines
57
+
58
+ ### Reference module: commit-workflow (simple) | design-craft (with references)
59
+ ### Reference files: `skills/commit-workflow/SKILL.md`, `skills/design-craft/SKILL.md`
60
+
61
+ ### Task splits
62
+ - **SkillDef** (steps 1-5): Patterns: `patterns.md` P12, `guards.md` Skills | Depends on: none
63
+
64
+ ### File hierarchy
65
+ | Level | Component | Depends on |
66
+ |-------|-----------|-----------|
67
+ | 1 | `skills/{name}/SKILL.md` | -- |
68
+ | 2 | `skills/{name}/references/examples.md` | SKILL.md |
69
+
70
+ ## Recipe: New Sync Script
71
+
72
+ ### Steps
73
+ 1. Create `scripts/{script-name}.js` with shebang and JSDoc header
74
+ 2. Use only Node.js built-ins (fs, path, child_process, crypto)
75
+ 3. Read ROOT from `path.resolve(__dirname, '..', '..')` → `patterns.md` P8
76
+ 4. Handle missing files/dirs gracefully with try/catch
77
+ 5. Output JSON to stdout for consumption by other tools
78
+ 6. Test manually: `node scripts/{script-name}.js`
79
+
80
+ ### Reference module: sync-detect.js (complex) | sync-registry.js (medium)
81
+ ### Reference files: `scripts/sync-detect.js`, `scripts/sync-registry.js`
82
+
83
+ ### Task splits
84
+ - **ScriptImpl** (steps 1-5): Patterns: `patterns.md` P7, P8 | Depends on: none
85
+ - **ScriptTest** (step 6): Depends on: ScriptImpl
86
+
87
+ ### File hierarchy
88
+ | Level | Component | Depends on |
89
+ |-------|-----------|-----------|
90
+ | 1 | `scripts/{name}.js` | -- |
91
+ | 2 | manual test | scripts/{name}.js |
@@ -0,0 +1,86 @@
1
+ <!-- mustard:generated at:2026-03-25T00:00:00.000Z role:general -->
2
+ # Stack: Templates
3
+
4
+ > Technology stack and tooling for the Mustard templates subproject.
5
+
6
+ ## Runtime
7
+
8
+ | Component | Version | Notes |
9
+ |-----------|---------|-------|
10
+ | Node.js | >=18 | All hooks/scripts use CommonJS (`require`) |
11
+ | JavaScript | ES2020+ | Optional chaining, nullish coalescing, `Set`, `Map` |
12
+
13
+ ## Dependencies
14
+
15
+ None. All template files are dependency-free — they use only Node.js built-in modules:
16
+
17
+ | Module | Used In |
18
+ |--------|---------|
19
+ | `fs` | All hooks, all scripts |
20
+ | `path` | All hooks, all scripts |
21
+ | `child_process` | `auto-format.js`, `pre-compact.js`, `statusline.js`, `sync-detect.js`, `sync-registry.js` |
22
+ | `crypto` | `sync-detect.js` (SHA-256 hashing) |
23
+ | `os` | `statusline.js`, `session-cleanup.js` |
24
+
25
+ ## File Categories
26
+
27
+ | Category | Path | Count | Purpose |
28
+ |----------|------|-------|---------|
29
+ | Hooks | `hooks/*.js` | 8 | PreToolUse/PostToolUse/Session lifecycle guards |
30
+ | Scripts | `scripts/*.js` | 3 | Sync-detect, sync-registry, statusline |
31
+ | Commands | `commands/mustard/*/SKILL.md` | 14 | Slash command definitions |
32
+ | Skills | `skills/*/SKILL.md` | 6 | Foundation skills (design-craft, react-best-practices, etc.) |
33
+ | Config | `settings.json` | 1 | Hook wiring, permissions, statusline |
34
+ | Config | `pipeline-config.md` | 1 | Agent dispatch rules, wave system, model selection |
35
+ | Template | `CLAUDE.md` | 1 | Orchestrator rules template |
36
+
37
+ ## Commands
38
+
39
+ ```bash
40
+ # Run hook tests
41
+ node --test hooks/__tests__/hooks.test.js
42
+
43
+ # Run sync-detect (outputs JSON)
44
+ node scripts/sync-detect.js
45
+ node scripts/sync-detect.js --no-cache
46
+
47
+ # Run sync-registry
48
+ node scripts/sync-registry.js
49
+ node scripts/sync-registry.js --force
50
+ ```
51
+
52
+ ## Structure
53
+
54
+ ```
55
+ templates/
56
+ ├── CLAUDE.md # Orchestrator rules (copied to .claude/CLAUDE.md)
57
+ ├── settings.json # Hook wiring + permissions
58
+ ├── pipeline-config.md # Agent/wave/model config
59
+ ├── commands/mustard/ # 14 slash commands
60
+ │ ├── feature/SKILL.md
61
+ │ ├── bugfix/SKILL.md
62
+ │ ├── scan/SKILL.md
63
+ │ ├── git/SKILL.md
64
+ │ └── ... (approve, complete, resume, status, task, etc.)
65
+ ├── hooks/ # 8 lifecycle hooks
66
+ │ ├── bash-safety.js # PreToolUse — block dangerous commands
67
+ │ ├── file-guard.js # PreToolUse — block sensitive files
68
+ │ ├── enforce-registry.js # PreToolUse — require entity-registry
69
+ │ ├── auto-format.js # PostToolUse — prettier/dotnet format
70
+ │ ├── guard-verify.js # PostToolUse — architectural rules
71
+ │ ├── subagent-tracker.js # Pre/SubagentStart/Stop — agent state
72
+ │ ├── pre-compact.js # PreCompact — snapshot before compaction
73
+ │ ├── session-cleanup.js # SessionEnd — prune stale state
74
+ │ └── __tests__/hooks.test.js # Tests (node:test + node:assert)
75
+ ├── scripts/
76
+ │ ├── sync-detect.js # Subproject discovery + role detection
77
+ │ ├── sync-registry.js # Entity registry generation
78
+ │ └── statusline.js # ANSI statusline renderer
79
+ └── skills/ # Foundation skills
80
+ ├── commit-workflow/
81
+ ├── design-craft/
82
+ ├── pipeline-execution/
83
+ ├── react-best-practices/
84
+ ├── senior-architect/
85
+ └── skill-creator/
86
+ ```
@@ -0,0 +1,90 @@
1
+ ---
2
+ name: templates-command-authoring
3
+ description: "Pattern for writing slash command SKILL.md files with trigger, procedure,
4
+ rules, and ULTRATHINK. Use when creating a new mustard command, adding a pipeline
5
+ command, writing a /command, or the user says 'new command', 'add slash command',
6
+ 'create /feature-like command', 'write command template'."
7
+ ---
8
+ <!-- mustard:generated at:2026-03-25T00:00:00.000Z role:general -->
9
+
10
+ # Command Authoring Pattern
11
+
12
+ Slash commands are SKILL.md files in `commands/mustard/{command-name}/SKILL.md` that define orchestrator behavior.
13
+
14
+ ## Pattern
15
+
16
+ ### File Convention
17
+ - Location: `commands/mustard/{command-name}/SKILL.md`
18
+ - No YAML frontmatter (commands are not auto-loaded by description)
19
+ - End with `ULTRATHINK` keyword
20
+
21
+ ### Structure
22
+
23
+ ```markdown
24
+ # /{command-name} - Title
25
+
26
+ > Advisory note (optional)
27
+
28
+ ## Trigger
29
+ `/{command-name} <args>`
30
+
31
+ ## Description
32
+ What the command does and when to use it.
33
+
34
+ ## Procedure / ## Action
35
+ Step-by-step process. Use:
36
+ - Tables for signal → action mappings
37
+ - Numbered steps for sequential flow
38
+ - Code blocks for bash commands
39
+ - `### Phase` headers for multi-phase pipelines
40
+
41
+ ## Rules
42
+ - Explicit constraints (NEVER, ALWAYS, MUST)
43
+ - Budget limits (max reads, max API calls)
44
+ - Delegation requirements
45
+
46
+ ULTRATHINK
47
+ ```
48
+
49
+ ### Key Rules
50
+ - Commands NEVER implement code directly — they orchestrate via Task tool
51
+ - Pipeline commands create spec files and pipeline state JSON
52
+ - Git commands read `mustard.json` for branch flow configuration
53
+ - Zero-confirmation: most commands execute without asking user
54
+
55
+ ### Command Categories
56
+
57
+ | Category | Examples | Characteristic |
58
+ |----------|----------|---------------|
59
+ | Pipeline | `/feature`, `/bugfix`, `/approve`, `/complete`, `/resume` | Multi-phase, creates spec, state tracking |
60
+ | Task | `/task-analyze`, `/task-review`, `/task-refactor` | Single delegation, no spec |
61
+ | Git | `/git sync`, `/git commit`, `/git push`, `/git merge` | Reads `mustard.json`, submodule-aware |
62
+ | Scan | `/scan`, `/scan-format` | Discovery + analysis + generation |
63
+ | Status | `/status`, `/validate` | Read-only, reporting |
64
+
65
+ ## Example
66
+
67
+ ```markdown
68
+ # /my-command - Do Something
69
+
70
+ ## Trigger
71
+ `/my-command <name>`
72
+
73
+ ## Procedure
74
+ 1. Read `pipeline-config.md` for agent config
75
+ 2. Dispatch Task agent with context
76
+ 3. Collect results and report
77
+
78
+ ## Rules
79
+ - NEVER implement code directly
80
+ - ALWAYS delegate via Task tool
81
+ - Budget: max 5 API calls
82
+
83
+ ULTRATHINK
84
+ ```
85
+ Ref: `commands/mustard/feature/SKILL.md`, `commands/mustard/status/SKILL.md`
86
+
87
+ ## References
88
+
89
+ For full code examples with variants:
90
+ > Read `references/examples.md`
@@ -0,0 +1,83 @@
1
+ <!-- mustard:generated at:2026-03-25T00:00:00.000Z role:general -->
2
+ # Command Authoring Examples
3
+
4
+ ## Example 1: Simple Status Command
5
+
6
+ ```markdown
7
+ # /status - Consolidated Status
8
+
9
+ ## Trigger
10
+ `/status`
11
+
12
+ ## Description
13
+ Shows consolidated project status.
14
+
15
+ ## Information
16
+ 1. **Git Status** — branch, modified files, pending push
17
+ 2. **Pipeline** — active pipeline, current phase
18
+ 3. **Build** — last validation result
19
+ 4. **Entity Registry** — entity count, last update
20
+
21
+ ULTRATHINK
22
+ ```
23
+ Ref: `commands/mustard/status/SKILL.md`
24
+
25
+ ## Example 2: Pipeline Command (Feature)
26
+
27
+ Key sections from the feature command:
28
+
29
+ ```markdown
30
+ # /feature - Feature Pipeline
31
+
32
+ ## Trigger
33
+ `/feature <feature-name>`
34
+
35
+ ### ANALYZE Phase
36
+ 1. Read `pipeline-config.md`
37
+ 2. Read `entity-registry.json` via Grep
38
+ 3. Determine layers from signals
39
+
40
+ #### Scope Detection
41
+ | Signal | Scope |
42
+ |--------|-------|
43
+ | 1-2 layers, ≤5 files | Light |
44
+ | 3+ layers, 5+ files | Full |
45
+
46
+ ### PLAN Phase
47
+ Create `.claude/spec/active/{date}-{name}/spec.md`
48
+
49
+ ## Rules
50
+ - NEVER implement code in Full scope
51
+ - ALWAYS create pipeline state at PLAN phase
52
+ - Light scope + user chose "implement now" → EXECUTE inline
53
+
54
+ ULTRATHINK
55
+ ```
56
+ Ref: `commands/mustard/feature/SKILL.md`
57
+
58
+ ## Example 3: Git Command with Action Dispatch
59
+
60
+ ```markdown
61
+ # /git - Git Operations
62
+
63
+ ## Trigger
64
+ `/git <action>`
65
+
66
+ ## Actions
67
+ | Action | Description |
68
+ |--------|-------------|
69
+ | `sync` | Pull parent into current |
70
+ | `commit` | Create commit (no push) |
71
+ | `push` | Sync + commit + push |
72
+
73
+ ## Step 0 — Resolve Parent
74
+ cat mustard.json → match branch against flow patterns
75
+
76
+ ## Behavior
77
+ - ZERO confirmations
78
+ - Minimize Bash calls — chain with &&
79
+ - Submodules BEFORE parent
80
+
81
+ ULTRATHINK
82
+ ```
83
+ Ref: `commands/mustard/git/SKILL.md`
@@ -0,0 +1,73 @@
1
+ ---
2
+ name: templates-hook-protocol
3
+ description: "Pattern for writing Claude Code JavaScript hooks with stdin/stdout JSON protocol,
4
+ fail-open error handling, and correct response formats. Use when creating a new hook,
5
+ adding a guard, writing a PreToolUse or PostToolUse handler, or the user says
6
+ 'add hook', 'new guard', 'block command', 'validate file access'."
7
+ ---
8
+ <!-- mustard:generated at:2026-03-25T00:00:00.000Z role:general -->
9
+
10
+ # Hook Protocol Pattern
11
+
12
+ All Claude Code hooks are Node.js scripts that read JSON from stdin and write JSON to stdout.
13
+
14
+ ## Pattern
15
+
16
+ ### File Convention
17
+ - Location: `hooks/{hook-name}.js`
18
+ - Shebang: `#!/usr/bin/env node`
19
+ - JSDoc: version, purpose, what it blocks/allows
20
+ - Module system: CommonJS (`require`)
21
+ - Dependencies: Node.js built-ins only (`fs`, `path`, `child_process`)
22
+
23
+ ### Stdin/Stdout Contract
24
+
25
+ 1. Read full stdin as UTF-8 string
26
+ 2. Parse JSON — contains `tool_name`, `tool_input`, `hook_event_name`, `cwd`
27
+ 3. Process: check tool name, extract relevant input, apply rules
28
+ 4. Respond:
29
+ - **Approve**: `process.exit(0)` silently (no stdout)
30
+ - **PreToolUse block**: `console.log(JSON.stringify({ hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'block', permissionDecisionReason: '...' } }))`
31
+ - **PostToolUse block**: `process.stdout.write(JSON.stringify({ decision: 'block', reason: '...' }))`
32
+ 5. **Always fail-open**: wrap in try/catch, exit 0 on error
33
+
34
+ ### Key Rules
35
+ - PreToolUse uses `permissionDecision` (block/deny/allow)
36
+ - PostToolUse uses `decision` (approve/block)
37
+ - NEVER mix the two formats
38
+ - ALWAYS normalize Windows paths before matching (`replace(/\\/g, '/')`)
39
+
40
+ ## Example
41
+
42
+ ```js
43
+ #!/usr/bin/env node
44
+ let input = '';
45
+ process.stdin.setEncoding('utf8');
46
+ process.stdin.on('data', chunk => input += chunk);
47
+ process.stdin.on('end', () => {
48
+ try {
49
+ const data = JSON.parse(input);
50
+ if (data.tool_name !== 'Bash') { process.exit(0); }
51
+ const cmd = data.tool_input?.command || '';
52
+ if (/dangerous-pattern/.test(cmd)) {
53
+ console.log(JSON.stringify({
54
+ hookSpecificOutput: {
55
+ hookEventName: 'PreToolUse',
56
+ permissionDecision: 'deny',
57
+ permissionDecisionReason: '[hook-name] Blocked: reason'
58
+ }
59
+ }));
60
+ }
61
+ process.exit(0);
62
+ } catch (err) {
63
+ process.stderr.write(`[hook-name] Error: ${err.message}\n`);
64
+ process.exit(0);
65
+ }
66
+ });
67
+ ```
68
+ Ref: `hooks/bash-safety.js`
69
+
70
+ ## References
71
+
72
+ For full code examples with variants:
73
+ > Read `references/examples.md`
@@ -0,0 +1,74 @@
1
+ <!-- mustard:generated at:2026-03-25T00:00:00.000Z role:general -->
2
+ # Hook Protocol Examples
3
+
4
+ ## Example 1: PreToolUse — Regex-Based Blocking (bash-safety.js)
5
+
6
+ Simple pattern: array of `{ re, msg }` tested against command string.
7
+
8
+ ```js
9
+ const DANGEROUS = [
10
+ { re: /\brm\s+(-\w*r\w*f|--no-preserve-root)\b/i, msg: 'Recursive delete blocked' },
11
+ { re: /\bgit\s+push\s+(-\w*f|--force)\b/i, msg: 'Force push blocked' },
12
+ ];
13
+ // ... stdin reading ...
14
+ for (const { re, msg } of DANGEROUS) {
15
+ if (re.test(cmd)) {
16
+ console.log(JSON.stringify({
17
+ hookSpecificOutput: {
18
+ hookEventName: 'PreToolUse',
19
+ permissionDecision: 'deny',
20
+ permissionDecisionReason: `[bash-safety] ${msg}.`
21
+ }
22
+ }));
23
+ process.exit(0);
24
+ }
25
+ }
26
+ ```
27
+ Ref: `hooks/bash-safety.js`
28
+
29
+ ## Example 2: PreToolUse — File Existence Check (enforce-registry.js)
30
+
31
+ Validates that a required file exists and has valid content before allowing a skill.
32
+
33
+ ```js
34
+ const registryPath = path.join(process.cwd(), '.claude', 'entity-registry.json');
35
+ if (!fs.existsSync(registryPath)) {
36
+ console.log(JSON.stringify({
37
+ hookSpecificOutput: {
38
+ hookEventName: 'PreToolUse',
39
+ permissionDecision: 'block',
40
+ permissionDecisionReason: 'Entity registry not found. Run /sync-registry first.'
41
+ }
42
+ }));
43
+ return;
44
+ }
45
+ const registry = JSON.parse(fs.readFileSync(registryPath, 'utf8'));
46
+ // validate version, entities, patterns...
47
+ ```
48
+ Ref: `hooks/enforce-registry.js`
49
+
50
+ ## Example 3: PostToolUse — Content Validation (guard-verify.js)
51
+
52
+ Checks the content being written against architectural rules.
53
+
54
+ ```js
55
+ const CRITICAL_RULES = [
56
+ { pattern: /\bDbContext\b/i, scope: /Services?[/\\]/, msg: 'DbContext in Services' },
57
+ ];
58
+ // ...
59
+ const violations = [];
60
+ for (const rule of CRITICAL_RULES) {
61
+ if (!rule.scope.test(relPath)) continue;
62
+ if (!rule.pattern.test(newContent)) continue;
63
+ violations.push(rule.msg);
64
+ }
65
+ if (violations.length > 0) {
66
+ process.stdout.write(JSON.stringify({
67
+ decision: 'block',
68
+ reason: violations.map(v => `CRITICAL: ${v}`).join('\n')
69
+ }));
70
+ } else {
71
+ process.stdout.write(JSON.stringify({ decision: 'approve' }));
72
+ }
73
+ ```
74
+ Ref: `hooks/guard-verify.js`
@@ -0,0 +1,75 @@
1
+ ---
2
+ name: templates-settings-wiring
3
+ description: "Pattern for wiring hooks, permissions, and statusline in settings.json.
4
+ Use when adding a new hook to settings, changing permissions, updating lifecycle
5
+ event matchers, configuring statusline, or the user says 'register hook',
6
+ 'add permission', 'wire up', 'configure settings'."
7
+ ---
8
+ <!-- mustard:generated at:2026-03-25T00:00:00.000Z role:general -->
9
+
10
+ # Settings.json Wiring Pattern
11
+
12
+ The `settings.json` file is the central configuration for Claude Code hook lifecycle, permissions, and statusline.
13
+
14
+ ## Pattern
15
+
16
+ ### Lifecycle Events
17
+
18
+ | Event | Matcher Examples | Purpose |
19
+ |-------|-----------------|---------|
20
+ | `PreToolUse` | `Bash`, `Read\|Write\|Edit`, `Skill`, `Task` | Guard before tool execution |
21
+ | `PostToolUse` | `Write\|Edit` | Validate/format after tool execution |
22
+ | `SessionStart` | `startup` | Clean stale state |
23
+ | `SessionEnd` | `prompt_input_exit\|clear\|other` | Prune state files |
24
+ | `PreCompact` | `auto\|manual` | Snapshot before compaction |
25
+ | `SubagentStart` | (no matcher) | Register agent |
26
+ | `SubagentStop` | (no matcher) | Deregister agent |
27
+
28
+ ### Hook Registration Structure
29
+
30
+ ```json
31
+ {
32
+ "matcher": "ToolName|OtherTool",
33
+ "hooks": [{
34
+ "type": "command",
35
+ "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/{hook}.js",
36
+ "timeout": 5
37
+ }]
38
+ }
39
+ ```
40
+
41
+ ### Key Rules
42
+ - `$CLAUDE_PROJECT_DIR` resolves to the project root at runtime
43
+ - Always quote the path: `\"$CLAUDE_PROJECT_DIR\"`
44
+ - Timeout: 3-5s for simple checks, 10-15s for format/compile
45
+ - Multiple hooks under same matcher run sequentially
46
+ - Matcher uses `|` for OR: `"Write|Edit"`, `"Read|Write|Edit"`
47
+
48
+ ### Permissions
49
+
50
+ - `allow`: array of tool patterns (`"Bash(git:*)"`, `"Read"`)
51
+ - `deny`: array of blocked patterns (`"Bash(rm -rf:*)"`)
52
+ - Deny overrides allow
53
+
54
+ ## Example
55
+
56
+ ```json
57
+ {
58
+ "hooks": {
59
+ "PreToolUse": [{
60
+ "matcher": "Bash",
61
+ "hooks": [{
62
+ "type": "command",
63
+ "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/my-hook.js",
64
+ "timeout": 5
65
+ }]
66
+ }]
67
+ }
68
+ }
69
+ ```
70
+ Ref: `settings.json`
71
+
72
+ ## References
73
+
74
+ For full code examples with variants:
75
+ > Read `references/examples.md`
@@ -0,0 +1,59 @@
1
+ <!-- mustard:generated at:2026-03-25T00:00:00.000Z role:general -->
2
+ # Settings Wiring Examples
3
+
4
+ ## Example 1: PreToolUse with Multiple Matchers
5
+
6
+ ```json
7
+ {
8
+ "PreToolUse": [
9
+ {
10
+ "matcher": "Bash",
11
+ "hooks": [{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/bash-safety.js", "timeout": 5 }]
12
+ },
13
+ {
14
+ "matcher": "Read|Write|Edit",
15
+ "hooks": [{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/file-guard.js", "timeout": 5 }]
16
+ },
17
+ {
18
+ "matcher": "Skill",
19
+ "hooks": [{ "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/enforce-registry.js", "timeout": 5 }]
20
+ }
21
+ ]
22
+ }
23
+ ```
24
+ Ref: `settings.json` (lines 74-114)
25
+
26
+ ## Example 2: PostToolUse with Sequential Hooks
27
+
28
+ Two hooks run sequentially on the same matcher — format first, then verify:
29
+
30
+ ```json
31
+ {
32
+ "PostToolUse": [{
33
+ "matcher": "Write|Edit",
34
+ "hooks": [
35
+ { "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/auto-format.js", "timeout": 15 },
36
+ { "type": "command", "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/guard-verify.js", "timeout": 5 }
37
+ ]
38
+ }]
39
+ }
40
+ ```
41
+ Ref: `settings.json` (lines 117-133)
42
+
43
+ ## Example 3: Permission Configuration
44
+
45
+ ```json
46
+ {
47
+ "permissions": {
48
+ "allow": [
49
+ "Read", "Edit", "Write", "Glob", "Grep", "Skill", "Task",
50
+ "Bash(git:*)", "Bash(node:*)", "Bash(npm:*)", "Bash(dotnet:*)"
51
+ ],
52
+ "deny": [
53
+ "Bash(rm -rf:*)", "Bash(git push --force:*)", "Bash(git reset --hard:*)",
54
+ "Bash(shutdown:*)", "Bash(reboot:*)"
55
+ ]
56
+ }
57
+ }
58
+ ```
59
+ Ref: `settings.json` (lines 8-70)
@@ -0,0 +1,97 @@
1
+ ---
2
+ name: templates-skill-authoring
3
+ description: "Pattern for writing foundation and subproject skills with YAML frontmatter,
4
+ pushy descriptions, and references. Use when creating a new skill, writing a
5
+ SKILL.md, adding skill references, or the user says 'new skill', 'create skill',
6
+ 'add pattern skill', 'write foundation skill'."
7
+ ---
8
+ <!-- mustard:generated at:2026-03-25T00:00:00.000Z role:general -->
9
+
10
+ # Skill Authoring Pattern
11
+
12
+ Skills are auto-loaded by Claude based on task description matching the skill's `description` field.
13
+
14
+ ## Pattern
15
+
16
+ ### File Convention
17
+ - Location: `skills/{skill-name}/SKILL.md` (foundation) or `{sub}/.claude/skills/{skill-name}/SKILL.md` (subproject)
18
+ - YAML frontmatter: `name`, `description`, optional `disable-model-invocation`
19
+ - `<!-- mustard:generated -->` goes AFTER closing `---` (never before opening `---`)
20
+ - Max 500 lines (ideally under 200)
21
+
22
+ ### Description Writing (Critical)
23
+
24
+ Descriptions are the PRIMARY trigger mechanism. They must be "pushy":
25
+
26
+ **Good:**
27
+ ```yaml
28
+ description: "Pattern for .NET Minimal API endpoints with validation and auth.
29
+ Use when creating new routes, adding HTTP verbs, wiring endpoints, or the user
30
+ says 'add endpoint', 'new route', 'expose via API'."
31
+ ```
32
+
33
+ **Bad:**
34
+ ```yaml
35
+ description: "API patterns"
36
+ ```
37
+
38
+ ### SKILL.md Structure
39
+
40
+ ```markdown
41
+ ---
42
+ name: {skill-name}
43
+ description: "{What}. {When — be specific and pushy}."
44
+ ---
45
+ <!-- mustard:generated at:{ISO} role:{role} -->
46
+
47
+ # {Skill Title}
48
+
49
+ {1-2 sentence summary.}
50
+
51
+ ## Pattern
52
+
53
+ {Concise rules, file conventions, key constraints.}
54
+
55
+ ## Example
56
+
57
+ {5-10 line code example — happy path only.}
58
+ Ref: `{path/to/real/file}`
59
+
60
+ ## References
61
+
62
+ For full code examples with variants:
63
+ > Read `references/examples.md`
64
+ ```
65
+
66
+ ### references/examples.md
67
+
68
+ - 2-3 real examples at different complexity levels
69
+ - Always include `Ref: path/to/file.ext`
70
+ - Max 15 lines per example
71
+ - Starts with `<!-- mustard:generated -->` header
72
+
73
+ ## Example
74
+
75
+ ```yaml
76
+ ---
77
+ name: commit-workflow
78
+ description: Git commit strategy, submodule-aware, budget <=15 API calls.
79
+ disable-model-invocation: true
80
+ ---
81
+ <!-- mustard:generated -->
82
+
83
+ # Commit Workflow
84
+
85
+ > Git strategy for mono-repo with submodules.
86
+
87
+ ## Strategy
88
+ 1. `git status` — see all changes
89
+ 2. Group changes by subproject
90
+ 3. Per subproject: `git add` specific files -> `git commit`
91
+ ```
92
+ Ref: `skills/commit-workflow/SKILL.md`
93
+
94
+ ## References
95
+
96
+ For full code examples with variants:
97
+ > Read `references/examples.md`
@@ -0,0 +1,69 @@
1
+ <!-- mustard:generated at:2026-03-25T00:00:00.000Z role:general -->
2
+ # Skill Authoring Examples
3
+
4
+ ## Example 1: Simple Foundation Skill (commit-workflow)
5
+
6
+ ```yaml
7
+ ---
8
+ name: commit-workflow
9
+ description: Git commit strategy, submodule-aware, budget ≤15 API calls.
10
+ disable-model-invocation: true
11
+ ---
12
+ <!-- mustard:generated -->
13
+
14
+ # Commit Workflow
15
+
16
+ > Git strategy for mono-repo with submodules. Budget ≤15 API calls.
17
+
18
+ ## Strategy
19
+ 1. `git status` — see all changes
20
+ 2. `git diff --stat` — understand scope
21
+ 3. Group changes by subproject
22
+ 4. Per subproject: `git add` specific files → `git commit`
23
+
24
+ ## Rules
25
+ - Budget: ≤15 API calls total
26
+ - NEVER use `git add .` — always specific files
27
+ ```
28
+ Ref: `skills/commit-workflow/SKILL.md`
29
+
30
+ ## Example 2: Complex Skill with References (pipeline-execution)
31
+
32
+ ```yaml
33
+ ---
34
+ name: pipeline-execution
35
+ description: Pipeline phases, dispatch rules, wave system, validate, retry.
36
+ Load for /feature /resume /approve.
37
+ disable-model-invocation: true
38
+ ---
39
+ <!-- mustard:generated -->
40
+
41
+ # Pipeline Execution Detail
42
+
43
+ > Phases, role rules, dispatch mechanics, validation, bugfix paths.
44
+
45
+ ## Pipeline Feature
46
+ ### ANALYZE Phase
47
+ 1. AUTO-SYNC: `node .claude/scripts/sync-registry.js`
48
+ 2. Read `entity-registry.json` → entity found? → infer layers
49
+ ```
50
+ Ref: `skills/pipeline-execution/SKILL.md`
51
+
52
+ ## Example 3: Skill with Rich References (design-craft)
53
+
54
+ Structure with multiple reference files:
55
+
56
+ ```
57
+ skills/design-craft/
58
+ ├── SKILL.md
59
+ └── references/
60
+ ├── critique.md
61
+ ├── example.md
62
+ ├── palettes-catalog.md
63
+ ├── principles.md
64
+ ├── styles-catalog.md
65
+ ├── typography-catalog.md
66
+ ├── ux-guidelines.md
67
+ └── validation.md
68
+ ```
69
+ Ref: `skills/design-craft/SKILL.md`
@@ -0,0 +1,62 @@
1
+ ---
2
+ name: templates-sync-detect
3
+ description: "Pattern for subproject discovery, role detection via scoring, and SHA-256
4
+ incremental hashing in sync-detect.js. Use when modifying detection logic,
5
+ adding a new role/stack, changing hash computation, adding new scoring signals,
6
+ or the user says 'add stack detection', 'new role', 'detect framework',
7
+ 'fix detection', 'change scoring'."
8
+ ---
9
+ <!-- mustard:generated at:2026-03-25T00:00:00.000Z role:general -->
10
+
11
+ # Sync-Detect Pattern
12
+
13
+ sync-detect.js discovers subprojects, detects their role via weighted scoring, and computes SHA-256 hashes for incremental scan.
14
+
15
+ ## Pattern
16
+
17
+ ### Discovery Order
18
+ 1. `git submodule status` — prefer submodule paths
19
+ 2. Fallback: scan root for dirs containing `CLAUDE.md`
20
+
21
+ ### Role Scoring (weighted signals)
22
+
23
+ | Weight | Constant | Signal Type |
24
+ |--------|----------|-------------|
25
+ | 10 | `HIGH` | Config files: `.csproj` Sdk.Web, `next.config.*`, `drizzle.config.*`, `pubspec.yaml` |
26
+ | 5 | `MEDIUM` | Package deps: `react`, `express`, `drizzle-orm` in package.json |
27
+ | 3 | `LOW` | Directories: `Controllers/`, `app/`+`components/`, `migrations/` |
28
+
29
+ Roles: `api`, `ui`, `database`, `library`, `mobile`, `general` (fallback).
30
+ Role maps to agent: `api→backend`, `ui→frontend`, `database→database`, `library→backend`, `mobile→mobile`.
31
+
32
+ ### Incremental Hashing
33
+ - Collect source files (`.cs`, `.ts`, `.tsx`, `.js`, `.jsx`, `.dart`)
34
+ - Exclude: `node_modules`, `.next`, `bin`, `obj`, `dist`, `migrations`, `_backup`, dotfiles
35
+ - Sort files → hash(path + content) per file → SHA-256 digest
36
+ - Module-level hashes for fine-grained incremental (backend: `Modules/v{N}/{Module}/`, frontend: `app/(dashboard)/*/`)
37
+
38
+ ### Output
39
+ JSON to stdout: `{ subprojects, agents, detectedAgents, sourceHashes, moduleHashes }`
40
+ Writes `.claude/.detect-cache.json` (unless `--no-cache`).
41
+
42
+ ## Example
43
+
44
+ ```js
45
+ function detectRole(absPath) {
46
+ const scores = { api: 0, ui: 0, database: 0, library: 0, mobile: 0 };
47
+ if (isCsprojWeb(absPath)) scores.api += 10;
48
+ if (fileExists(absPath, 'next.config.*')) scores.ui += 10;
49
+ // ... more signals ...
50
+ let maxScore = 0, role = 'general';
51
+ for (const [r, s] of Object.entries(scores)) {
52
+ if (s > maxScore) { maxScore = s; role = r; }
53
+ }
54
+ return { role, scores };
55
+ }
56
+ ```
57
+ Ref: `scripts/sync-detect.js`
58
+
59
+ ## References
60
+
61
+ For full code examples with variants:
62
+ > Read `references/examples.md`
@@ -0,0 +1,55 @@
1
+ <!-- mustard:generated at:2026-03-25T00:00:00.000Z role:general -->
2
+ # Sync-Detect Examples
3
+
4
+ ## Example 1: Adding a New Role Signal
5
+
6
+ To detect a new framework, add scoring in `detectRole()`:
7
+
8
+ ```js
9
+ // In detectRole(absPath):
10
+ // Python FastAPI → api (HIGH)
11
+ if (fileExists(absPath, 'pyproject.toml')) {
12
+ if (pyprojectHas(absPath, ['fastapi', 'django', 'flask'])) {
13
+ scores.api += ROLE_WEIGHTS.HIGH;
14
+ }
15
+ }
16
+ ```
17
+ Ref: `scripts/sync-detect.js` (lines 271-276)
18
+
19
+ ## Example 2: Adding Package.json Dep Detection
20
+
21
+ ```js
22
+ const deps = getPackageJsonDeps(absPath);
23
+ if (deps.length > 0) {
24
+ if (hasAnyDep(deps, ['express', 'fastify', 'hono', 'koa', 'nestjs'])) {
25
+ scores.api += ROLE_WEIGHTS.MEDIUM;
26
+ }
27
+ if (hasAnyDep(deps, ['react', 'next', 'vue', 'nuxt', 'svelte'])) {
28
+ scores.ui += ROLE_WEIGHTS.MEDIUM;
29
+ }
30
+ }
31
+ ```
32
+ Ref: `scripts/sync-detect.js` (lines 240-254)
33
+
34
+ ## Example 3: Module-Level Hash Computation
35
+
36
+ ```js
37
+ function computeModuleHashes(subprojectPath, role) {
38
+ const modules = {};
39
+ if (role === 'api' || role === 'library') {
40
+ const allModuleDirs = findAllModulesDirs(absPath);
41
+ // ... collect files per module, compute SHA-256 per module
42
+ for (const [modName, files] of Object.entries(moduleFiles)) {
43
+ files.sort();
44
+ const hash = crypto.createHash('sha256');
45
+ for (const f of files) {
46
+ hash.update(f);
47
+ hash.update(fs.readFileSync(path.join(ROOT, f), 'utf-8'));
48
+ }
49
+ modules[modName] = { hash: hash.digest('hex'), files: files.length };
50
+ }
51
+ }
52
+ return modules;
53
+ }
54
+ ```
55
+ Ref: `scripts/sync-detect.js` (lines 665-784)
@@ -26,5 +26,52 @@ ANALYZE → PLAN → EXECUTE → CLOSE
26
26
  Agents auto-load skills from `{subproject}/.claude/skills/` based on task description.
27
27
  Guards always loaded via `{subproject}/CLAUDE.md`.
28
28
 
29
+ ## Stack
30
+
31
+ Node.js (>=18), CommonJS, no external dependencies. 8 lifecycle hooks, 3 sync scripts, 14 slash commands, 6 foundation skills.
32
+
33
+ ## Commands
34
+
35
+ ```bash
36
+ # Run hook tests
37
+ node --test hooks/__tests__/hooks.test.js
38
+
39
+ # Subproject discovery (outputs JSON)
40
+ node scripts/sync-detect.js
41
+ node scripts/sync-detect.js --no-cache
42
+
43
+ # Entity registry generation
44
+ node scripts/sync-registry.js
45
+ node scripts/sync-registry.js --force
46
+ ```
47
+
48
+ ## Guards
49
+
50
+ - All hooks fail-open (exit 0 on error) — never block due to hook bugs
51
+ - All hooks use only Node.js built-ins — no npm dependencies
52
+ - PreToolUse hooks use `permissionDecision` response format
53
+ - PostToolUse hooks use `decision` response format
54
+ - Every new hook must be registered in `settings.json` with a timeout
55
+ - Generated files must start with `<!-- mustard:generated -->` header
56
+ - Skills must have YAML frontmatter BEFORE the `<!-- mustard:generated -->` line
57
+
58
+ ## Scan References
59
+
60
+ | File | Description |
61
+ |------|-------------|
62
+ | `.claude/commands/stack.md` | Technology stack, structure, tooling |
63
+ | `.claude/commands/patterns.md` | 12 recurring code patterns with refs |
64
+ | `.claude/commands/guards.md` | DO/DON'T rules for hooks, scripts, commands, skills |
65
+ | `.claude/commands/recipes.md` | Implementation recipes for new hooks, commands, skills, scripts |
66
+ | `.claude/commands/notes.md` | Manual notes (never overwritten) |
67
+
68
+ ## Recommended Skills
69
+
70
+ - `templates-hook-protocol` — Hook stdin/stdout JSON protocol
71
+ - `templates-settings-wiring` — settings.json hook registration
72
+ - `templates-sync-detect` — Subproject discovery and role detection
73
+ - `templates-command-authoring` — Slash command SKILL.md structure
74
+ - `templates-skill-authoring` — Foundation/subproject skill creation
75
+
29
76
  ## Full Reference
30
77
  Rules, pipeline, naming: `pipeline-config.md`
@@ -7,16 +7,16 @@
7
7
 
8
8
  "permissions": {
9
9
  "allow": [
10
- "Bash(git:*)",
11
- "Bash(cd:*)",
12
- "Bash(find:*)",
13
- "Bash(ls:*)",
14
- "Bash(cat:*)",
15
- "Bash(echo:*)",
16
- "Bash(node:*)",
17
- "Bash(pnpm:*)",
18
- "Bash(dotnet build:*)",
19
- "Bash(dotnet test:*)"
10
+ "Read",
11
+ "Edit",
12
+ "Write",
13
+ "Glob",
14
+ "Grep",
15
+ "Skill",
16
+ "Task",
17
+ "WebFetch",
18
+ "WebSearch",
19
+ "Bash"
20
20
  ],
21
21
  "deny": [
22
22
  "Bash(rm -rf:*)",