easy-coding-harness 0.2.1 → 0.3.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/CHANGELOG.md CHANGED
@@ -6,6 +6,16 @@
6
6
  - `y`:常规功能升级
7
7
  - `z`:日常 bug 修复
8
8
 
9
+ ## 0.3.0
10
+
11
+ - 补充 `repository` / `homepage` / `bugs` 包元数据,并把 README 中的 CHANGELOG 链接改为 GitLab 绝对地址,修复 npm 页面相对链接跳转到 404 的问题。
12
+ - README 改为使用导向说明,主线调整为安装、两阶段初始化、日常 `/ec-workflow` 入口、命令表、平台差异和真实 skill 清单。
13
+ - MEMORY_LONG 门控改由 `easy_coding_state.py transition` 机械下发 `memory_long` 指令,避免短期记忆未超过阈值时被 prompt 误触发长期沉淀。
14
+ - ec-memory 补充短期记忆消费后的删除步骤:成功蒸馏更早条目并更新长期索引后,删除已消费短期文件,仅保留最近 `short_term_keep` 条。
15
+ - 实施 / 审查 / 验证三阶段统一强制子代理:IMPLEMENT 删除"主代理直接实现"分支,`single` / `sequential` / `parallel` 都派子代理(仅编排形态不同——单个串行执行也起子代理),保护主代理上下文不被实现细节污染;REVIEW / VERIFICATION 口径校齐,去掉"改动集大才派子代理"等矛盾表述。
16
+ - 新增 `easy-coding update` 命令:更新全局 CLI 到最新发布版;存量项目仍按需单独执行 `easy-coding upgrade`。
17
+ - 存量项目需要执行 `easy-coding upgrade` 才能拿到新的 hook 与 skill 模板。
18
+
9
19
  ## 0.2.1
10
20
 
11
21
  - 新增 `easy_coding_state.py` 运行时状态 API,统一收口当前任务指针、任务状态、阶段流转、关闭/完成、`repo_paths` 等读写入口。
package/README.md CHANGED
@@ -1,23 +1,16 @@
1
1
  # Easy Coding Harness
2
2
 
3
- 把"AI 编码 Harness"一键安装到各 agent 平台标准目录的 CLI 脚手架。在项目里跑一次
4
- `easy-coding init`,按所选平台把 skills / hooks / 子代理 / 主约束文件写入平台标准目录,
5
- agent 原生识别——用 `/ec-`(Claude Code / Qoder)或 `$ec-`(Codex)即可调用。
3
+ Easy Coding Harness 是一个 CLI 脚手架,用来把 Easy Coding 工作流安装到 Claude Code、Codex、Qoder 的原生目录。它只负责部署 skills、hooks、子代理、主约束文件和 `.easy-coding/` 运行时骨架,不分析项目代码;项目理解由安装后的 agent 通过 `ec-init` 完成。
6
4
 
7
- ## 核心理念
8
-
9
- - **平台标准目录**:skills / hooks / agents 写进 `.claude/`、`.agents/` + `.codex/`、
10
- `.qoder/`,复用 agent 已有的发现机制,不造新轮子。
11
- - **运行时 dead-drop**:`.easy-coding/` 存放 config / state / tasks / memory,所有产物
12
- 平台无关。换 agent、跨会话,信息零损失。
13
- - **约束即护城河**:8 阶段状态机 + 2 终态,WAITING_CONFIRM 与 VERIFICATION 是硬门控,
14
- "没跑过的命令不算通过"。
5
+ 下文默认用 `/ec-*` 表示 Claude Code / Qoder 的触发方式;Codex 中对应使用 `$ec-*`。
15
6
 
16
7
  ## 安装
17
8
 
18
9
  ```bash
19
- # 方式一:源码(开发者 / 内网)
20
- git clone <repo> && cd easy-coding-harness && ./install.sh
10
+ # 方式一:源码安装(开发者 / 内网)
11
+ git clone <repo>
12
+ cd easy-coding-harness
13
+ ./install.sh
21
14
 
22
15
  # 方式二:npm 正式环境(latest)
23
16
  npm install -g easy-coding-harness
@@ -28,89 +21,138 @@ npm install -g easy-coding-harness@beta
28
21
  easy-coding --version
29
22
  ```
30
23
 
