@house365/comate 0.2.7 → 0.2.9

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.md CHANGED
@@ -41,6 +41,15 @@ skills 装到用户级(`~/.agents/skills`),装一次所有项目共用;`
41
41
 
42
42
  装完输入 `/comate` 开始使用,`comate doctor` 可自检。
43
43
 
44
+ ## 更新
45
+
46
+ ```bash
47
+ npm install -g @house365/comate@latest
48
+ cd your-project && comate init
49
+ ```
50
+
51
+ 两步都要跑:`npm` 只换 CLI 本身,skills 是 `comate init` 铺到 `~/.agents/skills` 的,npm 不管。这里的 `@latest` 不能省——本地已装时,不带 tag 的 `npm install -g` 可能认为已满足而不去 registry 取新版。
52
+
44
53
  ## 用法
45
54
 
46
55
  输入 `/comate` 自动探测当前阶段并分派,或直接调用某个阶段 skill。状态记录在每个 change 的 `openspec/changes/<name>/.comate.yaml` 中,支持上下文压缩后断点恢复。
package/bin/init-run.mjs CHANGED
@@ -3,8 +3,10 @@ import { spawn } from 'node:child_process';
3
3
  import { existsSync, readFileSync } from 'node:fs';
4
4
  import { join, resolve } from 'node:path';
5
5
 
6
+ import { findBash } from './doctor.mjs';
6
7
  import {
7
8
  NPM_TIMEOUT_MS,
9
+ capture,
8
10
  SKILLS_TIMEOUT_MS,
9
11
  npmInvocation,
10
12
  openSpecState,
@@ -55,6 +57,19 @@ export async function init(pkgRoot) {
55
57
  return 1;
56
58
  }
57
59
 
60
+ // comate's skills are bash scripts needing associative arrays (bash 4+), and
61
+ // macOS ships 3.2. Fail here rather than installing everything and letting the
62
+ // first /comate call die inside a sourced library.
63
+ const bash = bashVersion();
64
+ if (bash !== null && bash < 4) {
65
+ console.error(
66
+ `\ncomate 的脚本需要 bash >= 4,当前 ${bash === 0 ? '未知版本' : `bash ${bash}.x`}。\n` +
67
+ 'macOS 自带 bash 3.2(授权原因),装一个新的:\n\n brew install bash\n\n' +
68
+ '装好后重跑 comate init。',
69
+ );
70
+ return 3;
71
+ }
72
+
58
73
  const stopSpinner = startSpinner('Initializing…');
59
74
 
60
75
  // 1. OpenSpec CLI — a PATH command, so always global.
@@ -236,6 +251,22 @@ export function banner(version, { ci = isCI() } = {}) {
236
251
  ].join('\n');
237
252
  }
238
253
 
254
+ // Major version of the bash that comate's scripts will actually run under, or
255
+ // null when there is no bash at all — that is doctor's diagnosis to deliver, not
256
+ // a reason to block the install. Windows resolves through findBash so a Git Bash
257
+ // install is not mistaken for the WSL launcher.
258
+ // Parsed from --version rather than `-c 'echo $BASH_VERSINFO'`: capture() runs
259
+ // through a shell on Windows, which swallows the variable before bash sees it.
260
+ export function bashVersion(probe = (bin) => capture(bin, ['--version'])) {
261
+ const bin = process.platform === 'win32' ? findBash() : 'bash';
262
+ if (!bin) return null;
263
+ const out = probe(bin);
264
+ if (out === null) return null;
265
+ // "GNU bash, version 5.2.26(1)-release ..." / macOS: "... version 3.2.57(1)"
266
+ const major = out.match(/version (\d+)\./)?.[1];
267
+ return major === undefined ? 0 : Number(major);
268
+ }
269
+
239
270
  // Every major CI sets CI=true; GITHUB_ACTIONS covers the Actions runner even in
240
271
  // the odd config that doesn't.
241
272
  function isCI() {
package/bin/init.mjs CHANGED
@@ -98,12 +98,16 @@ function run({ command, args, shell }, timeout, { quiet = false } = {}) {
98
98
  return { ok: true };
99
99
  }
100
100
 
101
- function capture(command, args) {
101
+ // shell defaults to off: passing args with shell:true is deprecated in Node 24
102
+ // and is an injection surface, since the args are concatenated rather than
103
+ // escaped. Callers that genuinely need cmd.exe resolution (a bare `openspec`
104
+ // that only exists as openspec.cmd) opt in explicitly.
105
+ function capture(command, args, { shell = false } = {}) {
102
106
  const { status, stdout: out } = spawnSync(command, args, {
103
107
  encoding: 'utf8',
104
108
  stdio: ['ignore', 'pipe', 'ignore'],
105
109
  timeout: 15_000,
106
- shell: process.platform === 'win32',
110
+ ...(shell ? { shell: true } : {}),
107
111
  });
108
112
  return status === 0 ? out.trim() : null;
109
113
  }
@@ -138,7 +142,9 @@ function skillsInvocation(pkgRoot, args) {
138
142
  }
139
143
 
140
144
  function openSpecState() {
141
- const version = capture('openspec', ['--version']);
145
+ // shell:true on Windows: npm installs this as openspec.cmd, which cannot be
146
+ // spawned directly. bashVersion needs no shell — it has a real executable path.
147
+ const version = capture('openspec', ['--version'], { shell: process.platform === 'win32' });
142
148
  if (version === null) return { status: 'missing' };
143
149
  return { status: atLeast(version, MIN_OPENSPEC) ? 'ready' : 'outdated', version };
144
150
  }
@@ -64,6 +64,13 @@ comate 是一个规约驱动、AI 辅助的开发编排器。它将 **OpenSpec**
64
64
 
65
65
  ## 2. 安装与前置条件
66
66
 
67
+ ```bash
68
+ npm install -g @house365/comate
69
+ cd your-project && comate init
70
+ ```
71
+
72
+ `init` 会装好下面 2.2–2.4 的全部内容。本节余下部分用于排查:init 报某项失败时,对照确认要装什么、怎么自查。
73
+
67
74
  ### 2.1 运行环境
68
75
 
69
76
  | 依赖 | 要求 | 检查方式 |
@@ -79,7 +86,9 @@ comate 是一个规约驱动、AI 辅助的开发编排器。它将 **OpenSpec**
79
86
 
80
87
  ```bash
