harness-engineer 0.1.0
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/LICENSE +21 -0
- package/README.md +176 -0
- package/README.zh-CN.md +174 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +145 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +23 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +66 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +3 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +76 -0
- package/dist/init.js.map +1 -0
- package/dist/presets.d.ts +17 -0
- package/dist/presets.d.ts.map +1 -0
- package/dist/presets.js +2344 -0
- package/dist/presets.js.map +1 -0
- package/dist/render.d.ts +5 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +28 -0
- package/dist/render.js.map +1 -0
- package/dist/status.d.ts +3 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +50 -0
- package/dist/status.js.map +1 -0
- package/dist/tasks.d.ts +4 -0
- package/dist/tasks.d.ts.map +1 -0
- package/dist/tasks.js +121 -0
- package/dist/tasks.js.map +1 -0
- package/dist/types.d.ts +84 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +20 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +108 -0
- package/dist/utils.js.map +1 -0
- package/package.json +63 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 harness-engineer contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# harness-engineer
|
|
2
|
+
|
|
3
|
+
`harness-engineer` is a Codex-first scaffolding CLI for repository-owned agent orchestration workflows.
|
|
4
|
+
|
|
5
|
+
It turns the "harness as files" pattern into a reusable npm package: fixed role definitions, durable memory, runbooks, and task lifecycle artifacts can all be generated into a blank repository with one command.
|
|
6
|
+
|
|
7
|
+
中文说明见 [README.zh-CN.md](./README.zh-CN.md)。
|
|
8
|
+
|
|
9
|
+
> License: [MIT](./LICENSE)
|
|
10
|
+
|
|
11
|
+
## What It Creates
|
|
12
|
+
|
|
13
|
+
- `AGENTS.md` as the short collaboration entrypoint
|
|
14
|
+
- `.codex/config.toml` and fixed role files under `.codex/agents/`
|
|
15
|
+
- durable memory under `.codex/memory/`
|
|
16
|
+
- `docs/index.md` plus runbooks and source-of-truth placeholders
|
|
17
|
+
- task lifecycle folders under `docs/plans/` and `logs/codex/`
|
|
18
|
+
- a machine-readable `harness-engineer.config.json`
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
For published package usage:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm dlx harness-engineer@latest init . \
|
|
26
|
+
--preset generic-software \
|
|
27
|
+
--project-name "Acme Platform" \
|
|
28
|
+
--yes
|
|
29
|
+
|
|
30
|
+
harness-engineer task new 2026-04-02-auth-debug --class B
|
|
31
|
+
harness-engineer status
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
If you are running from this source repository:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pnpm install
|
|
38
|
+
pnpm build
|
|
39
|
+
|
|
40
|
+
node dist/cli.js init . \
|
|
41
|
+
--preset generic-software \
|
|
42
|
+
--project-name "Acme Platform" \
|
|
43
|
+
--yes
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Install From npm
|
|
47
|
+
|
|
48
|
+
Without cloning this repository, users can initialize a project directly from npm:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
pnpm dlx harness-engineer@latest init . \
|
|
52
|
+
--preset generic-software \
|
|
53
|
+
--project-name "Acme Platform" \
|
|
54
|
+
--language bilingual \
|
|
55
|
+
--yes
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Or install it into a project first:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npm install -D harness-engineer
|
|
62
|
+
npx harness-engineer init . --preset generic-software --project-name "Acme Platform"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Presets
|
|
66
|
+
|
|
67
|
+
### `generic-software`
|
|
68
|
+
|
|
69
|
+
The default preset for Codex-driven software repositories.
|
|
70
|
+
|
|
71
|
+
Fixed roles:
|
|
72
|
+
|
|
73
|
+
- `architect-backend`
|
|
74
|
+
- `architect-frontend`
|
|
75
|
+
- `runtime-integrations`
|
|
76
|
+
- `product-ui`
|
|
77
|
+
- `reviewer`
|
|
78
|
+
- `qa-guard`
|
|
79
|
+
|
|
80
|
+
Truth-source docs live under `docs/source-of-truth/`.
|
|
81
|
+
|
|
82
|
+
### `agentadmin-codex`
|
|
83
|
+
|
|
84
|
+
A compatibility preset extracted from the AgentAdmin harness structure.
|
|
85
|
+
|
|
86
|
+
It keeps the AgentAdmin-specific document layering (`dev-docs/ + spec/`) and the original fixed role names:
|
|
87
|
+
|
|
88
|
+
- `architect-backend`
|
|
89
|
+
- `architect-frontend`
|
|
90
|
+
- `runtime-executor`
|
|
91
|
+
- `console-ui`
|
|
92
|
+
- `reviewer`
|
|
93
|
+
- `qa-guard`
|
|
94
|
+
|
|
95
|
+
## CLI
|
|
96
|
+
|
|
97
|
+
### `init`
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
harness-engineer init [dir] \
|
|
101
|
+
--preset <preset> \
|
|
102
|
+
--project-name <name> \
|
|
103
|
+
[--language en|zh|bilingual] \
|
|
104
|
+
[--dev-command "<cmd>"] \
|
|
105
|
+
[--force] \
|
|
106
|
+
[--yes]
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Notes:
|
|
110
|
+
|
|
111
|
+
- Generates files only when missing by default.
|
|
112
|
+
- Use `--force` to overwrite managed templates.
|
|
113
|
+
- `--dev-command` generates `.codex/environments/environment.toml`.
|
|
114
|
+
- `init` also adds `harness-engineer` to `devDependencies`.
|
|
115
|
+
- `--language bilingual` keeps the base `AGENTS.md` canonical and adds a bilingual `AGENTS.override.md` plus localized core harness docs.
|
|
116
|
+
|
|
117
|
+
### `task new`
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
harness-engineer task new <slug> --class A|B|C
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Creates:
|
|
124
|
+
|
|
125
|
+
- `docs/plans/active/<slug>.md`
|
|
126
|
+
- `logs/codex/active/<slug>/run.md`
|
|
127
|
+
- `logs/codex/active/<slug>/handoff.md`
|
|
128
|
+
|
|
129
|
+
### `task archive`
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
harness-engineer task archive <slug>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Moves the task from active to completed and appends completion sections to the plan if needed.
|
|
136
|
+
|
|
137
|
+
### `status`
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
harness-engineer status
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Reports:
|
|
144
|
+
|
|
145
|
+
- active tasks
|
|
146
|
+
- missing managed files
|
|
147
|
+
- drifted managed files
|
|
148
|
+
- inconsistent task artifacts
|
|
149
|
+
|
|
150
|
+
## Local Development
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
pnpm install
|
|
154
|
+
pnpm test
|
|
155
|
+
pnpm test:coverage
|
|
156
|
+
pnpm build
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
The package is intentionally source-first. `dist/`, `coverage/`, and `node_modules/` are generated locally and are not meant to be committed.
|
|
160
|
+
|
|
161
|
+
## Testing Strategy
|
|
162
|
+
|
|
163
|
+
- unit tests for rendering, config helpers, and preset selection
|
|
164
|
+
- integration tests for init, task lifecycle, CLI smoke flow, and status drift detection
|
|
165
|
+
- a self-contained AgentAdmin compatibility snapshot test under `tests/integration/agentadmin-golden.test.ts`
|
|
166
|
+
|
|
167
|
+
## Repository Layout
|
|
168
|
+
|
|
169
|
+
```text
|
|
170
|
+
src/ source code for the CLI and generators
|
|
171
|
+
tests/ unit, integration, and fixture-backed compatibility tests
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## Open-Source Release Notes
|
|
175
|
+
|
|
176
|
+
Before publishing updates, review [OPEN_SOURCE_RELEASE_CHECKLIST.md](./OPEN_SOURCE_RELEASE_CHECKLIST.md).
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# harness-engineer
|
|
2
|
+
|
|
3
|
+
`harness-engineer` 是一个面向 Codex 的仓库协作脚手架 CLI,用来把“harness 作为文件结构”的工作方式封装成可复用 npm 包。
|
|
4
|
+
|
|
5
|
+
它可以在一个空白仓库里一次性生成固定角色、长期记忆、runbook、任务计划与 handoff 结构,适合团队把 AI 协作流程沉淀为仓库内真源。
|
|
6
|
+
|
|
7
|
+
> 许可证:[MIT](./LICENSE)
|
|
8
|
+
|
|
9
|
+
## 它会生成什么
|
|
10
|
+
|
|
11
|
+
- `AGENTS.md` 作为最短协作入口
|
|
12
|
+
- `.codex/config.toml` 和 `.codex/agents/` 下的固定角色文件
|
|
13
|
+
- `.codex/memory/` 下的长期记忆
|
|
14
|
+
- `docs/index.md`、runbook 和真源文档占位
|
|
15
|
+
- `docs/plans/` 与 `logs/codex/` 下的任务闭环目录
|
|
16
|
+
- 机器可读配置 `harness-engineer.config.json`
|
|
17
|
+
|
|
18
|
+
## 快速开始
|
|
19
|
+
|
|
20
|
+
发布后推荐这样使用:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pnpm dlx harness-engineer@latest init . \
|
|
24
|
+
--preset generic-software \
|
|
25
|
+
--project-name "Acme Platform" \
|
|
26
|
+
--yes
|
|
27
|
+
|
|
28
|
+
harness-engineer task new 2026-04-02-auth-debug --class B
|
|
29
|
+
harness-engineer status
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
如果你是在当前源码仓库里本地运行:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pnpm install
|
|
36
|
+
pnpm build
|
|
37
|
+
|
|
38
|
+
node dist/cli.js init . \
|
|
39
|
+
--preset generic-software \
|
|
40
|
+
--project-name "Acme Platform" \
|
|
41
|
+
--yes
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 直接从 npm 使用
|
|
45
|
+
|
|
46
|
+
用户不需要 clone 当前仓库,也可以直接从 npm 初始化项目:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pnpm dlx harness-engineer@latest init . \
|
|
50
|
+
--preset generic-software \
|
|
51
|
+
--project-name "Acme Platform" \
|
|
52
|
+
--language bilingual \
|
|
53
|
+
--yes
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
也可以先安装到项目里:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npm install -D harness-engineer
|
|
60
|
+
npx harness-engineer init . --preset generic-software --project-name "Acme Platform"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## 预设
|
|
64
|
+
|
|
65
|
+
### `generic-software`
|
|
66
|
+
|
|
67
|
+
默认的通用 Codex 软件仓库预设。
|
|
68
|
+
|
|
69
|
+
固定角色:
|
|
70
|
+
|
|
71
|
+
- `architect-backend`
|
|
72
|
+
- `architect-frontend`
|
|
73
|
+
- `runtime-integrations`
|
|
74
|
+
- `product-ui`
|
|
75
|
+
- `reviewer`
|
|
76
|
+
- `qa-guard`
|
|
77
|
+
|
|
78
|
+
真源文档落在 `docs/source-of-truth/`。
|
|
79
|
+
|
|
80
|
+
### `agentadmin-codex`
|
|
81
|
+
|
|
82
|
+
从 AgentAdmin harness 抽取出来的兼容预设。
|
|
83
|
+
|
|
84
|
+
它保留 AgentAdmin 当前的文档分层方式(`dev-docs/ + spec/`)和固定角色命名:
|
|
85
|
+
|
|
86
|
+
- `architect-backend`
|
|
87
|
+
- `architect-frontend`
|
|
88
|
+
- `runtime-executor`
|
|
89
|
+
- `console-ui`
|
|
90
|
+
- `reviewer`
|
|
91
|
+
- `qa-guard`
|
|
92
|
+
|
|
93
|
+
## CLI 命令
|
|
94
|
+
|
|
95
|
+
### `init`
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
harness-engineer init [dir] \
|
|
99
|
+
--preset <preset> \
|
|
100
|
+
--project-name <name> \
|
|
101
|
+
[--language en|zh|bilingual] \
|
|
102
|
+
[--dev-command "<cmd>"] \
|
|
103
|
+
[--force] \
|
|
104
|
+
[--yes]
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
说明:
|
|
108
|
+
|
|
109
|
+
- 默认只生成缺失文件,不覆盖已有模板。
|
|
110
|
+
- 使用 `--force` 可以覆盖受管理模板。
|
|
111
|
+
- 传入 `--dev-command` 时会生成 `.codex/environments/environment.toml`。
|
|
112
|
+
- `init` 会把 `harness-engineer` 自动加入 `devDependencies`。
|
|
113
|
+
- `--language bilingual` 会保留标准 `AGENTS.md`,并额外生成双语版 `AGENTS.override.md` 与本地化核心 harness 文档。
|
|
114
|
+
|
|
115
|
+
### `task new`
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
harness-engineer task new <slug> --class A|B|C
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
会创建:
|
|
122
|
+
|
|
123
|
+
- `docs/plans/active/<slug>.md`
|
|
124
|
+
- `logs/codex/active/<slug>/run.md`
|
|
125
|
+
- `logs/codex/active/<slug>/handoff.md`
|
|
126
|
+
|
|
127
|
+
### `task archive`
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
harness-engineer task archive <slug>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
会把任务从 active 移到 completed,并在 plan 中补齐结果段落。
|
|
134
|
+
|
|
135
|
+
### `status`
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
harness-engineer status
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
会报告:
|
|
142
|
+
|
|
143
|
+
- 当前 active 任务
|
|
144
|
+
- 缺失的受管理文件
|
|
145
|
+
- 漂移的受管理模板
|
|
146
|
+
- 不一致的任务产物
|
|
147
|
+
|
|
148
|
+
## 本地开发
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
pnpm install
|
|
152
|
+
pnpm test
|
|
153
|
+
pnpm test:coverage
|
|
154
|
+
pnpm build
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
仓库以源码为主,`dist/`、`coverage/` 和 `node_modules/` 都是本地产物,不应该提交。
|
|
158
|
+
|
|
159
|
+
## 测试策略
|
|
160
|
+
|
|
161
|
+
- 单元测试:渲染、配置、预设选择
|
|
162
|
+
- 集成测试:init、任务生命周期、CLI smoke、status 漂移检查
|
|
163
|
+
- 兼容性测试:`tests/integration/agentadmin-golden.test.ts`
|
|
164
|
+
|
|
165
|
+
## 仓库结构
|
|
166
|
+
|
|
167
|
+
```text
|
|
168
|
+
src/ CLI 与生成器源码
|
|
169
|
+
tests/ 单元、集成与 fixture 兼容性测试
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## 开源发布说明
|
|
173
|
+
|
|
174
|
+
准备发布更新前,请先阅读 [OPEN_SOURCE_RELEASE_CHECKLIST.md](./OPEN_SOURCE_RELEASE_CHECKLIST.md)。
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAQA,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,SAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAkFjF"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { initProject } from "./init.js";
|
|
3
|
+
import { readOwnPackageVersion } from "./config.js";
|
|
4
|
+
import { getStatus } from "./status.js";
|
|
5
|
+
import { archiveTask, createTask } from "./tasks.js";
|
|
6
|
+
export async function runCli(argv, cwd = process.cwd()) {
|
|
7
|
+
const [command, ...rest] = argv;
|
|
8
|
+
if (!command || command === "help" || command === "--help" || command === "-h") {
|
|
9
|
+
writeStdout(buildUsage());
|
|
10
|
+
return 0;
|
|
11
|
+
}
|
|
12
|
+
if (command === "init") {
|
|
13
|
+
const { positionals, options } = parseArgs(rest);
|
|
14
|
+
const targetDir = positionals[0] ?? ".";
|
|
15
|
+
const projectName = asRequiredString(options["project-name"], "--project-name is required.");
|
|
16
|
+
const preset = asString(options.preset) ?? "generic-software";
|
|
17
|
+
const languageOption = asString(options.language);
|
|
18
|
+
const language = languageOption ? parseHarnessLanguage(languageOption) : undefined;
|
|
19
|
+
const force = Boolean(options.force);
|
|
20
|
+
const devCommand = asString(options["dev-command"]);
|
|
21
|
+
const packageVersion = await readOwnPackageVersion(import.meta.url);
|
|
22
|
+
const result = await initProject({
|
|
23
|
+
cwd,
|
|
24
|
+
targetDir,
|
|
25
|
+
projectName,
|
|
26
|
+
preset,
|
|
27
|
+
language,
|
|
28
|
+
yes: Boolean(options.yes),
|
|
29
|
+
force,
|
|
30
|
+
devCommand,
|
|
31
|
+
packageVersion,
|
|
32
|
+
});
|
|
33
|
+
writeStdout(`Initialized ${result.targetDir}`);
|
|
34
|
+
writeStdout(`Created: ${result.createdFiles.length}`);
|
|
35
|
+
writeStdout(`Skipped: ${result.skippedFiles.length}`);
|
|
36
|
+
writeStdout(`Overwritten: ${result.overwrittenFiles.length}`);
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
if (command === "task") {
|
|
40
|
+
const [subcommand, ...taskArgs] = rest;
|
|
41
|
+
if (subcommand === "new") {
|
|
42
|
+
const { positionals, options } = parseArgs(taskArgs);
|
|
43
|
+
const slug = positionals[0];
|
|
44
|
+
if (!slug) {
|
|
45
|
+
throw new Error("task new requires a <slug>.");
|
|
46
|
+
}
|
|
47
|
+
const taskClass = (asString(options.class) ?? "B");
|
|
48
|
+
validateTaskClass(taskClass);
|
|
49
|
+
await createTask({
|
|
50
|
+
cwd,
|
|
51
|
+
slug,
|
|
52
|
+
taskClass,
|
|
53
|
+
});
|
|
54
|
+
writeStdout(`Created task "${slug}".`);
|
|
55
|
+
return 0;
|
|
56
|
+
}
|
|
57
|
+
if (subcommand === "archive") {
|
|
58
|
+
const { positionals } = parseArgs(taskArgs);
|
|
59
|
+
const slug = positionals[0];
|
|
60
|
+
if (!slug) {
|
|
61
|
+
throw new Error("task archive requires a <slug>.");
|
|
62
|
+
}
|
|
63
|
+
await archiveTask({ cwd, slug });
|
|
64
|
+
writeStdout(`Archived task "${slug}".`);
|
|
65
|
+
return 0;
|
|
66
|
+
}
|
|
67
|
+
throw new Error(`Unknown task subcommand "${subcommand ?? ""}".`);
|
|
68
|
+
}
|
|
69
|
+
if (command === "status") {
|
|
70
|
+
const status = await getStatus(cwd);
|
|
71
|
+
writeStdout(`Config: ${status.configPath}`);
|
|
72
|
+
writeStdout(`Active tasks: ${status.activeTasks.length === 0 ? "none" : status.activeTasks.join(", ")}`);
|
|
73
|
+
writeStdout(`Missing managed files: ${status.missingManagedFiles.length}`);
|
|
74
|
+
writeStdout(`Drifted managed files: ${status.driftedManagedFiles.length}`);
|
|
75
|
+
writeStdout(`Inconsistent tasks: ${status.inconsistentTasks.length}`);
|
|
76
|
+
return 0;
|
|
77
|
+
}
|
|
78
|
+
throw new Error(`Unknown command "${command}".`);
|
|
79
|
+
}
|
|
80
|
+
function buildUsage() {
|
|
81
|
+
return [
|
|
82
|
+
"Usage:",
|
|
83
|
+
" harness-engineer init [dir] --preset <preset> --project-name <name> [--yes] [--force] [--dev-command <cmd>] [--language <en|zh|bilingual>]",
|
|
84
|
+
" harness-engineer task new <slug> --class <A|B|C>",
|
|
85
|
+
" harness-engineer task archive <slug>",
|
|
86
|
+
" harness-engineer status",
|
|
87
|
+
].join("\n");
|
|
88
|
+
}
|
|
89
|
+
function parseArgs(argv) {
|
|
90
|
+
const positionals = [];
|
|
91
|
+
const options = {};
|
|
92
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
93
|
+
const token = argv[index];
|
|
94
|
+
if (!token) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (!token.startsWith("--")) {
|
|
98
|
+
positionals.push(token);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const optionName = token.slice(2);
|
|
102
|
+
const next = argv[index + 1];
|
|
103
|
+
if (!next || next.startsWith("--")) {
|
|
104
|
+
options[optionName] = true;
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
options[optionName] = next;
|
|
108
|
+
index += 1;
|
|
109
|
+
}
|
|
110
|
+
return { positionals, options };
|
|
111
|
+
}
|
|
112
|
+
function asString(value) {
|
|
113
|
+
return typeof value === "string" ? value : undefined;
|
|
114
|
+
}
|
|
115
|
+
function asRequiredString(value, errorMessage) {
|
|
116
|
+
const stringValue = asString(value);
|
|
117
|
+
if (!stringValue) {
|
|
118
|
+
throw new Error(errorMessage);
|
|
119
|
+
}
|
|
120
|
+
return stringValue;
|
|
121
|
+
}
|
|
122
|
+
function validateTaskClass(taskClass) {
|
|
123
|
+
if (!["A", "B", "C"].includes(taskClass)) {
|
|
124
|
+
throw new Error(`Invalid task class "${taskClass}". Use A, B, or C.`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function parseHarnessLanguage(language) {
|
|
128
|
+
if (language === "en" || language === "zh" || language === "bilingual") {
|
|
129
|
+
return language;
|
|
130
|
+
}
|
|
131
|
+
throw new Error(`Invalid language "${language}". Use en, zh, or bilingual.`);
|
|
132
|
+
}
|
|
133
|
+
function writeStdout(message) {
|
|
134
|
+
process.stdout.write(`${message}\n`);
|
|
135
|
+
}
|
|
136
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
137
|
+
runCli(process.argv.slice(2)).then((exitCode) => {
|
|
138
|
+
process.exitCode = exitCode;
|
|
139
|
+
}, (error) => {
|
|
140
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
141
|
+
process.stderr.write(`${message}\n`);
|
|
142
|
+
process.exitCode = 1;
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { HarnessConfig, HarnessRoleConfig } from "./types.js";
|
|
2
|
+
export declare const HARNESS_CONFIG_FILE = "harness-engineer.config.json";
|
|
3
|
+
export interface BuildConfigOptions {
|
|
4
|
+
cwd: string;
|
|
5
|
+
targetDir?: string;
|
|
6
|
+
projectName: string;
|
|
7
|
+
presetKey: string;
|
|
8
|
+
language?: HarnessConfig["language"];
|
|
9
|
+
devCommand?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function buildHarnessConfig(options: BuildConfigOptions): HarnessConfig;
|
|
12
|
+
export declare function loadHarnessConfig(cwd: string): Promise<HarnessConfig>;
|
|
13
|
+
export declare function readOwnPackageVersion(moduleUrl: string): Promise<string>;
|
|
14
|
+
export declare function buildHarnessDependencyVersion(version: string): string;
|
|
15
|
+
export declare function createDefaultPackageJson(projectName: string): {
|
|
16
|
+
name: string;
|
|
17
|
+
version: string;
|
|
18
|
+
private: true;
|
|
19
|
+
devDependencies: Record<string, string>;
|
|
20
|
+
};
|
|
21
|
+
export declare function serializeHarnessConfig(config: HarnessConfig): string;
|
|
22
|
+
export declare function getRoleByKey(config: HarnessConfig, key: string): HarnessRoleConfig;
|
|
23
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAInE,eAAO,MAAM,mBAAmB,iCAAiC,CAAC;AAElE,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,GAAG,aAAa,CAwB7E;AAED,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAO3E;AAED,wBAAsB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS9E;AAED,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErE;AAED,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,IAAI,CAAC;IACd,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC,CAOA;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAEpE;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAOlF"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
|
+
import { getPreset } from "./presets.js";
|
|
4
|
+
import { formatJson, pathExists, readJsonFile, sortPaths, toPackageName } from "./utils.js";
|
|
5
|
+
export const HARNESS_CONFIG_FILE = "harness-engineer.config.json";
|
|
6
|
+
export function buildHarnessConfig(options) {
|
|
7
|
+
const preset = getPreset(options.presetKey);
|
|
8
|
+
const targetDir = resolve(options.cwd, options.targetDir ?? ".");
|
|
9
|
+
const language = options.language ?? preset.defaultLanguage;
|
|
10
|
+
const roles = preset.roles.map((role) => ({ ...role }));
|
|
11
|
+
const truthSources = preset.truthSources.map((source) => ({ ...source }));
|
|
12
|
+
const config = {
|
|
13
|
+
projectName: options.projectName,
|
|
14
|
+
preset: preset.key,
|
|
15
|
+
language,
|
|
16
|
+
version: 1,
|
|
17
|
+
devCommand: options.devCommand ?? null,
|
|
18
|
+
paths: { ...preset.paths },
|
|
19
|
+
roles,
|
|
20
|
+
truthSources,
|
|
21
|
+
managedFiles: [],
|
|
22
|
+
};
|
|
23
|
+
config.managedFiles = sortPaths(preset.buildManagedFiles(config).map((entry) => entry.path));
|
|
24
|
+
void targetDir;
|
|
25
|
+
return config;
|
|
26
|
+
}
|
|
27
|
+
export async function loadHarnessConfig(cwd) {
|
|
28
|
+
const configPath = join(cwd, HARNESS_CONFIG_FILE);
|
|
29
|
+
if (!(await pathExists(configPath))) {
|
|
30
|
+
throw new Error(`Missing ${HARNESS_CONFIG_FILE} in ${cwd}. Run "harness-engineer init" first.`);
|
|
31
|
+
}
|
|
32
|
+
return readJsonFile(configPath);
|
|
33
|
+
}
|
|
34
|
+
export async function readOwnPackageVersion(moduleUrl) {
|
|
35
|
+
try {
|
|
36
|
+
const packageJsonUrl = new URL("../package.json", moduleUrl);
|
|
37
|
+
const contents = await readFile(packageJsonUrl, "utf8");
|
|
38
|
+
const parsed = JSON.parse(contents);
|
|
39
|
+
return parsed.version ?? "latest";
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return "latest";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export function buildHarnessDependencyVersion(version) {
|
|
46
|
+
return version === "latest" ? "latest" : `^${version}`;
|
|
47
|
+
}
|
|
48
|
+
export function createDefaultPackageJson(projectName) {
|
|
49
|
+
return {
|
|
50
|
+
name: toPackageName(projectName),
|
|
51
|
+
version: "0.0.0",
|
|
52
|
+
private: true,
|
|
53
|
+
devDependencies: {},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export function serializeHarnessConfig(config) {
|
|
57
|
+
return formatJson(config);
|
|
58
|
+
}
|
|
59
|
+
export function getRoleByKey(config, key) {
|
|
60
|
+
const role = config.roles.find((candidate) => candidate.key === key);
|
|
61
|
+
if (!role) {
|
|
62
|
+
throw new Error(`Unknown role "${key}" in harness config.`);
|
|
63
|
+
}
|
|
64
|
+
return role;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { runCli } from "./cli.js";
|
|
2
|
+
export { initProject } from "./init.js";
|
|
3
|
+
export { getPreset } from "./presets.js";
|
|
4
|
+
export { renderTemplate } from "./render.js";
|
|
5
|
+
export { getStatus } from "./status.js";
|
|
6
|
+
export { archiveTask, createTask } from "./tasks.js";
|
|
7
|
+
export type { HarnessConfig, HarnessLanguage, HarnessPathsConfig, HarnessRoleConfig, InitOptions, InitResult, StatusResult, TaskArchiveOptions, TaskClass, TaskNewOptions, TruthSourceConfig, } from "./types.js";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACrD,YAAY,EACV,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,YAAY,EACZ,kBAAkB,EAClB,SAAS,EACT,cAAc,EACd,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { runCli } from "./cli.js";
|
|
2
|
+
export { initProject } from "./init.js";
|
|
3
|
+
export { getPreset } from "./presets.js";
|
|
4
|
+
export { renderTemplate } from "./render.js";
|
|
5
|
+
export { getStatus } from "./status.js";
|
|
6
|
+
export { archiveTask, createTask } from "./tasks.js";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/init.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG1D,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CA4C3E"}
|