31
- 三种方式都注册全局命令 `easy-coding`,效果一致。
24
+ `0.x.x` 仍按内测版本管理时,优先使用 `easy-coding-harness@beta`;正式发布后使用默认 `latest` 安装命令。
32
25
 
33
- 当前 `0.x.x` 版本仍为内测版本时,优先使用 `beta` dist-tag;正式发布后使用默认 latest 安装命令。
26
+ ## 快速开始
34
27
 
35
- ## 版本
28
+ 1. 在目标项目根目录安装 harness 文件:
36
29
 
37
- 版本号严格使用 `x.y.z`:
30
+ ```bash
31
+ easy-coding init
32
+ ```
38
33
 
39
- - `x`:大的功能迭代;`0.x.x` 表示内测版本
40
- - `y`:常规功能升级
41
- - `z`:日常 bug 修复
34
+ 默认安装 Claude Code 支持。需要指定平台时:
42
35
 
43
- 完整更新日志见 [CHANGELOG.md](CHANGELOG.md)。
36
+ ```bash
37
+ easy-coding init --agent=claude-code,codex,qoder
38
+ ```
44
39
 
45
- ## 命令
40
+ 2. 打开目标 agent,运行项目知识初始化:
46
41
 
47
- | 命令 | 用途 |
48
- |------|------|
49
- | `easy-coding init` | 首次接入。`--agent=claude-code,codex,qoder` 选平台,`-y` 默认 claude-code |
50
- | `easy-coding add-agent` | 给已有项目追加平台支持 |
51
- | `easy-coding upgrade` | CLI 更新后同步项目里的功能文件(生成区覆盖,用户资产不动) |
52
- | `easy-coding status` | 查看已装平台、版本、当前任务状态 |
53
- | `easy-coding clear` | 移除 harness 安装物并保留 tasks / spec / memory / project.yaml;优先按 install manifest 精准清理,旧配置或损坏 manifest 会回退到模板兜底清理 |
42
+ ```text
43
+ /ec-init
44
+ ```
54
45
 
55
- ## 两阶段初始化
46
+ `ec-init` 会让 agent 读取项目,生成 `.easy-coding/SOUL.md`、`.easy-coding/RULES.md`、`.easy-coding/ABSTRACT.md`、`.easy-coding/TEST_STRATEGY.md` 等项目知识文件。这个步骤幂等,重复运行是安全的。
56
47
 
57
- CLI 是纯文件搬运工,不做任何项目分析。初始化分两步:
48
+ 3. 日常开发统一从工作流入口开始:
58
49
 
59
- 1. **CLI** `easy-coding init` —— 装文件 + 建 `project-init` 占位任务。
60
- 2. **Agent** `/ec-init` —— agent 分析代码,生成 SOUL / RULES / ABSTRACT / TEST_STRATEGY,
61
- 自动判断初创 vs 迭代项目。幂等,重复跑安全。
50
+ ```text
51
+ /ec-workflow 实现 xxx 功能
52
+ ```
53
+
54
+ `ec-workflow` 会创建或恢复任务,并按阶段调度分析、实现、审查、验证和记忆归档。
55
+
56
+ ## 工作流
57
+
58
+ ```text
59
+ INIT -> ANALYSIS -> WAITING_CONFIRM -> IMPLEMENT -> REVIEW -> VERIFICATION
60
+ ^ ^ |
61
+ | +---- repair loop -----+
62
+ +--- revision ---+ |
63
+ [user acceptance]
64
+ |
65
+ MEMORY_SHORT -> MEMORY_LONG -> COMPLETE
66
+ any stage --[user abort via ec-task-close]--> CLOSED
67
+ ```
68
+
69
+ - `WAITING_CONFIRM` 是计划确认硬门控,未确认不进入实现。
70
+ - `VERIFICATION` 是验证硬门控,未实际运行的 lint、typecheck、test 不算通过。
71
+ - `MEMORY_SHORT` 写入本次任务短期记忆。
72
+ - `MEMORY_LONG` 只有短期记忆数量超过阈值时才沉淀长期记忆,否则 no-op。
73
+
74
+ ## CLI 命令
75
+
76
+ | 命令 | 用途 |
77
+ | --- | --- |
78
+ | `easy-coding init` | 首次接入项目,安装所选平台的 skills、hooks、agents、主约束和运行时骨架 |
79
+ | `easy-coding add-agent` | 给已接入项目追加 Claude Code、Codex 或 Qoder 支持 |
80
+ | `easy-coding upgrade` | CLI 升级后同步项目内生成文件,生成区覆盖,用户资产保留 |
81
+ | `easy-coding update` | 更新全局 CLI 到最新发布版 |
82
+ | `easy-coding status` | 查看已安装平台、harness 版本、当前任务状态 |
83
+ | `easy-coding clear` | 移除 harness 安装物,保留 tasks、spec、memory、project.yaml 等用户资产 |
62
84
 