81
88
  npm install -g @fission-ai/openspec@latest
82
- cd <project-root> && openspec init
89
+ # --tools 必填:openspec 靠探测已有 agent 配置目录决定写哪些 tool 文件,
90
+ # 干净项目里探测不到会直接报 No tools detected 退出
91
+ cd <project-root> && openspec init . --tools none
83
92
  openspec list --json # 验证安装
84
93
  ```
85
94
 
@@ -89,7 +98,7 @@ comate 使用以下 OpenSpec 能力(以技能形式调用):`openspec-explo
89
98
 
90
99
  处理技术设计/规划/执行/收尾。comate 的 design、build 和 verify 阶段依赖它。
91
100
 
92
- Superpowers 是一个技能集。按你的平台约定安装。确认以下技能可加载:
101
+ `comate init` 已用 `skills add obra/superpowers -g` 装到用户级。手动补装同理。确认以下技能可加载:
93
102
 
94
103
  - `superpowers:brainstorming`
95
104
  - `superpowers:writing-plans`
@@ -102,7 +111,9 @@ Superpowers 是一个技能集。按你的平台约定安装。确认以下技
102
111
 
103
112
  ### 2.4 comate 本身
104
113
 
105
- 分发方式 = 将完整的 comate 技能目录复制到你的平台技能目录。本项目(Claude Code 插件)使用扁平布局:
114
+ comate 以 npm 包分发(`npm install -g @house365/comate`),`comate init` 通过 skills CLI 装到用户级 `~/.agents/skills`,一次装完所有项目共用,支持 Claude Code、Codex、Cursor 等 70+ agent。
115
+
116
+ 采用扁平布局——每个 phase 是顶层技能目录,而非 `comate/<phase>/` 嵌套。部分 agent(含 Claude Code)只发现顶层目录,扁平是共同可用的最小公倍数:
106
117
 
