@rosenfan/matrix 0.1.4 → 0.1.6

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.
Files changed (54) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +41 -40
  3. package/README.zh-CN.md +39 -38
  4. package/{.claude → assets}/skills/matrix/SKILL.md +79 -78
  5. package/{.claude → assets}/skills/matrix/agents/openai.yaml +4 -4
  6. package/{.claude → assets}/skills/matrix/scripts/matrix_claude.py +11 -11
  7. package/{.claude → assets}/skills/matrix/scripts/matrix_state.py +49 -49
  8. package/assets/skills/matrix/scripts/test_matrix_claude.py +69 -0
  9. package/assets/skills/matrix/scripts/test_matrix_state.py +69 -0
  10. package/{.claude → assets}/skills/matrix-archive/SKILL.md +36 -36
  11. package/{.claude/skills/matrix-hotfix → assets/skills/matrix-archive}/agents/openai.yaml +4 -4
  12. package/{.claude → assets}/skills/matrix-build/SKILL.md +41 -41
  13. package/{.claude/skills/matrix-archive → assets/skills/matrix-build}/agents/openai.yaml +4 -4
  14. package/{.claude → assets}/skills/matrix-design/SKILL.md +71 -65
  15. package/{.claude → assets}/skills/matrix-design/agents/openai.yaml +4 -4
  16. package/assets/skills/matrix-handoff/SKILL.md +89 -0
  17. package/{.claude/skills/matrix-claude → assets/skills/matrix-handoff}/agents/openai.yaml +4 -4
  18. package/{.claude → assets}/skills/matrix-hotfix/SKILL.md +8 -8
  19. package/{.claude/skills/matrix-build → assets/skills/matrix-hotfix}/agents/openai.yaml +4 -4
  20. package/{.claude → assets}/skills/matrix-open/SKILL.md +51 -40
  21. package/assets/skills/matrix-open/agents/openai.yaml +4 -0
  22. package/{.claude → assets}/skills/matrix-status/SKILL.md +15 -15
  23. package/{.claude → assets}/skills/matrix-status/agents/openai.yaml +4 -4
  24. package/{.claude → assets}/skills/matrix-tweak/SKILL.md +8 -8
  25. package/assets/skills/matrix-tweak/agents/openai.yaml +4 -0
  26. package/{.claude → assets}/skills/matrix-verify/SKILL.md +62 -62
  27. package/assets/skills/matrix-verify/agents/openai.yaml +4 -0
  28. package/assets/skills-zh-CN/matrix/SKILL.md +72 -71
  29. package/assets/skills-zh-CN/matrix-build/SKILL.md +4 -4
  30. package/assets/skills-zh-CN/matrix-design/SKILL.md +37 -20
  31. package/assets/skills-zh-CN/matrix-handoff/SKILL.md +79 -0
  32. package/assets/skills-zh-CN/matrix-open/SKILL.md +38 -28
  33. package/assets/skills-zh-CN/matrix-verify/SKILL.md +19 -19
  34. package/bin/matrix.js +15 -15
  35. package/package.json +4 -13
  36. package/src/catalog.js +79 -72
  37. package/src/cli.js +211 -141
  38. package/src/distribution.js +182 -179
  39. package/src/installer.js +10 -10
  40. package/src/matt-catalog.mjs +1 -1
  41. package/src/matt.js +9 -14
  42. package/src/messages.js +32 -23
  43. package/src/npm-invocation.js +23 -0
  44. package/src/project-index.js +43 -0
  45. package/src/runtime-resolver.js +76 -76
  46. package/src/self-update.js +88 -81
  47. package/src/ui.js +97 -89
  48. package/src/workflow-transaction.js +13 -13
  49. package/src/workflow.js +734 -705
  50. package/.claude/skills/matrix-claude/SKILL.md +0 -98
  51. package/.claude/skills/matrix-open/agents/openai.yaml +0 -4
  52. package/.claude/skills/matrix-tweak/agents/openai.yaml +0 -4
  53. package/.claude/skills/matrix-verify/agents/openai.yaml +0 -4
  54. package/assets/skills-zh-CN/matrix-claude/SKILL.md +0 -33
