create-harness-vibe-coding 0.8.1 → 0.8.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/README-CN.md +15 -11
- package/README.md +21 -12
- package/package.json +1 -1
- package/src/index.js +210 -10
- package/templates/common/.claude/agents/tdd-guide.md +55 -0
- package/templates/common/.claude/settings.json +22 -0
- package/templates/common/.claude/skills/tdd/SKILL.md +30 -0
- package/templates/common/.claude/skills/wf-auto/SKILL.md +107 -0
- package/templates/common/.claude/skills/wf-auto-spark/SKILL.md +39 -0
- package/templates/common/.claude/skills/wf-max/SKILL.md +10 -2
- package/templates/common/.claude/skills/wf-remove/SKILL.md +12 -5
- package/templates/common/.claude/skills/wf-update/SKILL.md +12 -5
- package/templates/common/.codex/hooks.json +59 -37
- package/templates/common/.harness-version +48 -25
- package/templates/common/AGENTS.md +5 -5
- package/templates/common/CLAUDE.md +12 -17
- package/templates/common/Harness/ECC-GUIDE.md +246 -0
- package/templates/common/Harness/README.md +129 -130
- package/templates/common/Harness/TDD-GUIDE.md +83 -0
- package/templates/common/Harness/WF-AUTO-SPARK.md +297 -0
- package/templates/common/Harness/WF-AUTO.md +508 -0
- package/templates/common/Harness/WF-MAX.md +24 -0
- package/templates/common/Harness/context-loading.md +38 -1
- package/templates/common/Harness/dispatch.md +40 -40
- package/templates/common/Harness/subagents.md +7 -21
- package/templates/common/Harness/tasks/_template/NAMING.md +47 -0
- package/templates/common/MEMORY.md +73 -66
- package/templates/common/SETUP.md +100 -78
- package/templates/common/scripts/validate-harness.mjs +92 -58
- package/templates/common/scripts/wf-mode-hook.mjs +642 -318
- package/templates/common/scripts/wf-remove.mjs +301 -81
- package/templates/common/scripts/wf-statusline.ps1 +62 -38
- package/templates/common/scripts/wf-statusline.sh +67 -48
- package/templates/common/scripts/wf-update-check.mjs +179 -81
package/README-CN.md
CHANGED
|
@@ -59,13 +59,15 @@ Claude Code 和 Codex 共用同一套核心 Harness 文档,但发现入口不
|
|
|
59
59
|
## 已有项目安全合并
|
|
60
60
|
|
|
61
61
|
```bash
|
|
62
|
-
#
|
|
63
|
-
npx create-harness-vibe-coding@latest my-app . -y --dry-run
|
|
62
|
+
# 先用机器可读预览,不写文件
|
|
63
|
+
npx create-harness-vibe-coding@latest my-app . -y --dry-run --json
|
|
64
64
|
|
|
65
65
|
# 只补缺失文件,不覆盖已有文件
|
|
66
|
-
npx create-harness-vibe-coding@latest my-app . -y --on-conflict skip
|
|
66
|
+
npx create-harness-vibe-coding@latest my-app . -y --on-conflict skip --json
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
+
JSON 输出就是 agent 的安装报告:`scan` 代替手写根目录探测,`plan.create` 交给脚本处理,只有 `agent.aiMergeRequired` 里的文件需要 AI 语义比较和用户监督合并。除非这个列表里出现冲突文件,否则不要读取包源码或模板。
|
|
70
|
+
|
|
69
71
|
`npx` 是安装和安全补缺入口,不是已安装 Harness 的同步更新器。项目里已经有 `Harness/` 后,Claude Code 用 `/wf-update`,Codex 用 `$wf-update`,或者直接运行:
|
|
70
72
|
|
|
71
73
|
```bash
|
|
@@ -107,14 +109,13 @@ npx create-harness-vibe-coding@latest my-app -y --recommend superpowers,codegrap
|
|
|
107
109
|
|
|
108
110
|
## Agent-link 安装前置问题
|
|
109
111
|
|
|
110
|
-
Agent
|
|
112
|
+
Agent 应先拿机器可读安装报告,再最多问 3 个阻塞问题:
|
|
111
113
|
|
|
112
|
-
|
|
113
|
-
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
- 已安装的 skills/plugins/rules
|
|
114
|
+
```bash
|
|
115
|
+
npx create-harness-vibe-coding@latest my-app . -y --dry-run --json
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
使用 `scan.markers`,不要手写一串根目录探测命令。`plan.create` 由脚本处理;只有 `agent.aiMergeRequired` 里的文件需要 AI 比较并由用户监督合并。
|
|
118
119
|
|
|
119
120
|
只在影响写入时提问:
|
|
120
121
|
|
|
@@ -127,8 +128,11 @@ Agent 必须先扫描根目录,再最多问 3 个阻塞问题。扫描要覆
|
|
|
127
128
|
## 验证
|
|
128
129
|
|
|
129
130
|
```bash
|
|
131
|
+
# 当前脚手架仓库
|
|
130
132
|
npm test
|
|
131
|
-
|
|
133
|
+
|
|
134
|
+
# 生成后的项目完成 bootstrap 后
|
|
135
|
+
node Harness/scripts/validate-harness.mjs --strict
|
|
132
136
|
```
|
|
133
137
|
|
|
134
138
|
## 项目结构
|
package/README.md
CHANGED
|
@@ -120,13 +120,15 @@ Root scan must include top-level files, `CLAUDE.md`, `AGENTS.md`, `.claude/`, `.
|
|
|
120
120
|
### Existing project — safe merge
|
|
121
121
|
|
|
122
122
|
```bash
|
|
123
|
-
#
|
|
124
|
-
npx create-harness-vibe-coding@latest my-app . -y --dry-run
|
|
125
|
-
|
|
123
|
+
# Machine-readable preview first. Always.
|
|
124
|
+
npx create-harness-vibe-coding@latest my-app . -y --dry-run --json
|
|
125
|
+
|
|
126
126
|
# Add only what's missing. Never overwrite.
|
|
127
|
-
npx create-harness-vibe-coding@latest my-app . -y --on-conflict skip
|
|
127
|
+
npx create-harness-vibe-coding@latest my-app . -y --on-conflict skip --json
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
+
The JSON output is the agent's install report: `scan` replaces hand-written root probes, `plan.create` is script-owned, and `agent.aiMergeRequired` is the only list that needs semantic AI review. Do not read package source or templates unless `agent.aiMergeRequired` names a conflicting file.
|
|
131
|
+
|
|
130
132
|
`npx` is an install and safe-merge entry, not an update engine for an already installed Harness. Once `Harness/` exists, use `/wf-update` in Claude Code, `$wf-update` in Codex, or `node Harness/scripts/wf-update-check.mjs`; root entry conflicts such as `CLAUDE.md`, `AGENTS.md`, `.claude/`, `.agents/`, `.codex/`, and local Harness docs need agent-mediated merge decisions.
|
|
131
133
|
|
|
132
134
|
| Flag | Does |
|
|
@@ -172,9 +174,13 @@ These are links for the user's agent to evaluate. The scaffold does not maintain
|
|
|
172
174
|
|
|
173
175
|
### Agent-link intake
|
|
174
176
|
|
|
175
|
-
When your agent reads the one-sentence prompt above, it
|
|
177
|
+
When your agent reads the one-sentence prompt above, it should get the machine-readable install report before asking broad questions:
|
|
176
178
|
|
|
177
|
-
|
|
179
|
+
```bash
|
|
180
|
+
npx create-harness-vibe-coding@latest my-app . -y --dry-run --json
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Use `scan.markers` instead of manual top-level probes. Ask **at most 3 blocking questions** before touching files. Files in `plan.create` are handled by the script; only files in `agent.aiMergeRequired` need AI comparison and user-supervised merge decisions.
|
|
178
184
|
|
|
179
185
|
Ask these only when they affect writes:
|
|
180
186
|
|
|
@@ -193,12 +199,15 @@ Harness docs always live in root `Harness/`; do not route Harness files through
|
|
|
193
199
|
"/wf-update" or "$wf-update" # pull latest harness improvements
|
|
194
200
|
```
|
|
195
201
|
|
|
196
|
-
### Verify
|
|
197
|
-
|
|
198
|
-
```bash
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
+
### Verify
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
# In this package repo
|
|
206
|
+
npm test
|
|
207
|
+
|
|
208
|
+
# In a generated project after bootstrap
|
|
209
|
+
node Harness/scripts/validate-harness.mjs --strict
|
|
210
|
+
```
|
|
202
211
|
|
|
203
212
|
---
|
|
204
213
|
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -81,11 +81,19 @@ const generationOptions = {
|
|
|
81
81
|
const DEFAULT_NAME = 'my-vibe-project';
|
|
82
82
|
|
|
83
83
|
// --json: machine-readable output, no prompts, no decorative output
|
|
84
|
-
if (generationOptions.json) {
|
|
85
|
-
const projectName = argName || DEFAULT_NAME;
|
|
86
|
-
const targetDir = argDir || `./${projectName}`;
|
|
87
|
-
const
|
|
88
|
-
|
|
84
|
+
if (generationOptions.json) {
|
|
85
|
+
const projectName = argName || DEFAULT_NAME;
|
|
86
|
+
const targetDir = argDir || `./${projectName}`;
|
|
87
|
+
const scan = scanTarget(targetDir);
|
|
88
|
+
const result = generate({ projectName, targetDir, ...generationOptions });
|
|
89
|
+
result.scan = createJsonScan(scan);
|
|
90
|
+
result.agent = createAgentGuidance(result, {
|
|
91
|
+
projectName,
|
|
92
|
+
targetDir,
|
|
93
|
+
options: generationOptions,
|
|
94
|
+
scan,
|
|
95
|
+
});
|
|
96
|
+
printJsonResult(result);
|
|
89
97
|
// printJsonResult exits with 1 on failure; we only reach here on success
|
|
90
98
|
process.exit(0);
|
|
91
99
|
}
|
|
@@ -429,6 +437,17 @@ function scanTarget(targetDir) {
|
|
|
429
437
|
? fs.readdirSync(resolvedDir)
|
|
430
438
|
: [];
|
|
431
439
|
const hasHarness = isDirectory && fs.existsSync(path.join(resolvedDir, 'Harness'));
|
|
440
|
+
const hasClaude = isDirectory && fs.existsSync(path.join(resolvedDir, 'CLAUDE.md'));
|
|
441
|
+
const hasAgents = isDirectory && fs.existsSync(path.join(resolvedDir, 'AGENTS.md'));
|
|
442
|
+
const hasAgentSkills = isDirectory && fs.existsSync(path.join(resolvedDir, '.agents'));
|
|
443
|
+
const hasCodex = isDirectory && fs.existsSync(path.join(resolvedDir, '.codex'));
|
|
444
|
+
const hasDocs = isDirectory && fs.existsSync(path.join(resolvedDir, 'docs'));
|
|
445
|
+
const hasReadme = isDirectory && fs.existsSync(path.join(resolvedDir, 'README.md'));
|
|
446
|
+
const hasPackageJson = isDirectory && fs.existsSync(path.join(resolvedDir, 'package.json'));
|
|
447
|
+
const hasPyproject = isDirectory && fs.existsSync(path.join(resolvedDir, 'pyproject.toml'));
|
|
448
|
+
const hasGoMod = isDirectory && fs.existsSync(path.join(resolvedDir, 'go.mod'));
|
|
449
|
+
const hasGithub = isDirectory && fs.existsSync(path.join(resolvedDir, '.github'));
|
|
450
|
+
const hasGitignore = isDirectory && fs.existsSync(path.join(resolvedDir, '.gitignore'));
|
|
432
451
|
|
|
433
452
|
return {
|
|
434
453
|
resolvedDir,
|
|
@@ -436,15 +455,196 @@ function scanTarget(targetDir) {
|
|
|
436
455
|
isDirectory,
|
|
437
456
|
entries,
|
|
438
457
|
hasHarness,
|
|
439
|
-
hasClaude
|
|
440
|
-
hasAgents
|
|
441
|
-
hasAgentSkills
|
|
442
|
-
hasCodex
|
|
443
|
-
hasDocs
|
|
458
|
+
hasClaude,
|
|
459
|
+
hasAgents,
|
|
460
|
+
hasAgentSkills,
|
|
461
|
+
hasCodex,
|
|
462
|
+
hasDocs,
|
|
463
|
+
hasReadme,
|
|
464
|
+
hasPackageJson,
|
|
465
|
+
hasPyproject,
|
|
466
|
+
hasGoMod,
|
|
467
|
+
hasGithub,
|
|
468
|
+
hasGitignore,
|
|
444
469
|
needsConflictPolicy: exists && (!isDirectory || entries.length > 0 || hasHarness),
|
|
445
470
|
};
|
|
446
471
|
}
|
|
447
472
|
|
|
473
|
+
function createJsonScan(scan) {
|
|
474
|
+
const topLevelEntries = scan.entries.slice(0, 50);
|
|
475
|
+
|
|
476
|
+
return {
|
|
477
|
+
resolvedDir: scan.resolvedDir,
|
|
478
|
+
exists: scan.exists,
|
|
479
|
+
isDirectory: scan.isDirectory,
|
|
480
|
+
entryCount: scan.entries.length,
|
|
481
|
+
topLevelEntries,
|
|
482
|
+
topLevelEntriesTruncated: scan.entries.length > topLevelEntries.length,
|
|
483
|
+
needsConflictPolicy: scan.needsConflictPolicy,
|
|
484
|
+
markers: {
|
|
485
|
+
hasHarness: scan.hasHarness,
|
|
486
|
+
hasClaude: scan.hasClaude,
|
|
487
|
+
hasAgents: scan.hasAgents,
|
|
488
|
+
hasAgentSkills: scan.hasAgentSkills,
|
|
489
|
+
hasCodex: scan.hasCodex,
|
|
490
|
+
hasDocs: scan.hasDocs,
|
|
491
|
+
hasReadme: scan.hasReadme,
|
|
492
|
+
hasPackageJson: scan.hasPackageJson,
|
|
493
|
+
hasPyproject: scan.hasPyproject,
|
|
494
|
+
hasGoMod: scan.hasGoMod,
|
|
495
|
+
hasGithub: scan.hasGithub,
|
|
496
|
+
hasGitignore: scan.hasGitignore,
|
|
497
|
+
},
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
function createAgentGuidance(result, { projectName, targetDir, options, scan }) {
|
|
502
|
+
const attentionFiles = [...new Set([
|
|
503
|
+
...(result.plan?.conflict || []),
|
|
504
|
+
...(result.plan?.skip || []),
|
|
505
|
+
])].sort();
|
|
506
|
+
const aiMergeRequired = attentionFiles.map(file => createFileGuidance(file));
|
|
507
|
+
const hasBlockingConflicts = (result.plan?.conflict || []).length > 0;
|
|
508
|
+
const safeMergeCommand = commandFor(projectName, targetDir, {
|
|
509
|
+
...options,
|
|
510
|
+
dryRun: false,
|
|
511
|
+
onConflict: 'skip',
|
|
512
|
+
json: true,
|
|
513
|
+
});
|
|
514
|
+
const previewCommand = commandFor(projectName, targetDir, {
|
|
515
|
+
...options,
|
|
516
|
+
dryRun: true,
|
|
517
|
+
json: true,
|
|
518
|
+
});
|
|
519
|
+
const next = [];
|
|
520
|
+
|
|
521
|
+
if (scan.hasHarness) {
|
|
522
|
+
next.push({
|
|
523
|
+
action: 'stop',
|
|
524
|
+
reason: 'Harness already exists; use wf-update or Harness/scripts/wf-update-check.mjs instead of reinstalling blindly.',
|
|
525
|
+
});
|
|
526
|
+
} else if (result.dryRun && !hasBlockingConflicts) {
|
|
527
|
+
next.push({
|
|
528
|
+
action: 'install',
|
|
529
|
+
command: safeMergeCommand,
|
|
530
|
+
reason: 'Dry-run has no blocking conflicts; let the script create missing files.',
|
|
531
|
+
});
|
|
532
|
+
} else if (result.dryRun && hasBlockingConflicts) {
|
|
533
|
+
next.push({
|
|
534
|
+
action: 'safe-merge',
|
|
535
|
+
command: safeMergeCommand,
|
|
536
|
+
reason: 'Default dry-run found existing files; rerun with --on-conflict skip so the script creates missing files and preserves existing ones.',
|
|
537
|
+
});
|
|
538
|
+
} else if (result.success) {
|
|
539
|
+
next.push({
|
|
540
|
+
action: 'bootstrap',
|
|
541
|
+
command: 'Read Harness/SETUP.md and use this JSON plan before opening any package templates.',
|
|
542
|
+
reason: 'Scaffold files were written; bootstrap project facts from local evidence.',
|
|
543
|
+
});
|
|
544
|
+
} else {
|
|
545
|
+
next.push({
|
|
546
|
+
action: 'inspect-errors',
|
|
547
|
+
reason: 'Generation failed before safe scaffold output was available.',
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
if (aiMergeRequired.length > 0) {
|
|
552
|
+
next.push({
|
|
553
|
+
action: 'ai-merge',
|
|
554
|
+
files: aiMergeRequired.map(item => item.file),
|
|
555
|
+
reason: 'Only these existing/conflicting files need semantic review. Files in plan.create are script-owned.',
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
return {
|
|
560
|
+
sourceOfTruth: 'Use this JSON scan/plan first. Do not read package source or templates unless aiMergeRequired lists a file.',
|
|
561
|
+
previewCommand,
|
|
562
|
+
safeMergeCommand,
|
|
563
|
+
scriptHandled: {
|
|
564
|
+
create: result.plan?.create?.length || 0,
|
|
565
|
+
mkdir: result.plan?.mkdir?.length || 0,
|
|
566
|
+
backup: result.plan?.backup?.length || 0,
|
|
567
|
+
overwrite: result.plan?.overwrite?.length || 0,
|
|
568
|
+
},
|
|
569
|
+
aiMergeRequired,
|
|
570
|
+
next,
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
function createFileGuidance(file) {
|
|
575
|
+
const normalized = file.replace(/\\/g, '/');
|
|
576
|
+
const guidance = {
|
|
577
|
+
file: normalized,
|
|
578
|
+
templateHint: templateHintFor(normalized),
|
|
579
|
+
requiresUserConsent: false,
|
|
580
|
+
defaultAction: 'preserve',
|
|
581
|
+
reason: 'Existing file or path needs semantic review before any merge.',
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
if (normalized.endsWith('/')) {
|
|
585
|
+
return {
|
|
586
|
+
...guidance,
|
|
587
|
+
templateHint: null,
|
|
588
|
+
defaultAction: 'stop',
|
|
589
|
+
reason: 'A file blocks a required scaffold directory. Stop and ask before moving or replacing it.',
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
if (normalized === 'CLAUDE.md' || normalized === 'AGENTS.md') {
|
|
594
|
+
return {
|
|
595
|
+
...guidance,
|
|
596
|
+
requiresUserConsent: true,
|
|
597
|
+
reason: 'Root agent entry contract. Preserve project rules and ask before merging Harness startup guidance.',
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
if (normalized === 'README.md') {
|
|
602
|
+
return {
|
|
603
|
+
...guidance,
|
|
604
|
+
reason: 'Project-owned public/development documentation. Preserve by default; append development notes only after review.',
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
if (normalized === 'Harness/README.md' || normalized === 'Harness/MEMORY.md') {
|
|
609
|
+
return {
|
|
610
|
+
...guidance,
|
|
611
|
+
reason: 'Harness router/registry conflict. Merge only missing routing or registration entries.',
|
|
612
|
+
};
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
return guidance;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
function templateHintFor(file) {
|
|
619
|
+
if (file === 'Harness/SETUP.md') return 'templates/common/SETUP.md';
|
|
620
|
+
return `templates/common/${file}`;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
function commandFor(projectName, targetDir, options) {
|
|
624
|
+
const args = [
|
|
625
|
+
'npx',
|
|
626
|
+
'create-harness-vibe-coding@latest',
|
|
627
|
+
projectName,
|
|
628
|
+
targetDir,
|
|
629
|
+
'-y',
|
|
630
|
+
];
|
|
631
|
+
|
|
632
|
+
if (options.dryRun) args.push('--dry-run');
|
|
633
|
+
if (options.onConflict) args.push('--on-conflict', options.onConflict);
|
|
634
|
+
if (options.withOptions?.length) args.push('--with', options.withOptions.join(','));
|
|
635
|
+
if (options.withoutOptions?.length) args.push('--without', options.withoutOptions.join(','));
|
|
636
|
+
if (options.externalOptions?.length) args.push('--recommend', options.externalOptions.join(','));
|
|
637
|
+
if (options.preset) args.push('--preset', options.preset);
|
|
638
|
+
if (options.json) args.push('--json');
|
|
639
|
+
|
|
640
|
+
return args.map(shellQuoteArg).join(' ');
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
function shellQuoteArg(arg) {
|
|
644
|
+
if (/^[A-Za-z0-9@._/\\:-]+$/.test(arg)) return arg;
|
|
645
|
+
return JSON.stringify(arg);
|
|
646
|
+
}
|
|
647
|
+
|
|
448
648
|
function printScan(scan) {
|
|
449
649
|
if (!scan.exists) return;
|
|
450
650
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tdd-guide
|
|
3
|
+
description: Test-Driven Development specialist enforcing write-tests-first methodology. Use PROACTIVELY when writing new features, fixing bugs, or refactoring code. Ensures 80%+ test coverage.
|
|
4
|
+
tools: Read, Write, Edit, Bash, Grep, Glob
|
|
5
|
+
model: sonnet
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# TDD Guide Agent
|
|
9
|
+
|
|
10
|
+
Enforces TDD workflow. Load `Harness/TDD-GUIDE.md` first, then ECC testing rules for the project stack.
|
|
11
|
+
|
|
12
|
+
## Inputs Required
|
|
13
|
+
|
|
14
|
+
- Task description and acceptance criteria from PLAN.md
|
|
15
|
+
- Current test coverage status
|
|
16
|
+
- Stack-specific testing tools (Jest, Pytest, Go test, etc.)
|
|
17
|
+
|
|
18
|
+
## Workflow
|
|
19
|
+
|
|
20
|
+
1. READ acceptance criteria
|
|
21
|
+
2. WRITE failing test (RED)
|
|
22
|
+
3. VERIFY test fails for expected reason
|
|
23
|
+
4. Report test file path and expected failure to Implementer
|
|
24
|
+
|
|
25
|
+
Do NOT write implementation code. Only tests.
|
|
26
|
+
|
|
27
|
+
## Allowed Write Set
|
|
28
|
+
|
|
29
|
+
- Test files only (`*.test.ts`, `*.test.tsx`, `test_*.py`, `*_test.go`, etc.)
|
|
30
|
+
- Test fixtures and mocks
|
|
31
|
+
- Test configuration files
|
|
32
|
+
|
|
33
|
+
## Forbidden
|
|
34
|
+
|
|
35
|
+
- Production/source code changes
|
|
36
|
+
- Loosening existing test assertions
|
|
37
|
+
- Deleting existing tests without explicit approval
|
|
38
|
+
|
|
39
|
+
## Verification
|
|
40
|
+
|
|
41
|
+
- Test MUST fail before handing off to Implementer
|
|
42
|
+
- Test MUST cover acceptance criteria + error paths
|
|
43
|
+
- Run `node Harness/scripts/validate-harness.mjs` after significant test additions
|
|
44
|
+
|
|
45
|
+
## Return Format
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
Agent: tdd-guide
|
|
49
|
+
Task: <task-id>
|
|
50
|
+
Tests written: <file paths>
|
|
51
|
+
Coverage before: X%
|
|
52
|
+
Expected coverage after: Y%
|
|
53
|
+
Failing tests: <list of test names and expected failure reasons>
|
|
54
|
+
Next: Dispatch Implementer to make tests pass
|
|
55
|
+
```
|
|
@@ -63,6 +63,28 @@
|
|
|
63
63
|
}
|
|
64
64
|
]
|
|
65
65
|
}
|
|
66
|
+
],
|
|
67
|
+
"PostToolUse": [
|
|
68
|
+
{
|
|
69
|
+
"matcher": "",
|
|
70
|
+
"hooks": [
|
|
71
|
+
{
|
|
72
|
+
"type": "command",
|
|
73
|
+
"command": "node Harness/scripts/wf-mode-hook.mjs"
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
"Stop": [
|
|
79
|
+
{
|
|
80
|
+
"matcher": "",
|
|
81
|
+
"hooks": [
|
|
82
|
+
{
|
|
83
|
+
"type": "command",
|
|
84
|
+
"command": "node Harness/scripts/wf-mode-hook.mjs"
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
66
88
|
]
|
|
67
89
|
}
|
|
68
90
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tdd
|
|
3
|
+
description: Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration tests.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# TDD Adapter
|
|
7
|
+
|
|
8
|
+
Thin tool adapter. Authoritative guide: `Harness/TDD-GUIDE.md`.
|
|
9
|
+
|
|
10
|
+
## Invocation
|
|
11
|
+
|
|
12
|
+
- Claude Code: use `/tdd` or select the `tdd` skill.
|
|
13
|
+
- Codex CLI or IDE: use `$tdd` or `/skills` then choose `tdd`.
|
|
14
|
+
|
|
15
|
+
## Load
|
|
16
|
+
|
|
17
|
+
1. `Harness/TDD-GUIDE.md`
|
|
18
|
+
2. ECC stack-specific testing rules (e.g., `typescript/testing.md`, `python/testing.md`)
|
|
19
|
+
3. Current task `PLAN.md`
|
|
20
|
+
|
|
21
|
+
## Rules
|
|
22
|
+
|
|
23
|
+
1. **RED first**: Write failing test before ANY implementation code.
|
|
24
|
+
2. **GREEN minimal**: Write only enough code to pass the test.
|
|
25
|
+
3. **REFACTOR safe**: Improve code while keeping all tests green.
|
|
26
|
+
4. **Coverage gate**: ≥80% before marking task complete.
|
|
27
|
+
5. **Test names**: Describe behavior — `test('returns X when Y')`.
|
|
28
|
+
6. **AAA structure**: Arrange → Act → Assert.
|
|
29
|
+
7. **Error paths**: Test failure cases, not just happy path.
|
|
30
|
+
8. **WF-MAX**: Test Writer agent dispatched BEFORE Implementer in every wave.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wf-auto
|
|
3
|
+
description: Perpetual auto-optimization mode. Never stops — continuously improves code until 8-angle exhaustion. Adaptive checkpoints, external spark search, evidence ledger. Use for Claude /wf-auto, Codex $wf-auto, auto mode, or when the user wants unbounded self-directed optimization.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# WF Auto — Perpetual Auto-Optimization
|
|
7
|
+
|
|
8
|
+
## Load (authoritative specs)
|
|
9
|
+
|
|
10
|
+
- `Harness/WF-AUTO.md` — full spec: perpetual loop, state machine, 8-angle exhaustion gate, cross-model oracle, spark candidate provider, Value Gate scoring, evidence ledger, Intent Checkpoints, anti-patterns, safety controls
|
|
11
|
+
- `Harness/subagents.md` — agent roster, controller role, efficiency ladder
|
|
12
|
+
- `Harness/dispatch.md` — handoff format, File claim, Concurrency group fields
|
|
13
|
+
- `Harness/agent-workflow.md` — build/review/test loop, cohesion rule, completion gate
|
|
14
|
+
- `.claude/skills/wf-review/SKILL.md` — cross-model invocation pattern (used by the oracle step)
|
|
15
|
+
|
|
16
|
+
## Trigger & When NOT to Use
|
|
17
|
+
|
|
18
|
+
- **Trigger**: Claude `/wf-auto`, Codex `$wf-auto`, `wf auto`, `auto mode`, or user wants continuous self-directed improvement
|
|
19
|
+
- **Do NOT use**: user has a specific bounded task (use `/wf`), task needs maximum parallelism (use `/wf-max`), production hotfix needed urgently, codebase <100 lines
|
|
20
|
+
|
|
21
|
+
## State Machine
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
auto.internal → auto.spark → auto.checkpoint → auto.exhausted → paused
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
CEO tracks state in `Harness/tasks/auto/PROGRESS.md`. Transitions are CEO-owned.
|
|
28
|
+
|
|
29
|
+
## Hard Constraints
|
|
30
|
+
|
|
31
|
+
1. **NEVER STOP except A-GATE.** No "task complete" early exit. The Angle Exhaustion Gate (internal + oracle + spark all empty, 3 confirm rounds) is the ONLY permitted stop.
|
|
32
|
+
2. **CEO never writes production code.** CEO uses Task, Read, Grep/Glob. No Edit/Write/Bash on source files. Exception: CEO MAY write to `Harness/tasks/auto/PROGRESS.md` and `Harness/tasks/auto/PLAN.md`.
|
|
33
|
+
3. **ALL sources in ONE message per cycle.** 8 angles + oracle + spark searchers. Batching is mandatory.
|
|
34
|
+
4. **ONE finding per cycle.** One change, ≤3 files, ≤50 lines diff. Big ideas (>50 lines) escalate to /wf or /wf-max then return.
|
|
35
|
+
5. **Two-gate review every cycle.** Spec review before code-quality review. No skipping.
|
|
36
|
+
6. **A-GATE has 3 tiers.** All 8 exhausted → Cross-Model Oracle → Spark search → 2 confirmation rounds → STOP.
|
|
37
|
+
7. **Value Gate is scored, not binary.** 5 dimensions (Impact, Evidence, Fit, Timing, Cost/Risk), 1-5 each. Pass: ≥18/25 AND no dimension <3.
|
|
38
|
+
8. **Intent Checkpoint is adaptive.** 2→5→10 cycles. Exactly 2 questions: "Still aligned?" + "What should change?" Early on drift signals.
|
|
39
|
+
9. **Evidence ledger per cycle.** Source, evidence type, expected impact, verification method, measured result, verdict. Track weak spark count.
|
|
40
|
+
|
|
41
|
+
## The 8 Angles (quick reference)
|
|
42
|
+
|
|
43
|
+
| # | Angle | Finds |
|
|
44
|
+
|---|-------|-------|
|
|
45
|
+
| 1 | Correctness | Bugs, edge cases, null safety, race conditions |
|
|
46
|
+
| 2 | Performance | Slow paths, memory, algorithmic complexity |
|
|
47
|
+
| 3 | Security | Injection, auth, secrets, dependency CVEs |
|
|
48
|
+
| 4 | Maintainability | Clarity, DRY, coupling, naming, dead code |
|
|
49
|
+
| 5 | Test Coverage | Missing tests, weak assertions, flaky tests |
|
|
50
|
+
| 6 | Architecture | Boundaries, dependency direction, layer discipline |
|
|
51
|
+
| 7 | UX / DX | Error messages, API ergonomics, documentation |
|
|
52
|
+
| 8 | Robustness | Resilience, retry, observability, recovery |
|
|
53
|
+
|
|
54
|
+
## Spark Sources (when internal + oracle empty)
|
|
55
|
+
|
|
56
|
+
| # | Source | Evidence Weight |
|
|
57
|
+
|---|--------|-----------------|
|
|
58
|
+
| 1 | Official Docs & Advisories | HIGH |
|
|
59
|
+
| 2 | Ecosystem Pulse | MEDIUM |
|
|
60
|
+
| 3 | GitHub Trending (same stack) | LOW-MEDIUM |
|
|
61
|
+
| 4 | Best Practices (latest) | MEDIUM |
|
|
62
|
+
| 5 | Competitor/Peer Projects | LOW |
|
|
63
|
+
| 6 | Real-world Issues | MEDIUM |
|
|
64
|
+
| 7 | Architecture Trends | LOW |
|
|
65
|
+
| 8 | Performance Benchmarks | MEDIUM |
|
|
66
|
+
|
|
67
|
+
Source-quality: official docs > blog posts. Trending ≠ correct. Competitor behavior is hypothesis only. Every spark MUST cite source with URL and date.
|
|
68
|
+
|
|
69
|
+
## Perpetual Loop
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
W0: SENSE (8 angles + oracle + 8 spark sources, all parallel)
|
|
73
|
+
A-GATE [findings? → W1 | all empty? → oracle → spark → confirm ×2 → STOP]
|
|
74
|
+
CHECKPOINT [every 2→5→10 cycles, 2 questions]
|
|
75
|
+
W1: PRIORITIZE (across internal + oracle + spark)
|
|
76
|
+
W2: IMPLEMENT → W3: REVIEW → W4: DEBUG → W5: VERIFY
|
|
77
|
+
RECORD + EVIDENCE LEDGER → LOOP W0
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Cycle Recording
|
|
81
|
+
|
|
82
|
+
Every cycle writes to `Harness/tasks/auto/PROGRESS.md`:
|
|
83
|
+
- Cycle number, timestamp, state
|
|
84
|
+
- Source (internal/oracle/spark-*), source citation
|
|
85
|
+
- Finding, change description, files changed
|
|
86
|
+
- Value Gate scores (if spark candidate)
|
|
87
|
+
- Review result, verification evidence
|
|
88
|
+
- Evidence Ledger: evidence type, expected impact, verification method, measured result, verdict
|
|
89
|
+
|
|
90
|
+
## Safety
|
|
91
|
+
|
|
92
|
+
- ≤3 files, ≤50 lines per cycle
|
|
93
|
+
- Big ideas (>50 lines) escalate to /wf or /wf-max, then return to auto
|
|
94
|
+
- Destructive changes flagged with rollback plan
|
|
95
|
+
- IDLE alarm after 5 empty cycles → re-scope → A-GATE candidate
|
|
96
|
+
- Spark stop: 5 failed Value Gates OR 3 weak measured impacts OR 2 repeated source families empty
|
|
97
|
+
- User can interrupt at any time
|
|
98
|
+
|
|
99
|
+
## Return Format
|
|
100
|
+
|
|
101
|
+
- Total cycles run
|
|
102
|
+
- Findings addressed per source (internal / oracle / spark)
|
|
103
|
+
- Evidence ledger with measured impacts
|
|
104
|
+
- Exhaustion evidence (3-round confirmation)
|
|
105
|
+
- Weak spark count
|
|
106
|
+
- Final codebase state
|
|
107
|
+
- Residual risk assessment
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wf-auto-spark
|
|
3
|
+
description: Use for /wf-auto-spark in Claude Code, $wf-auto-spark or /skills wf-auto-spark in Codex, or perpetual inspiration mode that never stops — external spark search, long-term roadmap with staged milestones, ≤50% deviation guard.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# WF-AUTO-SPARK Adapter
|
|
7
|
+
|
|
8
|
+
This skill is a thin tool adapter. The authoritative workflow lives in
|
|
9
|
+
`Harness/WF-AUTO-SPARK.md`; do not duplicate or override it here.
|
|
10
|
+
|
|
11
|
+
## Invocation
|
|
12
|
+
|
|
13
|
+
- Claude Code: use `/wf-auto-spark` or select the `wf-auto-spark` skill.
|
|
14
|
+
- Codex CLI or IDE: use `$wf-auto-spark` or `/skills` then choose `wf-auto-spark`.
|
|
15
|
+
|
|
16
|
+
## Load
|
|
17
|
+
|
|
18
|
+
1. `CLAUDE.md`
|
|
19
|
+
2. `Harness/MEMORY.md`
|
|
20
|
+
3. `Harness/README.md`
|
|
21
|
+
4. `Harness/WF-AUTO-SPARK.md`
|
|
22
|
+
5. `Harness/WF-AUTO.md`
|
|
23
|
+
6. `Harness/subagents.md`
|
|
24
|
+
7. `Harness/dispatch.md`
|
|
25
|
+
|
|
26
|
+
## Rules
|
|
27
|
+
|
|
28
|
+
WF-AUTO-SPARK is perpetual inspiration mode with roadmap anchoring:
|
|
29
|
+
1. **Roadmap first**: Declare North Star + staged milestones before any spark cycle.
|
|
30
|
+
2. **Never auto-stop**: Only user can stop. "No sparks found" → expand search.
|
|
31
|
+
3. **Deviation guard (≤50%)**: Every spark checked against North Star. Cumulative 10-cycle average ≥65%. Below → force Re-Anchor Gate.
|
|
32
|
+
4. **Milestones flexible within 50%**: Can reorder/split/merge/replace, but North Star changes need user confirmation.
|
|
33
|
+
5. **Value reflection every cycle**: CEO writes what was done, why it matters, deviation score, milestone progress.
|
|
34
|
+
6. **Re-Anchor Gate every 10 cycles**: User confirms direction or adjusts roadmap.
|
|
35
|
+
|
|
36
|
+
## Roadmap Location
|
|
37
|
+
|
|
38
|
+
Active roadmap lives at `Harness/tasks/auto/SPARK-ROADMAP.md`. Created at startup.
|
|
39
|
+
Per-cycle evidence at `Harness/tasks/auto/PROGRESS.md`.
|
|
@@ -26,8 +26,16 @@ This skill is a thin tool adapter. The authoritative workflow lives in
|
|
|
26
26
|
|
|
27
27
|
## Rules
|
|
28
28
|
|
|
29
|
-
-
|
|
30
|
-
|
|
29
|
+
WF-MAX is a three-layer architecture:
|
|
30
|
+
1. Global mode (`wf-max`)
|
|
31
|
+
2. Agent role (`ceo` | `manager` | `worker` | `reviewer`)
|
|
32
|
+
3. Dispatch permission (`writeSet`, `forbidden`, `verification`)
|
|
33
|
+
|
|
34
|
+
- Top-level orchestrator is CEO (reads, plans, dispatches). Delegated Workers follow dispatch packet with explicit writeSet. Global mode ≠ every agent is CEO.
|
|
35
|
+
- CEO: never edit source files directly. Spawn Workers with writeSet.
|
|
36
|
+
- Worker: edit only files in dispatch writeSet. Outside writeSet → blocked.
|
|
37
|
+
- Manager: scope, review, coordinate. No source edits by default.
|
|
38
|
+
- Reviewer: read and report only. No edits.
|
|
31
39
|
- Use the D-GATE in `Harness/WF-MAX.md` before any implementation wave:
|
|
32
40
|
dispatch table, self-audit, disjoint file claims, and reviewer plan.
|
|
33
41
|
- Use real subagents when the runtime supports them; otherwise record a
|
|
@@ -17,14 +17,21 @@ description: Use for /wf-remove in Claude Code, $wf-remove or /skills wf-remove
|
|
|
17
17
|
|
|
18
18
|
## Flow
|
|
19
19
|
|
|
20
|
-
1. Run `node Harness/scripts/wf-remove.mjs` for
|
|
20
|
+
1. Run `node Harness/scripts/wf-remove.mjs --json` for the machine-readable
|
|
21
|
+
plan.
|
|
21
22
|
2. Auto-remove only SAFE files that still match stored checksums.
|
|
22
23
|
3. Ask the user before every MODIFIED or uncertain file.
|
|
23
|
-
4.
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
4. Preserve USER DATA by default. For an explicit thorough uninstall, use
|
|
25
|
+
`--purge-user-data` (alias `--purge`); add `--keep-tasks` when the user wants task records
|
|
26
|
+
retained while project-fact Harness docs are removed.
|
|
27
|
+
5. Run the script, not manual deletes:
|
|
28
|
+
- safe default: `node Harness/scripts/wf-remove.mjs --apply --yes`
|
|
29
|
+
- thorough but keep tasks: `node Harness/scripts/wf-remove.mjs --apply --yes --purge-user-data --keep-tasks`
|
|
30
|
+
- exact modified decisions: add `--delete-modified <path>` for each
|
|
31
|
+
user-approved MODIFIED file.
|
|
26
32
|
|
|
27
33
|
## Return
|
|
28
34
|
|
|
29
35
|
Report SAFE removals, MODIFIED keep/delete decisions, preserved USER DATA,
|
|
30
|
-
directory cleanup, CLAUDE/AGENTS status,
|
|
36
|
+
PURGE removals, directory cleanup, CLAUDE/AGENTS status, `.harness-version`
|
|
37
|
+
status, and `git status` guidance.
|