107
118
  ```
108
119
  skills/
@@ -183,8 +194,8 @@ skills/
183
194
 
184
195
  | 场景 | 处理方式 |
185
196
  |----------|----------|
186
- | `openspec list --json` 失败 | 检查 openspec 安装,提示 `openspec init` |
187
- | 子技能不可用 | 停止流程,提示安装/启用该技能 |
197
+ | `openspec list --json` 失败 | 检查 openspec 安装,提示 `openspec init . --tools none` |
198
+ | 子技能不可用 | 停止流程,提示运行 `comate init` 补装 |
188
199
  | `.comate.yaml` 损坏或缺失 | 以文件状态为真相源,用 `state set` 修复后继续 |
189
200
  | 构建/测试失败 | 回到 build 阶段修复,不要进入 verify |
190
201
  | 变更目录结构不完整 | 按 comate-open 产出物要求补全缺失文件 |
@@ -542,8 +553,8 @@ bash comate/scripts/comate.sh status # 所有活动变更状态
542
553
  | Guard 持续报告 isolation/build_mode 未设置 | 断点恢复时未填写 | 返回 build 阶段完成设置 |
543
554
  | 验证失败后无法推进 | verify_result: fail | 用户先选择修复方案,智能体执行 `state transition <name> verify-fail` 后返回 build |
544
555
  | 变更目录结构不完整 | 流程中断 | 按 comate-open 产出物要求补全 |
545
- | `openspec list --json` 失败 | openspec 未安装或未初始化 | 运行 `openspec init` |
546
- | 子技能不可用 | Superpowers 未安装 | 按平台文档安装 |
556
+ | `openspec list --json` 失败 | openspec 未安装或未初始化 | 运行 `comate init`,或 `openspec init . --tools none` |
557
+ | 子技能不可用 | Superpowers 未安装 | 运行 `comate init` 补装 |
547
558
  | bash 版本过低 | bash < 4(无关联数组) | Windows:Git Bash/WSL;macOS:`brew install bash` |
548
559
  | .sh 文件包含 CRLF | git 配置问题 | 仓库有 `.gitattributes` 强制 `eol=lf`;如已损坏,使用 `dos2unix` |
549
560
  | 脏工作树无法推进 | 未遵循 dirty-worktree 协议 | 按协议归属,暂停并询问用户 |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@house365/comate",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "comate —— OpenSpec + Superpowers 规约驱动的 AI 开发编排器(Agent Skills)",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -75,7 +75,7 @@ agent 做决策只需读本节,其余参见末尾「参考附录」。决策
75
75
 
76
76
  | 场景 | 处理 |
77
77
  |------|------|
78
- | `openspec list --json` 失败 | 检查 openspec 是否安装,提示运行 `openspec init` |
78
+ | `openspec list --json` 失败 | 检查 openspec 是否安装,提示运行 `comate init` |
79
79
  | 子 skill 不可用 | 停止流程,提示安装或启用对应 skill |
80
80
  | `.comate.yaml` 损坏或缺失 | 以文件状态为真相源,用 `bash "$COMATE" state set` 修正后继续 |
81
81
  | 构建/测试失败 | 回 build 阶段修复,不进入 verify |
@@ -2,9 +2,9 @@
2
2
 
3
3
  规范路径:`comate/reference/prerequisites.md`
4
4
 
5
- comate 不附带安装器:OpenSpec 与 Superpowers 需要**手动安装**,comate 本身的分发方式就是「复制 `comate/` 文件夹」。本清单说明需要装什么、怎么自查、怎么补。
5
+ `comate init` 会自动装好 OpenSpec CLI、Superpowers 和 comate 自身,正常情况下不需要手动执行本清单。清单保留下来用于排查:init 报某项失败时,对照这里确认要装什么、怎么自查、怎么补。
6
6
 
7
- > 一键自查:运行 `bash comate/scripts/comate.sh doctor`。它会检查下列大部分项目并给出可执行提示。
7
+ > 一键自查:`comate doctor`(或直接 `bash comate/scripts/comate.sh doctor`)。它会检查下列大部分项目并给出可执行提示。
8
8
 
9
9
  ## 1. 运行环境
10
10
 
@@ -25,10 +25,10 @@ comate 不附带安装器:OpenSpec 与 Superpowers 需要**手动安装**,co
25
25
  npm install -g @fission-ai/openspec@latest
26
26
  ```
