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.
- package/dist/commands/init.js +137 -1
- package/dist/commands/init.js.map +1 -1
- package/package.json +1 -1
- package/templates/.claude/commands/guards.md +76 -0
- package/templates/.claude/commands/notes.md +22 -0
- package/templates/.claude/commands/patterns.md +173 -0
- package/templates/.claude/commands/recipes.md +91 -0
- package/templates/.claude/commands/stack.md +86 -0
- package/templates/.claude/skills/templates-command-authoring/SKILL.md +90 -0
- package/templates/.claude/skills/templates-command-authoring/references/examples.md +83 -0
- package/templates/.claude/skills/templates-hook-protocol/SKILL.md +73 -0
- package/templates/.claude/skills/templates-hook-protocol/references/examples.md +74 -0
- package/templates/.claude/skills/templates-settings-wiring/SKILL.md +75 -0
- package/templates/.claude/skills/templates-settings-wiring/references/examples.md +59 -0
- package/templates/.claude/skills/templates-skill-authoring/SKILL.md +97 -0
- package/templates/.claude/skills/templates-skill-authoring/references/examples.md +69 -0
- package/templates/.claude/skills/templates-sync-detect/SKILL.md +62 -0
- package/templates/.claude/skills/templates-sync-detect/references/examples.md +55 -0
- package/templates/CLAUDE.md +47 -0
- package/templates/commands/mustard/git/SKILL.md +145 -25
- package/templates/settings.json +10 -10
package/dist/commands/init.js
CHANGED
|
@@ -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":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAY,MAAM,IAAI,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAU,EAAE,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -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
|
+
```
|