63
- 之后日常工作统一走 `/ec-workflow`。
85
+ ## Skill 清单
64
86
 
65
- ## 12 个 skill
87
+ ### 流程 skills
66
88
 
67
89
  | skill | 职责 |
68
- |------|------|
69
- | ec-init | 项目知识初始化(幂等,一次性) |
70
- | ec-workflow | 工作流状态机 + 任务发现/恢复(日常入口) |
71
- | ec-brainstorming | 实现前设计探索(硬设计门,复刻 Superpowers 方法论) |
72
- | ec-analysis | 需求分析 + 执行计划 + 测试策略 |
73
- | ec-implementing | 编码实现 + 子代理并行调度 + 任务卡 |
74
- | ec-reviewing | 多维度审查(accept/fix/replan/blocked) |
75
- | ec-verification | 验证硬闸门 + 用户验收修复循环 |
76
- | ec-memory | 短期滑动窗口 + 长期记忆沉淀(schema v2) |
77
- | ec-task-management | 任务面板(创建 / 列表) |
78
- | ec-task-close | 任务中断与关闭 |
79
- | ec-git | git 操作约束 + 跨仓库提交 |
80
- | ec-meta | harness 自身架构理解 + 本地定制 |
81
-
82
- ## 三平台支持
83
-
84
- | | Claude Code | Codex | Qoder |
85
- |---|---|---|---|
86
- | Skills 目录 | `.claude/skills/` | `.agents/skills/` | `.qoder/skills/` |
87
- | 触发符 | `/` | `$` | `/` |
88
- | Hook 配置 | `.claude/settings.json` | `.codex/hooks.json` | `.qoder/settings.json` |
89
- | 主约束 | `CLAUDE.md` | `AGENTS.md` | `AGENTS.md` |
90
- | 中国版 | — | — | `.qodercn/` |
91
-
92
- 同一份 skill 模板,平台差异通过 `{{placeholder}}` 在安装时解析。
93
-
94
- ## 工作流状态机
90
+ | --- | --- |
91
+ | `ec-workflow` | 统一入口,负责任务创建、恢复、阶段流转和 stage skill 调度 |
92
+ | `ec-brainstorming` | 实现前的设计探索和方案发散 |
93
+ | `ec-analysis` | 生成 dev-spec、执行计划和测试策略 |
94
+ | `ec-implementing` | 按确认后的计划执行代码实现 |
95
+ | `ec-reviewing` | 多维度代码审查,输出 accept / fix / replan / blocked 结论 |
96
+ | `ec-verification` | 执行 lint、typecheck、test 等验证硬门控,并处理验收修复循环 |
97
+ | `ec-memory` | 写短期记忆,并在超过阈值时沉淀长期记忆 |
98
+ | `ec-task-management` | 查看、创建、选择、恢复任务 |
99
+ | `ec-task-close` | 用户主动中断任务并关闭 |
100
+ | `ec-git` | 约束 git diff、commit、push、跨仓库提交等交付动作 |
101
+
102
+ ### 内置 skills
95
103
 