@@ -1,24 +1,41 @@
1
- ---
2
- name: matrix-design
3
- description: 在实现前设计并冻结活动 Matrix 变更。
4
- ---
5
-
6
- # Matrix Design
7
-
8
- Design 只用于 full 和可恢复的旧 shortcut change。新的 lightweight hotfix/tweak 从 Open 直接进入 Build,不得为满足 full guard 补写 Design 产物。
9
-
10
- design 和 plan 正文使用 `node <matrix-skill-directory>/scripts/matrix-runtime.mjs inspect` 的 `artifact_language`;Runtime 所需英文标题 token 保持不变。
11
-
12
- 读取 `node <matrix-skill-directory>/scripts/matrix-runtime.mjs inspect`、proposal 与冻结 `orchestration`,写入 `design.md`(`## Decisions`、`## Boundaries`、`## Test seams`、`## Risks`)与 `plan.md`(`## Steps`、`## Validation`、`## Stop conditions`)。
13
-
14
- - **Prim**:使用 Matrix 自身能力调查并设计。
1
+ ---
2
+ name: matrix-design
3
+ description: 在实现前设计并冻结活动 Matrix 变更。
4
+ ---
5
+
6
+ # Matrix Design
7
+
8
+ Design 只用于 full 和可恢复的旧 shortcut change。新的 lightweight hotfix/tweak 从 Open 直接进入 Build,不得为满足 full guard 补写 Design 产物。
9
+
10
+ design 和 plan 正文使用 `node <matrix-skill-directory>/scripts/matrix-runtime.mjs inspect` 的 `artifact_language`;Runtime 所需英文标题 token 保持不变。
11
+
12
+ 读取 `node <matrix-skill-directory>/scripts/matrix-runtime.mjs inspect`、proposal 与冻结 `orchestration`,写入 `design.md`(`## Decisions`、`## Boundaries`、`## Test seams`、`## Risks`)与 `plan.md`(`## Steps`、`## Validation`、`## Stop conditions`)。
13
+
14
+ - **Prim**:使用 Matrix 自身能力调查并设计。
15
15
  - **Arch**:仅按事实触发 `domain-modeling`、`research`、`prototype`、`codebase-design`;当 Contract 修改 Skill、`AGENTS.md`、`CLAUDE.md` 或 agent 指针可达文档时触发 `writing-for-agents`。不得机械执行固定序列;每次调用前说明能力与原因。
16
-
16
+
17
17
  长期有效的领域、ADR 或研究产物遵循仓库约定,关键结论必须同步进入 Matrix design/plan。prototype 默认写入系统临时目录。companion 不得拥有 Matrix 状态或创建竞争计划。重大范围或架构决策须先由用户确认。
18
18
 
19
19
  `wayfinder` 与 `improve-codebase-architecture` 只能作为活动 Design 外的显式 handoff;说明原因后由用户调用,选中的结果可另行进入受治理 Change。