27
27
 
28
- 初始化(在项目根目录):
28
+ 初始化(在项目根目录)。`comate init` 已经做过这一步,手动补做时需要 `--tools`:openspec 靠探测已有的 agent 配置目录决定写哪些 tool 文件,干净项目里探测不到会直接报 `No tools detected` 退出。
29
29
 
30
30
  ```bash
31
- openspec init
31
+ openspec init . --tools none
32
32
  ```
33
33
 
34
34
  自查:
@@ -44,7 +44,7 @@ comate 用到的 OpenSpec 能力(以 skill 形式调用):`openspec-explore
44
44
 
45
45
  负责技术设计 / 计划 / 执行 / 收尾。comate 的 design / build / verify 阶段依赖它。
46
46
 
47
- Superpowers 是一组 skill,按你所用平台的约定安装到 skills 目录(如 `.claude/skills/`、`.cursor/skills/`、`~/.config/skills/` 等)。安装后确认下列 skill 可加载:
47
+ `comate init` 已用 `skills add obra/superpowers -g` 装到用户级。手动补装同理。安装后确认下列 skill 可加载:
48
48
 
49
49
  - `superpowers:brainstorming`
50
50
  - `superpowers:writing-plans`
@@ -58,7 +58,9 @@ Superpowers 是一组 skill,按你所用平台的约定安装到 skills 目录
58
58
 
59
59
  ## 4. comate 自身
60
60
 
61
- 分发 = 复制 comate 的全部 skill 目录到目标平台的 skills 目录。本项目(Claude Code 插件)采用**平铺布局**,因为 Claude Code 只发现顶层 skill 目录:
61
+ comate 以 npm 包分发(`npm install -g @house365/comate`),`comate init` 通过 skills CLI 装到用户级 `~/.agents/skills`,一次装完所有项目共用,支持 Claude Code、Codex、Cursor 等 70+ agent。
62
+
63
+ 采用**平铺布局**——每个 phase 是顶层 skill 目录,而非 `comate/<phase>/` 嵌套。部分 agent(含 Claude Code)只发现顶层目录,平铺是共同可用的最小公倍数:
62
64
 
63
65
  ```
64
66
  skills/
@@ -25,6 +25,24 @@
25
25
 
26
26
  set -euo pipefail
27
27
 
28
+ # Must come before sourcing the lib. comate-lib.sh declares associative arrays
29
+ # at load time, which bash 3.2 (what macOS ships as /bin/bash) parses as an
30
+ # ordinary array assignment — the subscript is then evaluated as arithmetic and
31
+ # `set -u` aborts with "schema_version: unbound variable". doctor has its own
32
+ # bash>=4 check, but it never got to run: the source above it already died.
33
+ if [ "${BASH_VERSINFO[0]:-0}" -lt 4 ]; then
34
+ cat >&2 <<EOF
35
+ comate needs bash >= 4 (associative arrays), found ${BASH_VERSION:-unknown}.
36
+
37
+ macOS ships bash 3.2 for licensing reasons. Install a current one:
38
+ brew install bash
39
+
40
+ Then re-run through it, e.g.:
41
+ $(command -v brew >/dev/null 2>&1 && echo "\$(brew --prefix)/bin/bash" || echo /opt/homebrew/bin/bash) $0 $*
42
+ EOF
43
+ exit 3
44
+ fi
45
+
28
46
  SCRIPT_DIR="$(cd "$(dirname "$(readlink -f "$0" 2>/dev/null || echo "$0")")" && pwd)"
29
47
  # shellcheck source=comate-lib.sh
30
48
  . "$SCRIPT_DIR/comate-lib.sh"