create-harness-vibe-coding 0.1.10 → 0.2.1
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 +94 -0
- package/README.md +86 -35
- package/package.json +3 -2
- package/src/generator.js +72 -12
- package/src/index.js +30 -11
- package/templates/common/.claude/agents/architect.md +4 -4
- package/templates/common/.claude/agents/debugger.md +1 -1
- package/templates/common/.claude/agents/docs-researcher.md +4 -4
- package/templates/common/.claude/agents/implementer.md +1 -1
- package/templates/common/.claude/agents/planner.md +3 -3
- package/templates/common/.claude/agents/researcher.md +4 -4
- package/templates/common/.claude/agents/reviewer.md +1 -1
- package/templates/common/.claude/agents/test-writer.md +2 -2
- package/templates/common/.claude/agents/verifier.md +1 -1
- package/templates/common/.claude/commands/wf.md +18 -0
- package/templates/common/.claude/rules/ecc/common.md +11 -10
- package/templates/common/.claude/skills/harness-build-loop/SKILL.md +4 -3
- package/templates/common/.claude/skills/harness-context/SKILL.md +4 -3
- package/templates/common/.claude/skills/harness-lifecycle/SKILL.md +3 -3
- package/templates/common/.claude/skills/harness-research/SKILL.md +4 -4
- package/templates/common/.claude/skills/harness-router/SKILL.md +7 -5
- package/templates/common/.claude/skills/readme-optimizer/SKILL.md +48 -0
- package/templates/common/.claude/skills/subagent-orchestrator/SKILL.md +39 -0
- package/templates/common/.claude/skills/wf-mode/SKILL.md +50 -0
- package/templates/common/AGENTS.md +2 -2
- package/templates/common/CLAUDE.md +40 -73
- package/templates/common/MEMORY.md +32 -27
- package/templates/common/README.md +41 -0
- package/templates/common/SETUP.md +101 -74
- package/templates/common/docs/README.md +71 -54
- package/templates/common/docs/domain/ports.md +4 -1
- package/templates/common/docs/features/_template.md +10 -10
- package/templates/common/docs/harness/PLAN.md +25 -2
- package/templates/common/docs/harness/WF.md +146 -0
- package/templates/common/docs/harness/agent-workflow.md +8 -8
- package/templates/common/docs/harness/architecture.md +31 -7
- package/templates/common/docs/harness/context-loading.md +16 -16
- package/templates/common/docs/harness/data-flow.md +1 -1
- package/templates/common/docs/harness/dispatch.md +5 -2
- package/templates/common/docs/harness/extension.md +14 -14
- package/templates/common/docs/harness/lifecycle.md +2 -2
- package/templates/common/docs/harness/state-machines.md +8 -0
- package/templates/common/docs/harness/subagents.md +176 -0
- package/templates/common/docs/research/PRD.md +1 -1
- package/templates/common/docs/research/README.md +5 -5
- package/templates/common/scripts/validate-harness.mjs +150 -56
- package/templates/optional/skills/browser-e2e/.claude/skills/browser-e2e/SKILL.md +5 -5
- package/templates/optional/skills/browser-e2e/docs/workflows/browser-e2e.md +1 -1
- package/templates/optional/skills/github-pr-review/.claude/skills/github-pr-review/SKILL.md +5 -5
- package/templates/optional/skills/python-backend/.claude/skills/python-backend/SKILL.md +5 -5
- package/templates/optional/skills/ts-react-frontend/.claude/skills/ts-react-frontend/SKILL.md +5 -5
- package/templates/optional/skills/ui-ux-review/.claude/skills/ui-ux-review/SKILL.md +5 -5
package/README-CN.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# create-harness-vibe-coding 中文说明
|
|
2
|
+
|
|
3
|
+
0-1 产品 Harness 脚手架,用于 AI 辅助工程:从想法、调研、PRD、架构、计划,到实现、验证和反馈闭环。
|
|
4
|
+
|
|
5
|
+
English README: [README.md](README.md)
|
|
6
|
+
|
|
7
|
+
## 一句话交给 Agent
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
请按照 https://github.com/zingspark/create-harness-vibe-coding 的 README 为当前项目配置 create-harness-vibe-coding;编辑前先询问 Agent-link 安装前置问题;新项目走 0-1 bootstrap,老项目或老架构升级先 dry-run,保留现有文件,只合并缺失的 Harness 规范,然后遵循 Harness/SETUP.md。
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 两种安装方式
|
|
14
|
+
|
|
15
|
+
### 1. npx 安装
|
|
16
|
+
|
|
17
|
+
适合需要确定性写入、明确冲突策略、可重复 dry-run 的场景。
|
|
18
|
+
|
|
19
|
+
### 2. 直接把链接丢给 agent
|
|
20
|
+
|
|
21
|
+
适合老项目、老架构升级、已有复杂 `CLAUDE.md` / `AGENTS.md` / `.claude/` 的场景。agent 应该读取这个仓库 README,理解当前项目结构,执行或模拟 dry-run,然后给出最小迁移方案。
|
|
22
|
+
|
|
23
|
+
如果项目里已经有 `CLAUDE.md`,agent 必须先告诉用户:`CLAUDE.md` 是根 agent 入口合同,不能静默覆盖或乱合并。正确流程是先请求用户确认是否重构/合并 `CLAUDE.md`,再在保留原项目规则的基础上补入 Harness 的 startup、memory、router、workflow、subagents 编排约束。
|
|
24
|
+
|
|
25
|
+
Agent-link 安装前置问题,编辑前先问:
|
|
26
|
+
|
|
27
|
+
只询问会影响写入、架构、安全或工作流的选择。开始时最多问 3 个 blocking 问题,其余采用安全默认值并记录到计划里,等真正触发时再继续追问。
|
|
28
|
+
|
|
29
|
+
| 主题 | 什么时候问 | 没回答时的默认值 |
|
|
30
|
+
| --- | --- | --- |
|
|
31
|
+
| 根 agent 入口 | 已存在 `CLAUDE.md`、`AGENTS.md`、`.claude/` 或其他 agent 入口文件 | 保留现有文件;合并 Harness 入口合同前必须询问用户 |
|
|
32
|
+
| Harness 存放位置 | `docs/` 已经用于 GitHub Pages、产品文档或生成文档 | 默认使用根目录 `Harness/`;不要把 Harness 文档写进 `docs/` |
|
|
33
|
+
| README 归属 | 根 `README.md` 是公开产品页、包文档或已有大量自定义内容 | 保留现有 README,只提议追加最小 Development section |
|
|
34
|
+
| README 优化 | 已有 README 过时、太单薄、缺少命令表格,或用户想要架构图/更生动的文档 | 可推荐 `readme-optimizer`;默认只追加 Development notes,结构化优化或重写必须先得到用户确认 |
|
|
35
|
+
| 扩展能力 | ECC、Superpowers、自定义 rules 或栈相关 skills 可能有用 | 先推荐;只有用户同意后才安装 |
|
|
36
|
+
| Skills | 技术栈已明确,测试、前端、后端、review、浏览器证据可用 optional skills 增强 | 用户同意后只安装 1-2 个最相关 skills |
|
|
37
|
+
| CI/CD | 已有 CI 配置,或项目缺少测试/构建 gate | 先记录现有命令;只有用户同意后才新增或规范 CI/CD |
|
|
38
|
+
| 验证深度 | 涉及浏览器可见行为、API、数据库、鉴权、支付或部署 | 必须有真实命令证据;相关场景必须有浏览器/API 证据 |
|
|
39
|
+
| Memory/隐私 | 仓库包含敏感领域数据、客户数据、密钥或私有流程 | 只启用 memory index;禁止记录 secrets 或私有数据 |
|
|
40
|
+
| Branch/worktree | 存在未提交改动、风险迁移或并行实现 lane | 保护当前工作区;大改前先提议 branch/worktree |
|
|
41
|
+
| 包管理器/技术栈 | 存在多个包管理器、monorepo apps 或技术栈边界不清 | 写文件前先确认当前 workspace/app 范围 |
|
|
42
|
+
|
|
43
|
+
## 一条命令
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npx create-harness-vibe-coding@latest my-project
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## 现有项目渐进安装
|
|
50
|
+
|
|
51
|
+
先预览,不写文件:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npx create-harness-vibe-coding@latest my-app . -y --dry-run
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
再保留现有文件,只补缺失的 Harness 文件:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx create-harness-vibe-coding@latest my-app . -y --on-conflict skip
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
安装后让 agent 先读 `Harness/SETUP.md`,再开始正常工作。
|
|
64
|
+
|
|
65
|
+
## 核心约束
|
|
66
|
+
|
|
67
|
+
- `CLAUDE.md` 只做薄入口和路由,不放项目架构、构建脚本、git 规范。
|
|
68
|
+
- 项目开发命令、构建、测试、git、发布流程放根目录 `README.md`。
|
|
69
|
+
- 架构说明放 `Harness/architecture.md` 或当前 feature 文档。
|
|
70
|
+
- Harness 文档、状态、记忆、工作流默认放根目录 `Harness/`。
|
|
71
|
+
- 如果已有 `AGENTS.md`,agent 必须先询问用户是否同意修改。
|
|
72
|
+
- 长任务、多文件、多 subagents、低置信度或重复失败时使用 `/wf`、`wf-mode` 和 `Harness/WF.md`。
|
|
73
|
+
|
|
74
|
+
## 常用生成物
|
|
75
|
+
|
|
76
|
+
| 文件 | 用途 |
|
|
77
|
+
| --- | --- |
|
|
78
|
+
| `CLAUDE.md` | Claude Code 根入口,保持短小 |
|
|
79
|
+
| `Harness/README.md` | Harness 路由器 |
|
|
80
|
+
| `Harness/SETUP.md` | 初次安装和 bootstrap 指南 |
|
|
81
|
+
| `Harness/MEMORY.md` | agents、skills、记忆文件索引 |
|
|
82
|
+
| `Harness/PLAN.md` | 当前计划、heartbeat、handoff、验证证据 |
|
|
83
|
+
| `Harness/WF.md` | 长链路 workflow 和恢复循环 |
|
|
84
|
+
| `Harness/subagents.md` | 多 subagents 编排方法论 |
|
|
85
|
+
| `.claude/skills/*` | Claude Code 可加载的 Harness skills |
|
|
86
|
+
|
|
87
|
+
## 验证
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npm test
|
|
91
|
+
node Harness/scripts/validate-harness.mjs
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
生成项目后,`Harness/scripts/validate-harness.mjs` 用于检查 Harness 结构、注册关系和必要规范是否完整。
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<h1 align="center">create-harness-vibe-coding</h1>
|
|
9
9
|
<p align="center">
|
|
10
10
|
<b>0-1 product harness scaffold for AI-assisted engineering.</b><br>
|
|
11
|
-
<sub>Idea -> Research -> PRD -> Architecture ->
|
|
11
|
+
<sub>Idea -> Research -> PRD -> Architecture -> Harness/PLAN.md -> Build -> Verify -> Feedback.</sub>
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
14
|
---
|
|
@@ -21,8 +21,10 @@ npx create-harness-vibe-coding@latest my-project
|
|
|
21
21
|
|
|
22
22
|
| What You Get | Purpose |
|
|
23
23
|
|-------------|---------|
|
|
24
|
-
| `CLAUDE.md` + `
|
|
25
|
-
| `
|
|
24
|
+
| `CLAUDE.md` + `Harness/README.md` | Thin root entry and dynamic doc router |
|
|
25
|
+
| `Harness/PLAN.md` | Active execution state, heartbeat, and handoffs |
|
|
26
|
+
| `Harness/WF.md` + `/wf` | Long-task workflow: explore, second-plan, build, review, verify, recover |
|
|
27
|
+
| `Harness/subagents.md` + `subagent-orchestrator` | Controller-led multi-agent orchestration with source-attributed methods |
|
|
26
28
|
| Research + PRD templates | Clarify idea, scope, non-goals, acceptance criteria |
|
|
27
29
|
| Research protocol | Route research agents, source search, and fallback tools |
|
|
28
30
|
| Built-in common agents | Research, planning, architecture, testing, implementation, debugging, review, verification |
|
|
@@ -30,9 +32,10 @@ npx create-harness-vibe-coding@latest my-project
|
|
|
30
32
|
| Dispatch protocol | Lightweight parallel-agent coordination without a scheduler |
|
|
31
33
|
| Extension contract | Keep stack-specific agents and skills compatible |
|
|
32
34
|
| Context-loading protocol | Inject only the right docs into each subagent |
|
|
35
|
+
| README optimizer skill | Optional README preservation, tables, and approved architecture diagrams |
|
|
33
36
|
| Skill-style loaders | `.claude/skills/*` route lifecycle, context, and build loops |
|
|
34
37
|
| Harness validator | Checks required files and unresolved project placeholders |
|
|
35
|
-
| `.claude/` skeleton |
|
|
38
|
+
| `.claude/` skeleton | Root runtime integration for Claude Code agents, skills, commands, and rules |
|
|
36
39
|
|
|
37
40
|
---
|
|
38
41
|
|
|
@@ -48,6 +51,7 @@ Most 0-1 AI coding projects fail before code quality matters:
|
|
|
48
51
|
| Process drift is invisible | validator checks core harness readiness |
|
|
49
52
|
| Architecture drifts silently | ports, data-flow, and state docs mark boundary changes |
|
|
50
53
|
| Tests come after implementation | workflow requires failing test or manual check first |
|
|
54
|
+
| Long tasks stall after failures | `/wf` adds heartbeat, recovery, debugger, review, and verifier loops |
|
|
51
55
|
|
|
52
56
|
---
|
|
53
57
|
|
|
@@ -55,10 +59,10 @@ Most 0-1 AI coding projects fail before code quality matters:
|
|
|
55
59
|
|
|
56
60
|
```text
|
|
57
61
|
npx scaffold
|
|
58
|
-
-> Claude reads SETUP.md
|
|
59
|
-
->
|
|
62
|
+
-> Claude reads Harness/SETUP.md
|
|
63
|
+
-> Harness router selects only needed harness docs
|
|
60
64
|
-> PRD/research/architecture/PLAN are filled
|
|
61
|
-
-> first vertical slice is built, tested, reviewed, and fed back
|
|
65
|
+
-> first vertical slice is built, tested, reviewed, verified, and fed back
|
|
62
66
|
-> validator catches missing project facts before release
|
|
63
67
|
```
|
|
64
68
|
|
|
@@ -74,41 +78,52 @@ The scaffold does not prebuild business code. It gives agents a compact process
|
|
|
74
78
|
my-project/
|
|
75
79
|
├── CLAUDE.md ← Short startup rules + context discipline
|
|
76
80
|
├── AGENTS.md ← Coding agent entry
|
|
77
|
-
├──
|
|
78
|
-
├── SETUP.md ← Temporary init guide (delete after setup)
|
|
81
|
+
├── README.md ← Project build/test/git/run notes
|
|
79
82
|
├── .gitignore
|
|
80
|
-
├──
|
|
83
|
+
├── Harness/
|
|
81
84
|
│ ├── README.md ← Dynamic doc router
|
|
82
|
-
│ ├──
|
|
83
|
-
│
|
|
84
|
-
│
|
|
85
|
-
│
|
|
86
|
-
│
|
|
87
|
-
│
|
|
88
|
-
│
|
|
89
|
-
│
|
|
90
|
-
│
|
|
91
|
-
│
|
|
85
|
+
│ ├── SETUP.md ← Temporary init guide (delete after setup)
|
|
86
|
+
│ ├── MEMORY.md ← Cross-session resource index
|
|
87
|
+
│ ├── PLAN.md ← Active execution plan, handoffs, heartbeat
|
|
88
|
+
│ ├── WF.md ← Long-task workflow and recovery loop
|
|
89
|
+
│ ├── lifecycle.md ← 0-1 product flow
|
|
90
|
+
│ ├── subagents.md ← Controller-led subagent orchestration
|
|
91
|
+
│ ├── context-loading.md ← Subagent context packs
|
|
92
|
+
│ ├── dispatch.md ← Lightweight parallel-agent protocol
|
|
93
|
+
│ ├── extension.md ← Stack-specific agent/skill contract
|
|
94
|
+
│ ├── architecture.md ← Layer rules, components, ADRs
|
|
95
|
+
│ ├── agent-workflow.md ← TDD loop, subagent roles, write sets
|
|
96
|
+
│ ├── data-flow.md ← Event lifecycle: normal + failure paths
|
|
97
|
+
│ ├── state-machines.md ← State enums, transition tables, guards
|
|
92
98
|
│ ├── domain/
|
|
93
|
-
│ │ └── ports.md
|
|
99
|
+
│ │ └── ports.md ← Port contracts: pre/postconditions, errors
|
|
94
100
|
│ ├── features/
|
|
95
|
-
│ │ └── _template.md
|
|
96
|
-
│
|
|
97
|
-
│
|
|
98
|
-
│
|
|
99
|
-
│
|
|
100
|
-
├──
|
|
101
|
-
│
|
|
101
|
+
│ │ └── _template.md ← Kiro-lite feature doc template
|
|
102
|
+
│ ├── research/
|
|
103
|
+
│ │ ├── README.md
|
|
104
|
+
│ │ ├── PRD.md
|
|
105
|
+
│ │ └── research-results.md
|
|
106
|
+
│ ├── memory/
|
|
107
|
+
│ │ ├── tool-usage-reflections.md
|
|
108
|
+
│ │ ├── user-corrections-preferences.md
|
|
109
|
+
│ │ └── agent-lessons-patterns.md
|
|
110
|
+
│ ├── workflows/ ← Optional workflow docs
|
|
111
|
+
│ └── scripts/
|
|
112
|
+
│ └── validate-harness.mjs
|
|
102
113
|
├── .claude/
|
|
103
114
|
│ ├── settings.json ← Base permissions
|
|
104
115
|
│ ├── agents/ ← Built-in common agents + stack-specific agents later
|
|
105
116
|
│ ├── skills/ ← Harness loaders + stack-specific skills
|
|
117
|
+
│ ├── commands/
|
|
118
|
+
│ │ └── wf.md ← Slash-command bridge into wf-mode
|
|
106
119
|
│ ├── hooks/ ← Configure automation after stack choice
|
|
107
120
|
│ └── rules/ecc/
|
|
108
121
|
│ └── common.md ← Universal coding rules
|
|
109
122
|
└── tests/ ← Your test suite goes here
|
|
110
123
|
```
|
|
111
124
|
|
|
125
|
+
`Harness/` is the default home for harness-owned docs, state, memory, workflows, and validation. The root `.claude/` directory remains at the project root because Claude Code discovers agents, skills, commands, settings, hooks, and rules there.
|
|
126
|
+
|
|
112
127
|
---
|
|
113
128
|
|
|
114
129
|
## Ecosystem Compatibility
|
|
@@ -134,6 +149,35 @@ npx create-harness-vibe-coding@latest
|
|
|
134
149
|
|
|
135
150
|
The scaffold is designed to be added to an existing repository without silently replacing project files.
|
|
136
151
|
|
|
152
|
+
Chinese README: [README-CN.md](README-CN.md)
|
|
153
|
+
|
|
154
|
+
One-sentence agent prompt: `Follow the README at https://github.com/zingspark/create-harness-vibe-coding to configure this project with create-harness-vibe-coding; before editing, ask the Agent-link install intake questions; for a new project run the 0-1 bootstrap, and for an existing project or legacy architecture run a dry-run first, preserve existing files, merge only missing Harness guidance, then follow Harness/SETUP.md.`
|
|
155
|
+
|
|
156
|
+
There are two installation paths:
|
|
157
|
+
|
|
158
|
+
- **npx install**: deterministic scaffold writes with explicit conflict policy. Use this when you want predictable files and a clear dry-run plan.
|
|
159
|
+
- **Agent-link install**: paste the one-sentence prompt above into Claude Code, Codex, Cursor, Gemini CLI, or another coding agent. This path is more flexible: the agent should read this README, inspect the existing project, run or emulate a dry-run, and propose a minimal migration plan before editing.
|
|
160
|
+
|
|
161
|
+
Agent-link install intake, asked before editing:
|
|
162
|
+
|
|
163
|
+
Ask only questions that affect writes, architecture, security, or workflow. Ask at most three blocking questions up front, record safe defaults for the rest, and ask follow-ups only when that choice becomes active.
|
|
164
|
+
|
|
165
|
+
| Topic | Ask When | Default If Unanswered |
|
|
166
|
+
| --- | --- | --- |
|
|
167
|
+
| Root agent entry | `CLAUDE.md`, `AGENTS.md`, `.claude/`, or other agent entry files already exist | Preserve files; ask before merging the Harness entry contract |
|
|
168
|
+
| Harness location | `docs/` is already used for GitHub Pages, product docs, or generated docs | Use root `Harness/`; do not write harness docs into `docs/` |
|
|
169
|
+
| README ownership | root `README.md` is a public product page, package docs, or heavily customized | Preserve existing README and propose a minimal Development section |
|
|
170
|
+
| README optimization | existing README is stale, sparse, missing command tables, or the user asks for diagrams/polished docs | Offer `readme-optimizer`; default to append-only Development notes until the user approves a structure pass or full rewrite |
|
|
171
|
+
| Extensions | ECC, Superpowers, custom rules, or stack-specific skills may be useful | Recommend first; install only after user approval |
|
|
172
|
+
| Skills | stack is known and optional skills could improve testing, frontend, backend, review, or browser evidence | Install 1-2 relevant skills only after user approval |
|
|
173
|
+
| CI/CD | CI config exists or the project lacks a test/build gate | Document existing commands first; add CI/CD only after user approval |
|
|
174
|
+
| Verification depth | browser-visible, API, database, auth, payment, or deployment behavior is affected | Require real command evidence; require browser/API evidence when relevant |
|
|
175
|
+
| Memory/privacy | repo contains sensitive domain data, customer data, secrets, or private workflows | Enable memory index only; never record secrets or private data |
|
|
176
|
+
| Branch/worktree | project has uncommitted changes, risky migration, or parallel implementation lanes | Preserve current worktree; propose branch/worktree before broad edits |
|
|
177
|
+
| Package manager/stack | multiple package managers, monorepo apps, or unclear stack boundaries exist | Ask which workspace/app is in scope before writing |
|
|
178
|
+
|
|
179
|
+
If `CLAUDE.md` already exists, the agent must tell the user it is the root agent entry contract and ask for confirmation before refactoring, merging, backing up, or replacing it. The correct outcome is a user-approved merge that preserves project-specific rules while adding the Harness startup, memory, router, workflow, and subagent orchestration contract.
|
|
180
|
+
|
|
137
181
|
```bash
|
|
138
182
|
# Preview the write plan first. No files or directories are created.
|
|
139
183
|
npx create-harness-vibe-coding@latest my-app . -y --dry-run
|
|
@@ -142,12 +186,12 @@ npx create-harness-vibe-coding@latest my-app . -y --dry-run
|
|
|
142
186
|
npx create-harness-vibe-coding@latest my-app . -y --on-conflict skip
|
|
143
187
|
```
|
|
144
188
|
|
|
145
|
-
By default, conflicts fail before writing. This protects existing `CLAUDE.md`, `AGENTS.md`, `.claude/`, `.gitignore`, docs, and scripts from accidental replacement.
|
|
189
|
+
By default, conflicts fail before writing. This protects existing `CLAUDE.md`, `AGENTS.md`, `README.md`, `.claude/`, `.gitignore`, project docs, and scripts from accidental replacement.
|
|
146
190
|
|
|
147
191
|
| Conflict mode | Meaning | Risk |
|
|
148
192
|
|---------------|---------|------|
|
|
149
193
|
| `fail` | Default. Stop if a target file already exists. | Safest for existing projects; requires a follow-up decision. |
|
|
150
|
-
| `skip` | Keep existing files and create only missing files. | Existing
|
|
194
|
+
| `skip` | Keep existing files and create only missing files. | Existing root entries may need manual links to new `Harness/` docs or workflows. |
|
|
151
195
|
| `backup` | Rename the existing file to `<name>.harness-backup`, then write the scaffold file. | Review backups before deleting; repeated runs may need cleanup. |
|
|
152
196
|
| `overwrite` | Replace existing files with scaffold versions. | Destructive. Use only after reviewing `--dry-run` output or with explicit approval. |
|
|
153
197
|
|
|
@@ -156,9 +200,15 @@ Recommended bootstrap for agents:
|
|
|
156
200
|
```bash
|
|
157
201
|
node bin/create-harness-vibe-coding.js my-app . -y --dry-run
|
|
158
202
|
node bin/create-harness-vibe-coding.js my-app . -y --on-conflict skip
|
|
159
|
-
node scripts/validate-harness.mjs
|
|
203
|
+
node Harness/scripts/validate-harness.mjs
|
|
160
204
|
```
|
|
161
205
|
|
|
206
|
+
After files are installed, agents must follow `Harness/SETUP.md` before normal project work. `CLAUDE.md` only points to the required Harness routers; setup details belong in `Harness/SETUP.md`.
|
|
207
|
+
|
|
208
|
+
If `AGENTS.md` already exists, the agent must ask for user consent before merging or replacing it. `AGENTS.md` is part of the root agent entry contract, just like `CLAUDE.md`.
|
|
209
|
+
|
|
210
|
+
Development commands, build scripts, git conventions, and release process belong in root `README.md`. Code architecture belongs in `Harness/architecture.md` or feature docs, not in `CLAUDE.md`.
|
|
211
|
+
|
|
162
212
|
### Agent / CI/CD
|
|
163
213
|
|
|
164
214
|
Agents and automation can skip all prompts with `-y`:
|
|
@@ -243,7 +293,7 @@ npm test
|
|
|
243
293
|
node bin/create-harness-vibe-coding.js --list-options
|
|
244
294
|
|
|
245
295
|
# After generating a project, validate the harness from that project root
|
|
246
|
-
node scripts/validate-harness.mjs
|
|
296
|
+
node Harness/scripts/validate-harness.mjs
|
|
247
297
|
```
|
|
248
298
|
|
|
249
299
|
The harness validator checks scaffold consistency. It is not a full React, Playwright, Chrome DevTools Protocol, or browser matrix test suite.
|
|
@@ -251,9 +301,10 @@ The harness validator checks scaffold consistency. It is not a full React, Playw
|
|
|
251
301
|
### After scaffolding, tell Claude:
|
|
252
302
|
|
|
253
303
|
```
|
|
254
|
-
"Read SETUP.md. Bootstrap this project from idea to first vertical slice."
|
|
255
|
-
"Read SETUP.md. This is a React TypeScript SaaS idea. Clarify PRD first, then plan the first slice."
|
|
256
|
-
"Read SETUP.md. This is a Python data product. Research the stack, define the MVP, then create
|
|
304
|
+
"Read Harness/SETUP.md. Bootstrap this project from idea to first vertical slice."
|
|
305
|
+
"Read Harness/SETUP.md. This is a React TypeScript SaaS idea. Clarify PRD first, then plan the first slice."
|
|
306
|
+
"Read Harness/SETUP.md. This is a Python data product. Research the stack, define the MVP, then create Harness/PLAN.md."
|
|
307
|
+
"Use /wf for this long migration. Explore first, make a second plan, then implement, review, verify, and recover with heartbeat updates."
|
|
257
308
|
```
|
|
258
309
|
|
|
259
310
|
---
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-harness-vibe-coding",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Scaffold a 0-1 product harness for AI-assisted research, PRD, planning, architecture, build, test, and feedback loops",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"files": [
|
|
10
10
|
"bin/",
|
|
11
11
|
"src/",
|
|
12
|
-
"templates/"
|
|
12
|
+
"templates/",
|
|
13
|
+
"README-CN.md"
|
|
13
14
|
],
|
|
14
15
|
"scripts": {
|
|
15
16
|
"start": "node src/index.js",
|
package/src/generator.js
CHANGED
|
@@ -12,6 +12,20 @@ const EMPTY_DIRS = [
|
|
|
12
12
|
'tests',
|
|
13
13
|
];
|
|
14
14
|
|
|
15
|
+
function harnessDest(file) {
|
|
16
|
+
if (file === 'SETUP.md') return 'Harness/SETUP.md';
|
|
17
|
+
if (file === 'MEMORY.md') return 'Harness/MEMORY.md';
|
|
18
|
+
if (file === 'scripts/validate-harness.mjs') return 'Harness/scripts/validate-harness.mjs';
|
|
19
|
+
if (file.startsWith('memory/')) return `Harness/${file}`;
|
|
20
|
+
if (file === 'docs/README.md') return 'Harness/README.md';
|
|
21
|
+
if (file.startsWith('docs/harness/')) return file.replace(/^docs\/harness\//, 'Harness/');
|
|
22
|
+
if (file.startsWith('docs/research/')) return file.replace(/^docs\/research\//, 'Harness/research/');
|
|
23
|
+
if (file.startsWith('docs/domain/')) return file.replace(/^docs\/domain\//, 'Harness/domain/');
|
|
24
|
+
if (file.startsWith('docs/features/')) return file.replace(/^docs\/features\//, 'Harness/features/');
|
|
25
|
+
if (file.startsWith('docs/workflows/')) return file.replace(/^docs\/workflows\//, 'Harness/workflows/');
|
|
26
|
+
return file;
|
|
27
|
+
}
|
|
28
|
+
|
|
15
29
|
/**
|
|
16
30
|
* Replace {{vars}} in file contents.
|
|
17
31
|
*/
|
|
@@ -109,7 +123,7 @@ function createCoreFileSpecs() {
|
|
|
109
123
|
.map(file => normalizePath(file))
|
|
110
124
|
.sort()
|
|
111
125
|
.map(file => ({
|
|
112
|
-
dest: file,
|
|
126
|
+
dest: harnessDest(file),
|
|
113
127
|
src: path.join(TEMPLATES_DIR, ...file.split('/')),
|
|
114
128
|
type: 'common',
|
|
115
129
|
}));
|
|
@@ -126,7 +140,7 @@ function createOptionalFileSpecs(selectedSkills) {
|
|
|
126
140
|
const absRoot = path.join(OPTIONAL_DIR, ...fileRoot.split('/'));
|
|
127
141
|
for (const file of walkFiles(absRoot).map(normalizePath).sort()) {
|
|
128
142
|
specs.push({
|
|
129
|
-
dest: file,
|
|
143
|
+
dest: harnessDest(file),
|
|
130
144
|
src: path.join(absRoot, ...file.split('/')),
|
|
131
145
|
type: 'optional',
|
|
132
146
|
skillId: skill.id,
|
|
@@ -138,6 +152,21 @@ function createOptionalFileSpecs(selectedSkills) {
|
|
|
138
152
|
return specs;
|
|
139
153
|
}
|
|
140
154
|
|
|
155
|
+
function duplicateDests(fileSpecs) {
|
|
156
|
+
const seen = new Set();
|
|
157
|
+
const duplicates = new Set();
|
|
158
|
+
|
|
159
|
+
for (const spec of fileSpecs) {
|
|
160
|
+
if (seen.has(spec.dest)) {
|
|
161
|
+
duplicates.add(spec.dest);
|
|
162
|
+
} else {
|
|
163
|
+
seen.add(spec.dest);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return [...duplicates].sort();
|
|
168
|
+
}
|
|
169
|
+
|
|
141
170
|
function createPlan(resolvedDir, fileSpecs) {
|
|
142
171
|
const plan = {
|
|
143
172
|
create: [],
|
|
@@ -166,7 +195,11 @@ function createPlan(resolvedDir, fileSpecs) {
|
|
|
166
195
|
const absDir = dir === '.'
|
|
167
196
|
? resolvedDir
|
|
168
197
|
: path.join(resolvedDir, ...dir.split('/'));
|
|
169
|
-
if (
|
|
198
|
+
if (fs.existsSync(absDir)) {
|
|
199
|
+
if (!fs.statSync(absDir).isDirectory()) {
|
|
200
|
+
plan.conflict.push(dir === '.' ? './' : `${dir}/`);
|
|
201
|
+
}
|
|
202
|
+
} else {
|
|
170
203
|
plan.mkdir.push(dir === '.' ? './' : `${dir}/`);
|
|
171
204
|
}
|
|
172
205
|
}
|
|
@@ -232,9 +265,9 @@ function nextBackupPath(destPath) {
|
|
|
232
265
|
function registerOptionalContent(file, content, selectedSkills) {
|
|
233
266
|
if (!selectedSkills.length) return content;
|
|
234
267
|
|
|
235
|
-
if (file === 'MEMORY.md') {
|
|
268
|
+
if (file === 'Harness/MEMORY.md') {
|
|
236
269
|
const lines = selectedSkills.map(skill => (
|
|
237
|
-
`- [${skill.id}](
|
|
270
|
+
`- [${skill.id}](../.claude/skills/${skill.id}/SKILL.md) - ${skill.description} Workflow: [workflows/${skill.id}.md](workflows/${skill.id}.md)`
|
|
238
271
|
));
|
|
239
272
|
return content.replace(
|
|
240
273
|
'Stack-specific skills can be added after the product shape is known.',
|
|
@@ -242,7 +275,7 @@ function registerOptionalContent(file, content, selectedSkills) {
|
|
|
242
275
|
);
|
|
243
276
|
}
|
|
244
277
|
|
|
245
|
-
if (file === '
|
|
278
|
+
if (file === 'Harness/README.md') {
|
|
246
279
|
const lines = selectedSkills.map(skill => (
|
|
247
280
|
`- [${skill.title}](workflows/${skill.id}.md) - ${skill.description}`
|
|
248
281
|
));
|
|
@@ -253,14 +286,25 @@ function registerOptionalContent(file, content, selectedSkills) {
|
|
|
253
286
|
}
|
|
254
287
|
|
|
255
288
|
function registrationWarnings(plan, selectedSkills) {
|
|
256
|
-
if (!selectedSkills.length) return [];
|
|
257
|
-
|
|
258
289
|
const warnings = [];
|
|
259
|
-
|
|
260
|
-
|
|
290
|
+
|
|
291
|
+
if (selectedSkills.length) {
|
|
292
|
+
if (plan.skip.includes('Harness/MEMORY.md')) {
|
|
293
|
+
warnings.push('Harness/MEMORY.md was skipped; manually register selected optional skills under #Skills.');
|
|
294
|
+
}
|
|
295
|
+
if (plan.skip.includes('Harness/README.md')) {
|
|
296
|
+
warnings.push('Harness/README.md was skipped; manually register selected optional workflow paths.');
|
|
297
|
+
}
|
|
261
298
|
}
|
|
262
|
-
|
|
263
|
-
|
|
299
|
+
|
|
300
|
+
if (plan.skip.includes('README.md')) {
|
|
301
|
+
warnings.push('README.md was skipped; keep project run, build, test, and git conventions there, not in CLAUDE.md.');
|
|
302
|
+
}
|
|
303
|
+
if (plan.skip.includes('CLAUDE.md') || plan.conflict.includes('CLAUDE.md')) {
|
|
304
|
+
warnings.push('CLAUDE.md already exists; ask the user to confirm refactoring or merging it with the Harness root-entry contract before editing.');
|
|
305
|
+
}
|
|
306
|
+
if (plan.skip.includes('AGENTS.md')) {
|
|
307
|
+
warnings.push('AGENTS.md was skipped; ask for user consent before merging or replacing the project agent entry contract.');
|
|
264
308
|
}
|
|
265
309
|
|
|
266
310
|
return warnings;
|
|
@@ -290,6 +334,7 @@ export function generate({
|
|
|
290
334
|
];
|
|
291
335
|
const specsByDest = new Map(fileSpecs.map(spec => [spec.dest, spec]));
|
|
292
336
|
const plan = createPlan(resolvedDir, fileSpecs);
|
|
337
|
+
const duplicateDestinations = duplicateDests(fileSpecs);
|
|
293
338
|
|
|
294
339
|
if (!VALID_CONFLICT_POLICIES.has(onConflict)) {
|
|
295
340
|
errors.push(`Unknown conflict policy "${onConflict}". Use fail, skip, backup, or overwrite.`);
|
|
@@ -315,6 +360,18 @@ export function generate({
|
|
|
315
360
|
};
|
|
316
361
|
}
|
|
317
362
|
|
|
363
|
+
if (duplicateDestinations.length > 0) {
|
|
364
|
+
errors.push(`Generation stopped because duplicate template destination(s) were found: ${duplicateDestinations.join(', ')}`);
|
|
365
|
+
return {
|
|
366
|
+
success: false,
|
|
367
|
+
created,
|
|
368
|
+
errors,
|
|
369
|
+
plan,
|
|
370
|
+
summary: createSummary(plan, { noWrites: true }),
|
|
371
|
+
warnings,
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
|
|
318
375
|
addFileActions(plan, fileSpecs, resolvedDir, onConflict);
|
|
319
376
|
warnings.push(...registrationWarnings(plan, optional.selectedSkills));
|
|
320
377
|
|
|
@@ -332,6 +389,9 @@ export function generate({
|
|
|
332
389
|
|
|
333
390
|
if (plan.conflict.length > 0) {
|
|
334
391
|
errors.push(`Generation stopped because ${plan.conflict.length} file conflict(s) were found: ${plan.conflict.join(', ')}`);
|
|
392
|
+
if (plan.conflict.includes('CLAUDE.md')) {
|
|
393
|
+
errors.push('CLAUDE.md already exists. It is the root agent entry contract; ask the user to confirm refactoring or merging it with the Harness entry contract before editing, backing up, or overwriting.');
|
|
394
|
+
}
|
|
335
395
|
return {
|
|
336
396
|
success: false,
|
|
337
397
|
created,
|
package/src/index.js
CHANGED
|
@@ -100,7 +100,7 @@ if (argName || skipPrompts) {
|
|
|
100
100
|
console.log(pc.dim('────────────────────────────────────────────'));
|
|
101
101
|
console.log(` Project ${pc.green(projectName)}`);
|
|
102
102
|
console.log(` Directory ${pc.green(targetDir)}`);
|
|
103
|
-
console.log(` Creates ${pc.cyan('CLAUDE.md,
|
|
103
|
+
console.log(` Creates ${pc.cyan('CLAUDE.md, README.md, Harness/PLAN.md, Harness/, .claude/, tests/')}`);
|
|
104
104
|
if (generationOptions.dryRun) {
|
|
105
105
|
console.log(` Mode ${pc.yellow('dry-run')}`);
|
|
106
106
|
}
|
|
@@ -142,15 +142,30 @@ if (argName || skipPrompts) {
|
|
|
142
142
|
console.log(pc.dim('────────────────────────────────────────────'));
|
|
143
143
|
console.log(` Project ${pc.green(projectName)}`);
|
|
144
144
|
console.log(` Directory ${pc.green(targetDir)}`);
|
|
145
|
-
console.log(` Creates ${pc.cyan('CLAUDE.md,
|
|
145
|
+
console.log(` Creates ${pc.cyan('CLAUDE.md, README.md, Harness/PLAN.md, Harness/, .claude/, tests/')}`);
|
|
146
146
|
console.log(` Conflicts ${pc.cyan(generationOptions.onConflict)}`);
|
|
147
147
|
console.log(pc.dim('────────────────────────────────────────────'));
|
|
148
148
|
console.log('');
|
|
149
149
|
|
|
150
|
+
const preview = generate({ projectName, targetDir, ...generationOptions, dryRun: true });
|
|
151
|
+
if (!preview.success) {
|
|
152
|
+
printResult(preview, targetDir);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
console.log(pc.yellow('Planned changes: no files have been written yet.'));
|
|
156
|
+
printSummary(preview.summary);
|
|
157
|
+
printPlan(preview.plan);
|
|
158
|
+
printWarnings(preview);
|
|
159
|
+
console.log('');
|
|
160
|
+
|
|
161
|
+
if (generationOptions.dryRun) {
|
|
162
|
+
process.exit(0);
|
|
163
|
+
}
|
|
164
|
+
|
|
150
165
|
let proceed = true;
|
|
151
166
|
try {
|
|
152
167
|
proceed = await p.confirm({
|
|
153
|
-
message: 'Confirm generation?',
|
|
168
|
+
message: 'Confirm generation with this plan?',
|
|
154
169
|
initialValue: true,
|
|
155
170
|
});
|
|
156
171
|
if (p.isCancel(proceed)) proceed = false;
|
|
@@ -187,19 +202,14 @@ function printResult(result, targetDir) {
|
|
|
187
202
|
console.log(pc.green('\nGeneration complete.\n'));
|
|
188
203
|
printSummary(result.summary);
|
|
189
204
|
|
|
190
|
-
|
|
191
|
-
console.log(pc.yellow('\nWarning(s):'));
|
|
192
|
-
for (const warning of result.warnings) {
|
|
193
|
-
console.log(pc.yellow(` - ${warning}`));
|
|
194
|
-
}
|
|
195
|
-
}
|
|
205
|
+
printWarnings(result);
|
|
196
206
|
|
|
197
207
|
console.log(pc.bold('Next steps:'));
|
|
198
208
|
console.log(` ${pc.cyan(`cd ${targetDir}`)}`);
|
|
199
209
|
console.log(` ${pc.cyan('claude')} # Start Claude Code`);
|
|
200
|
-
console.log(` Tell Claude: "${pc.yellow('Read SETUP.md. Bootstrap this project from idea to first vertical slice.')}"`);
|
|
210
|
+
console.log(` Tell Claude: "${pc.yellow('Read Harness/SETUP.md. Bootstrap this project from idea to first vertical slice.')}"`);
|
|
201
211
|
console.log('');
|
|
202
|
-
console.log(pc.dim(' SETUP.md is temporary. Delete it after initialization.'));
|
|
212
|
+
console.log(pc.dim(' Harness/SETUP.md is temporary. Delete it after initialization.'));
|
|
203
213
|
console.log('');
|
|
204
214
|
|
|
205
215
|
} else {
|
|
@@ -326,6 +336,15 @@ function printPlan(plan) {
|
|
|
326
336
|
}
|
|
327
337
|
}
|
|
328
338
|
|
|
339
|
+
function printWarnings(result) {
|
|
340
|
+
if (!result.warnings.length) return;
|
|
341
|
+
|
|
342
|
+
console.log(pc.yellow('\nWarning(s):'));
|
|
343
|
+
for (const warning of result.warnings) {
|
|
344
|
+
console.log(pc.yellow(` - ${warning}`));
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
329
348
|
function printJsonResult(result) {
|
|
330
349
|
// Remove `created` array from output — it is already in the plan, avoid duplication
|
|
331
350
|
const { created, ...rest } = result;
|
|
@@ -12,10 +12,10 @@ You are an architecture review agent for this project harness.
|
|
|
12
12
|
|
|
13
13
|
Load first:
|
|
14
14
|
|
|
15
|
-
- `
|
|
16
|
-
- `
|
|
17
|
-
- `
|
|
18
|
-
- `
|
|
15
|
+
- `Harness/architecture.md`
|
|
16
|
+
- `Harness/domain/ports.md`
|
|
17
|
+
- `Harness/data-flow.md` when runtime flow may change
|
|
18
|
+
- `Harness/state-machines.md` when state may change
|
|
19
19
|
- current PRD or feature doc
|
|
20
20
|
|
|
21
21
|
Rules:
|
|
@@ -12,10 +12,10 @@ You are a documentation verification agent for this project harness.
|
|
|
12
12
|
|
|
13
13
|
Load first:
|
|
14
14
|
|
|
15
|
-
- `
|
|
16
|
-
- `
|
|
17
|
-
- `
|
|
18
|
-
- `
|
|
15
|
+
- `Harness/research/README.md`
|
|
16
|
+
- `Harness/architecture.md` when boundaries may change
|
|
17
|
+
- `Harness/domain/ports.md` when APIs cross layers
|
|
18
|
+
- `Harness/PLAN.md`
|
|
19
19
|
|
|
20
20
|
Inputs you must receive:
|
|
21
21
|
|
|
@@ -12,7 +12,7 @@ You are an implementation agent for this project harness.
|
|
|
12
12
|
|
|
13
13
|
Load first:
|
|
14
14
|
|
|
15
|
-
- current task from `
|
|
15
|
+
- current task from `Harness/PLAN.md`
|
|
16
16
|
- current feature doc when present
|
|
17
17
|
- failing test or manual check
|
|
18
18
|
- relevant architecture/ports docs if boundaries are touched
|
|
@@ -12,9 +12,9 @@ You are a planning agent for this project harness.
|
|
|
12
12
|
|
|
13
13
|
Load first:
|
|
14
14
|
|
|
15
|
-
- `
|
|
16
|
-
- `
|
|
17
|
-
- `
|
|
15
|
+
- `Harness/PLAN.md`
|
|
16
|
+
- `Harness/lifecycle.md`
|
|
17
|
+
- `Harness/dispatch.md`
|
|
18
18
|
- current PRD or feature doc if present
|
|
19
19
|
|
|
20
20
|
Rules:
|