20
-
21
- ```powershell
22
- node <matrix-skill-directory>/scripts/matrix-runtime.mjs guard design
23
- node <matrix-skill-directory>/scripts/matrix-runtime.mjs transition build
24
- ```
20
+
21
+ ```powershell
22
+ node <matrix-skill-directory>/scripts/matrix-runtime.mjs guard design
23
+ ```
24
+
25
+ ## 执行主体确认点(Build 前)
26
+
27
+ `guard design` 通过后、`transition build` 之前,必须暂停并向用户确认执行主体,未确认不得推进:
28
+
29
+ - **选项 A:当前 agent / 原模型继续(默认)**——直接推进:
30
+ ```powershell
31
+ node <matrix-skill-directory>/scripts/matrix-runtime.mjs transition build
32
+ ```
33
+ 随后进入 `$matrix-build` 在本会话内实现。
34
+ - **选项 B:切换模型、保留本 agent**——用户在自己的客户端完成模型切换(例如设计用强模型、实现用高性价比模型),回到会话确认后按选项 A 推进。Matrix 无法感知客户端模型,只提供强制暂停点。
35
+ - **选项 C:切换执行 agent**——先推进进 Build 批准冻结 Contract,再用 `$matrix-handoff` 为目标 agent 导出有界任务包(例如 Codex 设计、Claude Code 实现,或 zcode 设计、opencode 实现)。实现 agent 完成并补齐 `## Build evidence` 后:
36
+ ```powershell
37
+ node <matrix-skill-directory>/scripts/matrix-runtime.mjs guard build
38
+ node <matrix-skill-directory>/scripts/matrix-runtime.mjs transition verify
39
+ ```
40
+
41
+ 所选选项必须写入 `design.md` 的 `## Decisions`,随 Contract 冻结。
@@ -0,0 +1,79 @@
1
+ ---
2
+ name: matrix-handoff
3
+ description: 将已批准的 Matrix Contract 导出为受边界约束的通用 agent 任务包(Claude Code、opencode 或其他 agent),不改变 Matrix 工作流状态。
4
+ ---
5
+
6
+ # Matrix Handoff(Implementation Handoff)
7
+
8
+ 这是可选旁路,不是 Matrix phase。它不得执行 `transition`、`archive`,也不得写入 `matrix.yaml` 或 `events.jsonl`。它只支持匹配的 full 或 legacy-full 三产物 Contract;新的 lightweight hotfix/tweak 不支持导出。
9
+
10
+ 人类可读 handoff 内容使用 inspect 的 `artifact_language`;稳定的机器可读标题和 metadata key 保持不变。
11
+
12
+ ## 何时使用
13
+
14
+ 满足以下条件时使用 `$matrix-handoff`:
15
+
16
+ - 变更已进入 Build,且 `design -> build` 已批准精确 Contract;
17
+ - 你希望由另一个 agent 实现冻结的设计——例如 Codex 设计、Claude Code 实现,或 zcode 设计、opencode 实现;
18
+ - 你需要一份带全部实现细节的有界任务包。
19
+
20
+ ## 前置条件
21
+
22
+ 导出器写任何内容前先做只读检查:
23
+
24
+ ```powershell
25
+ node <matrix-skill-directory>/scripts/matrix-runtime.mjs guard build
26
+ ```
27
+
28
+ 若结果为 `CONTRACT_CHANGED`、`CONTRACT_UNAPPROVED` 或 `CONTRACT_READ_FAILED`,回到 `$matrix-design`,修订后重新进入 Build 取得新批准。导出只读取批准快照中的 `proposal.md`、`design.md` 与 `plan.md`。
29
+
30
+ ## 导出
31
+
32
+ 实现 agent 由用户显式选择,通过 `--agent <agent-id>`(kebab-case)传入;可用 `--from <agent-id>` 标注设计方 agent。
33
+
34
+ ```powershell
35
+ # 通用 agent 交接:写入 artifacts/handoff-task-<ID>.md
36
+ node <matrix-skill-directory>/scripts/matrix-runtime.mjs export --task-id <ID> --agent opencode
37
+ node <matrix-skill-directory>/scripts/matrix-runtime.mjs export --task-id <ID> --agent claude-code --from codex
38
+
39
+ # 兼容形态(Claude Code):写入 artifacts/claude-task.md
40
+ node <matrix-skill-directory>/scripts/matrix-runtime.mjs export --task-id <ID> --target generic
41
+
42
+ # FnSec:仅在 active.md 含有 NO_ACTIVE_OBJECTIVE 时更新看板
43
+ node <matrix-skill-directory>/scripts/matrix-runtime.mjs export --task-id <ID> --target fnsec --apply-fnsec-board
44
+ ```
45
+
46
+ `--agent` 与 `--target` 互斥。新交接推荐 `--agent`;`--target generic` 仅为兼容保留。
47
+
48
+ ## 任务包内容
49
+
50
+ 导出包(`artifacts/handoff-task-<task-id>.md`)的元数据记录 `Implementation actor`(`--agent` 值)与 `Decision owner`(`--from` 值,缺省为 "Matrix change owner"),并包含批准的 Contract hash 与 revision,以及同一冻结快照的 proposal、design、plan。Objective、Allowed/Prohibited work 与 Stop conditions 原样携带——它们与具体 agent 无关。
51
+
52
+ ## 实现 agent 完成后
53
+
54
+ 继续 `$matrix-verify` 前先核对以下证据:
55
+
56
+ - [ ] `artifacts/verification.md` 存在且含 `## Build evidence`
57
+ - [ ] Build evidence 含具体命令与结果
58
+ - [ ] plan 的 Validation 命令全部执行
59
+ - [ ] `NEEDS_DECISION` 项已解决或已记录
60
+
61
+ 证据缺失时,让实现 agent 补齐后再继续。
62
+
63
+ ## 恢复 Matrix 工作流
64
+
65
+ 实现 agent 完成且证据齐备后:
66
+
67
+ ```powershell
68
+ node <matrix-skill-directory>/scripts/matrix-runtime.mjs guard build
69
+ node <matrix-skill-directory>/scripts/matrix-runtime.mjs transition verify
70
+ ```
71
+
72
+ guard 失败则退回实现 agent 补齐缺失证据;通过后进入 `$matrix-verify` 继续验证流程。
73
+
74
+ ## 重要约束
75
+
76
+ - 本旁路不改变 Matrix 阶段、workflow 或 guard 结果
77
+ - Matrix 状态停留在 `build`;导出本身不推进阶段
78
+ - 实现 agent 产出的证据必须满足 build guard 条件
79
+ - 成功 transition 到 verify 后,走正常验证流程
@@ -1,30 +1,40 @@
1
- ---
2
- name: matrix-open
3
- description: 将开发请求澄清为有证据的 Matrix 提案。
4
- ---
5
-
6
- # Matrix Open
7
-
8
- 读取 `node <matrix-skill-directory>/scripts/matrix-runtime.mjs inspect` 返回的 `profile` 与 `evidence_policy`。
9
-
10
- proposal 正文使用其中的 `artifact_language`;Runtime 所需的英文标题 token 必须原样保留,仅标题下内容本地化。
11
-
12
- - full proposal 包含 `## Goal`、`## Scope`、`## Non-goals`、`## Acceptance`、`## Risks`,随后进入 Design。
13
- - lightweight proposal 在修改项目实现前完整定义 `## Goal`、`## Scope`、`## Non-goals`、`## Approach`、`## Acceptance`、`## Validation`、`## Risks`、`## Upgrade conditions`。
14
- - hotfix 额外包含 `## Expected behavior`、`## Actual behavior`、`## Reproduction`。
15
- - tweak 额外包含 `## Current behavior`、`## Preserved behavior`、`## Diff boundary`。
16
-
17
- - **Prim**:使用 Matrix 自身能力澄清并编写提案。
18
- - **Arch**:仅在存在重大歧义或用户要求压力测试时调用 `grilling`;仅在领域词汇、不变量或架构决定不清晰时调用 `domain-modeling`。调用前说明能力与原因。
1
+ ---
2
+ name: matrix-open
3
+ description: 将开发请求澄清为有证据的 Matrix 提案。
4
+ ---
5
+
6
+ # Matrix Open
7
+
8
+ 读取 `node <matrix-skill-directory>/scripts/matrix-runtime.mjs inspect` 返回的 `profile` 与 `evidence_policy`。
9
+
10
+ proposal 正文使用其中的 `artifact_language`;Runtime 所需的英文标题 token 必须原样保留,仅标题下内容本地化。
11
+
12
+ - full proposal 包含 `## Goal`、`## Scope`、`## Non-goals`、`## Acceptance`、`## Risks`,随后进入 Design。
13
+ - lightweight proposal 在修改项目实现前完整定义 `## Goal`、`## Scope`、`## Non-goals`、`## Approach`、`## Acceptance`、`## Validation`、`## Risks`、`## Upgrade conditions`。
14
+ - hotfix 额外包含 `## Expected behavior`、`## Actual behavior`、`## Reproduction`。
15
+ - tweak 额外包含 `## Current behavior`、`## Preserved behavior`、`## Diff boundary`。
16
+
17
+ - **Prim**:使用 Matrix 自身能力进行结构化澄清(目标、范围、非目标、验收标准、风险、时限),并编写提案。
18
+ - **Arch**:Open 开始即说明能力与原因,默认调用 `grilling` 澄清需求;仅在领域词汇、不变量或架构决定不清晰时调用 `domain-modeling`。
19
+ - **豁免澄清**:仅当用户同时满足 (1) 自带清晰的执行计划,(2) 明确说明不需要澄清过程 时,才可跳过澄清;跳过仍必须生成 `clarification.md` 的豁免记录。
20
+
21
+ ## 澄清产物(强制)
22
+
23
+ 在编写 proposal 之前生成 `<change>/clarification.md`,无论澄清或豁免都必须落盘:
24
+
25
+ - 正常澄清:`## Questions` / `## Answers` / `## Resolved scope`(英文标题 token 固定,正文使用 `artifact_language`);
26
+ - 豁免路径:`## Exemption record`(豁免原因 + 用户计划要点 + proposal 如何采纳该计划)。
27
+
28
+ lightweight(hotfix/tweak)同样适用,但澄清精简为一轮核心问题。该文件是 Open 阶段的证据类产物:不参与 Contract identity 计算,Runtime 不校验其存在;0.1.5 及更早创建、停在 open 的 change 无需补写即可继续推进。
19
29
 
