peaks-loop 4.0.32 → 4.0.34
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 +39 -0
- package/README-en.md +3 -4
- package/README.md +20 -28
- package/dist/cli/commands/_register.js +4 -3
- package/dist/cli/commands/audit-commands.js +12 -39
- package/dist/cli/commands/capability-commands.d.ts +6 -0
- package/dist/cli/commands/capability-commands.js +20 -2
- package/dist/cli/commands/code-commands.js +2 -0
- package/dist/cli/commands/code-mode-gate-commands.js +3 -3
- package/dist/cli/commands/code-mode-status-command.d.ts +17 -0
- package/dist/cli/commands/code-mode-status-command.js +51 -0
- package/dist/cli/commands/code-run-command.js +8 -1
- package/dist/cli/commands/code-runtime-commands.js +13 -5
- package/dist/cli/commands/core/skill-command.js +1 -1
- package/dist/cli/commands/ecc-commands.js +3 -2
- package/dist/cli/commands/project-commands.js +1 -1
- package/dist/cli/commands/request-commands.js +3 -7
- package/dist/cli/commands/session-24h-mode.js +9 -1
- package/dist/cli/commands/shadcn-commands.d.ts +32 -0
- package/dist/cli/commands/shadcn-commands.js +120 -0
- package/dist/cli/commands/slice-commands.js +1 -4
- package/dist/services/24h-mode/auto-engage.d.ts +39 -0
- package/dist/services/24h-mode/auto-engage.js +46 -0
- package/dist/services/24h-mode/decider.d.ts +11 -5
- package/dist/services/24h-mode/decider.js +13 -13
- package/dist/services/audit/enforcers/active-skill-resolver.d.ts +3 -1
- package/dist/services/audit/enforcers/active-skill-resolver.js +3 -5
- package/dist/services/audit/static-service.d.ts +1 -1
- package/dist/services/audit/static-service.js +1 -1
- package/dist/services/code/auto-compact-lifecycle.d.ts +1 -1
- package/dist/services/code/auto-compact-lifecycle.js +1 -1
- package/dist/services/code/auto-compact-modes.d.ts +1 -1
- package/dist/services/code/auto-compact-modes.js +1 -1
- package/dist/services/code/auto-compact-orchestrator.js +18 -22
- package/dist/services/code/mode-gate.d.ts +6 -2
- package/dist/services/code/mode-gate.js +9 -5
- package/dist/services/code/orchestrator-can-do.js +2 -2
- package/dist/services/code-review/ecc-bridge.d.ts +94 -15
- package/dist/services/code-review/ecc-bridge.js +133 -13
- package/dist/services/config/config-service.d.ts +17 -0
- package/dist/services/config/config-service.js +34 -0
- package/dist/services/context/auto-compact-dispatcher.d.ts +2 -2
- package/dist/services/context/auto-compact-dispatcher.js +4 -4
- package/dist/services/context/auto-compact-reader.js +8 -1
- package/dist/services/context/auto-compact-types.d.ts +13 -1
- package/dist/services/context/build-dispatch-system-prompt.js +2 -2
- package/dist/services/context/context-schema.d.ts +1 -1
- package/dist/services/dashboard/project-dashboard-service.d.ts +0 -7
- package/dist/services/dashboard/project-dashboard-service.js +1 -9
- package/dist/services/hooks/auto-compact-hook-install.d.ts +2 -2
- package/dist/services/hooks/auto-compact-hook-install.js +2 -2
- package/dist/services/ide/adapters/claude-code-adapter.d.ts +51 -0
- package/dist/services/ide/adapters/claude-code-adapter.js +84 -14
- package/dist/services/ide/ide-types.d.ts +10 -1
- package/dist/services/mode/mode-enforcement.d.ts +4 -1
- package/dist/services/mode/mode-enforcement.js +26 -28
- package/dist/services/mode/mode-status-service.d.ts +81 -0
- package/dist/services/mode/mode-status-service.js +108 -0
- package/dist/services/preferences/preferences-types.d.ts +16 -7
- package/dist/services/recommendations/capability-seed-items.js +0 -1
- package/dist/services/recommendations/installed-capability-detector.d.ts +33 -0
- package/dist/services/recommendations/installed-capability-detector.js +76 -0
- package/dist/services/scan/orphan-service.js +1 -1
- package/dist/services/skills/presence-lease-service.d.ts +21 -0
- package/dist/services/skills/presence-lease-service.js +26 -0
- package/dist/services/skills/skill-presence-service.d.ts +10 -1
- package/dist/services/skills/skill-presence-service.js +32 -4
- package/dist/services/skills/skill-statusline-service.js +6 -3
- package/dist/services/slice/multi-pass-orchestrator.js +0 -13
- package/dist/services/slice/slice-decompose-import-edges.d.ts +2 -2
- package/dist/services/slice/slice-decompose-import-edges.js +1 -29
- package/dist/services/slice/slice-decompose-runners.d.ts +2 -4
- package/dist/services/slice/slice-decompose-runners.js +1 -23
- package/dist/services/slice/slice-decompose-service.d.ts +3 -4
- package/dist/services/slice/slice-decompose-service.js +10 -29
- package/dist/services/slice/slice-decompose-types.d.ts +6 -47
- package/dist/services/slice/slice-decompose-types.js +3 -2
- package/dist/services/slice/slice-topology-types.d.ts +2 -3
- package/package.json +5 -5
- package/schemas/decomposition-v1.json +0 -12
- package/schemas/decomposition-v2.json +1 -15
- package/skills/bee/peaks-prd/SKILL.md +0 -1
- package/skills/bee/peaks-rd/SKILL.md +1 -1
- package/skills/bee/peaks-rd/references/external-references.md +1 -3
- package/skills/bee/peaks-rd/references/parallel-review-fanout.md +7 -2
- package/skills/bee/peaks-rd/references/rd-fanout-contracts.md +22 -8
- package/skills/bee/peaks-rd/references/rd-runbook.md +0 -2
- package/skills/bee/peaks-txt/SKILL.md +0 -12
- package/skills/peaks-code/SKILL.md +9 -9
- package/skills/peaks-code/references/mode-selection.md +7 -3
- package/skills/peaks-code/references/periodic-checkpoint.md +4 -4
- package/skills/peaks-code/references/runbook.md +10 -5
- package/skills/peaks-code/references/session-overload-signal-index.md +2 -2
- package/skills/peaks-code/references/standards-preflight.md +1 -1
- package/skills/peaks-code/references/startup-sequence.md +1 -1
- package/skills/peaks-code/references/step-0-8-gate.md +1 -1
- package/skills/peaks-code/references/swarm-dispatch-contract.md +2 -2
- package/skills/peaks-code/references/workflow-gates-and-types.md +1 -1
- package/skills/peaks-doctor/SKILL.md +1 -1
- package/skills/peaks-slice-decompose/SKILL.md +0 -1
- package/skills/peaks-slice-decompose/references/v2-schema.md +1 -12
- package/dist/cli/commands/understand-commands.d.ts +0 -3
- package/dist/cli/commands/understand-commands.js +0 -148
- package/dist/services/understand/hybrid-types.d.ts +0 -32
- package/dist/services/understand/hybrid-types.js +0 -1
- package/dist/services/understand/understand-hybrid-service.d.ts +0 -10
- package/dist/services/understand/understand-hybrid-service.js +0 -100
- package/dist/services/understand/understand-scan-service.d.ts +0 -28
- package/dist/services/understand/understand-scan-service.js +0 -170
- package/dist/services/understand/understand-types.d.ts +0 -50
- package/dist/services/understand/understand-types.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,44 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.0.34 — 2026-09-09 (mode 模型收敛 + auto-compact 死命令 + 上下文窗口覆盖 + 确认门去 TTY)
|
|
4
|
+
|
|
5
|
+
**Highlights**:
|
|
6
|
+
|
|
7
|
+
1. **mode 模型收敛(用户设计)** — 此前 `SkillPresenceMode` 与 24h 状态机是两个互不相识的自主性开关。
|
|
8
|
+
|
|
9
|
+
- `SkillPresenceMode = full-auto | assisted | strict | 24h`(四选一,并列)。
|
|
10
|
+
- `swarm` 从"模式"降级为**所有 mode 的默认执行策略**(与"fan-out 强制、不可退回串行"一致)。
|
|
11
|
+
- 24h 的 6 状态机保留为 **24h mode 的内部状态**;24h 是**唯一可自动开启**的 mode(T1–T5),其余 mode 仍需用户选。
|
|
12
|
+
- 新增 `peaks code mode status`:一条命令输出 presence mode / 24h 状态 / job mode / auto-compact profile。
|
|
13
|
+
- **顺带修好一个严重 bug**:`getSkillPresence()` 一直在丢掉 `mode` 字段,导致所有读 `presence.mode` 的守卫(mode-enforcement、assisted/strict 边界、post-compact-detector)**全是死代码**——用户选的 mode 从未真正生效。
|
|
14
|
+
|
|
15
|
+
2. **auto-compact 契约指向不存在的命令(根因)** — `peaks compact auto --execute` 在 `skills/` + `src/` 出现 **49 次**(含 CLI 自己返回的 `next`),实际执行是 `COMMAND_NOT_FOUND`。真命令是 `peaks code auto-compact`。LLM 按契约执行 → 撞死命令 → 只能回头让用户手动 compact。全部引用已改指真命令,并加守卫测试防回归。
|
|
16
|
+
|
|
17
|
+
3. **上下文窗口不再对未知模型默认 20w** — 新增 `PEAKS_CONTEXT_WINDOW_TOKENS`(env)与 `context.windowTokens`(config)覆盖,优先级 env > config > 启发式 > 默认;`peaks code context-now` 新增 `capacitySource` 字段,一眼看出窗口值来自哪。
|
|
18
|
+
|
|
19
|
+
4. **assisted/strict 确认门不再阻塞在 TTY** — `requireUserConfirmation` 此前会开 `readline` 的 `(y/N)` 提示;LLM 会话里 stdin 非 TTY → 直接挂死,且违反 Human-NL-Choice-Only。现改为立即抛出带 `transitionKey` + `mode` + 可执行 nextActions 的错误,由 LLM 用 `AskUserQuestion` 承接、用户同意后重跑 `--confirm`。bypass 语义(`--confirm` / `--force-confirm` / `PEAKS_AUTO_CONFIRM`)完全不变。
|
|
20
|
+
|
|
21
|
+
**验证**:build clean、tsc clean、全量 126 files / 1102 passed(1 skipped);实测 `capacitySource` 默认 `model-heuristic`、`PEAKS_CONTEXT_WINDOW_TOKENS=400000` → `env-override`。
|
|
22
|
+
|
|
23
|
+
## 4.0.33 — 2026-09-09 (ECC 去插件化 + 动态获取修复 + 移除 understand-anything)
|
|
24
|
+
|
|
25
|
+
**Highlights**:
|
|
26
|
+
|
|
27
|
+
1. **ECC 去插件化** — 此前 ECC code-review 依赖用户手动安装 Claude Code 插件,新开发机缺失即静默降级为 inline review。
|
|
28
|
+
|
|
29
|
+
- **物化到 `~/.peaks/agents/ecc/`**(peaks 自有目录,**永不写 `~/.claude/`**)。
|
|
30
|
+
- **缓存后备路径**:插件缺失时自动确保缓存 → 把物化指令注入通用子代理 → 经同一 bridge 渲染,新增 `detectEcc` 状态 `ready-via-cache`。
|
|
31
|
+
- **按真实名解析**:新增 `resolveMaterializedAgentName()`(候选名 + 确定性回退),修正物化文件名 `code-review.md` → 上游实际 `code-reviewer.md`。
|
|
32
|
+
- **修正原生插件 id**:`everything-claude-code:code-review` → **`ecc:code-reviewer`**(插件实名 `ecc`、agent 实名 `code-reviewer`;旧名是退役的仓库名)。
|
|
33
|
+
|
|
34
|
+
2. **修复 `peaks ecc install` 下载链(此前从未真正跑通)** — 三条 D-010 路径全挂:`ecc.tar.gz` 资产已不存在(404)、`tarball_url` 请求发 `accept: application/octet-stream` 被 GitHub 拒(415)、无 `.tgz` 资产可回退。现改为 `tarball_url → 资产 → PRD url` + 正确 accept 头;tar 根目录剥离改为按形状(codeload 与 api 前缀不同)。实测 `peaks ecc install` exit 0,物化 68 个 agent。
|
|
35
|
+
|
|
36
|
+
3. **死代码 / 坏引用修复** — `getInstalledCapabilityIds` 从写死 `[]` 改为真实只读检测;`peaks shadcn init`(skill 引用但命令不存在)实现为 `npx --package shadcn@4.21.0` 动态包装;清除 AgentShield 的 3 处误导残留(死 flag / 每次必印的假提示 / 过期注释)。
|
|
37
|
+
|
|
38
|
+
4. **移除 understand-anything 集成** — 命令 + 服务 + 能力目录 + skill/docs/README/宣传片引用全部删除,切片拆解与分析统一走 codegraph。
|
|
39
|
+
|
|
40
|
+
**验证**:全量 124 files / 1057 passed(原 119 / 1014);tsc clean;实测 `~/.claude/` 零写入。
|
|
41
|
+
|
|
3
42
|
## 4.0.32 — 2026-09-08 (CI 首次全绿 — 工作流修复 + Linux-only 测试修复)
|
|
4
43
|
|
|
5
44
|
**Highlights**:
|
package/README-en.md
CHANGED
|
@@ -174,11 +174,10 @@ Every lane opens with **one slash command**.
|
|
|
174
174
|
| Role | Project | One-liner |
|
|
175
175
|
| --- | --- | --- |
|
|
176
176
|
| **Sediment + gates** | [**peaks-loop**](https://github.com/SquabbyZ/peaks-loop) ← you are here | loop-engineering crystallization system; install → PRD/RD/QA/UI/SC/TXT as one chain + sediment |
|
|
177
|
-
| **Tactical handbook** | [affaan-m/ECC](https://github.com/affaan-m/ECC) |
|
|
178
|
-
| **Code understanding** | [Egonex-AI/Understand-Anything](https://github.com/Egonex-AI/Understand-Anything) | any repo, one sentence to grok it — let the LLM actually *understand* the project, not guess |
|
|
177
|
+
| **Tactical handbook** | [affaan-m/ECC](https://github.com/affaan-m/ECC) | the best tactics, skills, and SOPs you can put on top of Claude Code |
|
|
179
178
|
| **Process & discipline** | [obra/superpowers](https://github.com/obra/superpowers) | brainstorming / TDD / debugging / code-review as flow disciplines, every one with a hard exit |
|
|
180
179
|
|
|
181
|
-
**One sentence to use them all**: clone the
|
|
180
|
+
**One sentence to use them all**: clone the two repos above, install peaks-loop, hand the rest to your LLM — it pulls what it needs, holds the gates, lands the tactics, sediments the flow.
|
|
182
181
|
|
|
183
182
|
### Tribute
|
|
184
183
|
|
|
@@ -312,7 +311,7 @@ Three common pitfalls:
|
|
|
312
311
|
- Changelog → [`CHANGELOG.md`](./CHANGELOG.md)
|
|
313
312
|
- Questions → [GitHub Issues](https://github.com/SquabbyZ/peaks-loop/issues)
|
|
314
313
|
- Tribute: [multica-ai/andrej-karpathy-skills](https://github.com/multica-ai/andrej-karpathy-skills) · [alchaincyf/darwin-skill](https://github.com/alchaincyf/darwin-skill)
|
|
315
|
-
- Recommended combo: [affaan-m/ECC](https://github.com/affaan-m/ECC) · [
|
|
314
|
+
- Recommended combo: [affaan-m/ECC](https://github.com/affaan-m/ECC) · [obra/superpowers](https://github.com/obra/superpowers)
|
|
316
315
|
|
|
317
316
|
---
|
|
318
317
|
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
[](https://github.com/SquabbyZ/peaks-loop/actions/workflows/ci.yml)
|
|
10
10
|
[](./LICENSE)
|
|
11
11
|
[](https://www.npmjs.com/package/peaks-loop)
|
|
12
|
-
[](#status)
|
|
13
13
|
[](https://github.com/SquabbyZ/peaks-loop/stargazers)
|
|
14
14
|
|
|
15
15
|
[English](./README-en.md) · **简体中文**
|
|
@@ -128,7 +128,7 @@ npm i -g peaks-loop
|
|
|
128
128
|
|
|
129
129
|
---
|
|
130
130
|
|
|
131
|
-
## 当前状态 · 4.0.
|
|
131
|
+
## 当前状态 · 4.0.32
|
|
132
132
|
|
|
133
133
|
<p align="center">
|
|
134
134
|
<img src="./assets/readme/pulse.svg" alt="peaks-loop live metrics — 4 tiles + sparkline + pipeline progress" width="92%"/>
|
|
@@ -140,40 +140,33 @@ npm i -g peaks-loop
|
|
|
140
140
|
|
|
141
141
|
| | |
|
|
142
142
|
| --- | --- |
|
|
143
|
-
| **最新版本** | [](https://www.npmjs.com/package/peaks-loop) — 4.0.
|
|
143
|
+
| **最新版本** | [](https://www.npmjs.com/package/peaks-loop) — 4.0.32(2026-09-08) |
|
|
144
144
|
| **覆盖域** | 代码(`peaks-code`) · 内容(`peaks-content`) · 项目健康(`peaks-doctor`) · 批量修 issue(`peaks-issue-fix-orchestrator`) · 自定义 SOP(`peaks-sop`) · 通用原语(`peaks-solo` 分诊 / `peaks-resume` 续 / `peaks-status` 看 / `peaks-test` 测 / `peaks-slice-decompose` 切片) |
|
|
145
145
|
| **沉淀池** | `~/.peaks/` 本地池 · 跑两次自动晋升成 bee · 跑翻车让你重定义 · bee 跟着你的口味长 |
|
|
146
|
-
| **测试套件** |
|
|
146
|
+
| **测试套件** | 1096 cases · 4 packages (peaks-loop 1015 / runtime 39 / mut 22 / shared-channel 20) · **CI 首次全绿**(ubuntu + windows) · 14 BDD caller-binding coverage |
|
|
147
147
|
| **适配 IDE** | ✅ Claude Code · ✅ Z Code · 🚧 Codex / Cursor / Trae / Tongyi Lingma / Hermes / OpenClaw / Qoder(适配中,欢迎共建) |
|
|
148
148
|
| **依赖运行时** | Node ≥ 20 |
|
|
149
149
|
| **License** | MIT |
|
|
150
150
|
|
|
151
|
-
### 4.0.
|
|
151
|
+
### 近期演进(4.0.18 → 4.0.32)
|
|
152
152
|
|
|
153
|
-
|
|
|
153
|
+
| 版本 | 解决的事 | 怎么验 |
|
|
154
154
|
| --- | --- | --- |
|
|
155
|
-
| **
|
|
156
|
-
| **
|
|
157
|
-
| **
|
|
158
|
-
| **
|
|
159
|
-
| **
|
|
160
|
-
| **
|
|
161
|
-
| **
|
|
162
|
-
| **
|
|
163
|
-
|
|
164
|
-
| Epic | 解决的事 | 怎么验 |
|
|
165
|
-
| --- | --- | --- |
|
|
166
|
-
| **测试体系从零重建** | 旧 559 文件单测卡 3 小时跑不完;现 11 test files / 161 cases 单测已上线,加上子包测试与新增切片,全量 4 packages 285+ cases 全绿,`pnpm test:full` ~80s。删旧断言、写生产合约、4 维分拆(render/behavior/integration/a11y)。 | commit `f17aa377` → `1d6233bc` · `.peaks/memory/2026-07-30-test-rebuild-epic-sediment.md` |
|
|
167
|
-
| **Karpathy 评估成本自审** | LLM 在 1-2 个 slice 后不再"今天差不多了明天继续"——`karpathy-reviewer` 报 `costRatio`,>10 时 `peaks job karpathy-cost-check` 自动降级 `block`→`warn`。24h-mode 仍是 override。 | `peaks job karpathy-cost-check --review-file <path>` · 21 cases 单测 |
|
|
168
|
-
| **Compact 显性可见** | `peaks compact history` 给 LLM 看本次会话所有 compact 事件;`peaks statusline compact` 单行指示给 IDE 状态栏( `--` / `compact pending (0.85)` / `REDLINE 0.95` / `just compacted (0.92→?)`)。 | `auto-compact-orchestrator` append 到 `compact-history.jsonl` · 19 cases 单测 |
|
|
169
|
-
| **子包独立单测 + `pnpm test:full` 覆盖全 workspace** | `peaks-loop-mut` / `peaks-loop-shared-channel` 各自 4 维单测;`peaks-loop-shared` 0 file (passWithNoTests);root 镜像冗余删除。 | commit `593ffcdf` → `08e92d8f` · `pnpm test:full` 一次跑完 4 packages |
|
|
170
|
-
| **CLI surface 收敛(73 → 5 super-commands)** | 5 个 super-command(`peaks code / audit / doctor / openspec / release / release-pack`)替换 73 个 leaf command,byte-identical 契约保留,改动对外透明。 | rid-009 · 26 routing test |
|
|
155
|
+
| **4.0.32** | **CI 首次全绿** —— ci.yml 此前死在第一个门(`pnpm/action-setup@v4` 在 Node 24 runner 上 self-installer 必挂),后面所有步骤从未被验证。修 5 层:corepack 替 pnpm action、删 pre-Build 的 `tsc`(结构性过不了:subpath 指向未生成的 dist)、移除 node 20 矩阵、CI 固定 `PEAKS_CALLER_ID`、3 类 Linux-only 测试 bug(`setImmediate` 闭包竞态 / 平台写死断言 / 墙钟 flake)。 | CI run 全 3 job success;双平台独立复跑 119 files / 0 failed |
|
|
156
|
+
| **4.0.31** | **codegraph 自动刷新失效修复** —— `.peaks-loop-marker` 被下游误判为"已初始化",悬空 `.codegraph/` 永远建不出 `codegraph.db`。改为按 `codegraph.db` 判真实初始化 + 源头真 `init` + 悬空态自愈。 | 现场从悬空态成功建出 24.71 MB 索引 |
|
|
157
|
+
| **4.0.30** | **搜索优先 preflight**(编排层"先搜再答":Context7/WebSearch → ≤5 条绑定指令注入 RD 派发)+ **9 个超行文件拆分**(`src/` 全量 ≤800 行)+ CLI 漂移修复。 | scoped + full suite |
|
|
158
|
+
| **4.0.29** | **codegraph 生命周期闭环** —— RD 规划前 pre-dispatch preflight 自动 init/index 并注入结构;slice 完成边界自动 refresh(CLI-internal,不可绕过)。 | 29 单测 |
|
|
159
|
+
| **4.0.28** | **codegraph 数据目录回根** + **env-first 1M 窗口识别**(修 1M 模型被误判 200K 导致 false soft-warn)。 | `context-now` 修复前 200K/0.884 → 修复后 1M/0.187 |
|
|
160
|
+
| **4.0.24** | zod v4 + Context7 接入 + **Step 2.5 best-practice scan**(业务感知的最佳实践扫描)。 | — |
|
|
161
|
+
| **4.0.21** | vendor-detect recovery + codegraph 集成 + anti-fake-green gate。 | — |
|
|
162
|
+
| **4.0.19 / 4.0.20** | **detached sub-agent**(真 OS 进程 + G8 无限上下文自压缩);`peaks-loop-internal-runtime` 作为公开 lockstep 包发布。 | — |
|
|
163
|
+
| **4.0.18** | statusline 24h overlay。 | — |
|
|
171
164
|
|
|
172
165
|
---
|
|
173
166
|
|
|
174
|
-
## 强烈推荐 ·
|
|
167
|
+
## 强烈推荐 · 三个项目组合起来用
|
|
175
168
|
|
|
176
|
-
> **0 学习成本。** 这是组合起来用最大的好处 ——
|
|
169
|
+
> **0 学习成本。** 这是组合起来用最大的好处 —— 不只是效果俱佳,更是因为这几个项目的**接口对齐到了"自然语言"**,你只需要说一句话,谁替你跑命令、按什么闸门、按什么战术手册,完全不用你记。
|
|
177
170
|
|
|
178
171
|
<p align="center">
|
|
179
172
|
<img src="./assets/readme/footer.svg" alt="peaks-loop 推荐组合" width="92%"/>
|
|
@@ -182,11 +175,10 @@ npm i -g peaks-loop
|
|
|
182
175
|
| 角色 | 项目 | 一句话 |
|
|
183
176
|
| --- | --- | --- |
|
|
184
177
|
| **结晶与门禁** | [**peaks-loop**](https://github.com/SquabbyZ/peaks-loop) ← 你在这里 | loop engineering 结晶系统,装上就有 PRD/RD/QA/UI/SC/TXT 一整条工程链 + 沉淀 |
|
|
185
|
-
| **战术手册** | [affaan-m/ECC](https://github.com/affaan-m/ECC) |
|
|
186
|
-
| **代码理解** | [Egonex-AI/Understand-Anything](https://github.com/Egonex-AI/Understand-Anything) | 任意仓库,一句话读懂 —— 让 LLM 真正"理解"项目,而不是猜 |
|
|
178
|
+
| **战术手册** | [affaan-m/ECC](https://github.com/affaan-m/ECC) | Claude Code 上能拿到的最好用的战术、技能、SOP 集合 |
|
|
187
179
|
| **流程与纪律** | [obra/superpowers](https://github.com/obra/superpowers) | brainstorming / TDD / debugging / code-review 等流程纪律,每条都自带硬退出条件 |
|
|
188
180
|
|
|
189
|
-
|
|
181
|
+
**用起来就一句话**:把上面两个仓库都 clone 到本地,peaks-loop 装上,剩下的交给 LLM —— 它会按需取用、按纪律守门、按战术落地、按需求沉淀。
|
|
190
182
|
|
|
191
183
|
### 致敬
|
|
192
184
|
|
|
@@ -319,7 +311,7 @@ npx peaks doctor --project .
|
|
|
319
311
|
- 更新日志 → [`CHANGELOG.md`](./CHANGELOG.md)
|
|
320
312
|
- 提问 → [GitHub Issues](https://github.com/SquabbyZ/peaks-loop/issues)
|
|
321
313
|
- 致敬: [multica-ai/andrej-karpathy-skills](https://github.com/multica-ai/andrej-karpathy-skills) · [alchaincyf/darwin-skill](https://github.com/alchaincyf/darwin-skill)
|
|
322
|
-
- 组合推荐: [affaan-m/ECC](https://github.com/affaan-m/ECC) · [
|
|
314
|
+
- 组合推荐: [affaan-m/ECC](https://github.com/affaan-m/ECC) · [obra/superpowers](https://github.com/obra/superpowers)
|
|
323
315
|
|
|
324
316
|
---
|
|
325
317
|
|
|
@@ -60,6 +60,7 @@ import { registerReviewerCommands } from './reviewer-commands.js';
|
|
|
60
60
|
import { registerRoleCommands } from './role-commands.js';
|
|
61
61
|
import { registerRuntimeCommands } from './runtime-commands.js';
|
|
62
62
|
import { registerScanCommands } from './scan-commands.js';
|
|
63
|
+
import { registerShadcnCommands } from './shadcn-commands.js';
|
|
63
64
|
import { registerSecurityAuditCommands } from './security-audit-commands.js';
|
|
64
65
|
import { registerSedimentCommands } from './sediment-commands.js';
|
|
65
66
|
import { registerSkillConformanceCommands } from './skill-conformance-commands.js';
|
|
@@ -75,7 +76,6 @@ import { registerSubAgentCommands } from './sub-agent-commands.js';
|
|
|
75
76
|
import { registerSubAgentShutdownCommands } from './sub-agent-shutdown-commands.js';
|
|
76
77
|
import { registerSubAgentDispatchGuard } from './sub-agent-dispatch-guard.js';
|
|
77
78
|
import { registerTestCommands } from './test-commands.js';
|
|
78
|
-
import { registerUnderstandCommands } from './understand-commands.js';
|
|
79
79
|
import { registerVendorDetectCommand } from './vendor-detect.js';
|
|
80
80
|
import { registerUpgradeCommands } from './upgrade-commands.js';
|
|
81
81
|
import { registerUserTouchpointCommands } from './user-touchpoint-commands.js';
|
|
@@ -97,7 +97,8 @@ const REGISTRATIONS = [
|
|
|
97
97
|
['perf-commands', registerPerfCommands], ['preferences-commands', registerPreferencesCommands],
|
|
98
98
|
['project-commands', registerProjectCommands], ['prd-commands', registerPrdCommands],
|
|
99
99
|
['request-commands', registerRequestCommands], ['retrospective-commands', registerRetrospectiveCommands],
|
|
100
|
-
['scan-commands', registerScanCommands], ['
|
|
100
|
+
['scan-commands', registerScanCommands], ['shadcn-commands', registerShadcnCommands],
|
|
101
|
+
['slice-commands', registerSliceCommands],
|
|
101
102
|
['sop-commands', registerSopCommands], ['feedback-commands', registerFeedbackCommands],
|
|
102
103
|
['fork-commands', registerForkCommands], ['impact-commands', registerImpactCommands],
|
|
103
104
|
['smoke-commands', registerSmokeCommands], ['release-commands', registerReleaseCommands],
|
|
@@ -111,7 +112,7 @@ const REGISTRATIONS = [
|
|
|
111
112
|
['governance-classify-contract-commands', registerContractCommands],
|
|
112
113
|
['sub-agent-dispatch-guard', registerSubAgentDispatchGuard], ['gate-commands', registerGateCommands],
|
|
113
114
|
['hook-handle', registerHookHandleCommand], ['hooks-commands', registerHooksCommands],
|
|
114
|
-
['heartbeat-commands', registerHeartbeatCommands], ['statusline-commands', registerStatusLineCommands],
|
|
115
|
+
['heartbeat-commands', registerHeartbeatCommands], ['statusline-commands', registerStatusLineCommands],
|
|
115
116
|
['workspace-commands', registerWorkspaceCommands], ['workflow-plan-commands', registerWorkflowPlanCommands],
|
|
116
117
|
['audit-commands', registerAuditCommands], ['final-review-commands', registerFinalReviewCommands],
|
|
117
118
|
['governance-classify-contract-commands', registerClassifyCommands], ['context-commands', registerContextCommands],
|
|
@@ -78,12 +78,6 @@ export function registerAuditCommands(program, io) {
|
|
|
78
78
|
process.exitCode = 1;
|
|
79
79
|
}
|
|
80
80
|
});
|
|
81
|
-
// Slice #6 L2.3 P2-a: peaks audit static — soft-optional ECC
|
|
82
|
-
// AgentShell integration. Reads `.peaks/preferences.json`'s
|
|
83
|
-
// `agentShieldEnabled` flag (default false). The CLI flags
|
|
84
|
-
// `--enable-agent-shield` / `--disable-agent-shield` override
|
|
85
|
-
// the preference for a single call.
|
|
86
|
-
//
|
|
87
81
|
// Slice K1 (2.8.0): `--record` persists the audit snapshot as a
|
|
88
82
|
// project-memory decision at `.peaks/memory/audit-decisions/<slug>.md`.
|
|
89
83
|
// `--rid <id>` is an optional disambiguator for multiple audits on
|
|
@@ -91,12 +85,16 @@ export function registerAuditCommands(program, io) {
|
|
|
91
85
|
// Per `peaks-loop-when-adding-a-new-subcommand-check-for-existing-top-level-first`
|
|
92
86
|
// and the dev-preference red line "Default-no on new CLI commands",
|
|
93
87
|
// we extend the existing command rather than register a new subcommand.
|
|
88
|
+
//
|
|
89
|
+
// 2026-09-09-ecc-dynamic-and-cleanup B3: the dead
|
|
90
|
+
// `--enable-agent-shield` / `--disable-agent-shield` flags were removed.
|
|
91
|
+
// `runStaticAudit`'s agentShield state is a frozen "always disabled" stub
|
|
92
|
+
// (Slice 3 of 4.0.0-beta.11 removed the subprocess), so the flags had no
|
|
93
|
+
// effect and the ECC opt-in prose misled users on every run.
|
|
94
94
|
addJsonOption(audit
|
|
95
95
|
.command('static')
|
|
96
|
-
.description('Run the static audit (peaks-loop lint
|
|
96
|
+
.description('Run the static audit (peaks-loop lint only; the ECC AgentShield subprocess was removed in 4.0.0-beta.11). Per spec §5.3.')
|
|
97
97
|
.requiredOption('--project <path>', 'target project root')
|
|
98
|
-
.option('--enable-agent-shield', 'force-enable ECC AgentShield subprocess for this call (overrides preference)')
|
|
99
|
-
.option('--disable-agent-shield', 'force-disable ECC AgentShield subprocess for this call (overrides preference)')
|
|
100
98
|
.option('--record', 'persist the audit snapshot to .peaks/memory/audit-decisions/ as a project-memory decision')
|
|
101
99
|
.option('--rid <rid>', 'disambiguator for the decision record slug (used with --record; pairs multiple audits on the same day)')).action(async (options) => {
|
|
102
100
|
const validation = validateProjectRoot(options.project);
|
|
@@ -105,14 +103,6 @@ export function registerAuditCommands(program, io) {
|
|
|
105
103
|
process.exitCode = 1;
|
|
106
104
|
return;
|
|
107
105
|
}
|
|
108
|
-
// Resolve the flag override. `--enable-agent-shield` and
|
|
109
|
-
// `--disable-agent-shield` are mutually exclusive; we surface
|
|
110
|
-
// a 422 if both are passed.
|
|
111
|
-
if (options.enableAgentShield && options.disableAgentShield) {
|
|
112
|
-
printResult(io, fail('audit.static', 'FLAGS_CONFLICT', '`--enable-agent-shield` and `--disable-agent-shield` are mutually exclusive', emptyStaticAuditData(), ['Pass at most one of the two flags']), options.json);
|
|
113
|
-
process.exitCode = 1;
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
106
|
// Slice K1: `--rid` is meaningful only with `--record`. Surface a 422
|
|
117
107
|
// when the user passes `--rid` without `--record` so the CLI fails
|
|
118
108
|
// loudly rather than silently ignoring the request id.
|
|
@@ -123,12 +113,7 @@ export function registerAuditCommands(program, io) {
|
|
|
123
113
|
}
|
|
124
114
|
try {
|
|
125
115
|
const result = runStaticAudit({
|
|
126
|
-
projectRoot: validation.projectRoot
|
|
127
|
-
...(options.enableAgentShield
|
|
128
|
-
? { enableAgentShield: true }
|
|
129
|
-
: options.disableAgentShield
|
|
130
|
-
? { enableAgentShield: false }
|
|
131
|
-
: {}),
|
|
116
|
+
projectRoot: validation.projectRoot
|
|
132
117
|
});
|
|
133
118
|
// Persist the decision record when `--record` is set. The writer is
|
|
134
119
|
// idempotent at the slug level (same date+rid → same file); repeated
|
|
@@ -153,22 +138,10 @@ export function registerAuditCommands(program, io) {
|
|
|
153
138
|
...(decision ? { decision } : {})
|
|
154
139
|
};
|
|
155
140
|
const nextActions = [];
|
|
156
|
-
//
|
|
157
|
-
//
|
|
158
|
-
//
|
|
159
|
-
//
|
|
160
|
-
// options are surfaced as machine-readable action strings
|
|
161
|
-
// — same pattern as understand-commands.ts `INSTALL_HINT`.
|
|
162
|
-
if (!result.agentShield.installed) {
|
|
163
|
-
nextActions.push('ECC AgentShield not installed. Pick one of the four options below:');
|
|
164
|
-
nextActions.push(' a) Install: run `npx ecc-agentshield --help` to install, then re-run `peaks audit static`.');
|
|
165
|
-
nextActions.push(' b) Skip this run: pass `--disable-agent-shield` to suppress the subprocess for this call.');
|
|
166
|
-
nextActions.push(' c) Skip forever: run `peaks preferences set agentShieldEnabled false` (writes to `.peaks/preferences.json`).');
|
|
167
|
-
nextActions.push(' d) Learn more: see docs/superpowers/specs/2026-06-11-peaks-loop-l1-l2-l3-redesign.md §5.3 + §7.2.');
|
|
168
|
-
}
|
|
169
|
-
if (result.agentShield.spawned && result.agentShield.findings.length > 0) {
|
|
170
|
-
nextActions.push(`${result.agentShield.findings.length} ECC findings merged into the audit. Review with \`peaks audit static --json\`.`);
|
|
171
|
-
}
|
|
141
|
+
// 2026-09-09-ecc-dynamic-and-cleanup B3: the ECC AgentShield opt-in
|
|
142
|
+
// nextActions block was removed. `agentShield.installed` is a frozen
|
|
143
|
+
// `false`, so the block printed on every run and pointed users at a
|
|
144
|
+
// removed subprocess, removed flags, and a dead preference.
|
|
172
145
|
if (decision) {
|
|
173
146
|
nextActions.push(`Decision record written: ${decision.filePath}`);
|
|
174
147
|
nextActions.push(`Index synced: ${decision.indexSynced ? 'yes' : 'no'} (memory hot.decision[] now includes this audit)`);
|
|
@@ -11,6 +11,12 @@ export declare function runCapabilityStatus(io: ProgramIO, options: {
|
|
|
11
11
|
json?: boolean;
|
|
12
12
|
}): void;
|
|
13
13
|
export declare function runCapabilityMap(io: ProgramIO, options: CapabilityMapOptions): void;
|
|
14
|
+
/**
|
|
15
|
+
* Read-only detection of already-satisfied capabilities. Delegates to
|
|
16
|
+
* `detectInstalledCapabilityIds` (no install side effect, fail-soft).
|
|
17
|
+
* `_config` is retained for signature back-compat — the probe needs the
|
|
18
|
+
* project root, which comes from the process cwd.
|
|
19
|
+
*/
|
|
14
20
|
export declare function getInstalledCapabilityIds(_config: PeaksConfig): string[];
|
|
15
21
|
export declare function parseCapabilityMapSource(source: string): CapabilityMapSourceFilter | null;
|
|
16
22
|
export {};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { readConfig } from '../../services/config/config-service.js';
|
|
2
|
+
import { findProjectRoot } from '../../services/config/config-safety.js';
|
|
2
3
|
import { resolveCapabilityAvailability } from '../../services/recommendations/capability-availability.js';
|
|
4
|
+
import { detectInstalledCapabilityIds } from '../../services/recommendations/installed-capability-detector.js';
|
|
3
5
|
import { createCapabilityMapPlan } from '../../services/recommendations/capability-map-service.js';
|
|
4
6
|
import { seedCapabilityItems, seedCapabilitySources } from '../../services/recommendations/seed-capability-catalog.js';
|
|
5
7
|
import { fail, ok } from 'peaks-loop-shared/result';
|
|
@@ -12,7 +14,9 @@ export function registerCapabilityCommands(program, io) {
|
|
|
12
14
|
addCapabilityMapOptions(program.command('capabilities').description('Show dry-run external capability landing map')).action((options) => runCapabilityMap(io, options));
|
|
13
15
|
}
|
|
14
16
|
export function runCapabilityStatus(io, options) {
|
|
15
|
-
const availability = resolveCapabilityAvailability(seedCapabilityItems
|
|
17
|
+
const availability = resolveCapabilityAvailability(seedCapabilityItems, {
|
|
18
|
+
installedCapabilityIds: getInstalledCapabilityIds(readConfig())
|
|
19
|
+
});
|
|
16
20
|
printResult(io, ok("capability.status", { sources: seedCapabilitySources, items: seedCapabilityItems, availability }), options.json);
|
|
17
21
|
}
|
|
18
22
|
function addCapabilityMapOptions(command) {
|
|
@@ -34,8 +38,22 @@ export function runCapabilityMap(io, options) {
|
|
|
34
38
|
...(httpProxy === undefined ? {} : { httpProxy })
|
|
35
39
|
})), options.json);
|
|
36
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Read-only detection of already-satisfied capabilities. Delegates to
|
|
43
|
+
* `detectInstalledCapabilityIds` (no install side effect, fail-soft).
|
|
44
|
+
* `_config` is retained for signature back-compat — the probe needs the
|
|
45
|
+
* project root, which comes from the process cwd.
|
|
46
|
+
*/
|
|
37
47
|
export function getInstalledCapabilityIds(_config) {
|
|
38
|
-
return
|
|
48
|
+
return detectInstalledCapabilityIds({ projectRoot: resolveProbeRoot() });
|
|
49
|
+
}
|
|
50
|
+
function resolveProbeRoot() {
|
|
51
|
+
try {
|
|
52
|
+
return findProjectRoot(process.cwd()) ?? process.cwd();
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return process.cwd();
|
|
56
|
+
}
|
|
39
57
|
}
|
|
40
58
|
export function parseCapabilityMapSource(source) {
|
|
41
59
|
if (CAPABILITY_SOURCE_FILTERS.has(source)) {
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
* registerCodeCommands (now a thin orchestrator).
|
|
24
24
|
*/
|
|
25
25
|
import { registerCodeRunCommand } from './code-run-command.js';
|
|
26
|
+
import { registerCodeModeStatusCommand } from './code-mode-status-command.js';
|
|
26
27
|
import { registerCodeModeGateCommands } from './code-mode-gate-commands.js';
|
|
27
28
|
import { registerCodeJobShapeCommands } from './code-job-shape-commands.js';
|
|
28
29
|
import { registerCodeRuntimeCommands } from './code-runtime-commands.js';
|
|
@@ -113,6 +114,7 @@ export function registerCodeCommands(program, io) {
|
|
|
113
114
|
.command('code', { hidden: true })
|
|
114
115
|
.description('peaks-code LLM-side workflow planner (slice 2 fast mode)');
|
|
115
116
|
registerCodeModeGateCommands(code, io);
|
|
117
|
+
registerCodeModeStatusCommand(code, io);
|
|
116
118
|
registerCodeJobShapeCommands(code, io);
|
|
117
119
|
registerCodeRuntimeCommands(code, io);
|
|
118
120
|
registerCodeOrchestratorCanDoCommand(code, io);
|
|
@@ -35,7 +35,7 @@ export function registerCodeModeGateCommands(code, io) {
|
|
|
35
35
|
addJsonOption(code
|
|
36
36
|
.command('should-pause')
|
|
37
37
|
.description('v2.11.0 D5: ask the mode-gate whether the LLM should pause for an AskUserQuestion at a given step. ' +
|
|
38
|
-
'full-auto /
|
|
38
|
+
'full-auto / 24h auto-proceed (recommended = chosen); assisted / strict pause. ' +
|
|
39
39
|
'The 3 hard-floor categories always pause regardless of mode. ' +
|
|
40
40
|
'v2.15.0 slice 002 AC-2: when --step step-1-mode-select AND the recorded skill presence is stale ' +
|
|
41
41
|
'(outer-session-mismatch / no-presence), the gate returns shouldPause: true with reason "stale-presence" ' +
|
|
@@ -50,7 +50,7 @@ export function registerCodeModeGateCommands(code, io) {
|
|
|
50
50
|
// pause on `step-1-mode-select` (mode-selection-itself) will
|
|
51
51
|
// pause regardless, and the LLM-side caller can present
|
|
52
52
|
// AskUserQuestion without first knowing the mode.
|
|
53
|
-
.option('--mode <mode>', 'one of: full-auto, assisted,
|
|
53
|
+
.option('--mode <mode>', 'one of: full-auto, assisted, strict, 24h. Defaults to full-auto when omitted (Step 1 chicken-and-egg fix).')
|
|
54
54
|
.option('--hard-floor <category>', 'optional hard-floor override (irreversible-external-side-effect | authentication-credential | multi-day-investment | commit-boundary-side-effect)')
|
|
55
55
|
.option('--recommended <option>', 'recommended option label to log when auto-proceeding', 'recommended-option')
|
|
56
56
|
.option('--project <path>', 'v2.15.0 slice 002 AC-2: project root for presence:check-stale. Default: cwd. Pass only when step=step-1-mode-select.')
|
|
@@ -64,7 +64,7 @@ export function registerCodeModeGateCommands(code, io) {
|
|
|
64
64
|
// step-1-mode-select will still pause regardless.
|
|
65
65
|
const mode = opts.mode ?? 'full-auto';
|
|
66
66
|
if (!isCodeMode(mode)) {
|
|
67
|
-
printResult(io, fail('code.should-pause', 'INVALID_MODE', `mode must be one of full-auto, assisted,
|
|
67
|
+
printResult(io, fail('code.should-pause', 'INVALID_MODE', `mode must be one of full-auto, assisted, strict, 24h (got "${mode}")`, { provided: mode }, ['Pass --mode full-auto | assisted | strict | 24h']), opts.json);
|
|
68
68
|
process.exitCode = 1;
|
|
69
69
|
return;
|
|
70
70
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slice 2026-09-09-mode-consolidation (Slice D) — `peaks code mode status`.
|
|
3
|
+
*
|
|
4
|
+
* One read for the whole stacked autonomy picture:
|
|
5
|
+
* - presence MODE (`full-auto | assisted | strict | 24h`),
|
|
6
|
+
* - the 24h internal state machine (only when the mode is `24h`),
|
|
7
|
+
* - Job mode,
|
|
8
|
+
* - the resolved auto-compact profile (`standard | partial`).
|
|
9
|
+
*
|
|
10
|
+
* Read-only and fail-soft: the service degrades every unreadable
|
|
11
|
+
* artifact to `null` / `false`; this command only wraps the call in an
|
|
12
|
+
* envelope. Nested under the existing `peaks code` verb (no new
|
|
13
|
+
* top-level verb — peaks-loop is enhancement, not a new CLI surface).
|
|
14
|
+
*/
|
|
15
|
+
import type { Command } from 'commander';
|
|
16
|
+
import { type ProgramIO } from '../cli-helpers.js';
|
|
17
|
+
export declare function registerCodeModeStatusCommand(code: Command, io: ProgramIO): void;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slice 2026-09-09-mode-consolidation (Slice D) — `peaks code mode status`.
|
|
3
|
+
*
|
|
4
|
+
* One read for the whole stacked autonomy picture:
|
|
5
|
+
* - presence MODE (`full-auto | assisted | strict | 24h`),
|
|
6
|
+
* - the 24h internal state machine (only when the mode is `24h`),
|
|
7
|
+
* - Job mode,
|
|
8
|
+
* - the resolved auto-compact profile (`standard | partial`).
|
|
9
|
+
*
|
|
10
|
+
* Read-only and fail-soft: the service degrades every unreadable
|
|
11
|
+
* artifact to `null` / `false`; this command only wraps the call in an
|
|
12
|
+
* envelope. Nested under the existing `peaks code` verb (no new
|
|
13
|
+
* top-level verb — peaks-loop is enhancement, not a new CLI surface).
|
|
14
|
+
*/
|
|
15
|
+
import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
|
|
16
|
+
import { fail, ok } from 'peaks-loop-shared/result';
|
|
17
|
+
import { resolveCanonicalProjectRoot } from '../../services/config/config-service.js';
|
|
18
|
+
import { resolveModeStatus } from '../../services/mode/mode-status-service.js';
|
|
19
|
+
export function registerCodeModeStatusCommand(code, io) {
|
|
20
|
+
// Explicit two-step nesting (NOT `.command('mode status')` — that form
|
|
21
|
+
// creates a positional `<status>` argument, not a subcommand).
|
|
22
|
+
const mode = code
|
|
23
|
+
.command('mode')
|
|
24
|
+
.description('Mode introspection (read-only). Sub-actions: status.');
|
|
25
|
+
addJsonOption(mode
|
|
26
|
+
.command('status')
|
|
27
|
+
.description('v4.0.34 (slice 2026-09-09-mode-consolidation): one read for the whole stacked ' +
|
|
28
|
+
'autonomy picture — presence mode, the 24h internal state (when mode=24h), Job mode, ' +
|
|
29
|
+
'and the resolved auto-compact profile. Read-only + fail-soft.')
|
|
30
|
+
.option('--project <path>', 'project root (defaults to current directory)')
|
|
31
|
+
.option('--session-id <sessionId>', 'explicit session id (defaults to the canonical binding)')).action((options) => {
|
|
32
|
+
try {
|
|
33
|
+
const projectRoot = resolveCanonicalProjectRoot(options.project ?? process.cwd());
|
|
34
|
+
const status = resolveModeStatus({
|
|
35
|
+
projectRoot,
|
|
36
|
+
sessionId: options.sessionId ?? null
|
|
37
|
+
});
|
|
38
|
+
printResult(io, ok('code.mode.status', { projectRoot, ...status }, [], [
|
|
39
|
+
status.mode === null
|
|
40
|
+
? 'No presence mode recorded — Step 1 mode selection has not run for this session.'
|
|
41
|
+
: `mode=${status.mode} (${status.modeSource}) → auto-compact profile=${status.autoCompactProfile}`
|
|
42
|
+
]), options.json);
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
printResult(io, fail('code.mode.status', 'MODE_STATUS_FAILED', getErrorMessage(error), null, [
|
|
46
|
+
'Verify the project path and try again'
|
|
47
|
+
]), options.json);
|
|
48
|
+
process.exitCode = 1;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { resolveCanonicalProjectRoot } from '../../services/config/config-service.js';
|
|
2
2
|
import { read24hState, write24hState } from '../../services/24h-mode/index.js';
|
|
3
|
+
import { applyAutoEngagePresenceMode } from '../../services/24h-mode/auto-engage.js';
|
|
3
4
|
import { getErrorMessage } from '../cli-helpers.js';
|
|
4
5
|
function emit(io, payload, json) {
|
|
5
6
|
io.stdout((json === true ? JSON.stringify(payload) : JSON.stringify(payload, null, 2)) + '\n');
|
|
@@ -54,9 +55,15 @@ export function registerCodeRunCommand(code, io) {
|
|
|
54
55
|
enteredFrom: current.state,
|
|
55
56
|
exitCondition: null
|
|
56
57
|
});
|
|
58
|
+
// Slice 2026-09-09-mode-consolidation (Slice B): auto-engage is the
|
|
59
|
+
// ONLY path allowed to set a mode without a user pick, and `24h` is
|
|
60
|
+
// the only mode it may set. Stamp it onto the in-flight presence
|
|
61
|
+
// lease so the mode gate / statusline / `peaks code mode status`
|
|
62
|
+
// see the same autonomy level the 24h state machine is running.
|
|
63
|
+
const presenceMode = applyAutoEngagePresenceMode({ projectRoot, sessionId: sid });
|
|
57
64
|
emit(io, {
|
|
58
65
|
ok: true,
|
|
59
|
-
data: { changeId: changeId ?? null, mode: '24H_ACTIVE', state: nextState, autoEngaged: true, trigger: options.trigger ?? options.tier, sessionId: sid, path: next.path },
|
|
66
|
+
data: { changeId: changeId ?? null, mode: '24H_ACTIVE', state: nextState, autoEngaged: true, trigger: options.trigger ?? options.tier, sessionId: sid, path: next.path, presenceMode },
|
|
60
67
|
next: 'Continue the existing 24H_ACTIVE flow; no brainstorming gate is required for T3/T4.'
|
|
61
68
|
}, options.json);
|
|
62
69
|
}
|
|
@@ -140,7 +140,11 @@ export function registerCodeRuntimeCommands(code, io) {
|
|
|
140
140
|
'hermes / openclaw register their own env-var via IdeAdapter.compact. ' +
|
|
141
141
|
'v3.1.2: when --enforce-job-mode is set OR job-shape.json says isJob=true, ' +
|
|
142
142
|
'≥0.85 emits action=auto-compact-now (MANDATORY, not advisory) and ' +
|
|
143
|
-
'≥0.95 emits action=red-line (forced hook fires next turn).'
|
|
143
|
+
'≥0.95 emits action=red-line (forced hook fires next turn). ' +
|
|
144
|
+
'Context-window override: set env PEAKS_CONTEXT_WINDOW_TOKENS=<positive int> ' +
|
|
145
|
+
'or `peaks config set --key context.windowTokens --value <positive int>`; ' +
|
|
146
|
+
'the JSON envelope reports the winning layer as capacitySource ' +
|
|
147
|
+
'(env-override | config | model-heuristic | default).')
|
|
144
148
|
.requiredOption('--project <path>', 'target project root')
|
|
145
149
|
.option('--session-id <sid>', 'override session id (default: read from active presence)')
|
|
146
150
|
.option('--enforce-job-mode', 'v3.1.2: treat ≥0.85 as MANDATORY auto-compact (not advisory). Auto-enabled when job-shape.json says isJob=true.')
|
|
@@ -190,12 +194,12 @@ export function registerCodeRuntimeCommands(code, io) {
|
|
|
190
194
|
let next = null;
|
|
191
195
|
if (probe.ratio >= 0.95) {
|
|
192
196
|
action = isJobMode ? 'red-line' : 'red-line';
|
|
193
|
-
next = 'peaks
|
|
197
|
+
next = 'peaks code auto-compact';
|
|
194
198
|
}
|
|
195
199
|
else if (probe.ratio >= 0.85) {
|
|
196
200
|
if (isJobMode) {
|
|
197
201
|
action = 'auto-compact-now';
|
|
198
|
-
next = 'peaks
|
|
202
|
+
next = 'peaks code auto-compact';
|
|
199
203
|
}
|
|
200
204
|
else {
|
|
201
205
|
action = 'soft-warn';
|
|
@@ -224,6 +228,10 @@ export function registerCodeRuntimeCommands(code, io) {
|
|
|
224
228
|
rawBytes: probe.rawBytes ?? null,
|
|
225
229
|
rawTokens: probe.rawTokens ?? null,
|
|
226
230
|
capacityTokens: probe.capacityTokens ?? null,
|
|
231
|
+
// Slice 2026-09-09-context-window-override: which layer produced
|
|
232
|
+
// capacityTokens (env-override | config | model-heuristic |
|
|
233
|
+
// default) — null for byte/percent sources, which have no window.
|
|
234
|
+
capacitySource: probe.capacitySource ?? null,
|
|
227
235
|
bytesPrompt: promptSizeBytes ?? null,
|
|
228
236
|
capturedAt: probe.capturedAt
|
|
229
237
|
}, [], [
|
|
@@ -233,8 +241,8 @@ export function registerCodeRuntimeCommands(code, io) {
|
|
|
233
241
|
? `Job-mode MANDATORY auto-compact. Code MUST call \`${next}\` WITHOUT confirmation.`
|
|
234
242
|
: action === 'soft-warn'
|
|
235
243
|
? isJobMode
|
|
236
|
-
? `Job mode soft-warn (50–85%). Continue working; the next \`peaks
|
|
237
|
-
: `Soft warn (50–85%). Continue working; the next \`peaks
|
|
244
|
+
? `Job mode soft-warn (50–85%). Continue working; the next \`peaks code auto-compact\` will re-check.`
|
|
245
|
+
: `Soft warn (50–85%). Continue working; the next \`peaks code auto-compact\` will re-check.`
|
|
238
246
|
: `Below 50%. No action required.`,
|
|
239
247
|
jobModeNotice
|
|
240
248
|
]), true);
|
|
@@ -202,7 +202,7 @@ export function registerSkillCommand(program, io) {
|
|
|
202
202
|
const projectOption = canonicalizeProjectOption(options.project);
|
|
203
203
|
const projectRoot = projectOption ?? findProjectRoot(process.cwd()) ?? process.cwd();
|
|
204
204
|
if (options.mode !== undefined && !isSkillPresenceMode(options.mode)) {
|
|
205
|
-
printResult(io, fail('skill.presence:set', 'INVALID_MODE', `Invalid mode: ${options.mode} (expected one of: full-auto, assisted,
|
|
205
|
+
printResult(io, fail('skill.presence:set', 'INVALID_MODE', `Invalid mode: ${options.mode} (expected one of: full-auto, assisted, strict, 24h)`, { name, mode: options.mode }, ['Use a valid mode: full-auto, assisted, strict, or 24h']), options.json);
|
|
206
206
|
process.exitCode = 1;
|
|
207
207
|
return;
|
|
208
208
|
}
|
|
@@ -4,7 +4,7 @@ import { fail, ok } from 'peaks-loop-shared/result';
|
|
|
4
4
|
export function registerEccCommands(program, io) {
|
|
5
5
|
const ecc = program
|
|
6
6
|
.command('ecc')
|
|
7
|
-
.description('affaan-m/
|
|
7
|
+
.description('affaan-m/ECC cache: download + read-only access for the LLM (no subprocess; no peaks agent run).');
|
|
8
8
|
addJsonOption(ecc
|
|
9
9
|
.command('install')
|
|
10
10
|
.description('Download affaan-m/ECC to ~/.peaks/cache/ecc-<sha>/ (selective extract: agents/ subtree only).')
|
|
@@ -14,6 +14,7 @@ export function registerEccCommands(program, io) {
|
|
|
14
14
|
const result = await downloadToCache(options.ref !== undefined && options.ref.length > 0 ? { ref: options.ref } : {});
|
|
15
15
|
const envelope = ok('ecc.install', result, [], [
|
|
16
16
|
`Cache landed at ~/.peaks/cache/ecc-${result.sha}/agents/`,
|
|
17
|
+
`Plugin-free copy materialized at ~/.peaks/agents/ecc/ (read it directly when the ECC plugin is absent)`,
|
|
17
18
|
`Inspect with: peaks ecc ls`,
|
|
18
19
|
`Consume one agent with: peaks ecc show <name>`,
|
|
19
20
|
]);
|
|
@@ -23,7 +24,7 @@ export function registerEccCommands(program, io) {
|
|
|
23
24
|
const message = getErrorMessage(error);
|
|
24
25
|
printResult(io, fail('ecc.install', 'FETCH_FAILED', message, { ref: options.ref ?? 'latest' }, [
|
|
25
26
|
'Network failure during ECC download. Manual fallback:',
|
|
26
|
-
' git clone https://github.com/affaan-m/
|
|
27
|
+
' git clone https://github.com/affaan-m/ECC.git',
|
|
27
28
|
' Copy <repo>/agents/*.md into ~/.peaks/cache/ecc-<sha>/agents/.',
|
|
28
29
|
' Drop a minimal ecc-installed.json manifest into ~/.peaks/cache/.',
|
|
29
30
|
]), asJson);
|
|
@@ -10,7 +10,7 @@ export function registerProjectCommands(program, io) {
|
|
|
10
10
|
const project = program.command('project').description('Aggregate Peaks state for a target project (read-only)');
|
|
11
11
|
addJsonOption(project
|
|
12
12
|
.command('dashboard')
|
|
13
|
-
.description('One-call snapshot of doctor / MCP / OpenSpec / requests /
|
|
13
|
+
.description('One-call snapshot of doctor / MCP / OpenSpec / requests / capabilities for a project')
|
|
14
14
|
.requiredOption('--project <path>', 'target project root')
|
|
15
15
|
.option('--strict', 'ok follows the doctor aggregate (legacy semantics). Default: workspace-only (ok tracks the runbook health)', false)).action(async (options) => {
|
|
16
16
|
try {
|