create-harness-vibe-coding 0.1.8 → 0.1.10
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/README.md +95 -1
- package/package.json +5 -2
- package/src/generator.js +347 -53
- package/src/index.js +212 -17
- package/templates/common/.claude/rules/ecc/common.md +9 -0
- package/templates/common/CLAUDE.md +5 -3
- package/templates/common/MEMORY.md +12 -8
- package/templates/common/SETUP.md +87 -2
- package/templates/common/docs/README.md +8 -0
- package/templates/common/docs/features/_template.md +24 -1
- package/templates/common/docs/harness/agent-workflow.md +3 -7
- package/templates/common/docs/harness/context-loading.md +3 -0
- package/templates/common/docs/harness/dispatch.md +3 -0
- package/templates/common/docs/harness/extension.md +12 -0
- package/templates/common/memory/agent-lessons-patterns.md +21 -0
- package/templates/common/memory/tool-usage-reflections.md +21 -0
- package/templates/common/memory/user-corrections-preferences.md +21 -0
- package/templates/common/scripts/validate-harness.mjs +99 -3
- package/templates/optional/catalog.json +43 -0
- package/templates/optional/skills/browser-e2e/.claude/skills/browser-e2e/SKILL.md +42 -0
- package/templates/optional/skills/browser-e2e/docs/workflows/browser-e2e.md +42 -0
- package/templates/optional/skills/github-pr-review/.claude/skills/github-pr-review/SKILL.md +40 -0
- package/templates/optional/skills/github-pr-review/docs/workflows/github-pr-review.md +28 -0
- package/templates/optional/skills/python-backend/.claude/skills/python-backend/SKILL.md +40 -0
- package/templates/optional/skills/python-backend/docs/workflows/python-backend.md +34 -0
- package/templates/optional/skills/ts-react-frontend/.claude/skills/ts-react-frontend/SKILL.md +43 -0
- package/templates/optional/skills/ts-react-frontend/docs/workflows/ts-react-frontend.md +35 -0
- package/templates/optional/skills/ui-ux-review/.claude/skills/ui-ux-review/SKILL.md +40 -0
- package/templates/optional/skills/ui-ux-review/docs/workflows/ui-ux-review.md +26 -0
package/src/index.js
CHANGED
|
@@ -2,14 +2,20 @@
|
|
|
2
2
|
import * as p from '@clack/prompts';
|
|
3
3
|
import pc from 'picocolors';
|
|
4
4
|
import { askProjectName, askTargetDir } from './prompts.js';
|
|
5
|
-
import { generate } from './generator.js';
|
|
5
|
+
import { generate, getOptionalCatalog } from './generator.js';
|
|
6
6
|
|
|
7
7
|
// ── CLI flags ──────────────────────────────────────────────
|
|
8
8
|
const raw = process.argv.slice(2);
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
|
|
9
|
+
const parsed = parseArgs(raw);
|
|
10
|
+
const showHelp = parsed.flags.help || parsed.flags.h;
|
|
11
|
+
const skipPrompts = parsed.flags.yes || parsed.flags.y;
|
|
12
|
+
|
|
13
|
+
if (parsed.errors.length > 0) {
|
|
14
|
+
for (const err of parsed.errors) {
|
|
15
|
+
console.error(pc.red(`Error: ${err}`));
|
|
16
|
+
}
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
13
19
|
|
|
14
20
|
if (showHelp) {
|
|
15
21
|
console.log('');
|
|
@@ -23,25 +29,60 @@ if (showHelp) {
|
|
|
23
29
|
console.log(' target-dir Directory to create the project in (default: ./<project-name>)');
|
|
24
30
|
console.log('');
|
|
25
31
|
console.log(' Flags:');
|
|
26
|
-
console.log(' -y, --yes
|
|
27
|
-
console.log(' -h, --help
|
|
32
|
+
console.log(' -y, --yes Skip all prompts, use defaults or provided args');
|
|
33
|
+
console.log(' -h, --help Show this help');
|
|
34
|
+
console.log(' --dry-run Print the planned writes without creating files');
|
|
35
|
+
console.log(' --on-conflict <policy> fail, skip, backup, or overwrite (default: fail)');
|
|
36
|
+
console.log(' --with <id,id> Add optional local workflow skills');
|
|
37
|
+
console.log(' --without <id,id> Remove optional workflow skills selected by --preset or --with');
|
|
38
|
+
console.log(' --preset <name> Add a built-in optional workflow preset');
|
|
39
|
+
console.log(' --list-options Print optional workflow skills and presets');
|
|
40
|
+
console.log(' --json Output machine-readable JSON (use with --dry-run for planning)');
|
|
28
41
|
console.log('');
|
|
29
42
|
console.log(' Examples:');
|
|
30
43
|
console.log(' npx create-harness-vibe-coding@latest');
|
|
31
44
|
console.log(' npx create-harness-vibe-coding@latest -y');
|
|
32
45
|
console.log(' npx create-harness-vibe-coding@latest my-project');
|
|
33
46
|
console.log(' npx create-harness-vibe-coding@latest my-project ./dist/my-project -y');
|
|
47
|
+
console.log(' npx create-harness-vibe-coding@latest legacy ./legacy -y --dry-run');
|
|
48
|
+
console.log(' npx create-harness-vibe-coding@latest legacy ./legacy -y --on-conflict skip');
|
|
49
|
+
console.log(' npx create-harness-vibe-coding@latest web ./web -y --with ts-react-frontend,browser-e2e');
|
|
50
|
+
console.log(' npx create-harness-vibe-coding@latest web ./web -y --preset web-app');
|
|
51
|
+
console.log(' npx create-harness-vibe-coding@latest api ./api -y --preset fullstack --without github-pr-review');
|
|
34
52
|
console.log('');
|
|
35
53
|
process.exit(0);
|
|
36
54
|
}
|
|
37
55
|
|
|
56
|
+
if (parsed.flags.listOptions) {
|
|
57
|
+
printOptions();
|
|
58
|
+
process.exit(0);
|
|
59
|
+
}
|
|
60
|
+
|
|
38
61
|
// Positional args (non-flag)
|
|
39
|
-
const positional =
|
|
62
|
+
const positional = parsed.positionals;
|
|
40
63
|
const argName = positional[0];
|
|
41
64
|
const argDir = positional[1];
|
|
65
|
+
const generationOptions = {
|
|
66
|
+
dryRun: Boolean(parsed.flags.dryRun),
|
|
67
|
+
onConflict: parsed.flags.onConflict || 'fail',
|
|
68
|
+
withOptions: parsed.flags.with || [],
|
|
69
|
+
withoutOptions: parsed.flags.without || [],
|
|
70
|
+
preset: parsed.flags.preset,
|
|
71
|
+
json: Boolean(parsed.flags.json),
|
|
72
|
+
};
|
|
42
73
|
|
|
43
74
|
const DEFAULT_NAME = 'my-vibe-project';
|
|
44
75
|
|
|
76
|
+
// --json: machine-readable output, no prompts, no decorative output
|
|
77
|
+
if (generationOptions.json) {
|
|
78
|
+
const projectName = argName || DEFAULT_NAME;
|
|
79
|
+
const targetDir = argDir || `./${projectName}`;
|
|
80
|
+
const result = generate({ projectName, targetDir, ...generationOptions });
|
|
81
|
+
printJsonResult(result);
|
|
82
|
+
// printJsonResult exits with 1 on failure; we only reach here on success
|
|
83
|
+
process.exit(0);
|
|
84
|
+
}
|
|
85
|
+
|
|
45
86
|
console.log('');
|
|
46
87
|
console.log(pc.magenta('╔══════════════════════════════════════════╗'));
|
|
47
88
|
console.log(pc.magenta('║ create-harness-vibe-coding ║'));
|
|
@@ -60,13 +101,26 @@ if (argName || skipPrompts) {
|
|
|
60
101
|
console.log(` Project ${pc.green(projectName)}`);
|
|
61
102
|
console.log(` Directory ${pc.green(targetDir)}`);
|
|
62
103
|
console.log(` Creates ${pc.cyan('CLAUDE.md, docs/harness/PLAN.md, docs/, scripts/, .claude/, SETUP.md, tests/')}`);
|
|
104
|
+
if (generationOptions.dryRun) {
|
|
105
|
+
console.log(` Mode ${pc.yellow('dry-run')}`);
|
|
106
|
+
}
|
|
107
|
+
console.log(` Conflicts ${pc.cyan(generationOptions.onConflict)}`);
|
|
108
|
+
if (generationOptions.withOptions.length > 0) {
|
|
109
|
+
console.log(` Optional ${pc.cyan(generationOptions.withOptions.join(','))}`);
|
|
110
|
+
}
|
|
111
|
+
if (generationOptions.withoutOptions.length > 0) {
|
|
112
|
+
console.log(` Without ${pc.cyan(generationOptions.withoutOptions.join(','))}`);
|
|
113
|
+
}
|
|
114
|
+
if (generationOptions.preset) {
|
|
115
|
+
console.log(` Preset ${pc.cyan(generationOptions.preset)}`);
|
|
116
|
+
}
|
|
63
117
|
if (skipPrompts) {
|
|
64
118
|
console.log(` Mode ${pc.dim('non-interactive (-y)')}`);
|
|
65
119
|
}
|
|
66
120
|
console.log(pc.dim('────────────────────────────────────────────'));
|
|
67
121
|
console.log('');
|
|
68
122
|
|
|
69
|
-
const result = generate({ projectName, targetDir });
|
|
123
|
+
const result = generate({ projectName, targetDir, ...generationOptions });
|
|
70
124
|
printResult(result, targetDir);
|
|
71
125
|
} else {
|
|
72
126
|
// Interactive mode
|
|
@@ -89,6 +143,7 @@ if (argName || skipPrompts) {
|
|
|
89
143
|
console.log(` Project ${pc.green(projectName)}`);
|
|
90
144
|
console.log(` Directory ${pc.green(targetDir)}`);
|
|
91
145
|
console.log(` Creates ${pc.cyan('CLAUDE.md, docs/harness/PLAN.md, docs/, scripts/, .claude/, SETUP.md, tests/')}`);
|
|
146
|
+
console.log(` Conflicts ${pc.cyan(generationOptions.onConflict)}`);
|
|
92
147
|
console.log(pc.dim('────────────────────────────────────────────'));
|
|
93
148
|
console.log('');
|
|
94
149
|
|
|
@@ -109,13 +164,35 @@ if (argName || skipPrompts) {
|
|
|
109
164
|
}
|
|
110
165
|
|
|
111
166
|
console.log('');
|
|
112
|
-
const result = generate({ projectName, targetDir });
|
|
167
|
+
const result = generate({ projectName, targetDir, ...generationOptions });
|
|
113
168
|
printResult(result, targetDir);
|
|
114
169
|
}
|
|
115
170
|
|
|
116
171
|
function printResult(result, targetDir) {
|
|
117
172
|
if (result.success) {
|
|
118
|
-
|
|
173
|
+
if (result.dryRun) {
|
|
174
|
+
console.log(pc.yellow('\nDry run: no files or directories were written.'));
|
|
175
|
+
printSummary(result.summary);
|
|
176
|
+
printPlan(result.plan);
|
|
177
|
+
if (result.warnings.length > 0) {
|
|
178
|
+
console.log(pc.yellow('\nWarning(s):'));
|
|
179
|
+
for (const warning of result.warnings) {
|
|
180
|
+
console.log(pc.yellow(` - ${warning}`));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
console.log('');
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
console.log(pc.green('\nGeneration complete.\n'));
|
|
188
|
+
printSummary(result.summary);
|
|
189
|
+
|
|
190
|
+
if (result.warnings.length > 0) {
|
|
191
|
+
console.log(pc.yellow('\nWarning(s):'));
|
|
192
|
+
for (const warning of result.warnings) {
|
|
193
|
+
console.log(pc.yellow(` - ${warning}`));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
119
196
|
|
|
120
197
|
console.log(pc.bold('Next steps:'));
|
|
121
198
|
console.log(` ${pc.cyan(`cd ${targetDir}`)}`);
|
|
@@ -125,12 +202,6 @@ function printResult(result, targetDir) {
|
|
|
125
202
|
console.log(pc.dim(' SETUP.md is temporary. Delete it after initialization.'));
|
|
126
203
|
console.log('');
|
|
127
204
|
|
|
128
|
-
if (result.errors.length > 0) {
|
|
129
|
-
console.log(pc.red(`\n${result.errors.length} warning(s):`));
|
|
130
|
-
for (const err of result.errors) {
|
|
131
|
-
console.log(pc.red(` - ${err}`));
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
205
|
} else {
|
|
135
206
|
console.log(pc.red('\nGeneration failed:'));
|
|
136
207
|
for (const err of result.errors) {
|
|
@@ -139,3 +210,127 @@ function printResult(result, targetDir) {
|
|
|
139
210
|
process.exit(1);
|
|
140
211
|
}
|
|
141
212
|
}
|
|
213
|
+
|
|
214
|
+
function parseArgs(args) {
|
|
215
|
+
const flags = {
|
|
216
|
+
with: [],
|
|
217
|
+
without: [],
|
|
218
|
+
};
|
|
219
|
+
const positionals = [];
|
|
220
|
+
const errors = [];
|
|
221
|
+
|
|
222
|
+
function readValue(flagName, index) {
|
|
223
|
+
const value = args[index + 1];
|
|
224
|
+
if (!value || value.startsWith('-')) {
|
|
225
|
+
errors.push(`${flagName} requires a value`);
|
|
226
|
+
return { value: undefined, nextIndex: index };
|
|
227
|
+
}
|
|
228
|
+
return { value, nextIndex: index + 1 };
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function readEqualsValue(flagName, value) {
|
|
232
|
+
if (!value || value.startsWith('-')) {
|
|
233
|
+
errors.push(`${flagName} requires a value`);
|
|
234
|
+
return undefined;
|
|
235
|
+
}
|
|
236
|
+
return value;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
240
|
+
const arg = args[i];
|
|
241
|
+
|
|
242
|
+
if (arg === '-h') {
|
|
243
|
+
flags.h = true;
|
|
244
|
+
} else if (arg === '--help') {
|
|
245
|
+
flags.help = true;
|
|
246
|
+
} else if (arg === '-y') {
|
|
247
|
+
flags.y = true;
|
|
248
|
+
} else if (arg === '--yes') {
|
|
249
|
+
flags.yes = true;
|
|
250
|
+
} else if (arg === '--dry-run') {
|
|
251
|
+
flags.dryRun = true;
|
|
252
|
+
} else if (arg === '--list-options') {
|
|
253
|
+
flags.listOptions = true;
|
|
254
|
+
} else if (arg === '--json') {
|
|
255
|
+
flags.json = true;
|
|
256
|
+
} else if (arg === '--on-conflict') {
|
|
257
|
+
const parsedValue = readValue('--on-conflict', i);
|
|
258
|
+
flags.onConflict = parsedValue.value;
|
|
259
|
+
i = parsedValue.nextIndex;
|
|
260
|
+
} else if (arg.startsWith('--on-conflict=')) {
|
|
261
|
+
flags.onConflict = readEqualsValue('--on-conflict', arg.slice('--on-conflict='.length));
|
|
262
|
+
} else if (arg === '--with') {
|
|
263
|
+
const parsedValue = readValue('--with', i);
|
|
264
|
+
if (parsedValue.value !== undefined) flags.with.push(parsedValue.value);
|
|
265
|
+
i = parsedValue.nextIndex;
|
|
266
|
+
} else if (arg.startsWith('--with=')) {
|
|
267
|
+
const value = readEqualsValue('--with', arg.slice('--with='.length));
|
|
268
|
+
if (value !== undefined) flags.with.push(value);
|
|
269
|
+
} else if (arg === '--without') {
|
|
270
|
+
const parsedValue = readValue('--without', i);
|
|
271
|
+
if (parsedValue.value !== undefined) flags.without.push(parsedValue.value);
|
|
272
|
+
i = parsedValue.nextIndex;
|
|
273
|
+
} else if (arg.startsWith('--without=')) {
|
|
274
|
+
const value = readEqualsValue('--without', arg.slice('--without='.length));
|
|
275
|
+
if (value !== undefined) flags.without.push(value);
|
|
276
|
+
} else if (arg === '--preset') {
|
|
277
|
+
const parsedValue = readValue('--preset', i);
|
|
278
|
+
flags.preset = parsedValue.value;
|
|
279
|
+
i = parsedValue.nextIndex;
|
|
280
|
+
} else if (arg.startsWith('--preset=')) {
|
|
281
|
+
flags.preset = readEqualsValue('--preset', arg.slice('--preset='.length));
|
|
282
|
+
} else if (arg.startsWith('-')) {
|
|
283
|
+
errors.push(`Unknown flag "${arg}"`);
|
|
284
|
+
} else {
|
|
285
|
+
positionals.push(arg);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return { flags, positionals, errors };
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function printOptions() {
|
|
293
|
+
const catalog = getOptionalCatalog();
|
|
294
|
+
|
|
295
|
+
console.log('');
|
|
296
|
+
console.log(pc.bold('Optional workflow skills:'));
|
|
297
|
+
for (const skill of catalog.skills) {
|
|
298
|
+
console.log(` ${pc.cyan(skill.id)} - ${skill.description}`);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
console.log('');
|
|
302
|
+
console.log(pc.bold('Presets:'));
|
|
303
|
+
for (const [name, skills] of Object.entries(catalog.presets)) {
|
|
304
|
+
console.log(` ${pc.cyan(name)} - ${skills.join(', ')}`);
|
|
305
|
+
}
|
|
306
|
+
console.log('');
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function printSummary(summary) {
|
|
310
|
+
console.log(` created ${pc.green(summary.created)}`);
|
|
311
|
+
console.log(` skipped ${pc.yellow(summary.skipped)}`);
|
|
312
|
+
console.log(` backed up ${pc.cyan(summary.backedUp)}`);
|
|
313
|
+
console.log(` overwritten ${pc.cyan(summary.overwritten)}`);
|
|
314
|
+
console.log(` conflicts ${summary.conflicts > 0 ? pc.red(summary.conflicts) : pc.dim(summary.conflicts)}`);
|
|
315
|
+
console.log(` directories ${pc.dim(summary.mkdir)}`);
|
|
316
|
+
console.log('');
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
function printPlan(plan) {
|
|
320
|
+
for (const [label, files] of Object.entries(plan)) {
|
|
321
|
+
if (!files.length) continue;
|
|
322
|
+
console.log(` ${label}:`);
|
|
323
|
+
for (const file of files) {
|
|
324
|
+
console.log(` - ${file}`);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function printJsonResult(result) {
|
|
330
|
+
// Remove `created` array from output — it is already in the plan, avoid duplication
|
|
331
|
+
const { created, ...rest } = result;
|
|
332
|
+
console.log(JSON.stringify(rest, null, 2));
|
|
333
|
+
if (!result.success) {
|
|
334
|
+
process.exit(1);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
@@ -10,6 +10,8 @@ alwaysApply: true
|
|
|
10
10
|
- Start with `CLAUDE.md`, `MEMORY.md`, and `docs/README.md`.
|
|
11
11
|
- Do not bulk-read `docs/`. Load by router trigger.
|
|
12
12
|
- Keep `docs/harness/PLAN.md` current when work has multiple steps, files, or agents.
|
|
13
|
+
- project files are the only durable communication channel. chat/subagent transcript state is non-authoritative.
|
|
14
|
+
- Important assumptions, decisions, blockers, evidence, and handoffs must be written to `docs/harness/PLAN.md`, the current feature doc, `MEMORY.md`, or `memory/*` as appropriate.
|
|
13
15
|
|
|
14
16
|
## Verification
|
|
15
17
|
|
|
@@ -28,6 +30,13 @@ alwaysApply: true
|
|
|
28
30
|
- If the runtime cannot spawn subagents, emulate the same role pack in a separate bounded pass.
|
|
29
31
|
- Main agent owns integration and final verification.
|
|
30
32
|
|
|
33
|
+
## Memory
|
|
34
|
+
|
|
35
|
+
- Record a lightweight reflection in `memory/tool-usage-reflections.md` when the same tool/use pattern fails 3+ times.
|
|
36
|
+
- Record repeated user corrections or durable preferences in `memory/user-corrections-preferences.md` when the user corrects the same assumption/pattern 2+ times.
|
|
37
|
+
- Record reusable review/debug lessons in `memory/agent-lessons-patterns.md`.
|
|
38
|
+
- Keep memory entries concise and never include secrets.
|
|
39
|
+
|
|
31
40
|
## Security
|
|
32
41
|
|
|
33
42
|
- No secrets in source code.
|
|
@@ -86,6 +86,8 @@ Strong success criteria let you loop independently. Weak criteria ("make it work
|
|
|
86
86
|
|
|
87
87
|
## 6. Memory & Self-Learning
|
|
88
88
|
|
|
89
|
-
-
|
|
90
|
-
- **Tool
|
|
91
|
-
-
|
|
89
|
+
- `MEMORY.md` is the index. Detailed durable memory lives in `memory/`.
|
|
90
|
+
- **Tool reflection trigger**: record a lightweight reflection when the same tool/use pattern fails 3+ times, or when a better command pattern/environment fix is found. Write it newest-first in `memory/tool-usage-reflections.md`.
|
|
91
|
+
- **User correction trigger**: record a lightweight preference/correction when the user asks to remember it, or when the user corrects the same assumption/pattern 2+ times. Write it newest-first in `memory/user-corrections-preferences.md`.
|
|
92
|
+
- **Agent lesson trigger**: record reusable lessons from review/debug loops in `memory/agent-lessons-patterns.md` when they would prevent recurrence.
|
|
93
|
+
- Update old entries instead of duplicating them. Never record secrets, credentials, tokens, or private data. If a memory is ambiguous, ask before writing.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
# MEMORY.md
|
|
1
|
+
# MEMORY.md - {{projectName}} Project Resource Index
|
|
2
2
|
|
|
3
3
|
> The project fact source is reached via `CLAUDE.md -> docs/README.md`. This file persists cross-session context: resource index, user preferences, tool usage standards.
|
|
4
|
+
> Detailed memory lives in `memory/`. Keep entries short, newest first, and free of secrets.
|
|
4
5
|
|
|
5
6
|
## Agents (Sub-agents)
|
|
6
7
|
|
|
@@ -46,13 +47,16 @@ Located under `.claude/rules/ecc/`, auto-loaded by the CC engine:
|
|
|
46
47
|
- [Agent workflow](docs/harness/agent-workflow.md)
|
|
47
48
|
- [Harness validator](scripts/validate-harness.mjs)
|
|
48
49
|
|
|
49
|
-
##
|
|
50
|
+
## Memory Folder
|
|
50
51
|
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
- [Tool usage/reflections](memory/tool-usage-reflections.md) - repeated tool failures, better command patterns, environment-specific fixes.
|
|
53
|
+
- [User corrections/preferences](memory/user-corrections-preferences.md) - repeated user corrections, durable preferences, common-sense course corrections.
|
|
54
|
+
- [Agent lessons/patterns](memory/agent-lessons-patterns.md) - reusable lessons from review, debugging, validation, and handoff loops.
|
|
53
55
|
|
|
54
|
-
|
|
56
|
+
Write to the memory folder when the guidance should survive chat context loss:
|
|
55
57
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
- Use `memory/tool-usage-reflections.md` when the same tool/use pattern fails 3+ times, a better command pattern is found, or an environment-specific fix should be reused.
|
|
59
|
+
- Use `memory/user-corrections-preferences.md` when the user explicitly asks to remember a preference, or the user corrects the same assumption/pattern 2+ times.
|
|
60
|
+
- Use `memory/agent-lessons-patterns.md` when a review/debug loop yields a reusable lesson or regression guard.
|
|
61
|
+
- Use `MEMORY.md` for the resource index and routing pointers, not long-form lessons.
|
|
62
|
+
- Never record secrets, credentials, tokens, or private data. If a memory is ambiguous, ask before writing.
|
|
@@ -10,6 +10,7 @@ This scaffold is a 0-1 product harness:
|
|
|
10
10
|
- dynamic docs router
|
|
11
11
|
- PRD, research protocol, architecture, ports, data-flow, state templates
|
|
12
12
|
- active `docs/harness/PLAN.md`
|
|
13
|
+
- `MEMORY.md` plus a `memory/` folder for durable self-learning, user corrections, and tool reflections
|
|
13
14
|
- built-in common agents
|
|
14
15
|
- subagent context-loading protocol
|
|
15
16
|
- skill-style dynamic loaders in `.claude/skills/`
|
|
@@ -32,7 +33,7 @@ First clarify the idea, then create PRD, research, architecture, docs/harness/PL
|
|
|
32
33
|
|
|
33
34
|
Claude must follow this order:
|
|
34
35
|
|
|
35
|
-
1. Read `CLAUDE.md`, `MEMORY.md`, `docs/README.md`, and `docs/harness/lifecycle.md`.
|
|
36
|
+
1. Read `CLAUDE.md`, `MEMORY.md`, `docs/README.md`, and `docs/harness/lifecycle.md`. Load `memory/*` only when the router or memory trigger applies.
|
|
36
37
|
2. Ask up to 3 blocking product questions. If not blocked, record assumptions in `docs/harness/PLAN.md`.
|
|
37
38
|
3. Fill `docs/research/PRD.md` with MVP, non-goals, and acceptance criteria.
|
|
38
39
|
4. Read `docs/research/README.md`, then fill `docs/research/research-results.md` with adopted/rejected research choices.
|
|
@@ -42,7 +43,86 @@ Claude must follow this order:
|
|
|
42
43
|
8. Fill `docs/harness/data-flow.md` or `docs/harness/state-machines.md` only when the slice changes runtime flow, failure behavior, or state.
|
|
43
44
|
9. Implement only after a failing test or manual verification step is defined.
|
|
44
45
|
10. Run `node scripts/validate-harness.mjs --strict`.
|
|
45
|
-
11. Record final verification and next feedback step in `docs/harness/PLAN.md`.
|
|
46
|
+
11. Record final verification and next feedback step in `docs/harness/PLAN.md`. If repeated tool failures, repeated user corrections, or reusable review/debug lessons appeared, record the concise reflection in the relevant `memory/` file.
|
|
47
|
+
|
|
48
|
+
## Existing Project Bootstrap Sequence
|
|
49
|
+
|
|
50
|
+
When adding this harness to a project that already has source code, docs, CI, or tool configuration, treat the existing project as the source of truth before filling harness docs.
|
|
51
|
+
|
|
52
|
+
1. Scan existing project facts first: `README.md`, package files (`package.json`, `pyproject.toml`, `go.mod`, etc.), test commands, app entry points, CI files, existing docs, and current run/build scripts.
|
|
53
|
+
2. Record discovered facts and open questions in `docs/harness/PLAN.md` before changing harness docs.
|
|
54
|
+
3. Fill `docs/research/PRD.md`, `docs/research/research-results.md`, `docs/harness/architecture.md`, and `docs/domain/ports.md` from observed project facts plus explicit user input.
|
|
55
|
+
4. Existing configuration is project fact. Do not overwrite `CLAUDE.md`, `AGENTS.md`, `.claude/`, `.gitignore`, settings, hooks, package files, CI, docs routers, or workflow docs unless the user explicitly approves that exact overwrite.
|
|
56
|
+
5. When a harness file conflicts with an existing file, preserve the existing file and register any missing harness guidance manually using `docs/harness/extension.md`.
|
|
57
|
+
6. Run `node scripts/validate-harness.mjs` after registration, then run `node scripts/validate-harness.mjs --strict` only after project-fact placeholders have been resolved or intentionally recorded as open.
|
|
58
|
+
|
|
59
|
+
### Agent Conflict Resolution Protocol
|
|
60
|
+
|
|
61
|
+
When `--on-conflict skip` leaves existing files untouched, the agent resolves each conflict with user supervision.
|
|
62
|
+
|
|
63
|
+
**Workflow:**
|
|
64
|
+
|
|
65
|
+
1. Run the harness tool in planning mode to get the conflict list:
|
|
66
|
+
```
|
|
67
|
+
npx create-harness-vibe-coding@latest . . -y --dry-run --json
|
|
68
|
+
```
|
|
69
|
+
Parse the JSON output. Files in `plan.skip[]` need attention. Files in `plan.create[]` are handled automatically.
|
|
70
|
+
|
|
71
|
+
2. For each skipped file, locate the harness template counterpart:
|
|
72
|
+
- From npm: `node_modules/create-harness-vibe-coding/templates/common/<path>`
|
|
73
|
+
- From GitHub: `https://raw.githubusercontent.com/zingspark/create-harness-vibe-coding/main/templates/common/<path>`
|
|
74
|
+
|
|
75
|
+
3. For each skipped file:
|
|
76
|
+
- Read the existing project file.
|
|
77
|
+
- Read the harness template counterpart.
|
|
78
|
+
- Compare sections and headings. Identify structural sections, registration entries, and required text patterns that exist in the template but are missing from the existing file.
|
|
79
|
+
- Present each gap to the user as a choice:
|
|
80
|
+
- **[Merge]** — Edit the existing file to add only the missing sections. Preserve all existing content, ordering, and formatting.
|
|
81
|
+
- **[Overwrite]** — Replace with the template version. Optionally backup the original first (`--on-conflict backup`).
|
|
82
|
+
- **[Keep]** — Leave the existing file as-is. Skip this file.
|
|
83
|
+
|
|
84
|
+
4. For Merge: use Edit (not Write) to add missing content. Only insert sections, headings, and text that are structurally required. Do not reorder or modify existing content. Do not remove custom project-specific registrations.
|
|
85
|
+
|
|
86
|
+
5. After all merges, run `node scripts/validate-harness.mjs`. Fix any remaining validation errors, then run `node scripts/validate-harness.mjs --strict` only after project-fact placeholders are resolved.
|
|
87
|
+
|
|
88
|
+
**File-specific gap checklists:**
|
|
89
|
+
|
|
90
|
+
The harness validator checks for specific structural invariants. When comparing existing files against templates, verify these are present. Most other template content can vary; only the items below are required.
|
|
91
|
+
|
|
92
|
+
| File | Required check |
|
|
93
|
+
|------|----------------|
|
|
94
|
+
| `CLAUDE.md` | `## 1. Startup` with `If SETUP.md exists` line; `## 6. Memory & Self-Learning` section; the tool reflection trigger text (`same tool/use pattern fails 3+ times`); the user correction trigger text (`user corrects the same assumption/pattern 2+ times`); `Never bulk-read docs/` in Startup |
|
|
95
|
+
| `MEMORY.md` | All 9 common agents registered under `## Agents`; all 5 harness skills registered under `## Skills`; all 3 `memory/` files registered under `## Memory Folder`; `memory/` folder usage guidance; `Project Resource Index` in title |
|
|
96
|
+
| `.claude/rules/ecc/common.md` | `## Context` section with the durable communication invariant (`project files are the only durable communication channel`); `## Memory` section with three reflection file entries; `## Security` section |
|
|
97
|
+
| `docs/README.md` | `## Keyword Routing` heading; `## Load By Task` table with at minimum the rows: "Adding harness to existing project", "Need implementation plan", "Need durable memory or reflection"; `## Doc Map` with `memory/` entries; the durable communication invariant text; `docs/README.md is the primary router` |
|
|
98
|
+
| `docs/harness/extension.md` | `## Non-Invasive Extension Rules` section with the "Preserve existing" rule; `## Agent Contract` section; `## Registration` section |
|
|
99
|
+
| `docs/harness/dispatch.md` | The durable communication invariant; common agent entries for all 9 agents; `## Handoff Format` heading |
|
|
100
|
+
| `docs/harness/context-loading.md` | The durable communication invariant; `docs/README.md is the primary router`; all 10 subagent context packs (Explorer Pass, Planner, Researcher, Docs Researcher, Architect, Test Writer, Implementer, Reviewer, Debugger, Verifier) |
|
|
101
|
+
| `docs/harness/PLAN.md` | `## Current Goal`, `## Phase`, `## Success Criteria`, `## Loaded Context`, `## Tasks`, `## Parallel Dispatch`, `## Verification` headings |
|
|
102
|
+
| `SETUP.md` | Only meaningful for fresh projects. If the project has its own onboarding docs, skip this file entirely (it is temporary). If kept, ensure the "Existing Project Bootstrap Sequence" is present. |
|
|
103
|
+
| `docs/workflows/browser-e2e.md` (if installed as optional) | `data-testid`, `accessible labels/roles`, and `inputs, buttons, filters, rows, empty/error/loading states` requirement |
|
|
104
|
+
| `docs/workflows/ts-react-frontend.md` (if installed as optional) | Same UI selector contract as above |
|
|
105
|
+
| `docs/features/_template.md` | `## 1.5 UI Automation Hooks` with `data-testid` table |
|
|
106
|
+
|
|
107
|
+
**Files that do NOT need manual merge (auto-created by harness):**
|
|
108
|
+
|
|
109
|
+
- `memory/tool-usage-reflections.md`, `memory/user-corrections-preferences.md`, `memory/agent-lessons-patterns.md` — these are new empty files
|
|
110
|
+
- `.claude/agents/*.md` — all 9 common agents
|
|
111
|
+
- `.claude/skills/harness-*/SKILL.md` — all 5 harness skills
|
|
112
|
+
- `.claude/rules/ecc/common.md` — universal rules (unless the project has custom rules in this file)
|
|
113
|
+
- `.claude/settings.json` — harness settings
|
|
114
|
+
- `docs/harness/lifecycle.md`, `docs/harness/agent-workflow.md`, `docs/harness/architecture.md`, `docs/harness/data-flow.md`, `docs/harness/state-machines.md` — harness runtime docs
|
|
115
|
+
- `docs/research/*.md` — research protocol and templates
|
|
116
|
+
- `docs/domain/ports.md` — port contract template
|
|
117
|
+
- `AGENTS.md` — agent registry
|
|
118
|
+
- `scripts/validate-harness.mjs` and `tests/.gitkeep` — tooling
|
|
119
|
+
|
|
120
|
+
Optional workflow examples:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
npx create-harness-vibe-coding@latest my-app ./my-app -y --with browser-e2e,ts-react-frontend
|
|
124
|
+
npx create-harness-vibe-coding@latest my-app ./my-app -y --preset web-app
|
|
125
|
+
```
|
|
46
126
|
|
|
47
127
|
### Template Fill Guide
|
|
48
128
|
|
|
@@ -82,6 +162,11 @@ Each template doc contains `{{PLACEHOLDER}}` markers. Below is what every placeh
|
|
|
82
162
|
- `## Parallel Dispatch`: only when spawning subagents — fill agent roles, read/write boundaries.
|
|
83
163
|
- `## Verification`: record test results, review findings, docs sync checklist.
|
|
84
164
|
|
|
165
|
+
**`memory/`** — Durable self-evolution notes:
|
|
166
|
+
- `memory/tool-usage-reflections.md`: repeated tool failures, better command patterns, environment-specific fixes.
|
|
167
|
+
- `memory/user-corrections-preferences.md`: repeated user corrections, durable preferences, common-sense course corrections.
|
|
168
|
+
- `memory/agent-lessons-patterns.md`: reusable lessons from review, debugging, validation, and handoff loops.
|
|
169
|
+
|
|
85
170
|
**`docs/harness/data-flow.md`** — Runtime event paths (only when first slice has async/multi-step flow):
|
|
86
171
|
- `{{EVENT_1}}`: the first event type with producer, consumers, payload fields, delivery semantics.
|
|
87
172
|
- Happy Path: fill the Mermaid sequence diagram with actual ports and actions.
|
|
@@ -16,6 +16,8 @@ For the full phase contract, load [harness/lifecycle.md](harness/lifecycle.md).
|
|
|
16
16
|
|
|
17
17
|
- This file is a router, not a full spec.
|
|
18
18
|
- If the task does not clearly match a row below, search by keywords before loading more docs.
|
|
19
|
+
- project files are the only durable communication channel; chat/subagent transcript state is non-authoritative.
|
|
20
|
+
- Important assumptions, decisions, blockers, evidence, and handoffs must be written to [harness/PLAN.md](harness/PLAN.md), the current feature doc, `MEMORY.md`, or `memory/*` as appropriate.
|
|
19
21
|
- Core rules live in `CLAUDE.md` and `.claude/rules/ecc/common.md`.
|
|
20
22
|
- Phase rules live in [harness/lifecycle.md](harness/lifecycle.md).
|
|
21
23
|
- Build, review, test, and subagent rules live in [harness/agent-workflow.md](harness/agent-workflow.md).
|
|
@@ -50,9 +52,12 @@ Load the matching row only. Add adjacent docs only when the loaded doc directly
|
|
|
50
52
|
| Need market/tech direction | research, market, competitor, stack, library, pricing, policy | [research/README.md](research/README.md), [research/research-results.md](research/research-results.md) | research protocol, adopted/rejected choices |
|
|
51
53
|
| Need MVP/spec | PRD, MVP, scope, requirement, acceptance, non-goal | [research/PRD.md](research/PRD.md) | one-page PRD with verifiable acceptance criteria |
|
|
52
54
|
| Need architecture or boundaries | architecture, boundary, layer, domain, port, adapter, dependency | [harness/architecture.md](harness/architecture.md), [domain/ports.md](domain/ports.md) | layer map, ports, constraints |
|
|
55
|
+
| Adding harness to existing project | existing project, onboarding, migrate, bootstrap, preserve, conflict | [harness/extension.md](harness/extension.md), [harness/PLAN.md](harness/PLAN.md), root `README.md` and package/CI files | discovered project facts, preserved config, manual registration plan |
|
|
53
56
|
| Need implementation plan | plan, task, write set, verify, milestone, progress | [harness/PLAN.md](harness/PLAN.md), [harness/agent-workflow.md](harness/agent-workflow.md) | tasks, write set, verification commands |
|
|
54
57
|
| Need parallel agents | parallel, dispatch, handoff, write set, dependency, status | [harness/dispatch.md](harness/dispatch.md), [harness/context-loading.md](harness/context-loading.md), [harness/PLAN.md](harness/PLAN.md) | dispatch table, agent roles, read/write sets |
|
|
55
58
|
| Adding stack-specific agents/skills | extension, agent, skill, rule, hook, stack-specific, compatibility | [harness/extension.md](harness/extension.md), [harness/dispatch.md](harness/dispatch.md) | compatible agents, skills, rules, hooks |
|
|
59
|
+
| Optional workflow installed | workflow, optional, browser-e2e, ui-ux-review, github-pr-review, python-backend, ts-react-frontend | matching `docs/workflows/*.md`, [harness/extension.md](harness/extension.md) | workflow-specific evidence, commands, fallback path |
|
|
60
|
+
| Need durable memory or reflection | memory, remember, preference, correction, tool failure, lesson, reflection | `MEMORY.md`, `memory/tool-usage-reflections.md`, `memory/user-corrections-preferences.md`, `memory/agent-lessons-patterns.md` | concise newest-first memory entry or no-op rationale |
|
|
56
61
|
| Need subagents | subagent, role pack, context, inject, return format | [harness/context-loading.md](harness/context-loading.md) | role-specific context pack |
|
|
57
62
|
| Need feature work | feature, implementation, TDD, test, review, closeout | [features/_template.md](features/_template.md), [harness/agent-workflow.md](harness/agent-workflow.md) | feature doc, tests, implementation loop |
|
|
58
63
|
| Flow or failure behavior changes | data flow, event, failure, retry, recovery, caller behavior | [harness/data-flow.md](harness/data-flow.md) | happy path, failure path, caller behavior |
|
|
@@ -95,6 +100,9 @@ docs/features/_template.md feature work packet
|
|
|
95
100
|
docs/research/README.md research protocol
|
|
96
101
|
docs/research/PRD.md product scope
|
|
97
102
|
docs/research/research-results.md research results
|
|
103
|
+
memory/tool-usage-reflections.md repeated tool failures and better command patterns
|
|
104
|
+
memory/user-corrections-preferences.md durable user corrections and preferences
|
|
105
|
+
memory/agent-lessons-patterns.md reusable review/debug lessons
|
|
98
106
|
scripts/validate-harness.mjs lightweight harness gate
|
|
99
107
|
.claude/agents/* built-in common agents
|
|
100
108
|
.claude/skills/* skill-style dynamic loaders
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
# {{FEATURE_NAME}}
|
|
2
2
|
|
|
3
|
-
> **When to use**:
|
|
3
|
+
> **When to use**: Every PRD scope item in `research/PRD.md` Section 2 must have a feature doc — either a new one from this template, or an iteration on an existing one. Do not code a PRD scope item without a corresponding features doc.
|
|
4
|
+
>
|
|
5
|
+
> **New vs iterate**: If the scope item has ≥85% overlap with an existing feature doc, iterate the existing doc (bump `Version`, add a `## Changelog` entry). If overlap is below 85%, create a new file from this template. When in doubt, ask the user.
|
|
4
6
|
|
|
5
7
|
> **Status**: Draft / In Progress / Blocked / Done
|
|
6
8
|
> **Created**: {{YYYY-MM-DD}}
|
|
9
|
+
> **Version**: 1
|
|
7
10
|
> **Owner**: {{OWNER_OR_AGENT}}
|
|
8
11
|
> **Related Docs**: {{PRD_OR_ARCH_DOC_LINKS}}
|
|
9
12
|
|
|
@@ -31,6 +34,16 @@
|
|
|
31
34
|
- [ ] {{ACCEPTANCE_CRITERION_2}}
|
|
32
35
|
- [ ] {{ACCEPTANCE_CRITERION_3}}
|
|
33
36
|
|
|
37
|
+
### 1.5 UI Automation Hooks
|
|
38
|
+
|
|
39
|
+
For TS/React or browser workflows, define required stable accessible labels/roles and stable test hooks such as `data-testid` before implementation. These selectors must cover critical UI controls and states so CDP, Playwright, and manual verification can target inputs, buttons, filters, rows, empty/error/loading states, dialogs, navigation, and submitted/saved/error feedback without brittle DOM paths.
|
|
40
|
+
|
|
41
|
+
| Element / State | Accessible Role / Label | `data-testid` | Verification Target |
|
|
42
|
+
| --- | --- | --- | --- |
|
|
43
|
+
| {{INPUT_OR_CONTROL}} | {{ROLE_OR_LABEL}} | {{DATA_TESTID}} | {{PLAYWRIGHT_OR_MANUAL_CHECK}} |
|
|
44
|
+
| {{EMPTY_ERROR_LOADING_OR_ROW_STATE}} | {{ROLE_OR_LABEL}} | {{DATA_TESTID}} | {{PLAYWRIGHT_OR_MANUAL_CHECK}} |
|
|
45
|
+
| Not UI-facing | N/A | N/A | N/A |
|
|
46
|
+
|
|
34
47
|
---
|
|
35
48
|
|
|
36
49
|
## 2. Design
|
|
@@ -142,3 +155,13 @@ Estimate the context budget for this feature. If the main agent would need to re
|
|
|
142
155
|
|
|
143
156
|
Remaining risks:
|
|
144
157
|
- {{RISK_OR_NONE}}
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## 5. Changelog
|
|
162
|
+
|
|
163
|
+
> Only populate when iterating an existing feature doc (Version ≥ 2).
|
|
164
|
+
|
|
165
|
+
| Version | Date | What Changed | Reason |
|
|
166
|
+
| --- | --- | --- | --- |
|
|
167
|
+
| 1 | {{YYYY-MM-DD}} | Initial version | — |
|
|
@@ -12,15 +12,11 @@ If context grows, load [context-loading.md](context-loading.md) and split the wo
|
|
|
12
12
|
|
|
13
13
|
## Feature Packet
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Every PRD scope item (`research/PRD.md` Section 2) must have its own feature doc at `docs/features/<name>.md` created from `docs/features/_template.md`. One feature = one doc = one implementation unit. Do not code without a feature doc.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Small scope is not an exception — a short feature doc is better than none. If the work is truly too small for a full feature doc (single-file fix, no behavior change), it is not a PRD scope item.
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
- acceptance criteria
|
|
21
|
-
- allowed write set and forbidden scope
|
|
22
|
-
- task list with verification commands
|
|
23
|
-
- test results and residual risks
|
|
19
|
+
**New vs iterate**: if a PRD scope item has ≥85% overlap with an existing feature doc, open the existing doc, bump `Version`, and add a `## Changelog` entry. Only create a new file when the scope is substantially different. When unsure, ask.
|
|
24
20
|
|
|
25
21
|
## Standard Build Loop
|
|
26
22
|
|
|
@@ -8,6 +8,8 @@ Use when context is growing, subagents are needed, or an agent is unsure which h
|
|
|
8
8
|
|
|
9
9
|
If this file and `docs/README.md` disagree, follow `docs/README.md`, record the assumption in `docs/harness/PLAN.md`, and update this file later.
|
|
10
10
|
|
|
11
|
+
project files are the only durable communication channel; chat/subagent transcript state is non-authoritative. Important assumptions, decisions, blockers, evidence, and handoffs must be written to `docs/harness/PLAN.md`, the current feature doc, `MEMORY.md`, or `memory/*` as appropriate.
|
|
12
|
+
|
|
11
13
|
## Main Context
|
|
12
14
|
|
|
13
15
|
Always keep:
|
|
@@ -30,6 +32,7 @@ Load other docs only by trigger.
|
|
|
30
32
|
| layer, dependency, module boundary | `docs/harness/architecture.md`, `docs/domain/ports.md` |
|
|
31
33
|
| task split, owner, write set | `docs/harness/PLAN.md`, `docs/harness/agent-workflow.md` |
|
|
32
34
|
| parallel agents, dispatch, worktree decision | `docs/harness/dispatch.md`, `docs/harness/PLAN.md` |
|
|
35
|
+
| memory, repeated tool failure, repeated user correction, reusable lesson | `MEMORY.md`, the relevant `memory/*.md` file |
|
|
33
36
|
| event, retry, failure path | `docs/harness/data-flow.md` |
|
|
34
37
|
| status, transition, resume | `docs/harness/state-machines.md` |
|
|
35
38
|
| subagent spawn | this file plus the role pack below |
|
|
@@ -7,6 +7,8 @@ Use when work needs parallel reading, independent review, cross-layer analysis,
|
|
|
7
7
|
## Principles
|
|
8
8
|
|
|
9
9
|
- Main agent owns the final decision, integration, and verification.
|
|
10
|
+
- project files are the only durable communication channel; chat/subagent transcript state is non-authoritative.
|
|
11
|
+
- Important assumptions, decisions, blockers, evidence, and handoffs must be written to `docs/harness/PLAN.md`, the current feature doc, `MEMORY.md`, or `memory/*` as appropriate.
|
|
10
12
|
- Prefer three or fewer active agents.
|
|
11
13
|
- Read-only agents may run in parallel.
|
|
12
14
|
- Writing agents run serially unless write sets are disjoint.
|
|
@@ -76,6 +78,7 @@ PLAN patch:
|
|
|
76
78
|
```
|
|
77
79
|
|
|
78
80
|
Use `Files changed: none` for read-only agents. Use `PLAN patch: none` when no state update is needed.
|
|
81
|
+
If a handoff matters after context loss, write it to `docs/harness/PLAN.md`, the current feature doc, or `memory/*`; do not rely on chat transcript state.
|
|
79
82
|
|
|
80
83
|
## Statuses
|
|
81
84
|
|