20
30
  若进展被另一人掌握的事实或决定阻塞,说明 `to-questionnaire` 适用的原因并让用户显式调用;Matrix 不得自行嵌套该 wrapper。
21
-
22
- companion 输出只能作为当前 proposal 的证据,不得创建第二套工作流、提案、确认状态或阶段转换。正确安装的能力失败时最多执行一次同能力 Matrix fallback;安装完整性问题必须修复。
23
-
24
- ```powershell
25
- node <matrix-skill-directory>/scripts/matrix-runtime.mjs guard open
26
- # full
27
- node <matrix-skill-directory>/scripts/matrix-runtime.mjs transition design
28
- # hotfix/tweak,仅在用户明确确认后
29
- node <matrix-skill-directory>/scripts/matrix-runtime.mjs transition build --confirmed
30
- ```
31
+
32
+ companion 输出只能作为当前 proposal 的证据,不得创建第二套工作流、提案、确认状态或阶段转换。正确安装的能力失败时最多执行一次同能力 Matrix fallback;安装完整性问题必须修复。
33
+
34
+ ```powershell
35
+ node <matrix-skill-directory>/scripts/matrix-runtime.mjs guard open
36
+ # full
37
+ node <matrix-skill-directory>/scripts/matrix-runtime.mjs transition design
38
+ # hotfix/tweak,仅在用户明确确认后
39
+ node <matrix-skill-directory>/scripts/matrix-runtime.mjs transition build --confirmed
40
+ ```
@@ -5,28 +5,28 @@ description: 依据计划验证 Matrix 变更并审查差异。
5
5
 