96
- ```
97
- INIT ANALYSIS WAITING_CONFIRM → IMPLEMENT → REVIEW → VERIFICATION
98
- ↑ │
99
- └──── 修复循环 ────────┘
100
- [用户验收]
101
- MEMORY_SHORT → MEMORY_LONG → COMPLETE
102
- 任何阶段 ──[用户中断]──→ CLOSED
104
+ | skill | 职责 |
105
+ | --- | --- |
106
+ | `ec-init` | 项目知识初始化和升级后的知识适配 |
107
+ | `ec-meta` | 理解 harness 自身架构、平台文件和本地定制方式 |
108
+
109
+ ## 平台支持
110
+
111
+ | 平台 | Skills 目录 | 触发符 | Hook 配置 | 主约束 |
112
+ | --- | --- | --- | --- | --- |
113
+ | Claude Code | `.claude/skills/` | `/` | `.claude/settings.json` | `CLAUDE.md` |
114
+ | Codex | `.agents/skills/` | `$` | `.codex/hooks.json` | `AGENTS.md` |
115
+ | Qoder | `.qoder/skills/` | `/` | `.qoder/settings.json` | `AGENTS.md` |
116
+ | Qoder 中国版 | `.qodercn/skills/` | `/` | `.qodercn/settings.json` | `AGENTS.md` |
117
+
118
+ 同一份 skill 模板会在安装时根据平台替换 `{{placeholder}}`,因此日常使用遵循各平台自己的触发符和目录约定。
119
+
120
+ ## 升级
121
+
122
+ 全局 CLI 更新后,已接入的项目需要在项目根目录执行:
123
+
124
+ ```bash
125
+ easy-coding upgrade
103
126
  ```
104
127
 
105
- ## 开发
128
+ `upgrade` 会刷新生成区内的 skills、hooks、agents、主约束模板和运行时模板,不会删除已有任务、spec、memory、project.yaml 或项目知识文件。
129
+
130
+ ## 版本与更新日志
131
+
132
+ 版本号使用 `x.y.z`:
133
+
134
+ - `x`:大的功能迭代;`0.x.x` 表示内测版本
135
+ - `y`:常规功能升级
136
+ - `z`:日常 bug 修复
137
+
138
+ 完整更新日志见 [CHANGELOG.md](https://gitlab.alibaba-inc.com/shixin.ysx/easy-coding-harness/-/blob/master/CHANGELOG.md)。
139
+
140
+ ## 开发者命令
106
141
 
107
142
  ```bash
108
143
  npm install
