peaks-loop 3.0.0 → 3.0.2

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 (244) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/CHANGELOG.md +94 -59
  3. package/README-en.md +2 -2
  4. package/README.md +2 -2
  5. package/agents/karpathy-reviewer.md +2 -2
  6. package/dist/src/cli/commands/agent-commands.js +3 -3
  7. package/dist/src/cli/commands/audit-commands.d.ts +1 -1
  8. package/dist/src/cli/commands/audit-commands.js +6 -6
  9. package/dist/src/cli/commands/classify-classify-commands.js +1 -1
  10. package/dist/src/cli/commands/code-review-commands.d.ts +3 -3
  11. package/dist/src/cli/commands/code-review-commands.js +5 -5
  12. package/dist/src/cli/commands/compact-command.d.ts +21 -0
  13. package/dist/src/cli/commands/compact-command.js +252 -0
  14. package/dist/src/cli/commands/context-commands.d.ts +1 -1
  15. package/dist/src/cli/commands/context-commands.js +1 -1
  16. package/dist/src/cli/commands/contract-commands.d.ts +1 -1
  17. package/dist/src/cli/commands/core/session-command.js +17 -7
  18. package/dist/src/cli/commands/core/skill-command.js +1 -1
  19. package/dist/src/cli/commands/feedback-commands.js +1 -1
  20. package/dist/src/cli/commands/hook-handle.d.ts +1 -1
  21. package/dist/src/cli/commands/hook-handle.js +1 -1
  22. package/dist/src/cli/commands/legacy-commands.d.ts +1 -1
  23. package/dist/src/cli/commands/legacy-commands.js +2 -2
  24. package/dist/src/cli/commands/log-commands.js +2 -2
  25. package/dist/src/cli/commands/loop-commands.d.ts +1 -1
  26. package/dist/src/cli/commands/loop-commands.js +1 -1
  27. package/dist/src/cli/commands/loop-eval-commands.d.ts +1 -1
  28. package/dist/src/cli/commands/loop-eval-commands.js +1 -1
  29. package/dist/src/cli/commands/playwright-commands.d.ts +1 -1
  30. package/dist/src/cli/commands/playwright-commands.js +2 -2
  31. package/dist/src/cli/commands/request-commands.js +40 -1
  32. package/dist/src/cli/commands/role-commands.js +1 -1
  33. package/dist/src/cli/commands/slice-commands.js +5 -5
  34. package/dist/src/cli/commands/understand-commands.js +36 -0
  35. package/dist/src/cli/commands/upgrade-commands.d.ts +1 -1
  36. package/dist/src/cli/commands/upgrade-commands.js +6 -6
  37. package/dist/src/cli/commands/workspace/init-command.js +2 -2
  38. package/dist/src/cli/program.js +10 -1
  39. package/dist/src/services/agent/ecc-agent-service.js +5 -5
  40. package/dist/src/services/audit/artifact-writer.d.ts +1 -1
  41. package/dist/src/services/audit/artifact-writer.js +1 -1
  42. package/dist/src/services/audit/decision-writer.d.ts +1 -1
  43. package/dist/src/services/audit/decision-writer.js +1 -1
  44. package/dist/src/services/audit/enforcers/lint-output-style.js +5 -5
  45. package/dist/src/services/audit/enforcers/mock-placement.d.ts +1 -1
  46. package/dist/src/services/audit/enforcers/mock-placement.js +1 -1
  47. package/dist/src/services/audit/enforcers/no-root-pollution.js +1 -1
  48. package/dist/src/services/audit/red-line-catalog-p2-a.js +2 -2
  49. package/dist/src/services/audit/red-line-catalog-p2-b.js +2 -2
  50. package/dist/src/services/audit/static-service.d.ts +1 -1
  51. package/dist/src/services/audit/static-service.js +5 -5
  52. package/dist/src/services/audit/types.d.ts +1 -1
  53. package/dist/src/services/audit/types.js +1 -1
  54. package/dist/src/services/audit-independent/perf-audit-service.js +1 -1
  55. package/dist/src/services/audit-independent/security-audit-service.js +1 -1
  56. package/dist/src/services/classify/classify-service.d.ts +1 -1
  57. package/dist/src/services/classify/classify-service.js +1 -1
  58. package/dist/src/services/classify/classify-types.d.ts +1 -1
  59. package/dist/src/services/classify/classify-types.js +1 -1
  60. package/dist/src/services/code-review/ecc-bridge.d.ts +2 -2
  61. package/dist/src/services/code-review/ecc-bridge.js +2 -2
  62. package/dist/src/services/code-review/ocr-service.d.ts +9 -9
  63. package/dist/src/services/code-review/ocr-service.js +16 -16
  64. package/dist/src/services/compact/decision-tables.d.ts +66 -0
  65. package/dist/src/services/compact/decision-tables.js +127 -0
  66. package/dist/src/services/compact/request-transition-hook.d.ts +20 -0
  67. package/dist/src/services/compact/request-transition-hook.js +110 -0
  68. package/dist/src/services/compact/suggest-service.d.ts +74 -0
  69. package/dist/src/services/compact/suggest-service.js +203 -0
  70. package/dist/src/services/config/config-migration.js +1 -1
  71. package/dist/src/services/config/config-safety.d.ts +1 -1
  72. package/dist/src/services/config/config-safety.js +1 -1
  73. package/dist/src/services/config/config-service.d.ts +1 -1
  74. package/dist/src/services/config/config-service.js +1 -1
  75. package/dist/src/services/context/auto-compact-dispatcher.js +4 -4
  76. package/dist/src/services/context/auto-compact-types.d.ts +6 -6
  77. package/dist/src/services/context/auto-compact-types.js +5 -5
  78. package/dist/src/services/dispatch/sub-agent-dispatcher.js +1 -1
  79. package/dist/src/services/dispatch/test-tool-detection.d.ts +1 -1
  80. package/dist/src/services/dispatch/test-tool-detection.js +1 -1
  81. package/dist/src/services/doctor/doctor-service.d.ts +1 -1
  82. package/dist/src/services/doctor/doctor-service.js +5 -5
  83. package/dist/src/services/hooks/presence-marker-detector.js +5 -5
  84. package/dist/src/services/ide/adapters/claude-code-adapter.d.ts +1 -1
  85. package/dist/src/services/ide/adapters/claude-code-adapter.js +2 -2
  86. package/dist/src/services/ide/adapters/codex-adapter.d.ts +2 -2
  87. package/dist/src/services/ide/adapters/codex-adapter.js +2 -2
  88. package/dist/src/services/ide/adapters/cursor-adapter.d.ts +2 -2
  89. package/dist/src/services/ide/adapters/cursor-adapter.js +2 -2
  90. package/dist/src/services/ide/adapters/hermes-adapter.d.ts +1 -1
  91. package/dist/src/services/ide/adapters/hermes-adapter.js +1 -1
  92. package/dist/src/services/ide/adapters/openclaw-adapter.d.ts +1 -1
  93. package/dist/src/services/ide/adapters/openclaw-adapter.js +1 -1
  94. package/dist/src/services/ide/adapters/trae-adapter.d.ts +1 -1
  95. package/dist/src/services/ide/adapters/trae-adapter.js +1 -1
  96. package/dist/src/services/ide/ide-types.d.ts +9 -9
  97. package/dist/src/services/legacy/legacy-detector.d.ts +1 -1
  98. package/dist/src/services/legacy/legacy-detector.js +1 -1
  99. package/dist/src/services/log/log-commands-service.d.ts +1 -1
  100. package/dist/src/services/log/log-commands-service.js +1 -1
  101. package/dist/src/services/log/logger.d.ts +3 -3
  102. package/dist/src/services/log/logger.js +3 -3
  103. package/dist/src/services/log/redact.d.ts +1 -1
  104. package/dist/src/services/log/redact.js +1 -1
  105. package/dist/src/services/loop/evaluator-dispatcher.d.ts +1 -1
  106. package/dist/src/services/loop/evaluator-dispatcher.js +16 -15
  107. package/dist/src/services/loop/monotonic-guard.js +35 -18
  108. package/dist/src/services/loop/monotonic-runner.d.ts +3 -0
  109. package/dist/src/services/loop/monotonic-runner.js +62 -28
  110. package/dist/src/services/loop/run-driver.js +45 -24
  111. package/dist/src/services/memory/llm-reranker.d.ts +1 -1
  112. package/dist/src/services/memory/llm-reranker.js +1 -1
  113. package/dist/src/services/mut/production-stryker.d.ts +0 -5
  114. package/dist/src/services/mut/production-stryker.js +19 -10
  115. package/dist/src/services/openspec/openspec-propose-from-doctor-service.d.ts +1 -1
  116. package/dist/src/services/openspec/openspec-propose-from-doctor-service.js +1 -1
  117. package/dist/src/services/perf/perf-baseline-service.d.ts +2 -2
  118. package/dist/src/services/perf/perf-baseline-service.js +2 -2
  119. package/dist/src/services/prd/handoff-auto-regen.js +1 -1
  120. package/dist/src/services/prd/project-scan-sediment.js +3 -3
  121. package/dist/src/services/prd/project-scan-types.d.ts +1 -1
  122. package/dist/src/services/preferences/preferences-types.d.ts +3 -3
  123. package/dist/src/services/preferences/preferences-types.js +2 -2
  124. package/dist/src/services/role/role-registry.d.ts +1 -1
  125. package/dist/src/services/role/role-registry.js +1 -1
  126. package/dist/src/services/sc/sc-service.js +3 -3
  127. package/dist/src/services/skill/resume-detector.js +2 -2
  128. package/dist/src/services/skills/sync-service.d.ts +3 -3
  129. package/dist/src/services/skills/sync-service.js +9 -9
  130. package/dist/src/services/slice/calibration-store.d.ts +1 -1
  131. package/dist/src/services/slice/calibration-store.js +1 -1
  132. package/dist/src/services/solo/auto-compact-orchestrator.d.ts +1 -1
  133. package/dist/src/services/solo/auto-compact-orchestrator.js +7 -7
  134. package/dist/src/services/solo/dag-orchestrator.js +1 -1
  135. package/dist/src/services/solo/mode-gate.d.ts +1 -1
  136. package/dist/src/services/solo/mode-gate.js +4 -4
  137. package/dist/src/services/solo/user-touchpoint-classifier.js +1 -1
  138. package/dist/src/services/standards/migrate-claude-rules-service.js +5 -5
  139. package/dist/src/services/standards/migrate-service.d.ts +3 -3
  140. package/dist/src/services/standards/migrate-service.js +5 -5
  141. package/dist/src/services/standards/project-standards-service.js +1 -1
  142. package/dist/src/services/understand/hybrid-types.d.ts +32 -0
  143. package/dist/src/services/understand/hybrid-types.js +1 -0
  144. package/dist/src/services/understand/understand-hybrid-service.d.ts +10 -0
  145. package/dist/src/services/understand/understand-hybrid-service.js +100 -0
  146. package/dist/src/services/upgrade/gitignore-migrate-service.d.ts +3 -3
  147. package/dist/src/services/upgrade/gitignore-migrate-service.js +4 -4
  148. package/dist/src/services/upgrade/upgrade-service.d.ts +1 -1
  149. package/dist/src/services/upgrade/upgrade-service.js +5 -5
  150. package/dist/src/services/verdict/envelopes.d.ts +1 -1
  151. package/dist/src/services/verdict/envelopes.js +1 -1
  152. package/dist/src/services/workflow/workflow-loader.js +1 -1
  153. package/dist/src/services/workspace/migrate-1-4-1-service.d.ts +1 -1
  154. package/dist/src/services/workspace/migrate-1-4-1-service.js +1 -1
  155. package/dist/src/services/workspace/migrate-types.d.ts +1 -1
  156. package/dist/src/services/workspace/migrate-types.js +1 -1
  157. package/dist/src/services/workspace/workspace-claude-settings-materializer.d.ts +2 -2
  158. package/dist/src/services/workspace/workspace-claude-settings-materializer.js +9 -9
  159. package/dist/src/services/workspace/workspace-service.d.ts +1 -1
  160. package/dist/src/services/workspace/workspace-service.js +1 -1
  161. package/dist/src/shared/path-safety.d.ts +1 -1
  162. package/dist/src/shared/path-safety.js +1 -1
  163. package/dist/src/shared/version.d.ts +1 -1
  164. package/dist/src/shared/version.js +1 -1
  165. package/output-styles/peaks-skill-swarm.md +33 -33
  166. package/package.json +5 -4
  167. package/schemas/decomposition-v1.json +1 -1
  168. package/schemas/decomposition-v2.json +1 -1
  169. package/schemas/replay-fixture.schema.json +1 -1
  170. package/schemas/reviewer-envelope.schema.json +1 -1
  171. package/scripts/install-skills.mjs +11 -11
  172. package/skills/peaks-audit/SKILL.md +2 -2
  173. package/skills/peaks-doctor/SKILL.md +4 -4
  174. package/skills/peaks-final-review/SKILL.md +2 -2
  175. package/skills/peaks-ide/SKILL.md +3 -3
  176. package/skills/peaks-perf-audit/SKILL.md +1 -1
  177. package/skills/peaks-prd/SKILL.md +14 -14
  178. package/skills/peaks-prd/references/workflow.md +1 -1
  179. package/skills/peaks-qa/SKILL.md +17 -17
  180. package/skills/peaks-qa/references/artifact-per-request.md +1 -1
  181. package/skills/peaks-qa/references/browser-validation-contracts.md +2 -2
  182. package/skills/peaks-qa/references/codegraph-regression-focus.md +1 -1
  183. package/skills/peaks-qa/references/external-capability-guidance.md +2 -2
  184. package/skills/peaks-qa/references/qa-fanout-contract.md +1 -1
  185. package/skills/peaks-qa/references/qa-gstack-integration.md +3 -3
  186. package/skills/peaks-qa/references/qa-local-artifacts.md +1 -1
  187. package/skills/peaks-qa/references/qa-matt-pocock-integration.md +1 -1
  188. package/skills/peaks-qa/references/qa-runbook.md +3 -3
  189. package/skills/peaks-qa/references/qa-skill-presence.md +1 -1
  190. package/skills/peaks-qa/references/qa-standards-preflight.md +2 -2
  191. package/skills/peaks-qa/references/qa-transition-gates.md +9 -9
  192. package/skills/peaks-qa/references/regression-gates.md +1 -1
  193. package/skills/peaks-rd/SKILL.md +13 -13
  194. package/skills/peaks-rd/references/artifact-and-standards-output.md +1 -1
  195. package/skills/peaks-rd/references/codegraph-project-analysis.md +1 -1
  196. package/skills/peaks-rd/references/external-references.md +3 -3
  197. package/skills/peaks-rd/references/karpathy-reviewer-prompt.md +1 -1
  198. package/skills/peaks-rd/references/mandatory-perf-baseline.md +1 -1
  199. package/skills/peaks-rd/references/matt-pocock-integration.md +2 -2
  200. package/skills/peaks-rd/references/ocr-integration.md +19 -19
  201. package/skills/peaks-rd/references/openspec-cli.md +2 -2
  202. package/skills/peaks-rd/references/rd-gstack-integration.md +5 -5
  203. package/skills/peaks-rd/references/rd-runbook.md +9 -9
  204. package/skills/peaks-rd/references/rd-standards-preflight.md +1 -1
  205. package/skills/peaks-rd/references/rd-transition-gates.md +13 -13
  206. package/skills/peaks-rd/references/skill-presence-and-title.md +1 -1
  207. package/skills/peaks-reviewer/SKILL.md +2 -2
  208. package/skills/peaks-sc/SKILL.md +9 -9
  209. package/skills/peaks-security-audit/SKILL.md +1 -1
  210. package/skills/peaks-slice-decompose/SKILL.md +2 -2
  211. package/skills/peaks-solo/SKILL.md +49 -49
  212. package/skills/peaks-solo/references/a2a-artifact-mapping.md +8 -8
  213. package/skills/peaks-solo/references/anchoring-and-session-info.md +3 -3
  214. package/skills/peaks-solo/references/boundaries.md +4 -4
  215. package/skills/peaks-solo/references/browser-workflow.md +2 -2
  216. package/skills/peaks-solo/references/codegraph-orchestration.md +1 -1
  217. package/skills/peaks-solo/references/completion-handoff.md +2 -2
  218. package/skills/peaks-solo/references/external-references.md +3 -3
  219. package/skills/peaks-solo/references/external-skill-invocation.md +2 -2
  220. package/skills/peaks-solo/references/frontend-only-mode.md +1 -1
  221. package/skills/peaks-solo/references/gstack-integration.md +4 -4
  222. package/skills/peaks-solo/references/local-artifact-workspace.md +2 -2
  223. package/skills/peaks-solo/references/micro-cycle.md +4 -4
  224. package/skills/peaks-solo/references/mode-selection.md +5 -5
  225. package/skills/peaks-solo/references/openspec-workflow.md +2 -2
  226. package/skills/peaks-solo/references/playwright-mcp-multi-terminal.md +1 -1
  227. package/skills/peaks-solo/references/project-memory-loading.md +1 -1
  228. package/skills/peaks-solo/references/project-scan-checklist.md +1 -1
  229. package/skills/peaks-solo/references/quality-gate-cheatsheet.md +1 -1
  230. package/skills/peaks-solo/references/resume-detection.md +1 -1
  231. package/skills/peaks-solo/references/runbook.md +20 -20
  232. package/skills/peaks-solo/references/skill-presence-and-title.md +2 -2
  233. package/skills/peaks-solo/references/standards-preflight.md +2 -2
  234. package/skills/peaks-solo/references/step-0-55-1x-detection.md +3 -3
  235. package/skills/peaks-solo/references/sub-agent-dispatch.md +3 -3
  236. package/skills/peaks-solo/references/swarm-dispatch-contract.md +3 -3
  237. package/skills/peaks-solo/references/workflow-gates-and-types.md +34 -34
  238. package/skills/peaks-solo-resume/SKILL.md +2 -2
  239. package/skills/peaks-solo-status/SKILL.md +4 -4
  240. package/skills/peaks-solo-test/SKILL.md +4 -4
  241. package/skills/peaks-sop/SKILL.md +5 -5
  242. package/skills/peaks-txt/SKILL.md +17 -17
  243. package/skills/peaks-ui/SKILL.md +17 -17
  244. package/skills/peaks-ui/references/workflow.md +1 -1
