mustard-claude 3.0.1 → 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.
@@ -1,7 +1,8 @@
1
1
  import { existsSync, readdirSync } from 'fs';
2
- import { mkdir, copyFile, cp } from 'fs/promises';
2
+ import { mkdir, copyFile, cp, writeFile } from 'fs/promises';
3
3
  import { join, resolve, dirname } from 'path';
4
4
  import { fileURLToPath } from 'url';
5
+ import { execSync } from 'child_process';
5
6
  import chalk from 'chalk';
6
7
  import ora from 'ora';
7
8
  import inquirer from 'inquirer';
@@ -101,8 +102,143 @@ export async function initCommand(options) {
101
102
  count; // already counted
102
103
  }
103
104
  spinner.succeed(`Copied ${count} files to .claude/`);
105
+ // Generate mustard.json (git flow config)
106
+ await generateMustardJson(projectPath, options);
104
107
  printNextSteps();
105
108
  }
109
+ function detectDefaultBranch() {
110
+ try {
111
+ const ref = execSync('git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null', { encoding: 'utf-8' }).trim();
112
+ return ref.replace('refs/remotes/origin/', '');
113
+ }
114
+ catch {
115
+ try {
116
+ // Fallback: check if main or master exists
117
+ const branches = execSync('git branch -r', { encoding: 'utf-8' });
118
+ if (branches.includes('origin/main'))
119
+ return 'main';
120
+ if (branches.includes('origin/master'))
121
+ return 'master';
122
+ }
123
+ catch { /* not a git repo */ }
124
+ return 'main';
125
+ }
126
+ }
127
+ function detectHasSubmodules() {
128
+ try {
129
+ return existsSync(join(process.cwd(), '.gitmodules'));
130
+ }
131
+ catch {
132
+ return false;
133
+ }
134
+ }
135
+ function detectCurrentBranch() {
136
+ try {
137
+ return execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf-8' }).trim();
138
+ }
139
+ catch {
140
+ return null;
141
+ }
142
+ }
143
+ function detectRemoteBranches() {
144
+ try {
145
+ const output = execSync('git branch -r --format="%(refname:short)"', { encoding: 'utf-8' });
146
+ return output.split('\n').filter(Boolean).map(b => b.replace('origin/', ''));
147
+ }
148
+ catch {
149
+ return [];
150
+ }
151
+ }
152
+ async function generateMustardJson(projectPath, options) {
153
+ const configPath = join(projectPath, 'mustard.json');
154
+ if (existsSync(configPath)) {
155
+ console.log(chalk.gray('\n mustard.json already exists — preserved'));
156
+ return;
157
+ }
158
+ const defaultBranch = detectDefaultBranch();
159
+ const hasSubmodules = detectHasSubmodules();
160
+ const currentBranch = detectCurrentBranch();
161
+ const remoteBranches = detectRemoteBranches();
162
+ const hasDevBranch = remoteBranches.includes('dev') || remoteBranches.includes('develop');
163
+ console.log(chalk.bold('\nšŸ“‹ Git Flow Configuration\n'));
164
+ if (currentBranch) {
165
+ console.log(chalk.gray(` Detected: branch=${currentBranch}, default=${defaultBranch}, submodules=${hasSubmodules}`));
166
+ if (hasDevBranch)
167
+ console.log(chalk.gray(` Found dev branch: ${remoteBranches.includes('dev') ? 'dev' : 'develop'}`));
168
+ console.log();
169
+ }
170
+ let config;
171
+ if (options.yes) {
172
+ // Auto-config with sensible defaults
173
+ const flow = {};
174
+ if (hasDevBranch) {
175
+ flow['dev_*'] = remoteBranches.includes('dev') ? 'dev' : 'develop';
176
+ flow[remoteBranches.includes('dev') ? 'dev' : 'develop'] = defaultBranch;
177
+ }
178
+ config = {
179
+ git: {
180
+ flow,
181
+ pr: { enabled: true, provider: 'github' },
182
+ submodules: hasSubmodules
183
+ }
184
+ };
185
+ }
186
+ else {
187
+ // Interactive setup
188
+ const answers = await inquirer.prompt([
189
+ {
190
+ type: 'input',
191
+ name: 'production',
192
+ message: 'Production branch:',
193
+ default: defaultBranch
194
+ },
195
+ {
196
+ type: 'input',
197
+ name: 'devBranch',
198
+ message: 'Development branch (shared, leave empty to skip):',
199
+ default: hasDevBranch ? (remoteBranches.includes('dev') ? 'dev' : 'develop') : ''
200
+ },
201
+ {
202
+ type: 'input',
203
+ name: 'devPattern',
204
+ message: 'Personal branch pattern (glob → dev branch):',
205
+ default: 'dev_*',
206
+ when: (a) => !!a.devBranch
207
+ },
208
+ {
209
+ type: 'confirm',
210
+ name: 'prEnabled',
211
+ message: 'Use Pull Requests for merging?',
212
+ default: true
213
+ },
214
+ {
215
+ type: 'list',
216
+ name: 'provider',
217
+ message: 'Git provider:',
218
+ choices: ['github', 'gitlab', 'bitbucket'],
219
+ default: 'github',
220
+ when: (a) => a.prEnabled
221
+ }
222
+ ]);
223
+ const flow = {};
224
+ if (answers.devBranch) {
225
+ if (answers.devPattern) {
226
+ flow[answers.devPattern] = answers.devBranch;
227
+ }
228
+ flow[answers.devBranch] = answers.production;
229
+ }
230
+ config = {
231
+ git: {
232
+ flow,
233
+ pr: { enabled: answers.prEnabled, provider: answers.provider || 'github' },
234
+ submodules: hasSubmodules
235
+ }
236
+ };
237
+ }
238
+ const spinner = ora('Writing mustard.json...').start();
239
+ await writeFile(configPath, JSON.stringify(config, null, 2) + '\n');
240
+ spinner.succeed('Created mustard.json');
241
+ }
106
242
  function printNextSteps() {
107
243
  console.log(chalk.green.bold('\nāœ… Done!\n'));
108
244
  console.log(chalk.white('Next: open Claude Code and run /scan to analyze your codebase.\n'));
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mustard-claude",
3
- "version": "3.0.1",
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
+ ```