109
- npm run build # tsup 编译 + 拷贝模板到 templates/
110
- npm test # vitest
111
- npm run lint # biome
144
+ npm run build # tsup 编译 + 拷贝 src/templates 到 templates/
145
+ npm test # vitest
146
+ npm run lint # biome check src/
147
+ npm run typecheck # tsc --noEmit
112
148
  ```
113
149
 
114
- 源码结构:`src/commands/`(CLI 命令)、`src/configurators/`(平台配置器)、
115
- `src/templates/`(skills / hooks / 子代理 / 主约束模板)、`src/types/`(运行时数据契约)、
116
- `src/utils/`(文件写入 / 配置 / 分区替换等)。
150
+ 源码结构:
151
+
152
+ | 目录 | 职责 |
153
+ | --- | --- |
154
+ | `src/commands/` | CLI 命令 |
155
+ | `src/configurators/` | Claude Code、Codex、Qoder 平台安装器 |
156
+ | `src/templates/` | skills、hooks、agents、主约束、运行时模板源 |
157
+ | `src/types/` | 运行时状态和平台类型 |
158
+ | `src/utils/` | 文件写入、配置、模板路径、gitignore、marked region 等工具 |
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/cli.ts
4
- import chalk7 from "chalk";
4
+ import chalk8 from "chalk";
5
5
  import { Command } from "commander";
6
6
 
7
7
  // src/commands/add-agent.ts
@@ -1827,10 +1827,40 @@ async function status() {
1827
1827
  }
1828
1828
  }
1829
1829
 
1830
- // src/commands/upgrade.ts
1831
- import path19 from "path";
1830
+ // src/commands/update.ts
1831
+ import { execFileSync } from "child_process";
1832
1832
  import { cancel as cancel3, confirm as confirm3, outro as outro4 } from "@clack/prompts";
1833
1833
  import chalk6 from "chalk";
1834
+ async function update(opts) {
1835
+ renderBanner();
1836
+ const tag = opts.tag ?? "latest";
1837
+ const spec = `${PACKAGE_NAME}@${tag}`;
1838
+ const plan = ["update runs one step:", ` refresh the global CLI: npm install -g ${spec}`].join(
1839
+ "\n"
1840
+ );
1841
+ if (opts.dryRun) {
1842
+ console.log(plan);
1843
+ return;
1844
+ }
1845
+ if (!opts.yes) {
1846
+ const confirmed = await confirm3({
1847
+ message: `Update the global CLI to ${spec}?`,
1848
+ initialValue: true
1849
+ });
1850
+ if (typeof confirmed === "symbol" || !confirmed) {
1851
+ cancel3("Update cancelled.");
1852
+ return;
1853
+ }
1854
+ }
1855
+ console.log(chalk6.cyan(`\u2192 npm install -g ${spec}`));
1856
+ execFileSync("npm", ["install", "-g", spec], { stdio: "inherit" });
1857
+ outro4(chalk6.green("Global CLI updated."));
1858
+ }
1859
+
1860
+ // src/commands/upgrade.ts
1861
+ import path19 from "path";
1862
+ import { cancel as cancel4, confirm as confirm4, outro as outro5 } from "@clack/prompts";
1863
+ import chalk7 from "chalk";
1834
1864
  async function upgrade(opts) {
1835
1865
  renderBanner();
1836
1866
  const cwd = process.cwd();
@@ -1848,7 +1878,7 @@ async function upgrade(opts) {
1848
1878
  }
1849
1879
  const relation = compareVersions(installedVersion, VERSION);
1850
1880
  if (relation === 0) {
1851
- outro4(chalk6.green(`easy-coding harness is already up to date (${VERSION}).`));
1881
+ outro5(chalk7.green(`easy-coding harness is already up to date (${VERSION}).`));
1852
1882
  return;
1853
1883
  }
1854
1884
  if (relation === 1) {
@@ -1868,12 +1898,12 @@ async function upgrade(opts) {
1868
1898
  return;
1869
1899
  }
1870
1900
  if (!opts.yes) {
1871
- const shouldUpgrade = await confirm3({
1901
+ const shouldUpgrade = await confirm4({
1872
1902
  message: "Apply this harness upgrade?",
1873
1903
  initialValue: true
1874
1904
  });
1875
1905
  if (typeof shouldUpgrade === "symbol" || !shouldUpgrade) {
1876
- cancel3("Upgrade cancelled.");
1906
+ cancel4("Upgrade cancelled.");
1877
1907
  return;
1878
1908
  }
1879
1909
  }
@@ -1890,7 +1920,7 @@ async function upgrade(opts) {
1890
1920
  await ensureEasyCodingSessionsIgnored(cwd);
1891
1921
  await updateHarnessVersion(configPath, VERSION);
1892
1922
  await setPendingInitSince(cwd, VERSION);
1893
- outro4(chalk6.green(`easy-coding harness upgraded to ${VERSION}.`));
1923
+ outro5(chalk7.green(`easy-coding harness upgraded to ${VERSION}.`));
1894
1924
  }
1895
1925
 
1896
1926
  // src/cli.ts
@@ -1899,7 +1929,7 @@ function withErrorHandling(fn) {
1899
1929
  try {
1900
1930
  await fn(opts);
1901
1931
  } catch (error) {
1902
- console.error(chalk7.red("Error:"), error instanceof Error ? error.message : error);
1932
+ console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
1903
1933
  if (process.env.EC_DEBUG && error instanceof Error) {
1904
1934
  console.error(error.stack);
1905
1935
  }
@@ -1913,6 +1943,7 @@ program.name("easy-coding").description(PACKAGE_NAME).version(VERSION, "-v, --ve
1913
1943
  program.command("init").description("Initialize easy-coding harness in current project").option("--agent <list>", "Comma-separated platforms: claude-code,codex,qoder").option("-y, --yes", "Skip prompts, use defaults").action(withErrorHandling(init));
1914
1944
  program.command("add-agent").description("Add agent platform support to an existing project").option("--agent <list>", "Comma-separated platforms to add").action(withErrorHandling(addAgent));
1915
1945
  program.command("upgrade").description("Upgrade harness files to current CLI version").option("--dry-run", "Preview changes without applying").option("-y, --yes", "Skip confirmation").action(withErrorHandling(upgrade));
1946
+ program.command("update").description("Refresh the global CLI to the latest published version").option("--tag <tag>", "npm dist-tag or version to install", "latest").option("--dry-run", "Preview the install command without running it").option("-y, --yes", "Skip confirmation").action(withErrorHandling(update));
1916
1947
  program.command("status").description("Show installed agents, version, and tasks").action(withErrorHandling(status));
1917
1948
  program.command("clear").description("Remove installed harness files (skills, hooks, config); keep tasks, spec, memory").option("--dry-run", "Preview what would be removed without deleting").option("-y, --yes", "Skip confirmation").action(withErrorHandling(clear));
1918
1949
  program.parse();