@@ -13,9 +13,9 @@
13
13
  * - same multi-state reason enum (clear failure-mode reporting),
14
14
  * - same soft-fail policy (never blocks the umbrella).
15
15
  *
16
- * === Source of truth: peaks-cli's own config.json ===
16
+ * === Source of truth: peaks-loop's own config.json ===
17
17
  *
18
- * peaks-cli does NOT auto-configure the LLM endpoint, and it does
18
+ * peaks-loop does NOT auto-configure the LLM endpoint, and it does
19
19
  * NOT write `~/.opencodereview/config.json`. The user is the only
20
20
  * party that touches their LLM token / URL / model. The single
21
21
  * discoverable place they declare those values is
@@ -30,7 +30,7 @@
30
30
  *
31
31
  * When `runOcrReview` spawns the ocr subprocess it injects those
32
32
  * values as env vars. The ocr package treats env vars as the
33
- * highest-priority config source, so peaks-cli never has to
33
+ * highest-priority config source, so peaks-loop never has to
34
34
  * materialise `~/.opencodereview/config.json` itself.
35
35
  *
36
36
  * To see the JSON template to paste, run:
@@ -41,14 +41,14 @@
41
41
  * `optionalDependencies` in 2.0.3, then to `peerDependencies` in
42
42
  * 2.8.2 — the ocr postinstall downloads a Go binary via HTTPS,