6
6
  # Matrix Verify
7
7
 
8
- 运行已批准 Contract 的验证命令,在 `verification.md` 写入 `## Test evidence`。hotfix 另写 `## Regression evidence`;tweak 另写 `## Scope review evidence`。所有模式都必须写入 `## Review evidence`,并在其中保留内容充分的 `### Standards` 与 `### Spec` 两个子节。读取冻结 `orchestration`:
8
+ 运行已批准 Contract 的验证命令,在 `verification.md` 写入 `## Test evidence`。hotfix 另写 `## Regression evidence`;tweak 另写 `## Scope review evidence`。所有模式都必须写入 `## Review evidence`,并在其中保留内容充分的 `### Standards` 与 `### Spec` 两个子节。读取冻结 `orchestration`:
9
9
 
10
10
  验证正文使用 `artifact_language`;上述 Runtime 所需英文证据标题保持不变。
11
11
 
12
12
  - **Prim**:Matrix 自行完成 Standards 与 Spec 双轴审查。
13
13
  - **Arch**:调用 `code-review` 产生双轴证据,并说明调用原因。
14
14
 
15
- 审查结果只是 Matrix Verify 的输入;companion 不得决定阶段结果、扩大已批准架构、推进或归档。不得调用事后架构改进 wrapper。正确安装的审查能力失败时最多执行一次同能力 Matrix fallback;安装完整性问题必须停止。
16
-
17
- Arch 正常执行 `code-review` 后,使用项目 Runtime 把 fixed point、HEAD/diff、Contract、审查正文和工作区绑定为当前 revision 的回执:
18
-
19
- ```powershell
20
- node <matrix-skill-directory>/scripts/matrix-runtime.mjs review --source code-review --fixed-point <ref> --standards <passed|failed> --spec <passed|failed>
21
- ```
22
-
23
- 只有在无 Git 基线、已提交的 HEAD diff 为空、仍存在 staged/unstaged/untracked 候选,或 capability 真实执行失败时,才记录限制并使用一次有界 fallback:
24
-
25
- ```powershell
26
- node <matrix-skill-directory>/scripts/matrix-runtime.mjs review --source matrix-fallback --reason <git-baseline-unavailable|empty-head-diff|uncommitted-worktree|capability-execution-failed> [--fixed-point <ref-for-empty-head-diff-or-uncommitted-worktree>] --standards <passed|failed> --spec <passed|failed>
27
- ```
28
-
29
- 不得把 fallback 写成 `code-review` 成功。`empty-head-diff` 必须提供 fixed point,由 Runtime 核实三点 diff 确实为空。`uncommitted-worktree` 也必须提供 fixed point,Runtime 会把 staged、unstaged 与 untracked 候选内容绑定为 `candidate_hash`,之后任意变化都会使回执过期。当前 revision 已有回执或任一审查轴失败时,必须先受控 Return,不能覆盖回执后继续。
15
+ 审查结果只是 Matrix Verify 的输入;companion 不得决定阶段结果、扩大已批准架构、推进或归档。不得调用事后架构改进 wrapper。正确安装的审查能力失败时最多执行一次同能力 Matrix fallback;安装完整性问题必须停止。
16
+
17
+ Arch 正常执行 `code-review` 后,使用项目 Runtime 把 fixed point、HEAD/diff、Contract、审查正文和工作区绑定为当前 revision 的回执:
18
+
19
+ ```powershell
20
+ node <matrix-skill-directory>/scripts/matrix-runtime.mjs review --source code-review --fixed-point <ref> --standards <passed|failed> --spec <passed|failed>
21
+ ```
22
+
23
+ 只有在无 Git 基线、已提交的 HEAD diff 为空、仍存在 staged/unstaged/untracked 候选,或 capability 真实执行失败时,才记录限制并使用一次有界 fallback:
24
+
25
+ ```powershell
26
+ node <matrix-skill-directory>/scripts/matrix-runtime.mjs review --source matrix-fallback --reason <git-baseline-unavailable|empty-head-diff|uncommitted-worktree|capability-execution-failed> [--fixed-point <ref-for-empty-head-diff-or-uncommitted-worktree>] --standards <passed|failed> --spec <passed|failed>
27
+ ```
28
+
29
+ 不得把 fallback 写成 `code-review` 成功。`empty-head-diff` 必须提供 fixed point,由 Runtime 核实三点 diff 确实为空。`uncommitted-worktree` 也必须提供 fixed point,Runtime 会把 staged、unstaged 与 untracked 候选内容绑定为 `candidate_hash`,之后任意变化都会使回执过期。当前 revision 已有回执或任一审查轴失败时,必须先受控 Return,不能覆盖回执后继续。
30
30
 
