@ck123pm/harness-kit 0.1.1 → 0.1.2
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/PLAN.md +19 -113
- package/README.md +49 -119
- package/package.json +1 -1
- package/skills/harness-init/SKILL.md +92 -0
- package/skills/harness-update-spec/SKILL.md +88 -0
- package/src/cli.js +3 -3
- package/src/commands/doctor.js +24 -24
- package/src/commands/install.js +2 -2
- package/src/utils/registry.js +49 -6
- package/commands/harness-init.md +0 -115
- package/commands/harness-update-spec.md +0 -122
package/PLAN.md
CHANGED
|
@@ -1,123 +1,29 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Harness Kit Plan
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Current Direction
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This package now ships the harness capabilities as Claude skills instead of Claude commands.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
第一步:CLI 安装能力
|
|
9
|
-
npx @ck123pm/harness-kit install
|
|
7
|
+
Installed artifacts:
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
/harness-
|
|
9
|
+
- `skills/harness-init/SKILL.md`
|
|
10
|
+
- `skills/harness-update-spec/SKILL.md`
|
|
11
|
+
- `skills/md-to-html-doc.md`
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
comet init
|
|
16
|
-
```
|
|
13
|
+
## Intended Workflow
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
- **md-to-html-doc.md**:Claude skill,Markdown 转响应式 HTML
|
|
22
|
-
- **comet**:后续 OpenSpec + Superpowers workflow 管理
|
|
15
|
+
1. Run `harness-kit install`.
|
|
16
|
+
2. Open Claude and ask it to use `harness-init` to create `.harness/`.
|
|
17
|
+
3. Later, ask Claude to use `harness-update-spec` to refresh stale specs incrementally.
|
|
23
18
|
|
|
24
|
-
CLI
|
|
19
|
+
## CLI Responsibilities
|
|
25
20
|
|
|
26
|
-
|
|
21
|
+
- Install packaged skills into Claude config.
|
|
22
|
+
- Check optional external tools such as `comet` and `openspec`.
|
|
23
|
+
- Diagnose environment state.
|
|
24
|
+
- Update or uninstall installed skill artifacts.
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
@ck123pm/harness-kit
|
|
30
|
-
├── bin/
|
|
31
|
-
│ └── harness-kit.js # CLI shebang 入口
|
|
32
|
-
├── src/
|
|
33
|
-
│ ├── cli.js # Commander 程序定义
|
|
34
|
-
│ ├── commands/
|
|
35
|
-
│ │ ├── install.js # install 命令
|
|
36
|
-
│ │ ├── doctor.js # doctor 命令
|
|
37
|
-
│ │ ├── update.js # update 命令
|
|
38
|
-
│ │ └── uninstall.js # uninstall 命令
|
|
39
|
-
│ └── utils/
|
|
40
|
-
│ ├── platform.js # 平台检测(Windows/Mac/Linux 路径差异)
|
|
41
|
-
│ └── registry.js # command/skill 安装路径解析
|
|
42
|
-
├── commands/
|
|
43
|
-
│ └── harness-init.md # Claude command(智能初始化指令)
|
|
44
|
-
├── skills/
|
|
45
|
-
│ └── md-to-html-doc.md # Claude skill
|
|
46
|
-
├── scripts/
|
|
47
|
-
│ └── init-comet.js # 独立脚本:执行 comet init
|
|
48
|
-
├── package.json
|
|
49
|
-
└── README.md
|
|
50
|
-
```
|
|
26
|
+
## Notes
|
|
51
27
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
### `harness-kit install`
|
|
55
|
-
|
|
56
|
-
安装 harness 能力到 Claude 环境:
|
|
57
|
-
|
|
58
|
-
1. **检测 Claude 配置路径**:解析 `~/.claude/` 或 `CLAUDE_CONFIG_DIR` 环境变量
|
|
59
|
-
2. **安装 harness-init.md 到 commands**:复制 `commands/harness-init.md` → `~/.claude/commands/harness-init.md`
|
|
60
|
-
3. **安装 md-to-html-doc.md 到 skills**:复制 `skills/md-to-html-doc.md` → `~/.claude/skills/md-to-html-doc.md`
|
|
61
|
-
4. **检查/安装 @ck123pm/comet**:检测 `comet` 是否在 PATH,不在则 `npm install -g @ck123pm/comet`
|
|
62
|
-
5. **检查/安装 openspec**:检测 `openspec` 是否在 PATH,不在则 `npm install -g @fission-ai/openspec`
|
|
63
|
-
6. **写入安装记录**:`~/.claude/harness-kit.json`
|
|
64
|
-
7. **提示用户下一步**:"Open Claude and run `/harness-init` to initialize your project"
|
|
65
|
-
|
|
66
|
-
选项:
|
|
67
|
-
- `--scope <scope>`: global (默认) | local(安装到项目 .claude/ 而非全局)
|
|
68
|
-
- `--skip-comet`: 跳过 comet 安装
|
|
69
|
-
- `--skip-openspec`: 跳过 openspec 安装
|
|
70
|
-
- `--force`: 覆盖已有文件
|
|
71
|
-
|
|
72
|
-
### `harness-kit doctor`
|
|
73
|
-
|
|
74
|
-
环境健康检查,打印表格,每项绿色 ✓ 或红色 ✗:
|
|
75
|
-
|
|
76
|
-
- [ ] Claude command harness-init 是否已安装
|
|
77
|
-
- [ ] Claude skill md-to-html-doc 是否已安装
|
|
78
|
-
- [ ] comet 是否可用(版本)
|
|
79
|
-
- [ ] openspec 是否可用(版本)
|
|
80
|
-
- [ ] superpowers 是否可用
|
|
81
|
-
- [ ] 当前目录是否已有 `.harness/`
|
|
82
|
-
- [ ] 当前目录是否已有 `.comet.yaml`
|
|
83
|
-
- [ ] 当前目录是否已有 `openspec/`
|
|
84
|
-
|
|
85
|
-
末尾给出修复建议。
|
|
86
|
-
|
|
87
|
-
### `harness-kit update`
|
|
88
|
-
|
|
89
|
-
升级已安装的 command/skill:
|
|
90
|
-
|
|
91
|
-
1. 对比已安装文件与包内文件的哈希/大小
|
|
92
|
-
2. 如果有更新:提示用户,确认后覆盖
|
|
93
|
-
3. 如果已是最新:打印 "Up to date"
|
|
94
|
-
4. 可选:`--check` 仅检查不升级
|
|
95
|
-
|
|
96
|
-
### `harness-kit uninstall`
|
|
97
|
-
|
|
98
|
-
卸载已安装的 command/skill:
|
|
99
|
-
|
|
100
|
-
1. 删除 `~/.claude/commands/harness-init.md`
|
|
101
|
-
2. 删除 `~/.claude/skills/md-to-html-doc.md`
|
|
102
|
-
3. 删除 `~/.claude/harness-kit.json`
|
|
103
|
-
4. 打印确认信息
|
|
104
|
-
|
|
105
|
-
## 依赖配置
|
|
106
|
-
|
|
107
|
-
- **dependencies**: commander (^14.0.0), chalk (^5.3.0), fs-extra (^11.2.0)
|
|
108
|
-
- **peerDependencies**: @ck123pm/comet (>=0.2.0), @fission-ai/openspec (>=1.0.0)
|
|
109
|
-
- **peerDependenciesMeta**: 两者 optional: true
|
|
110
|
-
- **engines**: node >= 20
|
|
111
|
-
- **publishConfig**: { "access": "public" }
|
|
112
|
-
- **type**: "module"
|
|
113
|
-
|
|
114
|
-
## 验证方式
|
|
115
|
-
|
|
116
|
-
1. `npm install` 安装依赖
|
|
117
|
-
2. `node bin/harness-kit.js install` — 安装到全局
|
|
118
|
-
3. `node bin/harness-kit.js doctor` — 验证环境
|
|
119
|
-
4. 打开 Claude,执行 `/harness-init` — 验证 Claude 能识别 command
|
|
120
|
-
5. `node bin/harness-kit.js update` — 验证升级检测
|
|
121
|
-
6. `node bin/harness-kit.js uninstall` — 验证卸载
|
|
122
|
-
7. 测试 `--scope local` 安装到项目 `.claude/`
|
|
123
|
-
8. 测试 `--force` 覆盖
|
|
28
|
+
- `harness-init` and `harness-update-spec` are directory-based skills.
|
|
29
|
+
- The install/update record logic must support hashing whole directories, not only single files.
|
package/README.md
CHANGED
|
@@ -1,185 +1,115 @@
|
|
|
1
1
|
# @ck123pm/harness-kit
|
|
2
2
|
|
|
3
|
-
CLI for installing and managing Claude
|
|
3
|
+
CLI for installing and managing harness-related Claude skills.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Install
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npx @ck123pm/harness-kit install
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Or install globally first:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
14
|
npm install -g @ck123pm/harness-kit
|
|
15
15
|
harness-kit install
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
##
|
|
18
|
+
## What Gets Installed
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
`harness-kit install` installs these Claude skills:
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
- `harness-init`
|
|
23
|
+
- `harness-update-spec`
|
|
24
|
+
- `md-to-html-doc`
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
/harness-init
|
|
26
|
+
It also checks for:
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
```
|
|
28
|
+
- `@ck123pm/comet`
|
|
29
|
+
- `@fission-ai/openspec`
|
|
32
30
|
|
|
33
|
-
|
|
31
|
+
And writes an install record to `~/.claude/harness-kit.json` or the local `.claude/` scope.
|
|
34
32
|
|
|
35
|
-
|
|
33
|
+
## Usage Flow
|
|
36
34
|
|
|
37
|
-
|
|
35
|
+
1. Install the skills with `harness-kit install`.
|
|
36
|
+
2. Open Claude and ask it to use the `harness-init` skill to initialize the project harness.
|
|
37
|
+
3. After the harness exists, ask Claude to use the `harness-update-spec` skill when specs need to be refreshed.
|
|
38
|
+
4. Use `comet init` or `openspec` commands as needed for the surrounding workflow.
|
|
39
|
+
|
|
40
|
+
## CLI Commands
|
|
41
|
+
|
|
42
|
+
### `harness-kit install`
|
|
38
43
|
|
|
39
|
-
|
|
40
|
-
- 复制 `harness-update-spec.md` → `~/.claude/commands/`
|
|
41
|
-
- 复制 `md-to-html-doc.md` → `~/.claude/skills/`
|
|
42
|
-
- 检查/安装 `@ck123pm/comet`
|
|
43
|
-
- 检查/安装 `@fission-ai/openspec`
|
|
44
|
-
- 写入安装记录 `~/.claude/harness-kit.json`
|
|
44
|
+
Install the packaged Claude skills.
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
Options:
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
| `--skip-openspec` | 跳过 openspec 安装 |
|
|
53
|
-
| `--force` | 覆盖已有文件 |
|
|
48
|
+
- `--scope <scope>`: `global` or `local`
|
|
49
|
+
- `--skip-comet`: skip `@ck123pm/comet` install check
|
|
50
|
+
- `--skip-openspec`: skip `@fission-ai/openspec` install check
|
|
51
|
+
- `--force`: overwrite installed files
|
|
54
52
|
|
|
55
|
-
|
|
53
|
+
Examples:
|
|
56
54
|
|
|
57
55
|
```bash
|
|
58
|
-
# 全局安装(默认)
|
|
59
56
|
harness-kit install
|
|
60
|
-
|
|
61
|
-
# 安装到项目级 .claude/
|
|
62
57
|
harness-kit install --scope local
|
|
63
|
-
|
|
64
|
-
# 跳过 comet 和 openspec
|
|
65
58
|
harness-kit install --skip-comet --skip-openspec
|
|
66
59
|
```
|
|
67
60
|
|
|
68
61
|
### `harness-kit doctor`
|
|
69
62
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
```
|
|
73
|
-
🔍 harness-kit doctor
|
|
74
|
-
|
|
75
|
-
✓ Claude command harness-init Found
|
|
76
|
-
✓ Claude command harness-update-spec Found
|
|
77
|
-
✓ Claude skill md-to-html-doc Found
|
|
78
|
-
✗ comet Not found
|
|
79
|
-
✗ openspec Not found
|
|
80
|
-
✓ superpowers Built-in
|
|
81
|
-
✗ .harness/ Not found
|
|
82
|
-
✗ .comet.yaml Not found
|
|
83
|
-
✗ openspec/ Not found
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
末尾给出修复建议。
|
|
63
|
+
Check whether the required skills and supporting tools are present.
|
|
87
64
|
|
|
88
65
|
### `harness-kit update`
|
|
89
66
|
|
|
90
|
-
|
|
67
|
+
Update installed skill files from the current package contents.
|
|
91
68
|
|
|
92
|
-
|
|
93
|
-
- 有更新时提示确认后覆盖
|
|
94
|
-
- 已是最新时打印 "All files up to date"
|
|
69
|
+
Options:
|
|
95
70
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
| 选项 | 说明 |
|
|
99
|
-
|------|------|
|
|
100
|
-
| `--check` | 仅检查不升级 |
|
|
101
|
-
| `--force` | 强制覆盖不提示 |
|
|
102
|
-
|
|
103
|
-
**示例:**
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
# 检查是否有更新
|
|
107
|
-
harness-kit update --check
|
|
108
|
-
|
|
109
|
-
# 执行更新
|
|
110
|
-
harness-kit update
|
|
111
|
-
```
|
|
71
|
+
- `--check`: detect updates without applying them
|
|
72
|
+
- `--force`: overwrite without prompting
|
|
112
73
|
|
|
113
74
|
### `harness-kit uninstall`
|
|
114
75
|
|
|
115
|
-
|
|
76
|
+
Remove installed skill files and the install record.
|
|
116
77
|
|
|
117
|
-
|
|
118
|
-
harness-kit uninstall
|
|
119
|
-
```
|
|
78
|
+
## Installed Skills
|
|
120
79
|
|
|
121
|
-
|
|
80
|
+
### `harness-init`
|
|
122
81
|
|
|
123
|
-
|
|
82
|
+
Initializes the `.harness/` directory from the real codebase and splits project knowledge into the expected harness structure.
|
|
124
83
|
|
|
125
|
-
|
|
84
|
+
### `harness-update-spec`
|
|
126
85
|
|
|
127
|
-
|
|
128
|
-
|------|------|
|
|
129
|
-
| `/harness-init` | 智能初始化 `.harness/` 目录,基于项目代码推导生成全部 spec |
|
|
130
|
-
| `/harness-update-spec` | 分析当前项目状态,对比现有 `.harness/` spec,交互式建议更新或新增 |
|
|
86
|
+
Compares the current codebase against the existing `.harness/` specs and proposes or applies incremental updates.
|
|
131
87
|
|
|
132
|
-
|
|
88
|
+
### `md-to-html-doc`
|
|
133
89
|
|
|
134
|
-
|
|
90
|
+
Converts Markdown architecture and guide documents into responsive HTML output.
|
|
135
91
|
|
|
136
|
-
|
|
92
|
+
## Expected `.harness/` Structure
|
|
93
|
+
|
|
94
|
+
```text
|
|
137
95
|
.harness/
|
|
138
|
-
├── README.md
|
|
96
|
+
├── README.md
|
|
139
97
|
├── index/
|
|
140
|
-
│ ├── routing.md # 任务→上下文路由
|
|
141
|
-
│ ├── priority.md # 注入优先级 (MUST/SHOULD/HINT)
|
|
142
|
-
│ ├── module-map.md # 模块→spec 映射
|
|
143
|
-
│ └── project-profile.md # 项目身份卡片
|
|
144
98
|
├── rules/
|
|
145
|
-
│ ├── architecture.md # 架构约束
|
|
146
|
-
│ ├── coding.md # 编码规范
|
|
147
|
-
│ ├── testing.md # 测试规则
|
|
148
|
-
│ └── security.md # 安全约束
|
|
149
99
|
├── domain/
|
|
150
|
-
│ ├── glossary.md # 领域术语
|
|
151
|
-
│ ├── business-rules.md # 业务规则
|
|
152
|
-
│ └── runtime-semantics.md # 运行时语义
|
|
153
100
|
├── decisions/
|
|
154
|
-
│ ├── adr/ # 架构决策记录
|
|
155
|
-
│ └── tradeoffs.md # 设计权衡
|
|
156
101
|
├── guides/
|
|
157
|
-
│ ├── backend.md # 后端执行手册
|
|
158
|
-
│ └── ops.md # 运维操作指南
|
|
159
102
|
├── memory/
|
|
160
|
-
│ ├── pitfalls.md # 踩坑经验
|
|
161
|
-
│ ├── regressions.md # 回归问题
|
|
162
|
-
│ ├── patterns.md # 可复用模式
|
|
163
|
-
│ └── lessons.md # 经验总结
|
|
164
103
|
└── human-docs/
|
|
165
|
-
├── onboarding.html # 新人手册
|
|
166
|
-
├── architecture-intro.html # 架构介绍
|
|
167
|
-
└── operation-manual.html # 操作手册
|
|
168
104
|
```
|
|
169
105
|
|
|
170
|
-
##
|
|
171
|
-
|
|
172
|
-
| Skill | 说明 |
|
|
173
|
-
|-------|------|
|
|
174
|
-
| `md-to-html-doc` | Markdown 转响应式 HTML(含侧边栏导航、flexbox 流程图) |
|
|
175
|
-
|
|
176
|
-
## 环境要求
|
|
106
|
+
## Requirements
|
|
177
107
|
|
|
178
108
|
- Node.js >= 20
|
|
179
109
|
- Claude Code CLI
|
|
180
|
-
- `@ck123pm/comet
|
|
181
|
-
- `@fission-ai/openspec
|
|
110
|
+
- `@ck123pm/comet` optional
|
|
111
|
+
- `@fission-ai/openspec` optional
|
|
182
112
|
|
|
183
113
|
## License
|
|
184
114
|
|
|
185
|
-
MIT
|
|
115
|
+
MIT
|
package/package.json
CHANGED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: harness-init
|
|
3
|
+
description: Initialize a project's .harness/ directory by deriving high-value project knowledge from the real codebase, splitting content into the expected index/rules/domain/decisions/guides/memory/human-docs structure, and avoiding facts that can be re-derived from source.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Harness Init
|
|
7
|
+
|
|
8
|
+
Use this skill when the user wants to initialize a project's `.harness/` directory from the current codebase state.
|
|
9
|
+
|
|
10
|
+
## Core Principles
|
|
11
|
+
|
|
12
|
+
1. Do not record what the AI can cheaply derive from source code.
|
|
13
|
+
2. Split expensive-to-derive knowledge by type and place it in the right file.
|
|
14
|
+
3. Put design decisions, historical reasons, and tradeoffs into `decisions/`.
|
|
15
|
+
4. Put human-oriented docs in `human-docs/` as Markdown first, convert them to HTML with `md-to-html-doc`, then remove the Markdown source if the workflow requires generated HTML only.
|
|
16
|
+
5. Never fabricate content that is not supported by the actual repository state.
|
|
17
|
+
|
|
18
|
+
## Target Directory Structure
|
|
19
|
+
|
|
20
|
+
Create this structure under `.harness/`:
|
|
21
|
+
|
|
22
|
+
```text
|
|
23
|
+
.harness/
|
|
24
|
+
├── README.md
|
|
25
|
+
├── index/
|
|
26
|
+
│ ├── routing.md
|
|
27
|
+
│ ├── priority.md
|
|
28
|
+
│ ├── module-map.md
|
|
29
|
+
│ └── project-profile.md
|
|
30
|
+
├── rules/
|
|
31
|
+
│ ├── architecture.md
|
|
32
|
+
│ ├── coding.md
|
|
33
|
+
│ ├── testing.md
|
|
34
|
+
│ └── security.md
|
|
35
|
+
├── domain/
|
|
36
|
+
│ ├── glossary.md
|
|
37
|
+
│ ├── business-rules.md
|
|
38
|
+
│ └── runtime-semantics.md
|
|
39
|
+
├── decisions/
|
|
40
|
+
│ ├── adr/
|
|
41
|
+
│ └── tradeoffs.md
|
|
42
|
+
├── guides/
|
|
43
|
+
│ ├── backend.md
|
|
44
|
+
│ └── ops.md
|
|
45
|
+
├── memory/
|
|
46
|
+
│ ├── pitfalls.md
|
|
47
|
+
│ ├── regressions.md
|
|
48
|
+
│ ├── patterns.md
|
|
49
|
+
│ └── lessons.md
|
|
50
|
+
└── human-docs/
|
|
51
|
+
├── onboarding.html
|
|
52
|
+
├── architecture-intro.html
|
|
53
|
+
└── operation-manual.html
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Content Routing
|
|
57
|
+
|
|
58
|
+
| Information type | Destination |
|
|
59
|
+
| --- | --- |
|
|
60
|
+
| Project identity, tech stack, module structure, key constants | `index/project-profile.md` |
|
|
61
|
+
| Task-to-context routing | `index/routing.md` |
|
|
62
|
+
| Injection priority and intensity | `index/priority.md` |
|
|
63
|
+
| Module-to-spec mapping | `index/module-map.md` |
|
|
64
|
+
| Architecture constraints, module boundaries, ownership, high-risk chains | `rules/architecture.md` |
|
|
65
|
+
| Coding standards, serialization, locking, conventions | `rules/coding.md` |
|
|
66
|
+
| Test framework, file layout, strategy, fast commands | `rules/testing.md` |
|
|
67
|
+
| Security constraints | `rules/security.md` |
|
|
68
|
+
| Domain terminology | `domain/glossary.md` |
|
|
69
|
+
| Stable business rules | `domain/business-rules.md` |
|
|
70
|
+
| Runtime semantics, state transitions, magic values | `domain/runtime-semantics.md` |
|
|
71
|
+
| External-system runtime semantics, message flow, integration behavior | `guides/backend.md` |
|
|
72
|
+
| Build, startup, logs, config, monitoring, troubleshooting | `guides/ops.md` |
|
|
73
|
+
| ADRs and tradeoffs | `decisions/` |
|
|
74
|
+
| Historical pitfalls, regressions, reusable patterns, lessons | `memory/` |
|
|
75
|
+
|
|
76
|
+
## Exploration Strategy
|
|
77
|
+
|
|
78
|
+
Before writing files, inspect the repository in at least three passes:
|
|
79
|
+
|
|
80
|
+
1. Project metadata and top-level docs: `package.json`, `pom.xml`, `README`, `AGENTS.md`, workspace config.
|
|
81
|
+
2. Module boundaries and entry points: application bootstraps, services, APIs, entities, consumers, producers, config, tests.
|
|
82
|
+
3. Runtime and history signals: external integrations, state machines, queues, locks, transactions, recent commits, regressions.
|
|
83
|
+
|
|
84
|
+
Prefer CodeGraph when it is available. Use local search only when you need literal text or filesystem details.
|
|
85
|
+
|
|
86
|
+
## Execution
|
|
87
|
+
|
|
88
|
+
1. Explore the repository thoroughly and base all outputs on the current branch state.
|
|
89
|
+
2. Create the full `.harness/` tree, even if some files are initially brief.
|
|
90
|
+
3. Keep generated content concise and high-signal.
|
|
91
|
+
4. If `human-docs/` content is needed, write Markdown first, then use `md-to-html-doc` to produce HTML.
|
|
92
|
+
5. Verify the final `.harness/` tree is complete.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: harness-update-spec
|
|
3
|
+
description: Analyze an existing project's .harness/ specs against the current codebase, identify incremental updates or missing specs, and propose focused changes without regenerating everything from scratch.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Harness Update Spec
|
|
7
|
+
|
|
8
|
+
Use this skill when the user wants to inspect whether an existing `.harness/` directory is stale and update it incrementally.
|
|
9
|
+
|
|
10
|
+
## Core Principles
|
|
11
|
+
|
|
12
|
+
1. Use the current `.harness/` content as the baseline and compare it with the real codebase state.
|
|
13
|
+
2. Focus on incremental changes: what changed, what is missing, and what should be amended.
|
|
14
|
+
3. Prefer interactive confirmation when the user wants review-first behavior; otherwise execute the requested updates directly.
|
|
15
|
+
4. Do not add facts that can be cheaply re-derived from source code.
|
|
16
|
+
5. Preserve historical records in `decisions/` and `memory/` by appending when appropriate instead of overwriting blindly.
|
|
17
|
+
|
|
18
|
+
## Analysis Flow
|
|
19
|
+
|
|
20
|
+
### 1. Scan existing `.harness/`
|
|
21
|
+
|
|
22
|
+
Read the current `.harness/` files and build a quick index of:
|
|
23
|
+
|
|
24
|
+
- Which spec files already exist.
|
|
25
|
+
- What each file currently covers.
|
|
26
|
+
- Which expected files are missing.
|
|
27
|
+
|
|
28
|
+
If `.harness/` does not exist, stop and tell the user to initialize it with the `harness-init` skill first.
|
|
29
|
+
|
|
30
|
+
### 2. Re-scan the project
|
|
31
|
+
|
|
32
|
+
Inspect the live repository in at least three passes:
|
|
33
|
+
|
|
34
|
+
1. Tech stack changes: dependency additions, removals, or upgrades.
|
|
35
|
+
2. Module boundary changes: new or removed modules, services, entry points, entities.
|
|
36
|
+
3. Runtime flow changes: new consumers, producers, RPC edges, topics, configs, transactions, locks, external integrations.
|
|
37
|
+
4. High-risk chain changes: new distributed behavior, critical state transitions, external dependencies.
|
|
38
|
+
5. Recent git history: commits that imply architectural or behavior changes.
|
|
39
|
+
|
|
40
|
+
Prefer CodeGraph when it is available.
|
|
41
|
+
|
|
42
|
+
### 3. Derive a diff matrix
|
|
43
|
+
|
|
44
|
+
Map detected changes to spec targets:
|
|
45
|
+
|
|
46
|
+
| Change type | Likely spec target |
|
|
47
|
+
| --- | --- |
|
|
48
|
+
| Dependency or runtime identity changes | `index/project-profile.md` |
|
|
49
|
+
| Module structure changes | `index/module-map.md` |
|
|
50
|
+
| New services, consumers, producers, RPC or message flows | `guides/backend.md` |
|
|
51
|
+
| New runtime semantics or state machines | `domain/runtime-semantics.md` |
|
|
52
|
+
| Architecture boundary changes | `rules/architecture.md` |
|
|
53
|
+
| New design tradeoffs or ADR-worthy decisions | `decisions/tradeoffs.md` or `decisions/adr/` |
|
|
54
|
+
| New domain terms or business rules | `domain/glossary.md`, `domain/business-rules.md` |
|
|
55
|
+
| New pitfalls, regressions, or reusable patterns | `memory/` |
|
|
56
|
+
|
|
57
|
+
### 4. Report proposed updates
|
|
58
|
+
|
|
59
|
+
When the user asks for analysis first, present a compact report that includes:
|
|
60
|
+
|
|
61
|
+
- Newly detected changes.
|
|
62
|
+
- Missing spec files.
|
|
63
|
+
- Which `.harness/` files should be updated and why.
|
|
64
|
+
|
|
65
|
+
If the user asks you to proceed, apply only the selected or clearly necessary updates.
|
|
66
|
+
|
|
67
|
+
### 5. Apply updates
|
|
68
|
+
|
|
69
|
+
When updating:
|
|
70
|
+
|
|
71
|
+
1. Do not rewrite correct existing content without reason.
|
|
72
|
+
2. Append to history-oriented files when that better preserves context.
|
|
73
|
+
3. Keep internal references inside `.harness/` consistent after edits.
|
|
74
|
+
4. Re-run a quick file list check to ensure the directory remains coherent.
|
|
75
|
+
|
|
76
|
+
## Content Routing
|
|
77
|
+
|
|
78
|
+
Reuse the same content-routing rules as `harness-init`:
|
|
79
|
+
|
|
80
|
+
- Project identity goes to `index/project-profile.md`.
|
|
81
|
+
- Data flow and external runtime semantics go to `guides/backend.md`.
|
|
82
|
+
- High-risk chains and boundaries go to `rules/architecture.md`.
|
|
83
|
+
- Decisions and tradeoffs go to `decisions/`.
|
|
84
|
+
- Historical pitfalls, regressions, and patterns go to `memory/`.
|
|
85
|
+
|
|
86
|
+
## Human Docs
|
|
87
|
+
|
|
88
|
+
If you add or refresh `human-docs/` content, write Markdown first and then use `md-to-html-doc` to produce the HTML artifacts expected by the harness.
|
package/src/cli.js
CHANGED
|
@@ -15,7 +15,7 @@ program
|
|
|
15
15
|
|
|
16
16
|
program
|
|
17
17
|
.command('install')
|
|
18
|
-
.description('Install harness
|
|
18
|
+
.description('Install harness skills into Claude')
|
|
19
19
|
.option('--scope <scope>', 'Installation scope: global or local', 'global')
|
|
20
20
|
.option('--skip-comet', 'Skip @ck123pm/comet installation')
|
|
21
21
|
.option('--skip-openspec', 'Skip @fission-ai/openspec installation')
|
|
@@ -39,7 +39,7 @@ program
|
|
|
39
39
|
|
|
40
40
|
program
|
|
41
41
|
.command('update')
|
|
42
|
-
.description('Update installed
|
|
42
|
+
.description('Update installed skill files')
|
|
43
43
|
.option('--check', 'Check for updates without installing')
|
|
44
44
|
.option('--force', 'Force overwrite without prompting')
|
|
45
45
|
.action(async (options) => {
|
|
@@ -49,7 +49,7 @@ program
|
|
|
49
49
|
|
|
50
50
|
program
|
|
51
51
|
.command('uninstall')
|
|
52
|
-
.description('Remove installed
|
|
52
|
+
.description('Remove installed skill files')
|
|
53
53
|
.action(async () => {
|
|
54
54
|
const { default: action } = await import('./commands/uninstall.js');
|
|
55
55
|
await action();
|
package/src/commands/doctor.js
CHANGED
|
@@ -12,19 +12,19 @@ export default async function doctorAction() {
|
|
|
12
12
|
|
|
13
13
|
const checks = [];
|
|
14
14
|
|
|
15
|
-
// Check 1: Claude
|
|
16
|
-
let
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
if (await fs.pathExists(
|
|
20
|
-
|
|
21
|
-
} else if (await fs.pathExists(
|
|
22
|
-
|
|
15
|
+
// Check 1: Claude skill harness-init (check both scopes)
|
|
16
|
+
let initSkillPath = null;
|
|
17
|
+
const globalInitSkill = resolveTargetPath('skills/harness-init/SKILL.md', 'global');
|
|
18
|
+
const localInitSkill = resolveTargetPath('skills/harness-init/SKILL.md', 'local');
|
|
19
|
+
if (await fs.pathExists(globalInitSkill)) {
|
|
20
|
+
initSkillPath = globalInitSkill;
|
|
21
|
+
} else if (await fs.pathExists(localInitSkill)) {
|
|
22
|
+
initSkillPath = localInitSkill;
|
|
23
23
|
}
|
|
24
24
|
checks.push({
|
|
25
|
-
label: 'Claude
|
|
26
|
-
status:
|
|
27
|
-
detail:
|
|
25
|
+
label: 'Claude skill harness-init',
|
|
26
|
+
status: initSkillPath ? 'ok' : 'fail',
|
|
27
|
+
detail: initSkillPath ? `Found at ${initSkillPath}` : 'Not installed',
|
|
28
28
|
fix: 'Run: harness-kit install',
|
|
29
29
|
});
|
|
30
30
|
|
|
@@ -44,19 +44,19 @@ export default async function doctorAction() {
|
|
|
44
44
|
fix: 'Run: harness-kit install',
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
-
// Check 3: Claude
|
|
48
|
-
let
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
if (await fs.pathExists(
|
|
52
|
-
|
|
53
|
-
} else if (await fs.pathExists(
|
|
54
|
-
|
|
47
|
+
// Check 3: Claude skill harness-update-spec (check both scopes)
|
|
48
|
+
let updateSpecSkillPath = null;
|
|
49
|
+
const globalUpdateSpecSkill = resolveTargetPath('skills/harness-update-spec/SKILL.md', 'global');
|
|
50
|
+
const localUpdateSpecSkill = resolveTargetPath('skills/harness-update-spec/SKILL.md', 'local');
|
|
51
|
+
if (await fs.pathExists(globalUpdateSpecSkill)) {
|
|
52
|
+
updateSpecSkillPath = globalUpdateSpecSkill;
|
|
53
|
+
} else if (await fs.pathExists(localUpdateSpecSkill)) {
|
|
54
|
+
updateSpecSkillPath = localUpdateSpecSkill;
|
|
55
55
|
}
|
|
56
56
|
checks.push({
|
|
57
|
-
label: 'Claude
|
|
58
|
-
status:
|
|
59
|
-
detail:
|
|
57
|
+
label: 'Claude skill harness-update-spec',
|
|
58
|
+
status: updateSpecSkillPath ? 'ok' : 'fail',
|
|
59
|
+
detail: updateSpecSkillPath ? `Found at ${updateSpecSkillPath}` : 'Not installed',
|
|
60
60
|
fix: 'Run: harness-kit install',
|
|
61
61
|
});
|
|
62
62
|
|
|
@@ -109,7 +109,7 @@ export default async function doctorAction() {
|
|
|
109
109
|
label: '.harness/',
|
|
110
110
|
status: harnessExists ? 'ok' : 'fail',
|
|
111
111
|
detail: harnessExists ? 'Project initialized' : 'Not found',
|
|
112
|
-
fix: '
|
|
112
|
+
fix: 'Ask Claude to use the harness-init skill',
|
|
113
113
|
});
|
|
114
114
|
|
|
115
115
|
// Check 8: .comet.yaml
|
|
@@ -119,7 +119,7 @@ export default async function doctorAction() {
|
|
|
119
119
|
label: '.comet.yaml',
|
|
120
120
|
status: cometYamlExists ? 'ok' : 'fail',
|
|
121
121
|
detail: cometYamlExists ? 'Found' : 'Not found',
|
|
122
|
-
fix: '
|
|
122
|
+
fix: 'Ask Claude to use the harness-init skill or run comet init',
|
|
123
123
|
});
|
|
124
124
|
|
|
125
125
|
// Check 8: openspec/
|
package/src/commands/install.js
CHANGED
|
@@ -25,7 +25,7 @@ export default async function installAction(options) {
|
|
|
25
25
|
await ensureClaudeDirs(claudeDir);
|
|
26
26
|
|
|
27
27
|
// Step 2: Copy files
|
|
28
|
-
console.log(chalk.bold('Installing
|
|
28
|
+
console.log(chalk.bold('Installing skills:'));
|
|
29
29
|
const fileResults = [];
|
|
30
30
|
|
|
31
31
|
for (const mapping of FILE_MAPPINGS) {
|
|
@@ -113,5 +113,5 @@ export default async function installAction(options) {
|
|
|
113
113
|
// Step 6: Summary
|
|
114
114
|
console.log(chalk.bold.green('\n✅ Installation complete!\n'));
|
|
115
115
|
console.log('Next step:');
|
|
116
|
-
console.log(chalk.cyan(' Open Claude and
|
|
116
|
+
console.log(chalk.cyan(' Open Claude and ask it to use the harness-init skill to initialize your project\n'));
|
|
117
117
|
}
|
package/src/utils/registry.js
CHANGED
|
@@ -10,12 +10,12 @@ export const PACKAGE_ROOT = path.resolve(__dirname, '..', '..');
|
|
|
10
10
|
|
|
11
11
|
export const FILE_MAPPINGS = [
|
|
12
12
|
{
|
|
13
|
-
source: '
|
|
14
|
-
target: '
|
|
13
|
+
source: 'skills/harness-init',
|
|
14
|
+
target: 'skills/harness-init',
|
|
15
15
|
},
|
|
16
16
|
{
|
|
17
|
-
source: '
|
|
18
|
-
target: '
|
|
17
|
+
source: 'skills/harness-update-spec',
|
|
18
|
+
target: 'skills/harness-update-spec',
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
source: 'skills/md-to-html-doc.md',
|
|
@@ -33,10 +33,54 @@ export function resolveTargetPath(relativeTarget, scope = 'global') {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export async function hashFile(filePath) {
|
|
36
|
+
const stat = await fs.stat(filePath);
|
|
37
|
+
|
|
38
|
+
if (stat.isDirectory()) {
|
|
39
|
+
const hash = createHash('sha256');
|
|
40
|
+
await hashDirectoryInto(hash, filePath, filePath);
|
|
41
|
+
return hash.digest('hex').slice(0, 12);
|
|
42
|
+
}
|
|
43
|
+
|
|
36
44
|
const content = await fs.readFile(filePath);
|
|
37
45
|
return createHash('sha256').update(content).digest('hex').slice(0, 12);
|
|
38
46
|
}
|
|
39
47
|
|
|
48
|
+
async function hashDirectoryInto(hash, rootDir, currentDir) {
|
|
49
|
+
const entries = await fs.readdir(currentDir);
|
|
50
|
+
entries.sort();
|
|
51
|
+
|
|
52
|
+
for (const entry of entries) {
|
|
53
|
+
const fullPath = path.join(currentDir, entry);
|
|
54
|
+
const stat = await fs.stat(fullPath);
|
|
55
|
+
const relativePath = path.relative(rootDir, fullPath).replaceAll('\\', '/');
|
|
56
|
+
|
|
57
|
+
hash.update(relativePath);
|
|
58
|
+
hash.update(stat.isDirectory() ? 'dir' : 'file');
|
|
59
|
+
|
|
60
|
+
if (stat.isDirectory()) {
|
|
61
|
+
await hashDirectoryInto(hash, rootDir, fullPath);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const content = await fs.readFile(fullPath);
|
|
66
|
+
hash.update(content);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function getPathSize(targetPath) {
|
|
71
|
+
const stat = await fs.stat(targetPath);
|
|
72
|
+
if (stat.isFile()) {
|
|
73
|
+
return stat.size;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
let total = 0;
|
|
77
|
+
const entries = await fs.readdir(targetPath);
|
|
78
|
+
for (const entry of entries) {
|
|
79
|
+
total += await getPathSize(path.join(targetPath, entry));
|
|
80
|
+
}
|
|
81
|
+
return total;
|
|
82
|
+
}
|
|
83
|
+
|
|
40
84
|
export function getRecordPath(scope = 'global') {
|
|
41
85
|
const claudeDir = resolveClaudeConfigDir({ scope });
|
|
42
86
|
return path.join(claudeDir, 'harness-kit.json');
|
|
@@ -72,13 +116,12 @@ export async function copyFileRecord(sourceRel, targetRel, { force = false, scop
|
|
|
72
116
|
await ensureClaudeDirs(claudeDir);
|
|
73
117
|
await fs.copy(src, tgt, { overwrite: true });
|
|
74
118
|
const hash = await hashFile(tgt);
|
|
75
|
-
const stat = await fs.stat(tgt);
|
|
76
119
|
|
|
77
120
|
return {
|
|
78
121
|
target: tgt,
|
|
79
122
|
didUpdate: true,
|
|
80
123
|
hash,
|
|
81
|
-
size:
|
|
124
|
+
size: await getPathSize(tgt),
|
|
82
125
|
};
|
|
83
126
|
}
|
|
84
127
|
|
package/commands/harness-init.md
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: harness-init
|
|
3
|
-
description: Initialize .harness/ AI Engineering Harness directory structure, inject actual project code knowledge
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Harness Init
|
|
7
|
-
|
|
8
|
-
Based on the latest code on the current branch, initialize the corresponding files according to the directory structure below.
|
|
9
|
-
|
|
10
|
-
**Core Principles (strictly follow):**
|
|
11
|
-
1. **Don't record what code can derive**: Information the AI can derive directly from source code (class names, method signatures, simple logic) should not be recorded
|
|
12
|
-
2. **Split high-cost derivation info by type**: Project identity goes to `index/project-profile.md`, data flow/message flow and external system runtime semantics (DB/QMQ/RPC/translation service/lock/CAT/Shark) go to `guides/backend.md`, high-risk chains go to `rules/architecture.md`
|
|
13
|
-
3. **Undervable content goes to decisions**: Design decisions, historical reasons, trade-offs (why use magic numbers, why dual type system) go into `decisions/`
|
|
14
|
-
4. **Human-readable content in human-docs/**: onboarding, architecture intro, operation manuals — generate md first, convert to HTML, then delete the md
|
|
15
|
-
5. **Don't hardcode non-existent content**: Must derive from real project code, don't fabricate
|
|
16
|
-
|
|
17
|
-
**Target Directory Structure:**
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
.harness/
|
|
21
|
-
│
|
|
22
|
-
├── README.md
|
|
23
|
-
│ # Harness usage: principles, lifecycle, injection strategy
|
|
24
|
-
│
|
|
25
|
-
├── index/
|
|
26
|
-
│ ├── routing.md
|
|
27
|
-
│ │ # Task/phase/module → which context to inject (most important, decides context routing)
|
|
28
|
-
│ ├── priority.md
|
|
29
|
-
│ │ # Injection priority and intensity: MUST / SHOULD / HINT
|
|
30
|
-
│ ├── module-map.md
|
|
31
|
-
│ │ # Module → rules/domain/guides/memory mapping
|
|
32
|
-
│ └── project-profile.md
|
|
33
|
-
│ # Project identity card: app id, purpose, tech stack, runtime, key entry points, constants
|
|
34
|
-
│
|
|
35
|
-
├── rules/
|
|
36
|
-
│ ├── architecture.md
|
|
37
|
-
│ │ # Architecture constraints: dependency direction, module boundaries, Ownership, high-risk chains, prohibited cross-domain behavior
|
|
38
|
-
│ ├── coding.md
|
|
39
|
-
│ │ # Coding standards: naming, annotations, serialization, distributed locks
|
|
40
|
-
│ ├── testing.md
|
|
41
|
-
│ │ # Test rules: framework, file matching, strategy, fast test commands
|
|
42
|
-
│ └── security.md
|
|
43
|
-
│ # Security constraints: data security, SQL security, concurrency security, external call security
|
|
44
|
-
│
|
|
45
|
-
├── domain/
|
|
46
|
-
│ ├── glossary.md
|
|
47
|
-
│ │ # Domain terminology: core concepts, POI types, category IDs
|
|
48
|
-
│ ├── business-rules.md
|
|
49
|
-
│ │ # Long-term business rules
|
|
50
|
-
│ └── runtime-semantics.md
|
|
51
|
-
│ # Business semantics, state transitions, magic values, runtime rules
|
|
52
|
-
│
|
|
53
|
-
├── decisions/
|
|
54
|
-
│ ├── adr/
|
|
55
|
-
│ │ # Architecture Decision Records
|
|
56
|
-
│ └── tradeoffs.md
|
|
57
|
-
│ # Design tradeoffs: why designed this way, why not change casually
|
|
58
|
-
│
|
|
59
|
-
├── guides/
|
|
60
|
-
│ ├── backend.md
|
|
61
|
-
│ │ # AI execution manual: external system runtime semantics, message flow, new Service/Consumer/Producer, distributed locks, transactions
|
|
62
|
-
│ └── ops.md
|
|
63
|
-
│ # Operations manual: startup modes, logs, builds, config, monitoring, troubleshooting
|
|
64
|
-
│
|
|
65
|
-
├── memory/
|
|
66
|
-
│ ├── pitfalls.md
|
|
67
|
-
│ │ # Historical pitfall experiences
|
|
68
|
-
│ ├── regressions.md
|
|
69
|
-
│ │ # Historical regression issues
|
|
70
|
-
│ ├── patterns.md
|
|
71
|
-
│ │ # Reusable engineering patterns
|
|
72
|
-
│ └── lessons.md
|
|
73
|
-
│ # Long-term experience summary
|
|
74
|
-
│
|
|
75
|
-
└── human-docs/
|
|
76
|
-
├── onboarding.html
|
|
77
|
-
│ # Newcomer onboarding (for humans, not injected to AI)
|
|
78
|
-
├── architecture-intro.html
|
|
79
|
-
│ # Architecture intro for humans (not injected to AI)
|
|
80
|
-
└── operation-manual.html
|
|
81
|
-
# Operation manual for humans (not injected to AI)
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
**Content Split Rules:**
|
|
85
|
-
|
|
86
|
-
| Information Type | Location | Reason |
|
|
87
|
-
|---|---|---|
|
|
88
|
-
| Project identity (app id, tech stack, module structure, key constants) | `index/project-profile.md` | High-frequency access, quick project overview |
|
|
89
|
-
| Data flow/message flow (QMQ Topic, consumption chains) | `guides/backend.md` | Reference when developing new features |
|
|
90
|
-
| External system runtime semantics (DB/QMQ/RPC/translation/lock/CAT/Shark) | `guides/backend.md` | Integration knowledge needed for coding |
|
|
91
|
-
| ops (startup, logs, build, config, monitoring, troubleshooting) | `guides/ops.md` | Operations and publishing |
|
|
92
|
-
| High-risk chains | `rules/architecture.md` | Part of architecture constraints |
|
|
93
|
-
| Module boundaries/Ownership/prohibited cross-domain | `rules/architecture.md` | Part of architecture constraints |
|
|
94
|
-
| Design decisions/tradeoffs | `decisions/` | Understanding "why designed this way" |
|
|
95
|
-
|
|
96
|
-
**Exploration Strategy:**
|
|
97
|
-
|
|
98
|
-
1. Read project metadata: package.json/pom.xml (module structure, dependencies, versions), README.md, AGENTS.md
|
|
99
|
-
2. Identify tech stack: framework versions, RPC mode, database, message queue, cache
|
|
100
|
-
3. Map module boundaries: each module's responsibilities, dependency directions, prohibited behaviors
|
|
101
|
-
4. Deep dive into key code:
|
|
102
|
-
- Service entry points
|
|
103
|
-
- Entity definitions
|
|
104
|
-
- Consumer/Producer (message flow, Topic, serialization mode)
|
|
105
|
-
- Enums and state machines
|
|
106
|
-
- Config files (databases, external services, feature flags)
|
|
107
|
-
- Test structure
|
|
108
|
-
5. Check git history: recent commits, fix records, regressions
|
|
109
|
-
|
|
110
|
-
**Execution Steps:**
|
|
111
|
-
|
|
112
|
-
1. Thoroughly explore the project's real structure (at least 3 rounds: tech stack → modules → data flow/message flow). If codegraph MCP is available, prefer using it.
|
|
113
|
-
2. Create all `.harness/` directories and files based on actual code content, split info by content rules
|
|
114
|
-
3. For `human-docs/`, write `.md` first, then call `md-to-html-doc` skill to convert to `.html`, then delete `.md`
|
|
115
|
-
4. After completion, verify directory structure is complete
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: harness-update-spec
|
|
3
|
-
description: Analyze current project state and derive whether .harness/ specs need updating, provide interactive suggestions
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Harness Update Spec
|
|
7
|
-
|
|
8
|
-
基于当前项目最新代码状态,分析 `.harness/` 目录中的 spec 是否需要更新或新增。
|
|
9
|
-
|
|
10
|
-
**核心原则(严格遵守)**:
|
|
11
|
-
1. **对比驱动**:以 `.harness/` 现有内容为基准,对比当前代码真实状态
|
|
12
|
-
2. **增量更新**:只关注"什么变了"和"什么缺失了",不重新生成全部内容
|
|
13
|
-
3. **交互式建议**:列出变更候选项,用户确认后逐个执行
|
|
14
|
-
4. **不记录可推导信息**:AI 能从源码直接推导的信息不写入 spec
|
|
15
|
-
|
|
16
|
-
## 分析流程
|
|
17
|
-
|
|
18
|
-
### 第一步:扫描现有 .harness/ 内容
|
|
19
|
-
|
|
20
|
-
读取当前 `.harness/` 目录下的所有文件,建立内容索引:
|
|
21
|
-
- 每个文件的主题、关键声明、版本号(如有)
|
|
22
|
-
- 识别出哪些 spec 存在、哪些缺失
|
|
23
|
-
|
|
24
|
-
### 第二步:探索项目当前状态
|
|
25
|
-
|
|
26
|
-
至少 3 轮深入探索(如果存在 codegraph 则优先使用 codegraph MCP):
|
|
27
|
-
|
|
28
|
-
1. **技术栈变更**:package.json/pom.xml 的依赖新增/删除/升级
|
|
29
|
-
2. **模块边界变更**:新增/删除/重构的模块、服务入口、实体
|
|
30
|
-
3. **数据流/消息流变更**:新的 Consumer/Producer、RPC 调用、Topic
|
|
31
|
-
4. **高风险链路变更**:新的分布式锁、事务、外部集成
|
|
32
|
-
5. **Git 近期变更**:最近 commit message 中暗示的架构调整
|
|
33
|
-
|
|
34
|
-
### 第三步:推导差异矩阵
|
|
35
|
-
|
|
36
|
-
| 变更类型 | 影响 spec | 推导信号 |
|
|
37
|
-
|---|---|---|
|
|
38
|
-
| 新依赖 | `index/project-profile.md` | package.json/pom.xml 新增重要依赖 |
|
|
39
|
-
| 新模块 | `index/module-map.md` | 新目录/新 Maven module |
|
|
40
|
-
| 新服务入口 | `guides/backend.md` | 新 Consumer/Producer/Service |
|
|
41
|
-
| 新 RPC/DB/QMQ 集成 | `guides/backend.md` | 新配置、新 Topic、新 Entity |
|
|
42
|
-
| 新枚举/状态 | `domain/runtime-semantics.md` | 新增枚举类、状态定义 |
|
|
43
|
-
| 架构变更 | `rules/architecture.md` | 模块间依赖方向变化 |
|
|
44
|
-
| 新设计决策 | `decisions/tradeoffs.md` | commit message 中的权衡记录 |
|
|
45
|
-
| 新项目身份 | `index/project-profile.md` | 应用号、环境、关键常量变更 |
|
|
46
|
-
| 新业务术语 | `domain/glossary.md` | 新增领域概念 |
|
|
47
|
-
| 新项目业务规则 | `domain/business-rules.md` | 新的长期业务逻辑 |
|
|
48
|
-
| 新踩坑经验 | `memory/pitfalls.md` | 近期修复的问题 |
|
|
49
|
-
| 新回归问题 | `memory/regressions.md` | 回归修复记录 |
|
|
50
|
-
| 新模式 | `memory/patterns.md` | 可复用的新代码模式 |
|
|
51
|
-
|
|
52
|
-
### 第四步:交互式建议
|
|
53
|
-
|
|
54
|
-
以表格形式列出所有候选更新项:
|
|
55
|
-
|
|
56
|
-
```
|
|
57
|
-
🔍 harness-update-spec 分析报告
|
|
58
|
-
|
|
59
|
-
发现的变更(5 项):
|
|
60
|
-
|
|
61
|
-
# 类型 影响 spec 信号
|
|
62
|
-
─── ───────── ────────────────────────────────── ──────────────────────
|
|
63
|
-
1 新增 guides/backend.md 新增 QMQ Topic: order.create
|
|
64
|
-
2 变更 index/project-profile.md 新增依赖: @elastic/elasticsearch v8.x
|
|
65
|
-
3 缺失 domain/runtime-semantics.md 存在 OrderState 枚举但未记录
|
|
66
|
-
4 变更 rules/architecture.md module-a 开始依赖 module-c
|
|
67
|
-
5 新增 memory/pitfalls.md 修复了分布式锁超时问题 (#1234)
|
|
68
|
-
|
|
69
|
-
缺失的 spec(2 项):
|
|
70
|
-
~ decisions/tradeoffs.md 不存在,可能有新设计决策
|
|
71
|
-
~ memory/patterns.md 不存在,可能有新模式
|
|
72
|
-
|
|
73
|
-
请选择要执行的操作:
|
|
74
|
-
A. 全部更新
|
|
75
|
-
B. 交互式选择(逐项确认)
|
|
76
|
-
C. 取消
|
|
77
|
-
|
|
78
|
-
输入 [A/B/C]:
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
### 第五步:执行更新
|
|
82
|
-
|
|
83
|
-
根据用户选择执行:
|
|
84
|
-
|
|
85
|
-
**A. 全部更新**:
|
|
86
|
-
- 逐个生成/更新对应 spec 文件
|
|
87
|
-
- 遵循内容拆分规则
|
|
88
|
-
- 完成后用 `find .harness -type f | sort` 验证
|
|
89
|
-
|
|
90
|
-
**B. 交互式选择**:
|
|
91
|
-
- 逐项列出变更
|
|
92
|
-
- 每次询问用户是否更新该项
|
|
93
|
-
- 用户确认后执行该项更新
|
|
94
|
-
|
|
95
|
-
**C. 取消**:
|
|
96
|
-
- 打印摘要后退出
|
|
97
|
-
|
|
98
|
-
### 第六步:human-docs 处理
|
|
99
|
-
|
|
100
|
-
如果新增了 human-docs/ 下的内容:
|
|
101
|
-
1. 先写 `.md` 文件
|
|
102
|
-
2. 调用 `md-to-html-doc` skill 转 `.html`
|
|
103
|
-
3. 删除 `.md` 原文件
|
|
104
|
-
|
|
105
|
-
## 内容拆分规则(复用 harness-init)
|
|
106
|
-
|
|
107
|
-
| 信息类型 | 存放位置 |
|
|
108
|
-
|---|---|
|
|
109
|
-
| 项目身份(应用号、技术栈、模块结构、关键常量) | `index/project-profile.md` |
|
|
110
|
-
| 数据流/消息流(QMQ Topic、消费链路) | `guides/backend.md` |
|
|
111
|
-
| 外部系统运行语义(DB/QMQ/RPC/翻译服务/锁/CAT/Shark) | `guides/backend.md` |
|
|
112
|
-
| 高风险链路 | `rules/architecture.md` |
|
|
113
|
-
| 模块边界/Ownership/禁止跨域行为 | `rules/architecture.md` |
|
|
114
|
-
| 设计决策/权衡 | `decisions/` |
|
|
115
|
-
| 历史踩坑/回归/模式 | `memory/` |
|
|
116
|
-
|
|
117
|
-
## 更新时的注意事项
|
|
118
|
-
|
|
119
|
-
- **不要覆盖已有的正确内容**:只新增和变更部分
|
|
120
|
-
- **保留历史记录**:如果是 ADR 或 memory 类 spec,追加而非覆盖
|
|
121
|
-
- **验证一致性**:更新后检查 `.harness/` 内部引用是否一致
|
|
122
|
-
- **如果 .harness/ 不存在**:提示用户先运行 `/harness-init`
|