43
43
  * which fails in restricted/proxied environments and would
44
- * otherwise slow or abort the whole `npm i -g peaks-cli` flow).
44
+ * otherwise slow or abort the whole `npm i -g peaks-loop` flow).
45
45
  * Peaks-cli ships with ocr *not* installed; if the user wants it,
46
46
  * they run
47
47
  * `npm i -g @alibaba-group/open-code-review`
48
- * and peaks-cli's 5-state detector (below) reports whether the
48
+ * and peaks-loop's 5-state detector (below) reports whether the
49
49
  * binary is actually usable. pnpm-based installs additionally need
50
50
  * `pnpm approve-builds @alibaba-group/open-code-review` for the
51
- * binary download to run. Either way, peaks-cli never blocks on it.
51
+ * binary download to run. Either way, peaks-loop never blocks on it.
52
52
  */
53
53
  import { spawnSync } from 'node:child_process';
54
54
  import { existsSync } from 'node:fs';
@@ -57,7 +57,7 @@ import { fileURLToPath } from 'node:url';
57
57
  import { dirname } from 'node:path';
58
58
  const OCR_DETECT_TIMEOUT_MS = 5000;
59
59
  const OCR_REVIEW_TIMEOUT_MS = 180000;
60
- const OCR_INSTALL_HINT = 'Install: `npm i -g @alibaba-group/open-code-review` (peaks-cli 2.8.2 ships with ocr as a peer dependency — its postinstall downloads a Go binary via HTTPS, which fails in some restricted/proxied environments; that\'s why peaks-cli does not auto-install it). Then add your LLM endpoint to ~/.peaks/config.json — run `peaks code-review config-template` for the JSON snippet to paste. Under pnpm you also need `pnpm approve-builds @alibaba-group/open-code-review` to allow the binary download.';
60
+ const OCR_INSTALL_HINT = 'Install: `npm i -g @alibaba-group/open-code-review` (peaks-loop 2.8.2 ships with ocr as a peer dependency — its postinstall downloads a Go binary via HTTPS, which fails in some restricted/proxied environments; that\'s why peaks-loop does not auto-install it). Then add your LLM endpoint to ~/.peaks/config.json — run `peaks code-review config-template` for the JSON snippet to paste. Under pnpm you also need `pnpm approve-builds @alibaba-group/open-code-review` to allow the binary download.';
61
61
  const OCR_CONFIG_TEMPLATE = JSON.stringify({
62
62
  ocr: {
63
63
  llm: {
@@ -98,7 +98,7 @@ const DEFAULT_RUNNER = {
98
98
  /**
99
99
  * Locate the ocr launcher script (`bin/ocr.js`) inside our own
100
100
  * node_modules tree. Returns null when the npm package is not
101
- * present (peaks-cli was installed but its dependency tree is
101
+ * present (peaks-loop was installed but its dependency tree is
102
102
  * corrupt, or the user removed it).
103
103
  *
104
104
  * Walks up from this file (dist/src/services/code-review/) to
@@ -118,7 +118,7 @@ export function resolveOcrLauncher(searchRoots) {
118
118
  }
119
119
  /**
120
120
  * Resolve search roots for the ocr launcher. We look in two
121
- * places: (1) the peaks-cli install root (next to our own dist/),
121
+ * places: (1) the peaks-loop install root (next to our own dist/),
122
122
  * (2) the user's cwd.
123
123
  */
124
124
  export function defaultOcrSearchRoots(currentDirPath, cwd) {
@@ -133,7 +133,7 @@ export function defaultOcrSearchRoots(currentDirPath, cwd) {
133
133
  * the block is ready to drive the ocr subprocess.
134
134
  *
135
135
  * The block is independent of the OCR package's own
136
- * `~/.opencodereview/config.json` file. peaks-cli only ever reads
136
+ * `~/.opencodereview/config.json` file. peaks-loop only ever reads
137
137
  * from its own config; the env-var injection in `runOcrReview`
138
138
  * makes the legacy file irrelevant.
139
139
  */
@@ -151,7 +151,7 @@ export function getOcrLlmMissingFields(llm) {
151
151
  return missing;
152
152
  }
153
153
  /**
154
- * Build the env-var overlay peaks-cli injects into the ocr
154
+ * Build the env-var overlay peaks-loop injects into the ocr
155
155
  * subprocess. Maps `peaksConfig.ocr.llm` onto the OCR package's
156
156
  * env-var surface (its highest-priority config source).
157
157
  */
@@ -170,7 +170,7 @@ export function buildOcrEnv(llm) {
170
170
  return env;
171
171
  }
172
172
  /**
173
- * The JSON template the user pastes into their peaks-cli config
173
+ * The JSON template the user pastes into their peaks-loop config
174
174
  * (`peaksConfig.ocr.llm`). Returned as a stable string so the
175
175
  * `peaks code-review config-template` CLI command can print it
176
176
  * verbatim, and so the detector's `nextActions` payload embeds
@@ -203,7 +203,7 @@ export function detectOcr(options) {
203
203
  missingKeys: missing,
204
204
  warnings,
205
205
  nextActions: [
206
- '@alibaba-group/open-code-review is not installed in this project or peaks-cli root.',
206
+ '@alibaba-group/open-code-review is not installed in this project or peaks-loop root.',
207
207
  OCR_INSTALL_HINT,
208
208
  ],
209
209
  };
@@ -255,7 +255,7 @@ export function detectOcr(options) {
255
255
  configValid: false,
256
256
  missingKeys: missing,
257
257
  warnings: [
258
- `ocr is installed but peaks-cli's ocr.llm config is incomplete: missing ${missing.join(', ')}.`,
258
+ `ocr is installed but peaks-loop's ocr.llm config is incomplete: missing ${missing.join(', ')}.`,
259
259
  ],
260
260
  nextActions: [
261
261
  `Paste the following into ${options.peaksConfigPath} under "ocr.llm":`,
@@ -285,7 +285,7 @@ export function detectOcr(options) {
285
285
  * The LLM endpoint config from `peaksConfig.ocr.llm` is injected
286
286
  * as env vars (`OCR_LLM_URL` / `OCR_LLM_TOKEN` / ...), which the
287
287
  * ocr package treats as the highest-priority config source. This
288
- * is how peaks-cli wires the user-managed config into the ocr
288
+ * is how peaks-loop wires the user-managed config into the ocr
289
289
  * subprocess without ever writing `~/.opencodereview/config.json`.
290
290
  */
291
291
  export function runOcrReview(options) {
@@ -321,7 +321,7 @@ export function runOcrReview(options) {
321
321
  nextActions: ['Re-run `peaks code-review detect-ocr --json` to refresh.'],
322
322
  };
323
323
  }
324
- // Inject the LLM endpoint config from peaks-cli's config.json
324
+ // Inject the LLM endpoint config from peaks-loop's config.json
325
325
  // as env vars — the ocr package's highest-priority config path.
326
326
  const env = options.peaksOcrConfig === null
327
327
  ? process.env
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Strategic-compact decision tables (slice 2026-07-01-strategic-compact-cli).
3
+ *
4
+ * Pure data + lookup helpers. No I/O. The byte-for-byte text mirrors the
5
+ * "Compaction Decision Guide" + "What Survives Compaction" tables in
6
+ * ECC's strategic-compact SKILL.md (read-only reference at
7
+ * C:\Users\smallMark\.claude\plugins\cache\ecc\ecc\2.0.0\skills\strategic-compact\SKILL.md).
8
+ *
9
+ * The `peaks compact recommend` + `peaks compact survival` + `peaks
10
+ * compact dry-run` primitives read from these tables; any change to the
11
+ * upstream skill table must be mirrored here and re-asserted by the
12
+ * `tests/unit/cli/compact-command.test.ts` regression suite.
13
+ */
14
+ export type Phase = 'research' | 'planning' | 'implementation' | 'testing' | 'debugging';
15
+ export declare const PHASES: readonly Phase[];
16
+ export declare function isPhase(value: string): value is Phase;
17
+ /** Severity for a phase transition: matches the SKILL.md "Compact?" column. */
18
+ export type Severity = 'yes' | 'maybe' | 'no';
19
+ export interface PhaseTransitionDecision {
20
+ readonly from: Phase;
21
+ readonly to: Phase;
22
+ readonly severity: Severity;
23
+ readonly rationale: string;
24
+ }
25
+ /**
26
+ * Single source of truth for the strategic-compact "Compaction Decision
27
+ * Guide" table. Each row is a recommended from→to transition. The
28
+ * `rationale` field is the "Why" column verbatim from SKILL.md.
29
+ *
30
+ * The CLI accepts arbitrary from/to phase pairs; if the pair is not in
31
+ * the table (e.g. testing→implementation) the recommend primitive
32
+ * returns `severity: 'no'` with a `notInTable: true` flag and the
33
+ * default rationale "No documented transition; preserve context".
34
+ */
35
+ export declare const PHASE_TRANSITIONS: readonly PhaseTransitionDecision[];
36
+ /** Documented "no compact" rows from the SKILL.md table. */
37
+ export declare const PHASE_NO_TRANSITIONS: readonly {
38
+ from: Phase;
39
+ to: Phase;
40
+ rationale: string;
41
+ }[];
42
+ /**
43
+ * SKILL.md "What Survives Compaction" table — byte-for-byte.
44
+ * The `peaks compact survival` primitive emits these lists verbatim.
45
+ */
46
+ export declare const SURVIVAL_TABLE: Readonly<{
47
+ persists: readonly string[];
48
+ lost: readonly string[];
49
+ }>;
50
+ /**
51
+ * Resolve a (from, to) phase pair to a recommend() envelope.
52
+ * Unknown pairs return `severity: 'no'` with `notInTable: true` so the
53
+ * LLM can see "this transition isn't in the table" instead of silently
54
+ * getting a default.
55
+ */
56
+ export declare function lookupPhaseTransition(from: Phase, to: Phase): {
57
+ severity: Severity;
58
+ rationale: string;
59
+ notInTable: boolean;
60
+ };
61
+ /**
62
+ * LLM-ready `/compact Focus on ...` prompt string. The phrasing is
63
+ * deliberately terse — the upstream ECC suggest-compact hook uses a
64
+ * similar short imperative form.
65
+ */
66
+ export declare function buildSuggestedCompactMessage(from: Phase, to: Phase, severity: Severity): string;
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Strategic-compact decision tables (slice 2026-07-01-strategic-compact-cli).
3
+ *
4
+ * Pure data + lookup helpers. No I/O. The byte-for-byte text mirrors the
5
+ * "Compaction Decision Guide" + "What Survives Compaction" tables in
6
+ * ECC's strategic-compact SKILL.md (read-only reference at
7
+ * C:\Users\smallMark\.claude\plugins\cache\ecc\ecc\2.0.0\skills\strategic-compact\SKILL.md).
8
+ *
9
+ * The `peaks compact recommend` + `peaks compact survival` + `peaks
10
+ * compact dry-run` primitives read from these tables; any change to the
11
+ * upstream skill table must be mirrored here and re-asserted by the
12
+ * `tests/unit/cli/compact-command.test.ts` regression suite.
13
+ */
14
+ export const PHASES = [
15
+ 'research',
16
+ 'planning',
17
+ 'implementation',
18
+ 'testing',
19
+ 'debugging'
20
+ ];
21
+ export function isPhase(value) {
22
+ return PHASES.includes(value);
23
+ }
24
+ /**
25
+ * Single source of truth for the strategic-compact "Compaction Decision
26
+ * Guide" table. Each row is a recommended from→to transition. The
27
+ * `rationale` field is the "Why" column verbatim from SKILL.md.
28
+ *
29
+ * The CLI accepts arbitrary from/to phase pairs; if the pair is not in
30
+ * the table (e.g. testing→implementation) the recommend primitive
31
+ * returns `severity: 'no'` with a `notInTable: true` flag and the
32
+ * default rationale "No documented transition; preserve context".
33
+ */
34
+ export const PHASE_TRANSITIONS = [
35
+ {
36
+ from: 'research',
37
+ to: 'planning',
38
+ severity: 'yes',
39
+ rationale: 'Research context is bulky; plan is the distilled output'
40
+ },
41
+ {
42
+ from: 'planning',
43
+ to: 'implementation',
44
+ severity: 'yes',
45
+ rationale: 'Plan is in TodoWrite or a file; free up context for code'
46
+ },
47
+ {
48
+ from: 'implementation',
49
+ to: 'testing',
50
+ severity: 'maybe',
51
+ rationale: 'Keep if tests reference recent code; compact if switching focus'
52
+ },
53
+ {
54
+ from: 'debugging',
55
+ to: 'implementation',
56
+ severity: 'yes',
57
+ rationale: 'Debug traces pollute context for unrelated work'
58
+ }
59
+ ];
60
+ /** Documented "no compact" rows from the SKILL.md table. */
61
+ export const PHASE_NO_TRANSITIONS = [
62
+ {
63
+ from: 'implementation',
64
+ to: 'implementation',
65
+ rationale: 'Mid-implementation: losing variable names, file paths, and partial state is costly'
66
+ },
67
+ {
68
+ from: 'debugging',
69
+ to: 'debugging',
70
+ rationale: 'After a failed approach: keep context until you commit to a new direction'
71
+ }
72
+ ];
73
+ /**
74
+ * SKILL.md "What Survives Compaction" table — byte-for-byte.
75
+ * The `peaks compact survival` primitive emits these lists verbatim.
76
+ */
77
+ export const SURVIVAL_TABLE = {
78
+ persists: [
79
+ 'CLAUDE.md instructions',
80
+ 'TodoWrite task list',
81
+ 'Memory files (~/.claude/memory/)',
82
+ 'Git state (commits, branches)',
83
+ 'Files on disk'
84
+ ],
85
+ lost: [
86
+ 'Intermediate reasoning and analysis',
87
+ 'File contents you previously read',
88
+ 'Multi-step conversation context',
89
+ 'Tool call history and counts',
90
+ 'Nuanced user preferences stated verbally'
91
+ ]
92
+ };
93
+ /**
94
+ * Resolve a (from, to) phase pair to a recommend() envelope.
95
+ * Unknown pairs return `severity: 'no'` with `notInTable: true` so the
96
+ * LLM can see "this transition isn't in the table" instead of silently
97
+ * getting a default.
98
+ */
99
+ export function lookupPhaseTransition(from, to) {
100
+ const direct = PHASE_TRANSITIONS.find((row) => row.from === from && row.to === to);
101
+ if (direct !== undefined) {
102
+ return { severity: direct.severity, rationale: direct.rationale, notInTable: false };
103
+ }
104
+ const noRow = PHASE_NO_TRANSITIONS.find((row) => row.from === from && row.to === to);
105
+ if (noRow !== undefined) {
106
+ return { severity: 'no', rationale: noRow.rationale, notInTable: false };
107
+ }
108
+ return {
109
+ severity: 'no',
110
+ rationale: 'No documented transition; preserve context',
111
+ notInTable: true
112
+ };
113
+ }
114
+ /**
115
+ * LLM-ready `/compact Focus on ...` prompt string. The phrasing is
116
+ * deliberately terse — the upstream ECC suggest-compact hook uses a
117
+ * similar short imperative form.
118
+ */
119
+ export function buildSuggestedCompactMessage(from, to, severity) {
120
+ if (severity === 'no') {
121
+ return `/compact Preserve context for ongoing ${from} work; do not abandon in-flight state.`;
122
+ }
123
+ if (severity === 'maybe') {
124
+ return `/compact Focus on completing ${to} for the current thread; preserve recent code references.`;
125
+ }
126
+ return `/compact Focus on ${to}: ${from} context has been distilled into the plan / todo list.`;
127
+ }
@@ -0,0 +1,20 @@
1
+ export interface PreCompactHookInput {
2
+ readonly projectRoot: string;
3
+ readonly sessionId: string;
4
+ readonly transitionKey: string;
5
+ }
6
+ export interface PreCompactHookResult {
7
+ readonly triggered: boolean;
8
+ readonly checkpointPath: string | null;
9
+ readonly ratio: number;
10
+ readonly zone: 'none' | 'soft-warn' | 'pre-compact' | 'red-line';
11
+ readonly note: string;
12
+ }
13
+ /**
14
+ * Check the pre-compact zone and, if active, write a checkpoint.
15
+ * Returns a result envelope the caller can stitch into the
16
+ * transition response. NEVER throws; returns a `triggered: false`
17
+ * result on any error so the transition itself stays the contract
18
+ * surface.
19
+ */
20
+ export declare function maybePreCompactCheckpoint(input: PreCompactHookInput): PreCompactHookResult;
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Slice-boundary pre-compact hook (slice 2026-07-01-strategic-compact-cli).
3
+ *
4
+ * The RD → QA and QA → final-review slice-boundary transitions go
5
+ * through `peaks request transition`. When the active session is in
6
+ * the 0.85–0.95 pre-compact zone (per auto-compact-types.ts), this
7
+ * hook:
8
+ *
9
+ * 1. Detects the zone via the latest `.peaks/_runtime/<sid>/usage.jsonl`
10
+ * row, OR falls back to `peaks compact suggest --json`.
11
+ * 2. Writes a `context-fill` checkpoint BEFORE the transition so
12
+ * the post-compact LLM has a deterministic resume surface.
13
+ * 3. Attaches `preCompactCheckpoint: true` to the transition
14
+ * envelope so the LLM can audit the side-effect.
15
+ *
16
+ * The hook is INVOKED from `src/cli/commands/request-commands.ts`
17
+ * (RD→QA boundary) and from any future QA→final-review boundary. The
18
+ * 0.95 red line is NOT changed: the existing auto-compact
19
+ * orchestrator continues to refuse dispatch at ratio ≥ 0.95.
20
+ */
21
+ import { existsSync, readFileSync } from 'node:fs';
22
+ import { join } from 'node:path';
23
+ import { writeCheckpoint } from '../session/session-checkpoint-service.js';
24
+ import { AUTO_COMPACT_PRE_COMPACT_RATIO, AUTO_COMPACT_RED_LINE_RATIO } from '../context/auto-compact-types.js';
25
+ const PRE_COMPACT_ZONE = {
26
+ preCompact: AUTO_COMPACT_PRE_COMPACT_RATIO,
27
+ redLine: AUTO_COMPACT_RED_LINE_RATIO
28
+ };
29
+ function readLatestUsageRow(projectRoot, sessionId) {
30
+ const path = join(projectRoot, '.peaks', '_runtime', sessionId, 'usage.jsonl');
31
+ if (!existsSync(path))
32
+ return null;
33
+ try {
34
+ const raw = readFileSync(path, 'utf8');
35
+ const lines = raw.split(/\r?\n/).filter((l) => l.length > 0);
36
+ if (lines.length === 0)
37
+ return null;
38
+ const last = lines[lines.length - 1];
39
+ if (last === undefined)
40
+ return null;
41
+ return JSON.parse(last);
42
+ }
43
+ catch { // TODO(g2): legacy silent catch — grace: 1 minor release (v2.14.0)
44
+ return null;
45
+ }
46
+ }
47
+ /**
48
+ * Compute the context-fill ratio from a usage row. Defaults to a
49
+ * 200k window when the row is missing capacity. The auto-compact
50
+ * types use a 256KB byte-based estimate; this hook uses a 200k
51
+ * token-based window to match the strategic-compact SKILL.md.
52
+ */
53
+ function computeRatio(row) {
54
+ if (row === null)
55
+ return { ratio: 0, zone: 'none' };
56
+ const tokens = typeof row.tokens === 'number' && Number.isFinite(row.tokens) ? row.tokens : 0;
57
+ const capacity = typeof row.capacityTokens === 'number' && row.capacityTokens > 0 ? row.capacityTokens : 200_000;
58
+ const ratio = capacity > 0 ? tokens / capacity : 0;
59
+ if (ratio >= PRE_COMPACT_ZONE.redLine)
60
+ return { ratio, zone: 'red-line' };
61
+ if (ratio >= PRE_COMPACT_ZONE.preCompact)
62
+ return { ratio, zone: 'pre-compact' };
63
+ if (ratio >= 0.5)
64
+ return { ratio, zone: 'soft-warn' };
65
+ return { ratio, zone: 'none' };
66
+ }
67
+ /**
68
+ * Check the pre-compact zone and, if active, write a checkpoint.
69
+ * Returns a result envelope the caller can stitch into the
70
+ * transition response. NEVER throws; returns a `triggered: false`
71
+ * result on any error so the transition itself stays the contract
72
+ * surface.
73
+ */
74
+ export function maybePreCompactCheckpoint(input) {
75
+ try {
76
+ const row = readLatestUsageRow(input.projectRoot, input.sessionId);
77
+ const { ratio, zone } = computeRatio(row);
78
+ if (zone !== 'pre-compact') {
79
+ return {
80
+ triggered: false,
81
+ checkpointPath: null,
82
+ ratio,
83
+ zone,
84
+ note: `ratio=${(ratio * 100).toFixed(1)}% (zone=${zone}); pre-compact hook is in 0.85–0.95 zone only`
85
+ };
86
+ }
87
+ const result = writeCheckpoint(input.projectRoot, {
88
+ sessionId: input.sessionId,
89
+ reason: 'context-fill',
90
+ gitStatus: `preCompactCheckpoint: ${input.transitionKey}`,
91
+ currentPlan: `Slice boundary transition: ${input.transitionKey}`
92
+ });
93
+ return {
94
+ triggered: true,
95
+ checkpointPath: result.path,
96
+ ratio,
97
+ zone,
98
+ note: `Pre-compact checkpoint written at ratio=${(ratio * 100).toFixed(1)}% (zone=pre-compact). The LLM is still the decision-maker; the transition will proceed.`
99
+ };
100
+ }
101
+ catch (error) {
102
+ return {
103
+ triggered: false,
104
+ checkpointPath: null,
105
+ ratio: 0,
106
+ zone: 'none',
107
+ note: `pre-compact hook failed: ${error.message ?? String(error)}`
108
+ };
109
+ }
110
+ }
@@ -0,0 +1,74 @@
1
+ import { type Phase, type Severity } from './decision-tables.js';
2
+ /** Token window sizes supported by the suggest service. */
3
+ export type WindowKind = '200k' | '1m';
4
+ export interface SuggestOptions {
5
+ readonly projectRoot: string;
6
+ readonly sessionId: string | null;
7
+ readonly env?: NodeJS.ProcessEnv;
8
+ }
9
+ export interface SuggestResult {
10
+ readonly shouldSuggest: boolean;
11
+ readonly reason: string;
12
+ readonly ratio: number;
13
+ readonly windowKind: WindowKind;
14
+ readonly tokensUsed: number;
15
+ readonly toolCalls: number;
16
+ readonly thresholds: {
17
+ readonly contextTokens: number;
18
+ readonly contextInterval: number;
19
+ readonly toolCalls: number;
20
+ };
21
+ readonly dataUnavailable: boolean;
22
+ readonly source: 'usage-jsonl' | 'env-vars' | 'none';
23
+ }
24
+ /** Default tool-call threshold before first suggestion. */
25
+ export declare const DEFAULT_TOOL_CALL_THRESHOLD = 50;
26
+ /** Default additional tool calls before the suggestion repeats. */
27
+ export declare const TOOL_CALL_REMIND_STEP = 25;
28
+ /** Default context-size threshold on a 200k window. */
29
+ export declare const DEFAULT_CONTEXT_THRESHOLD_200K = 160000;
30
+ /** Default context-size threshold on a 1M window. */
31
+ export declare const DEFAULT_CONTEXT_THRESHOLD_1M = 250000;
32
+ /** Default re-remind interval for context size. */
33
+ export declare const DEFAULT_CONTEXT_INTERVAL = 60000;
34
+ export declare function suggestCompact(options: SuggestOptions): SuggestResult;
35
+ /**
36
+ * `peaks compact dry-run` envelope — composed of (a) suggest, (b)
37
+ * recommend, (c) survival. Pure composition over the helpers; no
38
+ * additional I/O. The CLI emits this so the LLM can decide in one
39
+ * tool-call whether to act.
40
+ */
41
+ export interface DryRunOptions {
42
+ readonly projectRoot: string;
43
+ readonly sessionId: string | null;
44
+ readonly from?: Phase;
45
+ readonly to?: Phase;
46
+ readonly env?: NodeJS.ProcessEnv;
47
+ }
48
+ export interface DryRunResult {
49
+ readonly action: 'compact' | 'skip';
50
+ readonly suggest: SuggestResult;
51
+ readonly recommend: {
52
+ readonly from: Phase | null;
53
+ readonly to: Phase | null;
54
+ readonly shouldCompact: boolean;
55
+ readonly severity: Severity | null;
56
+ readonly rationale: string | null;
57
+ readonly suggestedMessage: string | null;
58
+ };
59
+ readonly survival: {
60
+ readonly persists: readonly string[];
61
+ readonly lost: readonly string[];
62
+ };
63
+ }
64
+ export declare function dryRunCompact(options: DryRunOptions): DryRunResult;
65
+ export declare function buildRecommendEnvelopePure(from: Phase, to: Phase): {
66
+ from: Phase;
67
+ to: Phase;
68
+ shouldCompact: boolean;
69
+ severity: Severity;
70
+ rationale: string;
71
+ suggestedMessage: string;
72
+ };
73
+ export { PHASE_TRANSITIONS, lookupPhaseTransition, buildSuggestedCompactMessage, PHASES, isPhase, SURVIVAL_TABLE } from './decision-tables.js';
74
+ export type { Phase, Severity } from './decision-tables.js';