peaks-cli 1.4.2 → 2.0.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/.claude-plugin/marketplace.json +51 -0
- package/CHANGELOG.md +238 -0
- package/README-en.md +226 -0
- package/README.md +152 -122
- package/dist/src/cli/commands/agent-commands.d.ts +20 -0
- package/dist/src/cli/commands/agent-commands.js +48 -0
- package/dist/src/cli/commands/audit-commands.d.ts +18 -0
- package/dist/src/cli/commands/audit-commands.js +138 -0
- package/dist/src/cli/commands/classify-classify-commands.d.ts +19 -0
- package/dist/src/cli/commands/classify-classify-commands.js +151 -0
- package/dist/src/cli/commands/code-review-commands.d.ts +34 -0
- package/dist/src/cli/commands/code-review-commands.js +83 -0
- package/dist/src/cli/commands/config-commands.js +90 -0
- package/dist/src/cli/commands/context-commands.d.ts +21 -0
- package/dist/src/cli/commands/context-commands.js +167 -0
- package/dist/src/cli/commands/core-artifact-commands.js +60 -2
- package/dist/src/cli/commands/hook-handle.js +50 -0
- package/dist/src/cli/commands/loop-commands.d.ts +21 -0
- package/dist/src/cli/commands/loop-commands.js +128 -0
- package/dist/src/cli/commands/openspec-commands.js +37 -0
- package/dist/src/cli/commands/preferences-commands.d.ts +2 -0
- package/dist/src/cli/commands/preferences-commands.js +147 -0
- package/dist/src/cli/commands/skill-conformance-commands.d.ts +9 -0
- package/dist/src/cli/commands/skill-conformance-commands.js +39 -0
- package/dist/src/cli/commands/understand-commands.js +34 -0
- package/dist/src/cli/commands/upgrade-commands.d.ts +23 -0
- package/dist/src/cli/commands/upgrade-commands.js +57 -0
- package/dist/src/cli/commands/workflow-commands.js +70 -0
- package/dist/src/cli/commands/workspace-commands.js +86 -0
- package/dist/src/cli/program.js +30 -0
- package/dist/src/services/agent/ecc-agent-service.d.ts +47 -0
- package/dist/src/services/agent/ecc-agent-service.js +143 -0
- package/dist/src/services/artifacts/request-artifact-service.js +14 -0
- package/dist/src/services/audit/backing-detector.d.ts +24 -0
- package/dist/src/services/audit/backing-detector.js +59 -0
- package/dist/src/services/audit/classifier.d.ts +38 -0
- package/dist/src/services/audit/classifier.js +127 -0
- package/dist/src/services/audit/enforcers/active-skill-resolver.d.ts +29 -0
- package/dist/src/services/audit/enforcers/active-skill-resolver.js +71 -0
- package/dist/src/services/audit/enforcers/design-draft-confirm.d.ts +25 -0
- package/dist/src/services/audit/enforcers/design-draft-confirm.js +54 -0
- package/dist/src/services/audit/enforcers/lint-audit-regression.d.ts +21 -0
- package/dist/src/services/audit/enforcers/lint-audit-regression.js +86 -0
- package/dist/src/services/audit/enforcers/lint-catalog-governance.d.ts +27 -0
- package/dist/src/services/audit/enforcers/lint-catalog-governance.js +38 -0
- package/dist/src/services/audit/enforcers/lint-cli-back.d.ts +16 -0
- package/dist/src/services/audit/enforcers/lint-cli-back.js +35 -0
- package/dist/src/services/audit/enforcers/lint-output-style.d.ts +11 -0
- package/dist/src/services/audit/enforcers/lint-output-style.js +94 -0
- package/dist/src/services/audit/enforcers/lint-reference-integrity.d.ts +6 -0
- package/dist/src/services/audit/enforcers/lint-reference-integrity.js +83 -0
- package/dist/src/services/audit/enforcers/lint-reference-shape.d.ts +30 -0
- package/dist/src/services/audit/enforcers/lint-reference-shape.js +272 -0
- package/dist/src/services/audit/enforcers/lint-style.d.ts +49 -0
- package/dist/src/services/audit/enforcers/lint-style.js +173 -0
- package/dist/src/services/audit/enforcers/lint-workflow-shape.d.ts +5 -0
- package/dist/src/services/audit/enforcers/lint-workflow-shape.js +141 -0
- package/dist/src/services/audit/enforcers/login-gate.d.ts +23 -0
- package/dist/src/services/audit/enforcers/login-gate.js +40 -0
- package/dist/src/services/audit/enforcers/mock-placement.d.ts +25 -0
- package/dist/src/services/audit/enforcers/mock-placement.js +48 -0
- package/dist/src/services/audit/enforcers/no-root-pollution.d.ts +21 -0
- package/dist/src/services/audit/enforcers/no-root-pollution.js +56 -0
- package/dist/src/services/audit/enforcers/pre-rd-scan.d.ts +22 -0
- package/dist/src/services/audit/enforcers/pre-rd-scan.js +23 -0
- package/dist/src/services/audit/enforcers/prototype-fidelity.d.ts +25 -0
- package/dist/src/services/audit/enforcers/prototype-fidelity.js +75 -0
- package/dist/src/services/audit/enforcers/resume-detection.d.ts +21 -0
- package/dist/src/services/audit/enforcers/resume-detection.js +52 -0
- package/dist/src/services/audit/enforcers/solo-code-ban.d.ts +23 -0
- package/dist/src/services/audit/enforcers/solo-code-ban.js +27 -0
- package/dist/src/services/audit/enforcers/sub-agent-sid.d.ts +25 -0
- package/dist/src/services/audit/enforcers/sub-agent-sid.js +63 -0
- package/dist/src/services/audit/enforcers/tech-doc-presence.d.ts +28 -0
- package/dist/src/services/audit/enforcers/tech-doc-presence.js +35 -0
- package/dist/src/services/audit/red-line-catalog-p2-a.d.ts +21 -0
- package/dist/src/services/audit/red-line-catalog-p2-a.js +233 -0
- package/dist/src/services/audit/red-line-catalog-p2-b.d.ts +19 -0
- package/dist/src/services/audit/red-line-catalog-p2-b.js +225 -0
- package/dist/src/services/audit/red-line-catalog.d.ts +51 -0
- package/dist/src/services/audit/red-line-catalog.js +210 -0
- package/dist/src/services/audit/red-lines-service.d.ts +23 -0
- package/dist/src/services/audit/red-lines-service.js +486 -0
- package/dist/src/services/audit/scanners/openspec-scanner.d.ts +15 -0
- package/dist/src/services/audit/scanners/openspec-scanner.js +55 -0
- package/dist/src/services/audit/scanners/rules-tree-scanner.d.ts +16 -0
- package/dist/src/services/audit/scanners/rules-tree-scanner.js +56 -0
- package/dist/src/services/audit/scanners/skills-tree-scanner.d.ts +17 -0
- package/dist/src/services/audit/scanners/skills-tree-scanner.js +46 -0
- package/dist/src/services/audit/static-service.d.ts +57 -0
- package/dist/src/services/audit/static-service.js +125 -0
- package/dist/src/services/audit/types.d.ts +69 -0
- package/dist/src/services/audit/types.js +13 -0
- package/dist/src/services/classify/classify-service.d.ts +42 -0
- package/dist/src/services/classify/classify-service.js +122 -0
- package/dist/src/services/classify/classify-types.d.ts +79 -0
- package/dist/src/services/classify/classify-types.js +90 -0
- package/dist/src/services/code-review/ocr-service.d.ts +129 -0
- package/dist/src/services/code-review/ocr-service.js +362 -0
- package/dist/src/services/config/config-migration.d.ts +32 -0
- package/dist/src/services/config/config-migration.js +92 -0
- package/dist/src/services/config/config-restore.d.ts +10 -0
- package/dist/src/services/config/config-restore.js +47 -0
- package/dist/src/services/config/config-rollback.d.ts +13 -0
- package/dist/src/services/config/config-rollback.js +26 -0
- package/dist/src/services/config/config-service.d.ts +35 -2
- package/dist/src/services/config/config-service.js +81 -0
- package/dist/src/services/config/config-types.d.ts +58 -0
- package/dist/src/services/config/config-types.js +6 -0
- package/dist/src/services/doctor/doctor-service.js +96 -0
- package/dist/src/services/ide/adapters/hermes-adapter.d.ts +21 -0
- package/dist/src/services/ide/adapters/hermes-adapter.js +51 -0
- package/dist/src/services/ide/adapters/openclaw-adapter.d.ts +14 -0
- package/dist/src/services/ide/adapters/openclaw-adapter.js +42 -0
- package/dist/src/services/ide/ide-registry.js +7 -0
- package/dist/src/services/ide/ide-types.d.ts +1 -1
- package/dist/src/services/openspec/openspec-propose-from-doctor-service.d.ts +31 -0
- package/dist/src/services/openspec/openspec-propose-from-doctor-service.js +95 -0
- package/dist/src/services/preferences/preferences-service.d.ts +6 -0
- package/dist/src/services/preferences/preferences-service.js +43 -0
- package/dist/src/services/preferences/preferences-types.d.ts +90 -0
- package/dist/src/services/preferences/preferences-types.js +38 -0
- package/dist/src/services/skills/skill-conformance-service.d.ts +40 -0
- package/dist/src/services/skills/skill-conformance-service.js +136 -0
- package/dist/src/services/skills/skill-runbook-service.js +44 -10
- package/dist/src/services/skills/sync-service.d.ts +43 -0
- package/dist/src/services/skills/sync-service.js +99 -0
- package/dist/src/services/slice/slice-check-service.js +166 -13
- package/dist/src/services/slice/slice-check-types.d.ts +1 -1
- package/dist/src/services/standards/migrate-claude-rules-service.d.ts +19 -0
- package/dist/src/services/standards/migrate-claude-rules-service.js +193 -0
- package/dist/src/services/understand/understand-scan-service.js +15 -2
- package/dist/src/services/understand/understand-types.d.ts +26 -0
- package/dist/src/services/upgrade/1x-detector-service.d.ts +7 -0
- package/dist/src/services/upgrade/1x-detector-service.js +94 -0
- package/dist/src/services/upgrade/gitignore-migrate-service.d.ts +56 -0
- package/dist/src/services/upgrade/gitignore-migrate-service.js +170 -0
- package/dist/src/services/upgrade/upgrade-service.d.ts +47 -0
- package/dist/src/services/upgrade/upgrade-service.js +381 -0
- package/dist/src/services/workspace/sid-naming-guard.d.ts +14 -0
- package/dist/src/services/workspace/sid-naming-guard.js +31 -0
- package/dist/src/services/workspace/workspace-archive-service.d.ts +19 -0
- package/dist/src/services/workspace/workspace-archive-service.js +32 -0
- package/dist/src/services/workspace/workspace-clean-service.d.ts +41 -0
- package/dist/src/services/workspace/workspace-clean-service.js +86 -0
- package/dist/src/services/workspace/workspace-state-service.d.ts +7 -0
- package/dist/src/services/workspace/workspace-state-service.js +43 -0
- package/dist/src/shared/change-id.js +4 -1
- package/dist/src/shared/version.d.ts +1 -1
- package/dist/src/shared/version.js +1 -1
- package/package.json +8 -2
- package/schemas/doctor-report.schema.json +1 -1
- package/scripts/install-skills.mjs +296 -12
- package/skills/peaks-doctor/SKILL.md +59 -0
- package/skills/peaks-doctor/references/doctor-check-catalog.md +31 -0
- package/skills/peaks-doctor/references/from-doctor-flow.md +64 -0
- package/skills/peaks-doctor/test_prompts.json +17 -0
- package/skills/peaks-ide/SKILL.md +2 -0
- package/skills/peaks-qa/SKILL.md +9 -7
- package/skills/peaks-qa/references/artifact-per-request.md +19 -5
- package/skills/peaks-qa/references/qa-perf-test-plan.md +6 -6
- package/skills/peaks-qa/references/qa-runbook.md +1 -1
- package/skills/peaks-rd/SKILL.md +25 -10
- package/skills/peaks-rd/references/ocr-integration.md +214 -0
- package/skills/peaks-rd/references/rd-fanout-contracts.md +70 -0
- package/skills/peaks-rd/references/rd-runbook.md +1 -1
- package/skills/peaks-solo/SKILL.md +10 -4
- package/skills/peaks-solo/references/step-0-55-1x-detection.md +82 -0
- package/skills/peaks-solo/references/workflow-gates-and-types.md +9 -0
package/README.md
CHANGED
|
@@ -1,35 +1,60 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# ⛰️ Peaks
|
|
4
|
+
|
|
5
|
+
**让 AI IDE 像一支训练有素的工程团队一样工作**
|
|
2
6
|
|
|
3
7
|
[English](./README-en.md) | **简体中文**
|
|
4
8
|
|
|
5
9
|
[](https://www.npmjs.com/package/peaks-cli)
|
|
10
|
+
[](https://github.com/SquabbyZ/peaks-cli/stargazers)
|
|
6
11
|
[](https://github.com/SquabbyZ/peaks-cli)
|
|
12
|
+
[](https://skills.sh/SquabbyZ/peaks-cli)
|
|
13
|
+
[](LICENSE)
|
|
14
|
+
|
|
15
|
+
**一个 CLI + 11 个工作流技能,把 LLM 的随意发挥变成可审计的工程流程。**
|
|
16
|
+
|
|
17
|
+
[安装](#-30-秒跑起来) · [5 分钟上手](#-5-分钟上手) · [技能家族](#-11-个技能家族) · [杀手锏:不可绕过的门禁](#-杀手锏不可绕过的门禁)
|
|
18
|
+
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 🤔 为什么是 Peaks
|
|
7
24
|
|
|
8
|
-
|
|
25
|
+
> 你把 `git push --force`、`rm -rf`、`npm publish`、`DROP TABLE` 这类不可逆动作**写进 CLAUDE.md** 吗?
|
|
26
|
+
> LLM 不会真听。它有 99% 的概率会"尊重你的偏好",然后在下一次对话里忘掉。
|
|
27
|
+
> **CI 只能在合并时拦;规则只能靠自觉;只有门禁(gates)能在 agent 拔刀的瞬间摁住它。**
|
|
9
28
|
|
|
10
|
-
|
|
11
|
-
> - ✅ **Claude Code**(shipped, 当前主用):11 个 `peaks-*` 技能 + `.claude/settings.json` PreToolUse hook;agent team 在本 IDE 已 dogfood
|
|
12
|
-
> - ⚠️ **Trae**(adapter shipped, real-Trae unverified):slim `IdeAdapter` 已注册到 slice #1 registry(`hookEvent` / `toolMatcher` / `envVar` 是 1.x 假设,**未在真实 Trae 上验证**);真实 Trae 集成 dogfood 留到后续切片
|
|
13
|
-
> - 📋 **Codex / Cursor / Qoder / 通义灵码 等**(路线图)
|
|
29
|
+
Peaks 把 AI IDE 里的"工程团队"建模成 11 个工作流技能 + 一组**可执行的门禁**:
|
|
14
30
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
31
|
+
- 🧭 **技能(skills)**——`peaks-solo` 编排,`peaks-prd/rd/qa/ui/sc/txt/sop` 各管一段;LLM 按任务自动选对的人
|
|
32
|
+
- 🚧 **门禁(gates)**——SOP 在每个 phase 上挂"可检查条件"(文件存在 / grep 命中 / 命令退出码),不满足就把 `git push` 在 agent 自己面前拦下——**连 `--dangerously-skip-permissions` 都绕不过**
|
|
33
|
+
- 🧠 **项目记忆(memory)**——`.peaks/memory/` 把决策、踩坑、约定落盘到 git 一起被 commit;下个 session 接手不用问"为什么这么写"
|
|
34
|
+
- 🌐 **跨 IDE**——一个 CLI 适配 Claude Code / Trae / Cursor / Codex / Qoder;技能注册到 IDE 原生格式
|
|
35
|
+
- 📦 **生态可发现**——11 个技能同样发布到 [skills.sh](https://skills.sh),按需 `npx skills add` 单点装
|
|
18
36
|
|
|
19
|
-
##
|
|
37
|
+
## 🚀 30 秒跑起来
|
|
20
38
|
|
|
21
39
|
```bash
|
|
40
|
+
# 1. 装 CLI
|
|
22
41
|
npm install -g peaks-cli
|
|
42
|
+
|
|
43
|
+
# 2. 在你的项目里打开 Claude Code
|
|
44
|
+
cd /path/to/your-project && claude
|
|
45
|
+
|
|
46
|
+
# 3. 让 AI 干活
|
|
47
|
+
> peaks-solo 帮我给登录页加 OAuth 回调
|
|
23
48
|
```
|
|
24
49
|
|
|
25
|
-
|
|
50
|
+
完了。第一次跑 peaks 会自动建 `.peaks/` 工作区 + 扫一次项目原型 + 把任务分给对的技能(PRD → 工程切片 → UI → QA → 变更控制 → 知识压缩),中间产物全部落盘。**日常使用 1 个技能(`peaks-solo`)覆盖 ≥ 90% 的需求**。
|
|
26
51
|
|
|
27
|
-
## 5 分钟上手
|
|
52
|
+
## ⏱️ 5 分钟上手
|
|
28
53
|
|
|
29
|
-
|
|
54
|
+
在 IDE 对话里直接对 AI 说:
|
|
30
55
|
|
|
31
56
|
```text
|
|
32
|
-
peaks-solo 帮我给登录页加 OAuth 回调 #
|
|
57
|
+
peaks-solo 帮我给登录页加 OAuth 回调 # 端到端编排(最常用)
|
|
33
58
|
peaks-prd 为会员邀请功能整理产品目标、非目标和验收标准
|
|
34
59
|
peaks-rd 分析这次重构的最小实现切片和风险
|
|
35
60
|
peaks-qa 为这次改动设计测试和回归验证清单
|
|
@@ -39,158 +64,163 @@ peaks-txt 为当前模块生成上下文胶囊,保留关键决策
|
|
|
39
64
|
peaks-sop 帮我把"内容发布"流程变成带门禁的 SOP
|
|
40
65
|
```
|
|
41
66
|
|
|
42
|
-
|
|
67
|
+
**两种基本用法**:
|
|
68
|
+
|
|
69
|
+
1. **让 `peaks-solo` 编排**(绝大多数情况)——告诉它做什么,剩下 PRD → RD → UI → QA → SC → TXT 的链路它自己协调
|
|
70
|
+
2. **直接调单个角色技能**(进阶)——只想做工作流的某一段时,跳过整 pipeline
|
|
71
|
+
|
|
72
|
+
随时确认状态?让 AI 跑一下:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
peaks -V # 版本
|
|
76
|
+
peaks doctor --json # 环境/技能/配置一键体检
|
|
77
|
+
peaks project dashboard --project . --json # 当前项目一眼看完
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## 🧰 11 个技能家族
|
|
43
81
|
|
|
44
|
-
|
|
82
|
+
| 技能 | 你用它做什么 | 典型场景 |
|
|
83
|
+
|------|------------|----------|
|
|
84
|
+
| `peaks-solo` | **端到端编排入口**,自动协调 prd/rd/ui/qa/sc/txt | 全流程开发、PRD-to-ship、跨子任务批量迭代 |
|
|
85
|
+
| `peaks-prd` | 模糊意图 → **可验收 PRD**(目标/非目标/行为保留/验收) | 需求整理、PRD 撰写、重构目标 |
|
|
86
|
+
| `peaks-rd` | 工程分析 + 切片规划 + 风险 + 执行契约 | 架构分析、最小切片、风险评估 |
|
|
87
|
+
| `peaks-qa` | 测试设计 + 覆盖率 + 回归矩阵 + 验收证据 | 测试用例、回归、浏览器 E2E |
|
|
88
|
+
| `peaks-ui` | 视觉方向 + 交互方案 + 设计系统约束 | 页面设计、交互、原型、UI 回归 |
|
|
89
|
+
| `peaks-sc` | 变更追踪 + commit 边界 + 留存策略 + 回滚证据 | 影响范围、变更控制、审计 |
|
|
90
|
+
| `peaks-txt` | 上下文胶囊 + 决策记录 + 知识压缩 | 模块理解、决策留存、复盘 |
|
|
91
|
+
| `peaks-sop` | **把你的工作流变成带门禁的 SOP**(不只研发) | 内容发布、合规清单、数据 pipeline、运维 runbook |
|
|
92
|
+
| `peaks-solo-resume` | 继续刚才没做完的切片 | 「继续完成刚才未完成的」 |
|
|
93
|
+
| `peaks-solo-status` | 一眼看到现在到哪了 | 「现在到哪了」 |
|
|
94
|
+
| `peaks-solo-test` | 跑项目测试(自动探测 vitest/jest/pytest/...) | 「跑测试」 |
|
|
45
95
|
|
|
46
|
-
1
|
|
47
|
-
2. 在 IDE 里对 AI 说:**`peaks-solo 帮我做 X`**(X = 需求描述,如"给登录页加 OAuth 回调")
|
|
48
|
-
- LLM 会按任务和项目推荐模式;想直接定可以写 `peaks-solo 全自动做 X` / `peaks-solo swarm X` / `peaks-solo strict X`
|
|
96
|
+
**3 solo 包装 + 7 角色技能 + 1 编排器 = 11 个。日常 1 个 `peaks-solo` 覆盖 ≥ 90%。**
|
|
49
97
|
|
|
50
|
-
|
|
98
|
+
## 🚧 杀手锏:不可绕过的门禁
|
|
51
99
|
|
|
52
|
-
|
|
53
|
-
- 复杂任务按 PRD → RD → UI → QA → SC → TXT 协调;简单任务直接走 solo 全自动,无需分阶段
|
|
54
|
-
- 工作流进行中可用 `peaks-solo-status` 看看当前到哪了;中断后用 `peaks-solo-resume` 继续
|
|
55
|
-
- 工作流结束时把所有中间产物留在 `.peaks/<session-id>/`,并把"该记住的事实"写进 `.peaks/memory/`
|
|
100
|
+
> CI 只能在**合并时**拦;`CLAUDE.md` 规则靠 agent **自觉**。**SOP 能做到 CI 和提示词都做不到的事——在 agent 拔刀的瞬间把它摁住。**
|
|
56
101
|
|
|
57
|
-
|
|
102
|
+
```jsonc
|
|
103
|
+
// sop.json
|
|
104
|
+
"guards": [ { "phase": "publish", "bash": "git +push" } ]
|
|
105
|
+
```
|
|
58
106
|
|
|
59
107
|
```bash
|
|
60
|
-
peaks
|
|
61
|
-
peaks # 当前 quickstart + 已安装技能数
|
|
62
|
-
peaks doctor --json # 环境/技能/配置一键体检
|
|
63
|
-
peaks skill doctor --json
|
|
64
|
-
peaks project dashboard --project . --json # 当前项目 dashboard
|
|
108
|
+
peaks hooks install --project <repo> # 显式 opt-in:装一条 PreToolUse 规则
|
|
65
109
|
```
|
|
66
110
|
|
|
67
|
-
|
|
111
|
+
之后 agent 在 `publish` 阶段的门禁没全过就想 `git push`,Claude Code 会收到 `permissionDecision: "deny"`,**在任何权限检查之前就被拦下——连 `--dangerously-skip-permissions` 都绕不过**。门禁三种类型:
|
|
68
112
|
|
|
69
|
-
|
|
|
70
|
-
|
|
71
|
-
| `
|
|
72
|
-
| `
|
|
73
|
-
| `
|
|
74
|
-
| `peaks-ui` | UI/UX 交互和视觉约束、视觉方向、设计系统约束 | 页面设计、交互方案、原型、UI 回归 |
|
|
75
|
-
| `peaks-qa` | 测试设计 + 覆盖率 + 回归验证 + 验收证据 | 测试用例、回归矩阵、验收检查、浏览器 E2E |
|
|
76
|
-
| `peaks-sc` | 变更追踪、commit 边界、artifact 留存、回滚证据 | 影响范围记录、回滚证据、变更控制 |
|
|
77
|
-
| `peaks-txt` | 上下文胶囊、决策记录、知识压缩 | 模块理解、关键决策留存、复盘 |
|
|
78
|
-
| `peaks-sop` | **把你的工作流变成带门禁的 SOP**(不是研发专属) | 内容发布、合规清单、数据 pipeline、运维 runbook、个人流程 |
|
|
79
|
-
| `peaks-solo-resume` | **继续刚才没做完的切片**——一键检测 in-flight slice 的最深已完成 gate,省 3-5k token | 「继续完成刚才为完成的」「resume the unfinished slice」 |
|
|
80
|
-
| `peaks-solo-status` | **看一眼现在到哪了**——5-CLI snapshot 表格(presence + session + dashboard + request + memory) | 「现在到哪了」「show me the dashboard」 |
|
|
81
|
-
| `peaks-solo-test` | **跑项目测试**——从 `package.json` 探测测试工具(vitest / jest / mocha / pytest / ...),用项目原生命令跑并汇总 pass/fail | 「跑测试」「run the tests」 |
|
|
113
|
+
| 类型 | 含义 | 例子 |
|
|
114
|
+
|------|------|------|
|
|
115
|
+
| `file-exists` | 文件存在 → pass | `CHANGELOG.md` 存在 |
|
|
116
|
+
| `grep`(含 `absent`) | 文件内正则匹配 → pass;`absent: true` 反转 | "正文里没有 `TODO`" |
|
|
117
|
+
| `command` | 跑命令并按退出码判定(默认拒绝,需 `--allow-commands`) | 跑 `npm test` |
|
|
82
118
|
|
|
83
|
-
|
|
119
|
+
定义层(`sop.json` + `SKILL.md`)可以放**全局** `~/.peaks/sops/`(个人跨项目)或**仓库** `<repo>/.peaks/sops/`(随 git 提交、团队共享,仓库层优先)。**紧急放行**用 `peaks gate bypass --sop <id> --phase <phase> --reason "<原因>"`(一次性、记原因、有上限)。
|
|
84
120
|
|
|
85
|
-
|
|
121
|
+
## 🌍 真实场景
|
|
86
122
|
|
|
87
|
-
|
|
123
|
+
**场景 1:临时决定重构鉴权模块**
|
|
88
124
|
|
|
89
125
|
```text
|
|
90
|
-
peaks-
|
|
91
|
-
peaks-solo 全自动做 X # 显式 full-auto:端到端跑完
|
|
92
|
-
peaks-solo swarm 模式做 X # 显式 swarm:最大化子代理并行(适合大任务)
|
|
93
|
-
peaks-solo strict 模式做 X # 显式 strict:最严格门禁
|
|
126
|
+
> peaks-rd 分析 src/auth/ 的现状,给我一份最小切片方案
|
|
94
127
|
```
|
|
128
|
+
`peaks-rd` 出:3 阶段切片、风险评估、回归点、可执行契约。**写不写代码你定**。
|
|
95
129
|
|
|
96
|
-
|
|
130
|
+
**场景 2:把"内容发布"变成受控流程**
|
|
97
131
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
132
|
+
```text
|
|
133
|
+
> peaks-sop 帮我把"博客发布"做成带门禁的 SOP:草稿写完 → 自检(无 TODO/字数 ≥ 800) → 人工 review → 才允许发布
|
|
134
|
+
```
|
|
135
|
+
`peaks-sop` 生成 `sop.json` + `SKILL.md`,注册到全局,**从此 agent 跳过任何一步都发不出文章**。
|
|
101
136
|
|
|
102
|
-
|
|
137
|
+
**场景 3:浏览器 E2E 回归**
|
|
103
138
|
|
|
104
|
-
|
|
139
|
+
```text
|
|
140
|
+
> peaks-qa 用浏览器跑一次完整注册 → 登录 → 看板的核心流,把卡点列出来
|
|
141
|
+
```
|
|
142
|
+
`peaks-qa` 出:测试矩阵、回归清单、`code-review.md` 风格的证据文档。
|
|
105
143
|
|
|
106
|
-
|
|
107
|
-
|---|---|---|
|
|
108
|
-
| `peaks-prd` | 写 / 改 PRD(目标、非目标、行为保留、验收标准) | 想自己定义需求,不走 solo 整流程 |
|
|
109
|
-
| `peaks-rd` | 架构分析 + 最小切片规划 + 风险 | 只想拿一份技术分析,不要写代码 |
|
|
110
|
-
| `peaks-qa` | 测试用例 + 回归矩阵 + 验收证据 | 只想补测试,不走完整 solo |
|
|
111
|
-
| `peaks-ui` | 视觉方向 + 交互方案 + 设计系统约束 | 只做 UI 设计,不带实现 |
|
|
112
|
-
| `peaks-sc` | 影响范围 + commit 边界 + 留存策略 | 只想记录变更,不触发整流程 |
|
|
113
|
-
| `peaks-txt` | 上下文胶囊 + 决策记录 | 只想压缩知识,不走整流程 |
|
|
114
|
-
| `peaks-sop` | 把任意工作流(不只是开发)变成带门禁的 SOP | 想定义 / 注册自己的 SOP |
|
|
144
|
+
**场景 4:第二天回来继续昨天的切片**
|
|
115
145
|
|
|
116
|
-
|
|
146
|
+
```text
|
|
147
|
+
> peaks-solo-resume
|
|
148
|
+
```
|
|
149
|
+
检测 in-flight slice 的最深已完成 gate,省 3-5k token 重新读 artifact。**会话断了不丢上下文**。
|
|
117
150
|
|
|
118
|
-
##
|
|
151
|
+
## 📦 在 skills.sh 上发现 peaks 技能
|
|
119
152
|
|
|
120
|
-
|
|
153
|
+
peaks 的 11 个 `peaks-*` 技能自动收录到 [skills.sh](https://skills.sh) 注册表——**不需要单独去 skills.sh 网站注册**。收录靠仓库里**自带配置**:
|
|
121
154
|
|
|
122
|
-
|
|
155
|
+
- 11 个 `skills/<name>/SKILL.md`(每个都有 `name` + `description` YAML frontmatter)—— skills.sh 的标准发现约定
|
|
156
|
+
- `.claude-plugin/marketplace.json` —— 显式列出 11 个公开技能(隐藏的内部 `peaks-doctor` / `peaks-ide` 通过 `metadata.internal: true` 屏蔽)
|
|
123
157
|
|
|
124
|
-
|
|
158
|
+
任何装了 `npx skills` 的环境(Claude Code、Cursor、Codex 等)都能直接拉取:
|
|
125
159
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
160
|
+
```bash
|
|
161
|
+
# 装全部 11 个:
|
|
162
|
+
npx skills add SquabbyZ/peaks-cli
|
|
129
163
|
|
|
130
|
-
|
|
164
|
+
# 或只装一个:
|
|
165
|
+
npx skills add SquabbyZ/peaks-cli --skill peaks-solo
|
|
166
|
+
npx skills add SquabbyZ/peaks-cli --skill peaks-rd
|
|
167
|
+
npx skills add SquabbyZ/peaks-cli --skill peaks-sop
|
|
168
|
+
```
|
|
131
169
|
|
|
132
|
-
|
|
170
|
+
浏览 [skills.sh/SquabbyZ/peaks-cli](https://skills.sh/SquabbyZ/peaks-cli) 看完整目录。技能和 `npm install -g peaks-cli` 是同一份内容——两条路径产物一致。
|
|
133
171
|
|
|
134
|
-
|
|
172
|
+
## 🛠️ 怎么用:技能优先,CLI 是门禁
|
|
135
173
|
|
|
136
|
-
|
|
137
|
-
peaks workspace init --project <repo> --json # 创建 .peaks/ 工作区(每个 session 一次)
|
|
138
|
-
peaks workspace reconcile --project <repo> --json # 4-tier heuristic 重新指向 canonical session,干掉孤儿 dir(默认 dry-run,--apply 才删)
|
|
139
|
-
peaks scan archetype --project <repo> --json # 探测项目原型(greenfield/legacy-frontend/...)
|
|
140
|
-
peaks scan libraries --project <repo> --json # 枚举依赖 + 解析 major,支持 monorepo
|
|
141
|
-
peaks request init/show/transition # PRD/RD/QA/SC 的请求状态机
|
|
142
|
-
peaks session list/info/title/rotate # session 元数据;rotate 丢弃绑定让下次 peaks 自动重生成
|
|
143
|
-
peaks sop init/lint/check/advance/register # 你的自定义 SOP 生命周期
|
|
144
|
-
peaks hooks install --project <repo> # 装门禁的 PreToolUse hook
|
|
145
|
-
peaks project dashboard --project <repo> --json # 整个项目一眼看完
|
|
146
|
-
peaks project memories --project <repo> --json # 读取 .peaks/memory/ 里的历史决策
|
|
147
|
-
```
|
|
174
|
+
`peaks <cmd>` CLI **不是日常使用的主要入口**。它存在有三个理由,全是机器层保障:
|
|
148
175
|
|
|
149
|
-
|
|
176
|
+
1. **不可逆动作的显式 opt-in**(`peaks sop init --apply`、`peaks openspec archive --apply`)—— 不能靠 LLM"自觉"挥下
|
|
177
|
+
2. **结构化 JSON 契约**(`peaks request show ... --json`、`peaks scan archetype ... --json`)—— 让技能读回可机读判决作为下游决策
|
|
178
|
+
3. **hook / CI / 脚本场景下能被程序化调用**(`peaks hooks install`、`peaks gate enforce`)—— 把"必须满足门禁才能做 X"从纸面规则变成可执行规则
|
|
150
179
|
|
|
151
|
-
|
|
180
|
+
一句话:**技能 = 流程的大脑;CLI = 流程的骨节**。
|
|
152
181
|
|
|
153
|
-
|
|
154
|
-
> 告诉 Claude "帮我把『内容发布』做成一个 SOP",它会引导你定义阶段、设定门禁、调试、注册,全程不用手写 JSON。
|
|
182
|
+
### 你**会**看到的 CLI 命令
|
|
155
183
|
|
|
156
|
-
|
|
184
|
+
```bash
|
|
185
|
+
peaks workspace init / reconcile / scan archetype / scan libraries
|
|
186
|
+
peaks request init / show / transition # PRD/RD/QA/SC 请求状态机
|
|
187
|
+
peaks session list / info / title / rotate
|
|
188
|
+
peaks sop init / lint / check / advance / register
|
|
189
|
+
peaks code-review detect-ocr / config-template / run-ocr # 阿里 Open Code Review 第二意见
|
|
190
|
+
peaks hooks install / gate enforce / gate bypass
|
|
191
|
+
peaks project dashboard / memories
|
|
192
|
+
```
|
|
157
193
|
|
|
158
|
-
`peaks
|
|
194
|
+
完整列表跑 `peaks --help`。
|
|
159
195
|
|
|
160
|
-
|
|
161
|
-
|------|---------|---------|
|
|
162
|
-
| 内容 / 发布 | draft → edit → publish | `file-exists` 草稿;`grep` 没有 `TODO`/`TKTK`;`command` 跑字数/拼写检查 |
|
|
163
|
-
| 合规 / 审批 | prepare → review → sign-off | `file-exists` `approval.md`;`grep` 包含 "Approved" |
|
|
164
|
-
| 数据 pipeline | raw → cleaned → validated | `command` 跑校验脚本,退出码 0 |
|
|
165
|
-
| 运维 / 入职 | request → provision → done | `file-exists` 每个清单产物;`command` 校验配置 |
|
|
166
|
-
| 研发发布(典型但非唯一) | draft → review → ship | `file-exists` CHANGELOG;`grep` 源码里没有 `FIXME`;`command` 跑测试 |
|
|
167
|
-
| 个人流程 | 任何"不要忘步骤 X"的流程 | 把"判断"重新物化成一个文件/文本/退出码 |
|
|
196
|
+
## 🌐 支持的 IDE
|
|
168
197
|
|
|
169
|
-
|
|
198
|
+
| IDE | 状态 |
|
|
199
|
+
|---|---|
|
|
200
|
+
| ✅ **Claude Code** | 11 技能 + PreToolUse hook,agent team dogfood 通过 |
|
|
201
|
+
| ⚠️ **Trae** | slim `IdeAdapter` 已注册,真实 Trae 集成留到后续切片 |
|
|
202
|
+
| 📋 **Codex / Cursor / Qoder / 通义灵码 等** | 路线图 |
|
|
170
203
|
|
|
171
|
-
|
|
172
|
-
|------|------|------|
|
|
173
|
-
| `file-exists` | 文件存在 → pass | `CHANGELOG.md` 存在 |
|
|
174
|
-
| `grep`(含 `absent`) | 文件内正则匹配 → pass;加 `absent: true` 反转("不准有 X") | "正文里没有 `TODO`" |
|
|
175
|
-
| `command` | 跑命令并按退出码判定(默认拒绝,需 `--allow-commands`) | 跑 `npm test` |
|
|
204
|
+
## 🏗️ 项目状态
|
|
176
205
|
|
|
177
|
-
|
|
206
|
+
- ✅ **11 技能** + 跨 IDE CLI + 2800+ 测试
|
|
207
|
+
- ✅ **门禁机制** 已在真实项目 dogfood
|
|
208
|
+
- 📋 路线图:Trae / Codex / Cursor 真实集成、`peaks-doc` / `peaks-i18n`、SOP 模板市场
|
|
178
209
|
|
|
179
|
-
|
|
210
|
+
详细看 [`CHANGELOG.md`](./CHANGELOG.md) 和 [`docs/`](./docs/)。
|
|
180
211
|
|
|
181
|
-
|
|
182
|
-
// sop.json
|
|
183
|
-
"guards": [ { "phase": "publish", "bash": "git +push" } ]
|
|
184
|
-
```
|
|
212
|
+
## 📄 许可
|
|
185
213
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
214
|
+
[MIT](LICENSE) — 商用、改、私有 fork 都欢迎,保留版权即可。
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
<div align="center">
|
|
189
219
|
|
|
190
|
-
|
|
220
|
+
**觉得有用?**
|
|
191
221
|
|
|
192
|
-
|
|
222
|
+
⭐ [Star peaks-cli on GitHub](https://github.com/SquabbyZ/peaks-cli) · 🔍 [Browse on skills.sh](https://skills.sh/SquabbyZ/peaks-cli)
|
|
193
223
|
|
|
194
|
-
|
|
224
|
+
让你的 AI IDE 像一支训练有素的工程团队。
|
|
195
225
|
|
|
196
|
-
|
|
226
|
+
</div>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* peaks agent * CLI surface — Slice: ECC 64 agents soft-optional
|
|
3
|
+
* integration (per spec §7.2 line 818).
|
|
4
|
+
*
|
|
5
|
+
* Registers the new `peaks agent` top-level command with two
|
|
6
|
+
* subcommands:
|
|
7
|
+
* - `peaks agent run <name> [--target <path>]` — shell out to
|
|
8
|
+
* `npx ecc agent run <name> --target <path> --json` when ECC
|
|
9
|
+
* is installed; soft-fail with the 4-option install prompt
|
|
10
|
+
* when it isn't.
|
|
11
|
+
* - `peaks agent list` — emit the 12
|
|
12
|
+
* canonical ECC agents (the wrapper hardcodes the
|
|
13
|
+
* most-used subset; the full 64-agent list is
|
|
14
|
+
* discoverable at runtime via `npx ecc agent list`).
|
|
15
|
+
*
|
|
16
|
+
* The wrapper service is `src/services/agent/ecc-agent-service.ts`.
|
|
17
|
+
*/
|
|
18
|
+
import { Command } from 'commander';
|
|
19
|
+
import { type ProgramIO } from '../cli-helpers.js';
|
|
20
|
+
export declare function registerAgentCommands(program: Command, io: ProgramIO): void;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { runEccAgent, validateEccAgent, CANONICAL_ECC_AGENTS, } from '../../services/agent/ecc-agent-service.js';
|
|
2
|
+
import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
|
|
3
|
+
import { fail, ok } from '../../shared/result.js';
|
|
4
|
+
export function registerAgentCommands(program, io) {
|
|
5
|
+
const agent = program
|
|
6
|
+
.command('agent')
|
|
7
|
+
.description('Run an ECC agent (soft-optional per spec §7.2). 64 agents are npm-installable via npx ecc; peaks-cli shells out when ECC is installed and soft-fails with a 4-option install prompt when it is not. Native peaks-cli diagnostics still run via `peaks doctor scan`.');
|
|
8
|
+
addJsonOption(agent
|
|
9
|
+
.command('run <name>')
|
|
10
|
+
.description(`Run an ECC agent by name (e.g. 'security-reviewer', 'code-reviewer'). The canonical subprocess is \`npx ecc agent run <name> --target <path> --json\`.`)
|
|
11
|
+
.option('--target <path>', 'project root or file to analyze (default: cwd)')
|
|
12
|
+
.option('--enable', 'enable the ECC subprocess for this call (overrides default-off; soft-fails with the 4-option install prompt when ECC is missing)')).action(async (name, options) => {
|
|
13
|
+
const validationError = validateEccAgent(name);
|
|
14
|
+
if (validationError !== null) {
|
|
15
|
+
printResult(io, fail('agent.run', 'INVALID_AGENT_NAME', validationError, { agent: name }, [
|
|
16
|
+
'Use `peaks agent list` to see the canonical 12 agents',
|
|
17
|
+
]), options.json);
|
|
18
|
+
process.exitCode = 1;
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const projectRoot = options.target ?? process.cwd();
|
|
22
|
+
try {
|
|
23
|
+
const result = runEccAgent({
|
|
24
|
+
agent: name,
|
|
25
|
+
projectRoot,
|
|
26
|
+
enableAgent: options.enable === true,
|
|
27
|
+
});
|
|
28
|
+
const data = { ...result, projectRoot };
|
|
29
|
+
const nextActions = [];
|
|
30
|
+
if (result.reason === 'flag-enabled-but-ecc-missing') {
|
|
31
|
+
nextActions.push('ECC not installed. Pick one of the four options below:', ' a) Install: run `npx ecc --help` to install, then re-run `peaks agent run`.', ' b) Skip this run: use the peaks-cli native diagnostic via `peaks doctor scan`.', ' c) Skip forever: run `peaks preferences set agentShieldEnabled false`.', ' d) Learn more: see docs/superpowers/specs/2026-06-11-peaks-cli-l1-l2-l3-redesign.md §7.2.');
|
|
32
|
+
}
|
|
33
|
+
const envelope = ok('agent.run', data, [...result.warnings], nextActions);
|
|
34
|
+
printResult(io, envelope, options.json);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
const message = getErrorMessage(error);
|
|
38
|
+
printResult(io, fail('agent.run', 'AGENT_RUN_FAILED', message, { agent: name, projectRoot, spawned: false }, [message]), options.json);
|
|
39
|
+
process.exitCode = 1;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
addJsonOption(agent
|
|
43
|
+
.command('list')
|
|
44
|
+
.description(`List the 12 canonical ECC agents (peaks-cli ships a static subset; the full 64 are ECC-discovered).`)).action((options) => {
|
|
45
|
+
const envelope = ok('agent.list', { agents: CANONICAL_ECC_AGENTS.map((a) => ({ name: a.name, description: a.description })) }, [], ['Run any agent with: `peaks agent run <name> --target <path>`']);
|
|
46
|
+
printResult(io, envelope, options.json);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* peaks audit * CLI surface — Slice L2.1 + L2.3 P2-a.
|
|
3
|
+
*
|
|
4
|
+
* Registers the new `peaks audit` top-level command with the
|
|
5
|
+
* `red-lines` (L2.1) and `static` (L2.3 P2-a) subcommands.
|
|
6
|
+
* Per `peaks-cli-when-adding-a-new-subcommand-check-for-existing-top-level-first.md`
|
|
7
|
+
* we verified that no `peaks audit` top-level exists; this is the only
|
|
8
|
+
* file that owns the registration.
|
|
9
|
+
*/
|
|
10
|
+
import { Command } from 'commander';
|
|
11
|
+
import { type AgentShieldState } from '../../services/audit/static-service.js';
|
|
12
|
+
import { type ProgramIO } from '../cli-helpers.js';
|
|
13
|
+
import type { RedLineAudit } from '../../services/audit/types.js';
|
|
14
|
+
export interface StaticAuditData {
|
|
15
|
+
readonly audit: RedLineAudit;
|
|
16
|
+
readonly agentShield: AgentShieldState;
|
|
17
|
+
}
|
|
18
|
+
export declare function registerAuditCommands(program: Command, io: ProgramIO): void;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* peaks audit * CLI surface — Slice L2.1 + L2.3 P2-a.
|
|
3
|
+
*
|
|
4
|
+
* Registers the new `peaks audit` top-level command with the
|
|
5
|
+
* `red-lines` (L2.1) and `static` (L2.3 P2-a) subcommands.
|
|
6
|
+
* Per `peaks-cli-when-adding-a-new-subcommand-check-for-existing-top-level-first.md`
|
|
7
|
+
* we verified that no `peaks audit` top-level exists; this is the only
|
|
8
|
+
* file that owns the registration.
|
|
9
|
+
*/
|
|
10
|
+
import { existsSync, statSync } from 'node:fs';
|
|
11
|
+
import { resolve } from 'node:path';
|
|
12
|
+
import { runRedLinesAudit } from '../../services/audit/red-lines-service.js';
|
|
13
|
+
import { runStaticAudit } from '../../services/audit/static-service.js';
|
|
14
|
+
import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
|
|
15
|
+
import { fail, ok } from '../../shared/result.js';
|
|
16
|
+
function validateProjectRoot(projectArg) {
|
|
17
|
+
const projectRoot = resolve(projectArg);
|
|
18
|
+
if (!existsSync(projectRoot)) {
|
|
19
|
+
return { ok: false, code: 'PROJECT_NOT_FOUND', message: `project path does not exist: ${projectArg}` };
|
|
20
|
+
}
|
|
21
|
+
let stat;
|
|
22
|
+
try {
|
|
23
|
+
stat = statSync(projectRoot);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
return { ok: false, code: 'INVALID_PROJECT', message: getErrorMessage(error) };
|
|
27
|
+
}
|
|
28
|
+
if (!stat.isDirectory()) {
|
|
29
|
+
return { ok: false, code: 'INVALID_PROJECT', message: `project path is not a directory: ${projectArg}` };
|
|
30
|
+
}
|
|
31
|
+
return { ok: true, projectRoot };
|
|
32
|
+
}
|
|
33
|
+
export function registerAuditCommands(program, io) {
|
|
34
|
+
const audit = program
|
|
35
|
+
.command('audit')
|
|
36
|
+
.description('Audit a project for compliance with peaks-cli red lines (P0 / P1 / P2 tiers)');
|
|
37
|
+
addJsonOption(audit
|
|
38
|
+
.command('red-lines')
|
|
39
|
+
.description('Scan skills/, .claude/rules/, and openspec/changes/ for MANDATORY / BLOCKING / MUST NOT / RED LINE markers; classify each as cli-backed / partial / prose-only')
|
|
40
|
+
.requiredOption('--project <path>', 'target project root')).action(async (options) => {
|
|
41
|
+
const validation = validateProjectRoot(options.project);
|
|
42
|
+
if (!validation.ok) {
|
|
43
|
+
printResult(io, fail('audit.red-lines', validation.code, validation.message, { totalRedLines: 0, cliBacked: 0, partial: 0, proseOnly: 0, audit: [], enforcerFindings: [] }, ['Verify the project path exists and is a directory']), options.json);
|
|
44
|
+
process.exitCode = 1;
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const result = runRedLinesAudit({ projectRoot: validation.projectRoot });
|
|
49
|
+
const nextActions = [];
|
|
50
|
+
if (result.audit.proseOnly > 0) {
|
|
51
|
+
nextActions.push(`${result.audit.proseOnly} prose-only red lines remain. Plan P1/P2 enforcers in L2.2-L2.4.`);
|
|
52
|
+
}
|
|
53
|
+
if (result.audit.cliBacked > 0) {
|
|
54
|
+
nextActions.push(`${result.audit.cliBacked} red lines are now cli-backed. Re-run after each enforcer lands to track the prose-only ratio.`);
|
|
55
|
+
}
|
|
56
|
+
const envelope = ok('audit.red-lines', result.audit, result.warnings.map((w) => `${w.file}: ${w.message}`), nextActions);
|
|
57
|
+
printResult(io, envelope, options.json);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
printResult(io, fail('audit.red-lines', 'SCANNER_FAILED', getErrorMessage(error), { totalRedLines: 0, cliBacked: 0, partial: 0, proseOnly: 0, audit: [], enforcerFindings: [] }, ['Inspect scanner logs and re-run with the same --project path']), options.json);
|
|
61
|
+
process.exitCode = 1;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
// Slice #6 L2.3 P2-a: peaks audit static — soft-optional ECC
|
|
65
|
+
// AgentShell integration. Reads `.peaks/preferences.json`'s
|
|
66
|
+
// `agentShieldEnabled` flag (default false). The CLI flags
|
|
67
|
+
// `--enable-agent-shield` / `--disable-agent-shield` override
|
|
68
|
+
// the preference for a single call.
|
|
69
|
+
addJsonOption(audit
|
|
70
|
+
.command('static')
|
|
71
|
+
.description('Run the static audit (peaks-cli lint + optional ECC AgentShield subprocess). Per spec §5.3.')
|
|
72
|
+
.requiredOption('--project <path>', 'target project root')
|
|
73
|
+
.option('--enable-agent-shield', 'force-enable ECC AgentShield subprocess for this call (overrides preference)')
|
|
74
|
+
.option('--disable-agent-shield', 'force-disable ECC AgentShield subprocess for this call (overrides preference)')).action(async (options) => {
|
|
75
|
+
const validation = validateProjectRoot(options.project);
|
|
76
|
+
if (!validation.ok) {
|
|
77
|
+
printResult(io, fail('audit.static', validation.code, validation.message, emptyStaticAuditData(), ['Verify the project path exists and is a directory']), options.json);
|
|
78
|
+
process.exitCode = 1;
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// Resolve the flag override. `--enable-agent-shield` and
|
|
82
|
+
// `--disable-agent-shield` are mutually exclusive; we surface
|
|
83
|
+
// a 422 if both are passed.
|
|
84
|
+
if (options.enableAgentShield && options.disableAgentShield) {
|
|
85
|
+
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);
|
|
86
|
+
process.exitCode = 1;
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
const result = runStaticAudit({
|
|
91
|
+
projectRoot: validation.projectRoot,
|
|
92
|
+
...(options.enableAgentShield
|
|
93
|
+
? { enableAgentShield: true }
|
|
94
|
+
: options.disableAgentShield
|
|
95
|
+
? { enableAgentShield: false }
|
|
96
|
+
: {}),
|
|
97
|
+
});
|
|
98
|
+
const data = {
|
|
99
|
+
audit: result.audit,
|
|
100
|
+
agentShield: result.agentShield,
|
|
101
|
+
};
|
|
102
|
+
const nextActions = [];
|
|
103
|
+
// Per spec §5.3 + §7.2: when ECC is not installed, surface
|
|
104
|
+
// the canonical 4-option user opt-in UX (a/b/c/d) via
|
|
105
|
+
// nextActions. The peaks-cli `peaks audit static` CLI is
|
|
106
|
+
// non-interactive (JSON envelope by default), so the 4
|
|
107
|
+
// options are surfaced as machine-readable action strings
|
|
108
|
+
// — same pattern as understand-commands.ts `INSTALL_HINT`.
|
|
109
|
+
if (!result.agentShield.installed) {
|
|
110
|
+
nextActions.push('ECC AgentShield not installed. Pick one of the four options below:');
|
|
111
|
+
nextActions.push(' a) Install: run `npx ecc-agentshield --help` to install, then re-run `peaks audit static`.');
|
|
112
|
+
nextActions.push(' b) Skip this run: pass `--disable-agent-shield` to suppress the subprocess for this call.');
|
|
113
|
+
nextActions.push(' c) Skip forever: run `peaks preferences set agentShieldEnabled false` (writes to `.peaks/preferences.json`).');
|
|
114
|
+
nextActions.push(' d) Learn more: see docs/superpowers/specs/2026-06-11-peaks-cli-l1-l2-l3-redesign.md §5.3 + §7.2.');
|
|
115
|
+
}
|
|
116
|
+
if (result.agentShield.spawned && result.agentShield.findings.length > 0) {
|
|
117
|
+
nextActions.push(`${result.agentShield.findings.length} ECC findings merged into the audit. Review with \`peaks audit static --json\`.`);
|
|
118
|
+
}
|
|
119
|
+
const envelope = ok('audit.static', data, [...result.warnings], nextActions);
|
|
120
|
+
printResult(io, envelope, options.json);
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
printResult(io, fail('audit.static', 'SCANNER_FAILED', getErrorMessage(error), emptyStaticAuditData(), ['Inspect scanner logs and re-run with the same --project path']), options.json);
|
|
124
|
+
process.exitCode = 1;
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
function emptyStaticAuditData() {
|
|
129
|
+
return {
|
|
130
|
+
audit: { totalRedLines: 0, cliBacked: 0, partial: 0, proseOnly: 0, audit: [], enforcerFindings: [] },
|
|
131
|
+
agentShield: {
|
|
132
|
+
spawned: false,
|
|
133
|
+
installed: false,
|
|
134
|
+
reason: 'flag-disabled',
|
|
135
|
+
findings: [],
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* peaks classify CLI (Slice L1a + L1b).
|
|
3
|
+
*
|
|
4
|
+
* Subcommands:
|
|
5
|
+
* - peaks classify run --project <path> [--override <level> --reason "<text>"]
|
|
6
|
+
* Classify the current diff via the heuristic + return a JSON envelope
|
|
7
|
+
* with the chosen level, gate set, and audit log.
|
|
8
|
+
* - peaks classify override --level <level> --reason "<text>" --project <path>
|
|
9
|
+
* Force a level; writes the override to the audit log.
|
|
10
|
+
* - peaks classify upgrade --level <level> --reason "<text>" --project <path>
|
|
11
|
+
* Same as override but explicitly framed as an upgrade (audit log
|
|
12
|
+
* records the upgrade event separately from override).
|
|
13
|
+
*
|
|
14
|
+
* Downgrade is REFUSED (per spec §4: "peaks classify downgrade" always
|
|
15
|
+
* errors out). LLM may ask; the CLI never grants.
|
|
16
|
+
*/
|
|
17
|
+
import { Command } from 'commander';
|
|
18
|
+
import { type ProgramIO } from '../cli-helpers.js';
|
|
19
|
+
export declare function registerClassifyCommands(program: Command, io: ProgramIO): void;
|