31
31
  失败时使用受控 Return:
32
32
 
@@ -35,9 +35,9 @@ node <matrix-skill-directory>/scripts/matrix-runtime.mjs return build --reason v
35
35
  node <matrix-skill-directory>/scripts/matrix-runtime.mjs return design --reason acceptance-or-design-gap
36
36
  ```
37
37
 
38
- Return 会轮换旧 `verification.md`;不得把旧结论直接复制为新的当前证据。
39
-
40
- Arch 的 Return 也会轮换 `review-receipt.json`;新 revision 必须重新审查并生成新回执。仅有 Markdown 标题、旧回执或与当前工作区不匹配的回执都不能通过 guard。
38
+ Return 会轮换旧 `verification.md`;不得把旧结论直接复制为新的当前证据。
39
+
40
+ Arch 的 Return 也会轮换 `review-receipt.json`;新 revision 必须重新审查并生成新回执。仅有 Markdown 标题、旧回执或与当前工作区不匹配的回执都不能通过 guard。
41
41
 
42
42
  ```powershell
43
43
  node <matrix-skill-directory>/scripts/matrix-runtime.mjs guard verify
package/bin/matrix.js CHANGED
@@ -1,15 +1,15 @@
1
- #!/usr/bin/env node
2
-
3
- import { main } from "../src/cli.js";
4
-
5
- main(process.argv.slice(2)).then((exitCode) => {
6
- if (Number.isInteger(exitCode) && exitCode !== 0) process.exitCode = exitCode;
7
- }).catch((error) => {
8
- if (error.code === "CANCELLED") {
9
- console.log("\nCancelled.");
10
- process.exitCode = 0;
11
- } else {
12
- console.error(`\nMatrix error: ${error.message}`);
13
- process.exitCode = 1;
14
- }
15
- });
1
+ #!/usr/bin/env node
2
+
3
+ import { main } from "../src/cli.js";
4
+
5
+ main(process.argv.slice(2)).then((exitCode) => {
6
+ if (Number.isInteger(exitCode) && exitCode !== 0) process.exitCode = exitCode;
7
+ }).catch((error) => {
8
+ if (error.code === "CANCELLED") {
9
+ console.log("\nCancelled.");
10
+ process.exitCode = 0;
11
+ } else {
12
+ console.error(`\nMatrix error: ${error.message}`);
13
+ process.exitCode = 1;
14
+ }
15
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rosenfan/matrix",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Evidence-driven development workflow with Prim and Arch agent-skill orchestration.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -10,19 +10,10 @@
10
10
  "files": [
11
11
  "bin/",
12
12
  "src/",
13
+ "assets/skills",
13
14
  "assets/skills-zh-CN",
14
- ".claude/skills/matrix",
15
- ".claude/skills/matrix-open",
16
- ".claude/skills/matrix-design",
17
- ".claude/skills/matrix-build",
18
- ".claude/skills/matrix-verify",
19
- ".claude/skills/matrix-archive",
20
- ".claude/skills/matrix-hotfix",
21
- ".claude/skills/matrix-tweak",
22
- ".claude/skills/matrix-status",
23
- ".claude/skills/matrix-claude",
24
- "!.claude/skills/**/__pycache__",
25
- "!.claude/skills/**/scripts/test_*.py",
15
+ "!assets/skills/**/__pycache__",
16
+ "!assets/skills-zh-CN/**/__pycache__",
26
17
  "README.md",
27
18
  "README.zh-CN.md",
28
19
  "LICENSE"
package/src/catalog.js CHANGED
@@ -1,87 +1,94 @@
1
- import crypto from "node:crypto";
2
- import fs from "node:fs";
3
- import os from "node:os";
1
+ import crypto from "node:crypto";
2
+ import fs from "node:fs";
3
+ import os from "node:os";
4
4
  import path from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import { MATT_INSTALLABLE_SKILLS, MATT_ROLES } from "./matt-catalog.mjs";
7
-
8
- export const LANGUAGE_IDS = ["en", "zh-CN"];
9
- export const PLATFORM_IDS = ["claude-code", "codex"];
10
- export const MATRIX_SKILLS = [
11
- "matrix", "matrix-open", "matrix-design", "matrix-build", "matrix-verify",
12
- "matrix-archive", "matrix-hotfix", "matrix-tweak", "matrix-status", "matrix-claude"
13
- ];
7
+
8
+ export const LANGUAGE_IDS = ["en", "zh-CN"];
9
+ export const PLATFORM_IDS = ["claude-code", "codex"];
10
+ export const MATRIX_SKILLS = [
11
+ "matrix", "matrix-open", "matrix-design", "matrix-build", "matrix-verify",
12
+ "matrix-archive", "matrix-hotfix", "matrix-tweak", "matrix-status", "matrix-handoff"
13
+ ];
14
14
  export const MATT_SKILLS = MATT_INSTALLABLE_SKILLS;
15
15
  export const UNMANAGED_MATT_SKILLS = MATT_ROLES.incompatible;
16
-
16
+
17
17
  const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
18
18
  const packageManifest = JSON.parse(fs.readFileSync(path.join(packageRoot, "package.json"), "utf8"));
19
19
  export const MATRIX_VERSION = packageManifest.version;
20
-
21
- export const PLATFORMS = {
22
- "claude-code": {
23
- id: "claude-code", name: "Claude Code", skillsCliAgent: "claude-code",
24
- skillRoot(base) { return path.join(base, ".claude", "skills"); },
25
- legacyRoots() { return []; }
26
- },
27
- codex: {
28
- id: "codex", name: "Codex", skillsCliAgent: "codex",
29
- skillRoot(base) { return path.join(base, ".agents", "skills"); },
30
- legacyRoots(base) { return [path.join(base, ".codex", "skills")]; }
31
- }
32
- };
33
-
34
- export function sourceSkillsRoot(language = "en") {
35
- const localized = language === "zh-CN"
36
- ? path.join(packageRoot, "assets", "skills-zh-CN")
37
- : path.join(packageRoot, ".claude", "skills");
38
- if (!fs.existsSync(localized)) throw new Error(`Matrix package is incomplete: ${language} assets are missing.`);
39
- return localized;
40
- }
41
-
42
- export function scopeBase(scope, projectRoot, home = os.homedir()) {
43
- return scope === "global" ? home : projectRoot;
44
- }
45
-
46
- export function installationRoot(scope, projectRoot, home) {
47
- return path.join(scopeBase(scope, projectRoot, home), ".matrix");
48
- }
49
-
50
- export function manifestPath(scope, projectRoot, home) {
51
- return path.join(installationRoot(scope, projectRoot, home), "installation.json");
52
- }
53
-
54
- export function hashDirectory(directory, extraFiles = []) {
55
- const hash = crypto.createHash("sha256");
56
- const files = new Map();
57
- const visit = (current, relative = "") => {
58
- for (const entry of fs.readdirSync(current, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
59
- const child = path.join(current, entry.name);
60
- const childRelative = path.join(relative, entry.name).replaceAll("\\", "/");
61
- if (entry.isDirectory()) visit(child, childRelative);
62
- else if (entry.isFile()) {
63
- files.set(childRelative, fs.readFileSync(child));
64
- }
65
- }
66
- };
67
- visit(directory);
68
- for (const extra of extraFiles) files.set(extra.path, Buffer.from(extra.contents));
69
- for (const [relative, contents] of [...files.entries()].sort(([left], [right]) => left.localeCompare(right))) {
70
- hash.update(`${relative}\0`);
71
- hash.update(contents);
72
- }
73
- return hash.digest("hex");
74
- }
75
-
20
+
21
+ export const PLATFORMS = {
22
+ "claude-code": {
23
+ id: "claude-code", name: "Claude Code", skillsCliAgent: "claude-code",
24
+ skillRoot(base) { return path.join(base, ".claude", "skills"); },
25
+ legacyRoots() { return []; }
26
+ },
27
+ codex: {
28
+ id: "codex", name: "Codex", skillsCliAgent: "codex",
29
+ skillRoot(base) { return path.join(base, ".agents", "skills"); },
30
+ legacyRoots(base) { return [path.join(base, ".codex", "skills")]; }
31
+ }
32
+ };
33
+
34
+ export function sourceSkillsRoot(language = "en") {
35
+ const localized = language === "zh-CN"
36
+ ? path.join(packageRoot, "assets", "skills-zh-CN")
37
+ : path.join(packageRoot, "assets", "skills");
38
+ if (!fs.existsSync(localized)) throw new Error(`Matrix package is incomplete: ${language} assets are missing.`);
39
+ return localized;
40
+ }
41
+
42
+ export function scopeBase(scope, projectRoot, home = os.homedir()) {
43
+ return scope === "global" ? home : projectRoot;
44
+ }
45
+
46
+ export function installationRoot(scope, projectRoot, home) {
47
+ return path.join(scopeBase(scope, projectRoot, home), ".matrix");
48
+ }
49
+
50
+ export function manifestPath(scope, projectRoot, home) {
51
+ return path.join(installationRoot(scope, projectRoot, home), "installation.json");
52
+ }
53
+
54
+ // Content digests must identify logical file content, not checkout line endings:
55
+ // a git working tree (autocrlf CRLF), the npm tarball and a local tgz must agree.
56
+ // Generated caches (__pycache__) are skipped so dirty working trees cannot poison digests.
57
+ const normalizeEol = (contents) => Buffer.from(contents.toString("utf8").replaceAll("\r\n", "\n").replaceAll("\r", "\n"), "utf8");
58
+ const GENERATED_DIRS = new Set(["__pycache__"]);
59
+
60
+ export function hashDirectory(directory, extraFiles = []) {
61
+ const hash = crypto.createHash("sha256");
62
+ const files = new Map();
63
+ const visit = (current, relative = "") => {
64
+ for (const entry of fs.readdirSync(current, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
65
+ if (entry.isDirectory() && GENERATED_DIRS.has(entry.name)) continue;
66
+ const child = path.join(current, entry.name);
67
+ const childRelative = path.join(relative, entry.name).replaceAll("\\", "/");
68
+ if (entry.isDirectory()) visit(child, childRelative);
69
+ else if (entry.isFile()) {
70
+ files.set(childRelative, fs.readFileSync(child));
71
+ }
72
+ }
73
+ };
74
+ visit(directory);
75
+ for (const extra of extraFiles) files.set(extra.path, Buffer.from(extra.contents));
76
+ for (const [relative, contents] of [...files.entries()].sort(([left], [right]) => left.localeCompare(right))) {
77
+ hash.update(`${relative}\0`);
78
+ hash.update(normalizeEol(contents));
79
+ }
80
+ return hash.digest("hex");
81
+ }
82
+
76
83
  export function workflowRuntimeSource() { return path.join(packageRoot, "src", "workflow.js"); }
77
84
  export function workflowTransactionSource() { return path.join(packageRoot, "src", "workflow-transaction.js"); }
78
85
  export function mattCatalogSource() { return path.join(packageRoot, "src", "matt-catalog.mjs"); }
79
-
86
+
80
87
  export function releaseCatalog(language = "en") {
81
- if (!LANGUAGE_IDS.includes(language)) throw new Error(`Unsupported language: ${language}`);
82
- const root = sourceSkillsRoot(language);
83
- const missing = MATRIX_SKILLS.filter((skill) => !fs.existsSync(path.join(root, skill, "SKILL.md")));
84
- if (missing.length) throw new Error(`Matrix package is incomplete. Missing: ${missing.join(", ")}`);
88
+ if (!LANGUAGE_IDS.includes(language)) throw new Error(`Unsupported language: ${language}`);
89
+ const root = sourceSkillsRoot(language);
90
+ const missing = MATRIX_SKILLS.filter((skill) => !fs.existsSync(path.join(root, skill, "SKILL.md")));
91
+ if (missing.length) throw new Error(`Matrix package is incomplete. Missing: ${missing.join(", ")}`);
85
92
  const runtime = fs.readFileSync(workflowRuntimeSource());
86
93
  const transaction = fs.readFileSync(workflowTransactionSource());
87
94
  const mattCatalog = fs.readFileSync(mattCatalogSource());