peaks-loop 4.0.0-beta → 4.0.0-beta.3

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 (179) hide show
  1. package/CHANGELOG.md +105 -87
  2. package/README-en.md +17 -4
  3. package/README.md +17 -4
  4. package/dist/src/cli/commands/asset-commands.d.ts +45 -0
  5. package/dist/src/cli/commands/asset-commands.js +404 -0
  6. package/dist/src/cli/commands/bee-commands.d.ts +26 -0
  7. package/dist/src/cli/commands/bee-commands.js +169 -0
  8. package/dist/src/cli/commands/{solo-commands.d.ts → code-commands.d.ts} +24 -24
  9. package/dist/src/cli/commands/{solo-commands.js → code-commands.js} +78 -78
  10. package/dist/src/cli/commands/core/skill-command.js +1 -1
  11. package/dist/src/cli/commands/dispatch-from-dag.js +1 -1
  12. package/dist/src/cli/commands/evolution-commands.d.ts +27 -0
  13. package/dist/src/cli/commands/evolution-commands.js +393 -0
  14. package/dist/src/cli/commands/hook-handle.js +7 -7
  15. package/dist/src/cli/commands/job-commands.js +2 -2
  16. package/dist/src/cli/commands/loop-commands.d.ts +19 -13
  17. package/dist/src/cli/commands/loop-commands.js +147 -13
  18. package/dist/src/cli/commands/sediment-commands.js +9 -0
  19. package/dist/src/cli/commands/session-auto-compact-hook-command.js +2 -2
  20. package/dist/src/cli/commands/skill-loop-engineering-readiness-commands.d.ts +67 -0
  21. package/dist/src/cli/commands/skill-loop-engineering-readiness-commands.js +173 -0
  22. package/dist/src/cli/commands/sub-agent-shared.d.ts +1 -1
  23. package/dist/src/cli/commands/user-touchpoint-commands.d.ts +4 -4
  24. package/dist/src/cli/commands/user-touchpoint-commands.js +14 -14
  25. package/dist/src/cli/commands/workflow-commands.js +22 -22
  26. package/dist/src/cli/program.js +23 -6
  27. package/dist/src/services/artifacts/repair-cycle-service.js +1 -1
  28. package/dist/src/services/audit/enforcers/active-skill-resolver.d.ts +1 -1
  29. package/dist/src/services/audit/enforcers/active-skill-resolver.js +1 -1
  30. package/dist/src/services/audit/enforcers/{solo-code-ban.d.ts → code-ban.d.ts} +6 -6
  31. package/dist/src/services/audit/enforcers/{solo-code-ban.js → code-ban.js} +6 -6
  32. package/dist/src/services/audit/red-line-catalog.d.ts +2 -2
  33. package/dist/src/services/audit/red-line-catalog.js +5 -5
  34. package/dist/src/services/audit/types.d.ts +2 -2
  35. package/dist/src/services/{solo → code}/auto-compact-orchestrator.d.ts +1 -1
  36. package/dist/src/services/{solo → code}/auto-compact-orchestrator.js +3 -3
  37. package/dist/src/services/{solo → code}/dag-orchestrator.d.ts +1 -1
  38. package/dist/src/services/{solo → code}/dag-orchestrator.js +1 -1
  39. package/dist/src/services/{solo → code}/emit-handoff.d.ts +1 -1
  40. package/dist/src/services/{solo → code}/emit-handoff.js +1 -1
  41. package/dist/src/services/{solo → code}/job-shape-decision.d.ts +1 -1
  42. package/dist/src/services/{solo → code}/job-shape-decision.js +5 -5
  43. package/dist/src/services/{solo → code}/mode-gate.d.ts +9 -9
  44. package/dist/src/services/{solo → code}/mode-gate.js +5 -5
  45. package/dist/src/services/{solo → code}/post-compact-detector.d.ts +3 -3
  46. package/dist/src/services/{solo → code}/post-compact-detector.js +4 -4
  47. package/dist/src/services/{solo → code}/step-08-gate.d.ts +4 -4
  48. package/dist/src/services/{solo → code}/step-08-gate.js +4 -4
  49. package/dist/src/services/{solo → code}/user-touchpoint-classifier.d.ts +1 -1
  50. package/dist/src/services/{solo → code}/user-touchpoint-classifier.js +1 -1
  51. package/dist/src/services/context/auto-compact-dispatcher.d.ts +2 -2
  52. package/dist/src/services/context/auto-compact-dispatcher.js +2 -2
  53. package/dist/src/services/context/auto-compact-types.d.ts +1 -1
  54. package/dist/src/services/crystallization/crystallization-service.d.ts +239 -0
  55. package/dist/src/services/crystallization/crystallization-service.js +397 -0
  56. package/dist/src/services/crystallization/crystallization-store.d.ts +75 -0
  57. package/dist/src/services/crystallization/crystallization-store.js +193 -0
  58. package/dist/src/services/crystallization/crystallization-types.d.ts +313 -0
  59. package/dist/src/services/crystallization/crystallization-types.js +299 -0
  60. package/dist/src/services/crystallization/evidence-brief-builder.d.ts +237 -0
  61. package/dist/src/services/crystallization/evidence-brief-builder.js +240 -0
  62. package/dist/src/services/dispatch/slice-dag.d.ts +2 -2
  63. package/dist/src/services/dispatch/test-tool-detection.d.ts +1 -1
  64. package/dist/src/services/dispatch/test-tool-detection.js +1 -1
  65. package/dist/src/services/evolution/evolution-service.d.ts +137 -0
  66. package/dist/src/services/evolution/evolution-service.js +281 -0
  67. package/dist/src/services/evolution/evolution-store.d.ts +57 -0
  68. package/dist/src/services/evolution/evolution-store.js +232 -0
  69. package/dist/src/services/evolution/evolution-types.d.ts +706 -0
  70. package/dist/src/services/evolution/evolution-types.js +286 -0
  71. package/dist/src/services/evolution/independent-evaluator-runner.d.ts +90 -0
  72. package/dist/src/services/evolution/independent-evaluator-runner.js +106 -0
  73. package/dist/src/services/evolution/regression-skeptic-runner.d.ts +64 -0
  74. package/dist/src/services/evolution/regression-skeptic-runner.js +113 -0
  75. package/dist/src/services/feedback/feedback-promotion-service.js +2 -2
  76. package/dist/src/services/job/job-progress-store.d.ts +1 -1
  77. package/dist/src/services/job/job-progress-store.js +1 -1
  78. package/dist/src/services/loop/loop-bee-relation-service.d.ts +107 -0
  79. package/dist/src/services/loop/loop-bee-relation-service.js +211 -0
  80. package/dist/src/services/loop/loop-bee-relation-store.d.ts +53 -0
  81. package/dist/src/services/loop/loop-bee-relation-store.js +130 -0
  82. package/dist/src/services/loop/loop-bee-relation-types.d.ts +118 -0
  83. package/dist/src/services/loop/loop-bee-relation-types.js +114 -0
  84. package/dist/src/services/loop/loop-release-service.d.ts +46 -0
  85. package/dist/src/services/loop/loop-release-service.js +66 -0
  86. package/dist/src/services/loop/loop-release-store.d.ts +55 -0
  87. package/dist/src/services/loop/loop-release-store.js +134 -0
  88. package/dist/src/services/loop/loop-release-types.d.ts +250 -0
  89. package/dist/src/services/loop/loop-release-types.js +162 -0
  90. package/dist/src/services/preferences/preferences-service.d.ts +1 -1
  91. package/dist/src/services/preferences/preferences-types.d.ts +1 -1
  92. package/dist/src/services/rd/standards-diagnostic.d.ts +1 -1
  93. package/dist/src/services/rd/standards-diagnostic.js +2 -2
  94. package/dist/src/services/recommendations/capability-seed-items.js +1 -1
  95. package/dist/src/services/recommendations/capability-seed-mappings.js +1 -1
  96. package/dist/src/services/recommendations/recommendation-service.js +1 -1
  97. package/dist/src/services/refactor/refactor-service.d.ts +1 -1
  98. package/dist/src/services/share/bundle-reader.d.ts +100 -0
  99. package/dist/src/services/share/bundle-reader.js +434 -0
  100. package/dist/src/services/share/bundle-types.d.ts +392 -0
  101. package/dist/src/services/share/bundle-types.js +318 -0
  102. package/dist/src/services/share/bundle-writer.d.ts +97 -0
  103. package/dist/src/services/share/bundle-writer.js +429 -0
  104. package/dist/src/services/share/run-state-contract.d.ts +133 -0
  105. package/dist/src/services/share/run-state-contract.js +138 -0
  106. package/dist/src/services/signal/cancel-handler.js +3 -3
  107. package/dist/src/services/skill/resume-detector.js +1 -1
  108. package/dist/src/services/skillhub/release-import.js +7 -2
  109. package/dist/src/services/skillhub/release-retain.js +6 -1
  110. package/dist/src/services/skillhub/sqlite-store.js +17 -1
  111. package/dist/src/services/skillhub/types.d.ts +10 -0
  112. package/dist/src/services/skills/skill-presence-service.d.ts +1 -1
  113. package/dist/src/services/standards/loop-engineering-lint.d.ts +38 -0
  114. package/dist/src/services/standards/loop-engineering-lint.js +101 -0
  115. package/dist/src/services/standards/loop-engineering-readiness-lint.d.ts +111 -0
  116. package/dist/src/services/standards/loop-engineering-readiness-lint.js +248 -0
  117. package/dist/src/services/upgrade/1x-detector-service.js +1 -1
  118. package/dist/src/services/workflow/pipeline-verify-service.d.ts +1 -1
  119. package/dist/src/services/workflow/pipeline-verify-service.js +3 -3
  120. package/dist/src/services/workflow/workflow-autonomous-service.d.ts +3 -3
  121. package/dist/src/services/workflow/workflow-autonomous-service.js +2 -2
  122. package/dist/src/services/workflow/workflow-router-service.d.ts +6 -6
  123. package/dist/src/services/workflow/workflow-router-service.js +33 -33
  124. package/dist/src/services/workspace/claude-settings-template.d.ts +1 -1
  125. package/dist/src/services/workspace/claude-settings-template.js +5 -5
  126. package/dist/src/shared/version.d.ts +1 -1
  127. package/dist/src/shared/version.js +1 -1
  128. package/examples/video-demo/README.md +57 -0
  129. package/examples/video-demo/out/en-closing-960.png +0 -0
  130. package/examples/video-demo/out/zh-closing-960.png +0 -0
  131. package/examples/video-demo/preview/peaks-loop-demo-en.mp4 +0 -0
  132. package/examples/video-demo/preview/peaks-loop-demo.mp4 +0 -0
  133. package/output-styles/peaks-skill-swarm.md +3 -3
  134. package/package.json +6 -2
  135. package/skills/bee/peaks-qa/SKILL.md +1 -1
  136. package/skills/bee/peaks-qa/references/artifact-per-request.md +3 -3
  137. package/skills/bee/peaks-qa/references/qa-sub-agent-dispatch.md +6 -6
  138. package/skills/bee/peaks-rd/references/rd-fanout-contracts.md +1 -1
  139. package/skills/bee/peaks-rd/references/rd-runbook.md +1 -1
  140. package/skills/bee/peaks-rd/references/rd-sub-agent-dispatch.md +11 -11
  141. package/skills/bee/peaks-rd/references/rd-transition-gates.md +1 -1
  142. package/skills/bee/peaks-sc/SKILL.md +1 -1
  143. package/skills/bee/peaks-txt/SKILL.md +3 -3
  144. package/skills/bee/peaks-ui/SKILL.md +8 -8
  145. package/skills/peaks-code/SKILL.md +34 -21
  146. package/skills/peaks-code/references/anchoring-and-session-info.md +2 -2
  147. package/skills/peaks-code/references/artifact-contracts.md +1 -1
  148. package/skills/peaks-code/references/boundaries.md +3 -3
  149. package/skills/peaks-code/references/codegraph-orchestration.md +1 -1
  150. package/skills/peaks-code/references/dag-orchestrator.md +7 -7
  151. package/skills/peaks-code/references/external-references.md +2 -2
  152. package/skills/peaks-code/references/fanout-mandatory.md +3 -3
  153. package/skills/peaks-code/references/fast-mode.md +2 -2
  154. package/skills/peaks-code/references/frontend-only-mode.md +9 -9
  155. package/skills/peaks-code/references/job-loop.md +1 -1
  156. package/skills/peaks-code/references/local-artifact-workspace.md +2 -2
  157. package/skills/peaks-code/references/micro-cycle.md +14 -14
  158. package/skills/peaks-code/references/mode-selection-with-stale-presence.md +5 -5
  159. package/skills/peaks-code/references/mode-selection.md +3 -3
  160. package/skills/peaks-code/references/openspec-workflow.md +16 -16
  161. package/skills/peaks-code/references/periodic-checkpoint.md +4 -4
  162. package/skills/peaks-code/references/quality-gate-cheatsheet.md +1 -1
  163. package/skills/peaks-code/references/refactor-mode.md +1 -1
  164. package/skills/peaks-code/references/runbook.md +15 -15
  165. package/skills/peaks-code/references/step-0-55-1x-detection.md +1 -1
  166. package/skills/peaks-code/references/step-0-8-gate.md +11 -11
  167. package/skills/peaks-code/references/sub-agent-dispatch.md +8 -8
  168. package/skills/peaks-code/references/swarm-dispatch-contract.md +17 -17
  169. package/skills/peaks-code/references/workflow-gates-and-types.md +2 -2
  170. package/skills/peaks-code/references/workflow.md +5 -5
  171. package/skills/peaks-content/SKILL.md +272 -0
  172. package/skills/peaks-issue-fix-orchestrator/SKILL.md +307 -0
  173. package/skills/peaks-resume/SKILL.md +2 -2
  174. package/skills/peaks-status/SKILL.md +2 -2
  175. package/skills/peaks-test/SKILL.md +2 -2
  176. /package/dist/src/services/{solo → code}/batch-heartbeat-poller.d.ts +0 -0
  177. /package/dist/src/services/{solo → code}/batch-heartbeat-poller.js +0 -0
  178. /package/dist/src/services/{solo → code}/status-line-renderer.d.ts +0 -0
  179. /package/dist/src/services/{solo → code}/status-line-renderer.js +0 -0
@@ -0,0 +1,248 @@
1
+ /**
2
+ * Loop Engineering Readiness linter (M6 — peak-spec §7.5 + §8.4).
3
+ *
4
+ * Pure function: takes the raw markdown text of a peaks-* SKILL.md
5
+ * file and returns either
6
+ * { ok: true, findings: [] }
7
+ * or
8
+ * { ok: false, findings: string[] }.
9
+ *
10
+ * The lint asserts three structural properties the spec binds every
11
+ * Loop-Engineering-participating peaks-* skill to:
12
+ *
13
+ * 1. The skill references the shared guideline file
14
+ * `.peaks/standards/loop-engineering-guidelines.md` (or its
15
+ * alias `.peaks/standards/loop-engineering-guidelines.md`).
16
+ * Reference may appear anywhere in the body — code fence,
17
+ * plain prose, or list item — as long as the literal token is
18
+ * present.
19
+ *
20
+ * 2. The skill does NOT introduce a CLI verb that bypasses the
21
+ * LLM-coordinated model. We flag lines that look like
22
+ * "Run `peaks <verb>` to …" where `<verb>` is not in the
23
+ * allowlist of LLM-owned sediment / asset / evolution verbs.
24
+ * The user types NL; the LLM runs the CLI on the user's behalf
25
+ * (RL-1 / Human-NL-Choice-Only).
26
+ *
27
+ * 3. The skill does NOT introduce a JSON / manifest
28
+ * hand-authoring surface. We flag lines containing phrases
29
+ * like "Edit the manifest", "write the JSON", "fill the JSON
30
+ * file", etc., when they are not part of an explicit allowlist
31
+ * (allowlist only references; never an instructional phrase).
32
+ *
33
+ * Each finding is a single line of the form:
34
+ * "<rule>: <offending excerpt>"
35
+ * so a downstream CLI can render it directly without further
36
+ * parsing.
37
+ *
38
+ * The lint intentionally does NOT touch any application-level
39
+ * code; it only parses a SKILL.md text. The peaks CLI command
40
+ * `peaks skill lint --category loop-engineering-readiness
41
+ * --path <skill-dir>`
42
+ * (registered in src/cli/commands/skill-loop-engineering-readiness.ts)
43
+ * reads the SKILL.md from disk and calls this function.
44
+ *
45
+ * Per RL-1 / Human-NL-Choice-Only and
46
+ * `.peaks/memory/two-forms-only-rule.md`, the user only ever picks
47
+ * via AskUserQuestion or describes in NL; the LLM runs the CLI.
48
+ * This lint is what stops a future peaks-* skill from regressing
49
+ * that rule at the textual layer.
50
+ */
51
+ /**
52
+ * The shared guideline file that every Loop-Engineering-participating
53
+ * peaks-* skill must reference. Both the canonical path and the
54
+ * common alias are accepted.
55
+ *
56
+ * The alias is intentionally identical to the canonical path here:
57
+ * the spec sometimes renders it as
58
+ * `.peaks/standards/loop-engineering-guidelines.md`
59
+ * with a slash prefix and sometimes without. We accept both.
60
+ */
61
+ export const LOOP_ENGINEERING_GUIDELINE_PATHS = [
62
+ '.peaks/standards/loop-engineering-guidelines.md',
63
+ ];
64
+ /**
65
+ * The allowlist of CLI verbs that a peaks-* SKILL.md may legitimately
66
+ * instruct an LLM to invoke on the user's behalf. These are the
67
+ * sediment / asset / evolution surface verbs introduced in
68
+ * 2026-07-07-loop-engineering-crystallization-design §7.4 plus the
69
+ * 18-verb sediment pool from 2026-07-04-peaks-maker-dynamic-skill-
70
+ * sediment-design §4.2.
71
+ *
72
+ * Any other `peaks <verb>` token that appears in the form
73
+ * "Run `peaks <verb>` to …"
74
+ * is treated as a CLI-verb-bypass attempt and flagged.
75
+ */
76
+ export const ALLOWED_CLI_VERBS = new Set([
77
+ // sediment pool verbs (M6 reference; peak-maker's owned surface)
78
+ 'add-segment',
79
+ 'add-bee',
80
+ 'refine-bee',
81
+ 'clone-bee',
82
+ 'promote',
83
+ 'retire',
84
+ 'dispose',
85
+ 'releases',
86
+ 'release-show',
87
+ 'release-diff',
88
+ 'export',
89
+ 'import',
90
+ 'gc-blobs',
91
+ 'list',
92
+ 'show',
93
+ 'search',
94
+ 'recent',
95
+ 'rebuild-index',
96
+ // loop crystallizer surface (§7.4)
97
+ 'loop',
98
+ 'crystallize',
99
+ // evolution ratchet surface (§7.4)
100
+ 'evolution',
101
+ 'propose',
102
+ 'evaluate',
103
+ 'revert',
104
+ 'mark-keep',
105
+ // umbrella asset surface (§7.4)
106
+ 'asset',
107
+ 'status',
108
+ // adapter surface (peaks-maker's owned skill runtime)
109
+ 'adapter',
110
+ // lint surface (this command's own kind)
111
+ 'lint',
112
+ 'standards',
113
+ 'skill',
114
+ 'ready',
115
+ ]);
116
+ /**
117
+ * Phrases that constitute a JSON / manifest hand-authoring surface.
118
+ * If a SKILL.md instructs the user to perform one of these actions,
119
+ * it violates RL-1 / Human-NL-Choice-Only and is flagged.
120
+ *
121
+ * Each entry is a lowercase substring matched against each line of
122
+ * the SKILL.md. The match is case-insensitive; the surrounding
123
+ * `<verb>` placeholders in the original spec are matched literally.
124
+ */
125
+ export const JSON_HAND_AUTHORING_PHRASES = [
126
+ 'edit the manifest',
127
+ 'edit your manifest',
128
+ 'edit the json',
129
+ 'edit the .json file',
130
+ 'write the json',
131
+ 'write the json manifest',
132
+ 'write the manifest json',
133
+ 'fill the json',
134
+ 'fill in the json',
135
+ 'fill in the manifest',
136
+ 'fill in the manifest.json',
137
+ 'hand-author the manifest',
138
+ 'hand-author the json',
139
+ 'open the manifest and',
140
+ 'open the manifest.json and',
141
+ 'manually edit the manifest',
142
+ 'manually edit the json',
143
+ ];
144
+ /**
145
+ * Phrases that explicitly reference a JSON / manifest surface but
146
+ * in an ALLOWED way — e.g. "the manifest is written by the CLI" or
147
+ * "see manifest schema for details". A line that contains one of
148
+ * these allowlisted phrases is NOT flagged even if it contains a
149
+ * JSON-hand-authoring phrase elsewhere on the same line.
150
+ *
151
+ * The allowlist is intentionally narrow; it must mention either
152
+ * the CLI as the writer OR a schema reference, NOT an instructional
153
+ * verb targeting the user.
154
+ */
155
+ export const JSON_REFERENCE_ALLOWLIST = [
156
+ 'the cli writes',
157
+ 'written by the cli',
158
+ 'written by peaks',
159
+ 'manifest schema',
160
+ 'see the manifest schema',
161
+ 'see manifest schema',
162
+ 'schema_version',
163
+ 'peaks.bundle/1',
164
+ 'peaks.loop/1',
165
+ 'peaks.bee/1',
166
+ ];
167
+ // ---------------------------------------------------------------------------
168
+ // Pure function
169
+ // ---------------------------------------------------------------------------
170
+ /**
171
+ * Lint a SKILL.md text for Loop Engineering readiness.
172
+ *
173
+ * @param skillMdText raw markdown text of a peaks-* SKILL.md
174
+ * @returns a ReadinessLintResult
175
+ */
176
+ export function lintSkillLoopEngineeringReadiness(skillMdText) {
177
+ const findings = [];
178
+ if (typeof skillMdText !== 'string' || skillMdText.trim().length === 0) {
179
+ return {
180
+ ok: false,
181
+ findings: ['skill-md-empty: SKILL.md text is empty or missing'],
182
+ };
183
+ }
184
+ checkGuidelineReference(skillMdText, findings);
185
+ checkCliVerbBypass(skillMdText, findings);
186
+ checkJsonHandAuthoring(skillMdText, findings);
187
+ if (findings.length > 0) {
188
+ return { ok: false, findings };
189
+ }
190
+ return { ok: true, findings: [] };
191
+ }
192
+ // ---------------------------------------------------------------------------
193
+ // Individual checks
194
+ // ---------------------------------------------------------------------------
195
+ function checkGuidelineReference(text, findings) {
196
+ // Strip code fences before checking — references inside ``` blocks
197
+ // are still valid references (the lint accepts them), but we strip
198
+ // so the substring match is unambiguous.
199
+ const stripped = text;
200
+ for (const ref of LOOP_ENGINEERING_GUIDELINE_PATHS) {
201
+ if (stripped.includes(ref)) {
202
+ return;
203
+ }
204
+ }
205
+ findings.push(`missing-guideline-reference: SKILL.md must reference ${LOOP_ENGINEERING_GUIDELINE_PATHS[0]} (spec §7.5 / §8.4 / RL-8)`);
206
+ }
207
+ function checkCliVerbBypass(text, findings) {
208
+ // Match lines that contain `peaks <verb>` in a run-this-command
209
+ // pattern: "Run `peaks <verb>` to …" or "`peaks <verb>` to …" or
210
+ // "use `peaks <verb>` to …".
211
+ //
212
+ // The regex is intentionally narrow: it requires backticks around
213
+ // `peaks <verb>` so prose that mentions "peaks <verb>" as a noun
214
+ // (e.g. "peaks skill sediment list") is not flagged. The verb
215
+ // token is captured as the first `[a-z][a-z0-9-]*` chunk after
216
+ // "peaks "; everything between the verb and the closing backtick
217
+ // is allowed (e.g. `peaks custom-evolve my-bee` — verb is
218
+ // "custom-evolve", args are "my-bee").
219
+ const lineRegex = /^\s*[-*]?\s*(?:Run|Use|Type|Execute)\s+`peaks\s+([a-z][a-z0-9-]*)[^`]*`/gim;
220
+ const lines = text.split(/\r?\n/);
221
+ for (let i = 0; i < lines.length; i++) {
222
+ const line = lines[i];
223
+ let m;
224
+ lineRegex.lastIndex = 0;
225
+ while ((m = lineRegex.exec(line)) !== null) {
226
+ const verb = m[1];
227
+ if (!ALLOWED_CLI_VERBS.has(verb)) {
228
+ const excerpt = line.trim().slice(0, 120);
229
+ findings.push(`cli-verb-bypass: line ${i + 1} introduces CLI verb \`peaks ${verb}\` to be typed by the user (${excerpt}) — only LLM-coordinated verbs from the sediment/asset/evolution surface are allowed (RL-1)`);
230
+ }
231
+ }
232
+ }
233
+ }
234
+ function checkJsonHandAuthoring(text, findings) {
235
+ const lines = text.split(/\r?\n/);
236
+ for (let i = 0; i < lines.length; i++) {
237
+ const line = lines[i];
238
+ const lowered = line.toLowerCase();
239
+ const matchedPhrase = JSON_HAND_AUTHORING_PHRASES.find((p) => lowered.includes(p));
240
+ if (!matchedPhrase)
241
+ continue;
242
+ const isAllowlisted = JSON_REFERENCE_ALLOWLIST.some((p) => lowered.includes(p));
243
+ if (isAllowlisted)
244
+ continue;
245
+ const excerpt = line.trim().slice(0, 120);
246
+ findings.push(`json-hand-authoring: line ${i + 1} introduces JSON / manifest hand-authoring surface ("${matchedPhrase}") — ${excerpt} (RL-1: user only picks or describes in NL)`);
247
+ }
248
+ }
@@ -2,7 +2,7 @@
2
2
  * 1.x → 2.0 detection service — TypeScript mirror of
3
3
  * `scripts/install-skills.mjs:detect1xProjectState`.
4
4
  *
5
- * Slice: 2026-06-12-solo-step-0-55-1x-detection.
5
+ * Slice: 2026-06-12-code-step-0-55-1x-detection.
6
6
  *
7
7
  * The canonical implementation lives in the .mjs postinstall
8
8
  * (because the postinstall runs before any TS compile step).
@@ -63,7 +63,7 @@ export type PipelineVerification = {
63
63
  */
64
64
  gateH?: 'pass' | 'fail';
65
65
  /**
66
- * Slice 2026-06-28-solo-mode-bypass-fix (defect #3): `true` when
66
+ * Slice 2026-06-28-code-mode-bypass-fix (defect #3): `true` when
67
67
  * every evidence file resolved on the canonical path
68
68
  * (`.peaks/_runtime/change/<sessionId>/...`). `false` when at least
69
69
  * one evidence file resolved via a legacy fallback (`.peaks/<sessionId>/...`
@@ -26,7 +26,7 @@ async function findRequestFile(projectRoot, role, rid) {
26
26
  const artifact = await showRequestArtifact({ projectRoot, role: role, requestId: rid });
27
27
  if (artifact === null)
28
28
  return null;
29
- // Slice 2026-06-28-solo-mode-bypass-fix (defect #3): the legacy
29
+ // Slice 2026-06-28-code-mode-bypass-fix (defect #3): the legacy
30
30
  // `showRequestArtifact` returns the FULL SCOPE (`_runtime/<sid>`)
31
31
  // as `sessionId`, not just the trailing id segment. The canonical
32
32
  // evidence lookup needs only the bare id (`.peaks/_runtime/change/<id>/`).
@@ -158,7 +158,7 @@ export async function verifyPipeline(options) {
158
158
  // preferred filesystem scope; falling through to `options.rid` would
159
159
  // make every missing-evidence path look like a per-rid scope dir.
160
160
  const rdEvidenceDir = resolvedChangeId || options.sessionId || getSessionIdCanonical(options.projectRoot) || options.rid;
161
- // Slice 2026-06-28-solo-mode-bypass-fix (defect #3): track whether
161
+ // Slice 2026-06-28-code-mode-bypass-fix (defect #3): track whether
162
162
  // every resolved evidence file landed on the canonical path. Drives
163
163
  // the `usedCanonicalPath` envelope field. The flag stays `true` if
164
164
  // no evidence file was resolved at all (nothing to be non-canonical
@@ -410,7 +410,7 @@ export async function verifyPipeline(options) {
410
410
  : 'suffixed';
411
411
  const gateC = allQaGatesPassed ? 'pass' : 'fail';
412
412
  const gateH = allFeedbackGatesPassed ? 'pass' : 'fail';
413
- // Slice 2026-06-28-solo-mode-bypass-fix (defect #3): `true` when
413
+ // Slice 2026-06-28-code-mode-bypass-fix (defect #3): `true` when
414
414
  // every gate resolved on the canonical path; `false` when at least
415
415
  // one fell back to a legacy form. QA / TXT surface the value so the
416
416
  // user knows the legacy content must be moved into the canonical
@@ -1,7 +1,7 @@
1
1
  import type { CapabilityItemType } from '../recommendations/recommendation-types.js';
2
2
  import type { ModelProviderConfig, WorkspaceConfig } from '../config/config-types.js';
3
3
  import { type RdPlanResult } from '../rd/rd-service.js';
4
- import { type SoloMode, type WorkflowMode, type WorkflowRouterPlan } from './workflow-router-service.js';
4
+ import { type CodeMode, type WorkflowMode, type WorkflowRouterPlan } from './workflow-router-service.js';
5
5
  export { getResumeRequiredArtifacts, getResumeArtifactsStatus, createResumePlan } from './workflow-autonomous-resume-helpers.js';
6
6
  export type CapabilitySurface = 'skill' | 'mcp' | 'plugin' | 'expert';
7
7
  export type CapabilityPurpose = 'code-review' | 'security-review' | 'coding-standards' | 'docs-lookup' | 'browser-validation' | 'browser-debug' | 'design-context' | 'design-source' | 'code-search' | 'database-inspection' | 'browser-agent' | 'worker-guidance' | 'memory' | 'context-management' | 'ui-components' | 'spec-workflow' | 'repo-intelligence' | 'openspec' | 'workflow-methodology' | 'workflow-reference' | 'workflow-guidance' | 'product-guidance' | 'design-reference' | 'ui-reference' | 'engineering-guidance' | 'typescript-guidance' | 'quality-guidance' | 'skill-pack' | 'external-skill' | 'design-critique' | 'design-guidance' | 'cloud-skill-pack';
@@ -20,7 +20,7 @@ export type CapabilityCandidate = {
20
20
  };
21
21
  export type AutonomousWorkflowRequest = {
22
22
  readonly mode: WorkflowMode;
23
- readonly soloMode?: SoloMode;
23
+ readonly codeMode?: CodeMode;
24
24
  readonly sessionId: string;
25
25
  readonly goal: string;
26
26
  readonly maxWorkers?: number;
@@ -68,7 +68,7 @@ export type AutonomousStoragePlan = {
68
68
  };
69
69
  export type AutonomousMvpPackage = {
70
70
  readonly mode: WorkflowMode;
71
- readonly soloMode: SoloMode | undefined;
71
+ readonly codeMode: CodeMode | undefined;
72
72
  readonly executionMode: 'preview';
73
73
  readonly dryRun: true;
74
74
  readonly routePolicy: WorkflowRouterPlan['routePolicy'];
@@ -205,7 +205,7 @@ function createCapabilityPlan(request) {
205
205
  function createMvpPackage(request, routePlan, rdPlan, capabilityPlan, ready) {
206
206
  return {
207
207
  mode: request.mode,
208
- soloMode: routePlan.soloMode,
208
+ codeMode: routePlan.codeMode,
209
209
  executionMode: 'preview',
210
210
  dryRun: true,
211
211
  routePolicy: routePlan.routePolicy,
@@ -240,7 +240,7 @@ export function createAutonomousWorkflowPlan(request) {
240
240
  const available = hasArtifactWorkspace(request, artifactWorkspacePath);
241
241
  const routePlan = createWorkflowRouterPlan({
242
242
  mode: request.mode,
243
- ...(request.soloMode !== undefined ? { soloMode: request.soloMode } : {}),
243
+ ...(request.codeMode !== undefined ? { codeMode: request.codeMode } : {}),
244
244
  sessionId: request.sessionId,
245
245
  goal,
246
246
  maxWorkers,
@@ -1,18 +1,18 @@
1
1
  import { type ModelProviderConfig, type WorkspaceConfig } from '../config/config-types.js';
2
2
  import { type RdPlanResult } from '../rd/rd-service.js';
3
3
  import { type TechPlanResult, type TechStatus } from '../tech/tech-service.js';
4
- export type WorkflowMode = 'solo' | 'team';
5
- export type SoloMode = 'full-auto' | 'guided' | 'rnd';
4
+ export type WorkflowMode = 'code' | 'team';
5
+ export type CodeMode = 'full-auto' | 'guided' | 'rnd';
6
6
  export type ModelTier = 'top-tier' | 'mid-tier';
7
7
  export type ModelRole = 'strongest' | 'execution';
8
- export type WorkflowRoutePolicy = 'solo-broad-multi-model' | 'team-rd-limited-multi-model';
8
+ export type WorkflowRoutePolicy = 'code-broad-multi-model' | 'team-rd-limited-multi-model';
9
9
  export type WorkflowStepStage = 'product-direction' | 'design-direction' | 'tech-direction' | 'tech-review' | 'rd-planning' | 'coding-execution' | 'unit-test-execution' | 'quality-review';
10
10
  export type WorkflowStepOwner = 'peaks-code' | 'peaks-rd' | 'peaks-tech' | 'human';
11
11
  export type WorkflowRouterRequest = {
12
12
  sessionId: string;
13
13
  goal: string;
14
14
  mode: WorkflowMode;
15
- soloMode?: SoloMode;
15
+ codeMode?: CodeMode;
16
16
  maxWorkers?: number;
17
17
  dryRun: true;
18
18
  artifactWorkspacePath?: string;
@@ -64,7 +64,7 @@ export type WorkflowRouterPlan = {
64
64
  readonly sessionId: string;
65
65
  readonly goal: string;
66
66
  readonly mode: WorkflowMode;
67
- readonly soloMode?: SoloMode;
67
+ readonly codeMode?: CodeMode;
68
68
  readonly executionMode: 'autonomous';
69
69
  readonly decisionProfile: string;
70
70
  readonly dryRun: true;
@@ -81,5 +81,5 @@ export type WorkflowRouterPlan = {
81
81
  readonly constraints: readonly string[];
82
82
  };
83
83
  export declare function isWorkflowMode(mode: string): mode is WorkflowMode;
84
- export declare function isSoloMode(value: string): value is SoloMode;
84
+ export declare function isCodeMode(value: string): value is CodeMode;
85
85
  export declare function createWorkflowRouterPlan(request: WorkflowRouterRequest): WorkflowRouterPlan;
@@ -18,7 +18,7 @@ const EXECUTION_STAGES = ['coding-execution', 'unit-test-execution'];
18
18
  const GUIDED_DECISION_STAGES = ['product-direction', 'design-direction'];
19
19
  const GOVERNED_DECISION_STAGES = ['product-direction', 'design-direction', 'tech-direction', 'tech-review'];
20
20
  export function isWorkflowMode(mode) {
21
- return mode === 'solo' || mode === 'team';
21
+ return mode === 'code' || mode === 'team';
22
22
  }
23
23
  function assertSupportedMode(mode) {
24
24
  if (!isWorkflowMode(mode)) {
@@ -32,9 +32,9 @@ function normalizeGoal(goal) {
32
32
  }
33
33
  return normalized;
34
34
  }
35
- function assertSoloModeAllowed(mode, soloMode) {
36
- if (mode !== 'solo' && soloMode !== undefined) {
37
- throw new Error('soloMode requires solo workflow mode');
35
+ function assertCodeModeAllowed(mode, codeMode) {
36
+ if (mode !== 'code' && codeMode !== undefined) {
37
+ throw new Error('codeMode requires code workflow mode');
38
38
  }
39
39
  }
40
40
  function step(input, executionModelId) {
@@ -48,29 +48,29 @@ function step(input, executionModelId) {
48
48
  writesArtifacts: false
49
49
  };
50
50
  }
51
- export function isSoloMode(value) {
51
+ export function isCodeMode(value) {
52
52
  return value === 'full-auto' || value === 'guided' || value === 'rnd';
53
53
  }
54
- function getDecisionProfileSummary(mode, soloMode) {
54
+ function getDecisionProfileSummary(mode, codeMode) {
55
55
  if (mode === 'team') {
56
56
  return 'Team mode keeps product and design governance on a human-controlled path while RD execution follows recommended defaults.';
57
57
  }
58
- if (soloMode === 'guided') {
58
+ if (codeMode === 'guided') {
59
59
  return 'Guided mode keeps the user in the decision loop for the early recommended defaults, while later execution remains bounded by the routing plan.';
60
60
  }
61
- if (soloMode === 'rnd') {
61
+ if (codeMode === 'rnd') {
62
62
  return 'R&D mode asks for technical confirmation up front, then applies recommended defaults for implementation, testing, review, and safety checks.';
63
63
  }
64
64
  return 'Full-auto mode applies recommended defaults for product, design, and tech decisions, then runs the engineering pipeline end to end under routing gates.';
65
65
  }
66
- function annotateSteps(steps, soloMode) {
67
- const decisionStages = soloMode === 'guided'
66
+ function annotateSteps(steps, codeMode) {
67
+ const decisionStages = codeMode === 'guided'
68
68
  ? GUIDED_DECISION_STAGES
69
69
  : GOVERNED_DECISION_STAGES;
70
70
  return steps.map((currentStep) => {
71
71
  const isDecisionStage = decisionStages.includes(currentStep.stage);
72
72
  const reasonPrefix = isDecisionStage
73
- ? `[${soloMode}] decision stage`
73
+ ? `[${codeMode}] decision stage`
74
74
  : '[routed] execution stage';
75
75
  return {
76
76
  ...currentStep,
@@ -80,18 +80,18 @@ function annotateSteps(steps, soloMode) {
80
80
  }
81
81
  function createSoloSteps(executionModelId) {
82
82
  return [
83
- step({ id: 'solo-product-direction', stage: 'product-direction', owner: 'peaks-code', modelTier: 'top-tier', reason: 'Product direction needs strong judgment before execution work is delegated.', dependsOn: [] }, executionModelId),
84
- step({ id: 'solo-design-direction', stage: 'design-direction', owner: 'peaks-code', modelTier: 'top-tier', reason: 'Design direction uses the recommended default before cheaper implementation work.', dependsOn: ['solo-product-direction'] }, executionModelId),
85
- step({ id: 'solo-tech-direction', stage: 'tech-direction', owner: 'peaks-tech', modelTier: 'top-tier', reason: 'Technical boundaries and approval gates use the recommended default with high-confidence planning.', dependsOn: ['solo-design-direction'] }, executionModelId),
86
- step({ id: 'solo-tech-review', stage: 'tech-review', owner: 'peaks-tech', modelTier: 'top-tier', reason: 'Tech artifacts and gate decisions require strong review and a recommended default path.', dependsOn: ['solo-tech-direction'] }, executionModelId),
87
- step({ id: 'solo-rd-planning', stage: 'rd-planning', owner: 'peaks-rd', modelTier: 'top-tier', reason: 'RD task decomposition and acceptance criteria use the recommended default before execution delegation.', dependsOn: ['solo-tech-review'] }, executionModelId),
88
- step({ id: 'solo-coding-execution', stage: 'coding-execution', owner: 'peaks-rd', modelTier: executionModelId === STRONGEST_MODEL_ID ? 'top-tier' : 'mid-tier', reason: `Coding and routine refactoring must use the configured execution worker model ${executionModelId}.`, dependsOn: ['solo-rd-planning'] }, executionModelId),
89
- step({ id: 'solo-unit-test-execution', stage: 'unit-test-execution', owner: 'peaks-rd', modelTier: executionModelId === STRONGEST_MODEL_ID ? 'top-tier' : 'mid-tier', reason: `Unit test authoring and focused test runs must use the configured execution worker model ${executionModelId}.`, dependsOn: ['solo-coding-execution'] }, executionModelId),
90
- step({ id: 'solo-quality-review', stage: 'quality-review', owner: 'peaks-code', modelTier: 'top-tier', reason: 'Reducer and final quality gates need strong synthesis and risk review.', dependsOn: ['solo-unit-test-execution'] }, executionModelId)
83
+ step({ id: 'code-product-direction', stage: 'product-direction', owner: 'peaks-code', modelTier: 'top-tier', reason: 'Product direction needs strong judgment before execution work is delegated.', dependsOn: [] }, executionModelId),
84
+ step({ id: 'code-design-direction', stage: 'design-direction', owner: 'peaks-code', modelTier: 'top-tier', reason: 'Design direction uses the recommended default before cheaper implementation work.', dependsOn: ['code-product-direction'] }, executionModelId),
85
+ step({ id: 'code-tech-direction', stage: 'tech-direction', owner: 'peaks-tech', modelTier: 'top-tier', reason: 'Technical boundaries and approval gates use the recommended default with high-confidence planning.', dependsOn: ['code-design-direction'] }, executionModelId),
86
+ step({ id: 'code-tech-review', stage: 'tech-review', owner: 'peaks-tech', modelTier: 'top-tier', reason: 'Tech artifacts and gate decisions require strong review and a recommended default path.', dependsOn: ['code-tech-direction'] }, executionModelId),
87
+ step({ id: 'code-rd-planning', stage: 'rd-planning', owner: 'peaks-rd', modelTier: 'top-tier', reason: 'RD task decomposition and acceptance criteria use the recommended default before execution delegation.', dependsOn: ['code-tech-review'] }, executionModelId),
88
+ step({ id: 'code-coding-execution', stage: 'coding-execution', owner: 'peaks-rd', modelTier: executionModelId === STRONGEST_MODEL_ID ? 'top-tier' : 'mid-tier', reason: `Coding and routine refactoring must use the configured execution worker model ${executionModelId}.`, dependsOn: ['code-rd-planning'] }, executionModelId),
89
+ step({ id: 'code-unit-test-execution', stage: 'unit-test-execution', owner: 'peaks-rd', modelTier: executionModelId === STRONGEST_MODEL_ID ? 'top-tier' : 'mid-tier', reason: `Unit test authoring and focused test runs must use the configured execution worker model ${executionModelId}.`, dependsOn: ['code-coding-execution'] }, executionModelId),
90
+ step({ id: 'code-quality-review', stage: 'quality-review', owner: 'peaks-code', modelTier: 'top-tier', reason: 'Reducer and final quality gates need strong synthesis and risk review.', dependsOn: ['code-unit-test-execution'] }, executionModelId)
91
91
  ];
92
92
  }
93
- function createSoloStepsForMode(soloMode, executionModelId) {
94
- return annotateSteps(createSoloSteps(executionModelId), soloMode);
93
+ function createSoloStepsForMode(codeMode, executionModelId) {
94
+ return annotateSteps(createSoloSteps(executionModelId), codeMode);
95
95
  }
96
96
  function createTeamSteps(executionModelId) {
97
97
  return [
@@ -150,21 +150,21 @@ function createModeStatus(economyMode, swarmMode, executionModelId, executionMod
150
150
  summary: `${economySummary} ${swarmSummary}`
151
151
  };
152
152
  }
153
- function getSoloMode(mode, soloMode) {
154
- if (mode !== 'solo') {
153
+ function getCodeMode(mode, codeMode) {
154
+ if (mode !== 'code') {
155
155
  return undefined;
156
156
  }
157
- if (soloMode === undefined) {
157
+ if (codeMode === undefined) {
158
158
  return 'full-auto';
159
159
  }
160
- if (!isSoloMode(soloMode)) {
161
- throw new Error('Unsupported solo mode');
160
+ if (!isCodeMode(codeMode)) {
161
+ throw new Error('Unsupported code mode');
162
162
  }
163
- return soloMode;
163
+ return codeMode;
164
164
  }
165
165
  export function createWorkflowRouterPlan(request) {
166
166
  assertSupportedMode(request.mode);
167
- assertSoloModeAllowed(request.mode, request.soloMode);
167
+ assertCodeModeAllowed(request.mode, request.codeMode);
168
168
  // Slice 2026-06-29-change-id-root-removal: change-id is metadata-only;
169
169
  // no structural validation gate fires here.
170
170
  const goal = normalizeGoal(request.goal);
@@ -185,8 +185,8 @@ export function createWorkflowRouterPlan(request) {
185
185
  const effectiveProviders = request.config?.providers ?? { minimax: { model: 'minimax-2.7' } };
186
186
  const executionModelId = economyMode !== false ? getConfiguredExecutionModelId(effectiveProviders) : STRONGEST_MODEL_ID;
187
187
  const modeStatus = createModeStatus(economyMode, swarmMode, executionModelId, economyMode ? 'config.providers' : 'planner-reviewer-strongest-model');
188
- const soloMode = getSoloMode(request.mode, request.soloMode);
189
- const decisionProfile = getDecisionProfileSummary(request.mode, soloMode);
188
+ const codeMode = getCodeMode(request.mode, request.codeMode);
189
+ const decisionProfile = getDecisionProfileSummary(request.mode, codeMode);
190
190
  const artifactWorkspacePath = request.artifactWorkspacePath ?? (request.workspace ? getLocalArtifactPath(request.workspace) : undefined);
191
191
  const sharedWorkspaceOptions = {
192
192
  ...(artifactWorkspacePath ? { artifactWorkspacePath } : {}),
@@ -195,7 +195,7 @@ export function createWorkflowRouterPlan(request) {
195
195
  const techStatus = getTechStatus({ sessionId: request.sessionId, ...sharedWorkspaceOptions });
196
196
  const techPlan = createTechPlan({ sessionId: request.sessionId, goal, swarm: swarmMode, dryRun: true, ...sharedWorkspaceOptions });
197
197
  const rdPlan = createRdSwarmPlan({ skill: 'rd', sessionId: request.sessionId, goal, maxWorkers, swarmMode, executionModelId, dryRun: true, ...sharedWorkspaceOptions });
198
- const steps = soloMode ? createSoloStepsForMode(soloMode, executionModelId) : createTeamSteps(executionModelId);
198
+ const steps = codeMode ? createSoloStepsForMode(codeMode, executionModelId) : createTeamSteps(executionModelId);
199
199
  const blockedReasons = uniqueStrings([
200
200
  ...techStatus.blockedReasons,
201
201
  ...getTechPlanBlockedReasons(techPlan),
@@ -208,11 +208,11 @@ export function createWorkflowRouterPlan(request) {
208
208
  sessionId: request.sessionId,
209
209
  goal,
210
210
  mode: request.mode,
211
- ...(soloMode ? { soloMode } : {}),
211
+ ...(codeMode ? { codeMode } : {}),
212
212
  executionMode: 'autonomous',
213
213
  decisionProfile,
214
214
  dryRun: true,
215
- routePolicy: request.mode === 'solo' ? 'solo-broad-multi-model' : 'team-rd-limited-multi-model',
215
+ routePolicy: request.mode === 'code' ? 'code-broad-multi-model' : 'team-rd-limited-multi-model',
216
216
  modelRouting: createModelRouting(steps, executionModelId),
217
217
  modelAssignments: createModelAssignments(steps),
218
218
  modeStatus,
@@ -51,7 +51,7 @@ export declare const CLAUDE_SETTINGS_LOCAL_FILENAME = ".claude/settings.local.js
51
51
  * bypass is the only emit. Bash enforcement is owned by
52
52
  * `peaks gate enforce` in `settings.json`.
53
53
  * 1.3.0 — added the v3.1.2 `Bash` PreToolUse matcher that runs
54
- * `peaks solo gate-step-08 --project .` (Step 0.8 mechanical
54
+ * `peaks code gate-step-08 --project .` (Step 0.8 mechanical
55
55
  * gate). The existing Write|Edit|MultiEdit matcher is
56
56
  * preserved. The new matcher's exit code is the load-bearing
57
57
  * signal: 0 = allow, 2 = block (with stderr BLOCKED reason).
@@ -51,7 +51,7 @@ export const CLAUDE_SETTINGS_LOCAL_FILENAME = '.claude/settings.local.json';
51
51
  * bypass is the only emit. Bash enforcement is owned by
52
52
  * `peaks gate enforce` in `settings.json`.
53
53
  * 1.3.0 — added the v3.1.2 `Bash` PreToolUse matcher that runs
54
- * `peaks solo gate-step-08 --project .` (Step 0.8 mechanical
54
+ * `peaks code gate-step-08 --project .` (Step 0.8 mechanical
55
55
  * gate). The existing Write|Edit|MultiEdit matcher is
56
56
  * preserved. The new matcher's exit code is the load-bearing
57
57
  * signal: 0 = allow, 2 = block (with stderr BLOCKED reason).
@@ -216,7 +216,7 @@ export function buildClaudeSettingsLocalJson() {
216
216
  },
217
217
  {
218
218
  // v3.1.2 Step 0.8 — Mechanical PreToolUse gate. Runs
219
- // `peaks solo gate-step-08 --project .` before every Bash
219
+ // `peaks code gate-step-08 --project .` before every Bash
220
220
  // tool call. Exit 0 = allow (with structured stdout
221
221
  // describing the decision + optional `Next: slice #N+1 of
222
222
  // M (<currentSlice>)` line when progress.json exists). Exit
@@ -235,7 +235,7 @@ export function buildClaudeSettingsLocalJson() {
235
235
  };
236
236
  }
237
237
  /**
238
- * v3.1.2: build the Bash matcher command that runs `peaks solo
238
+ * v3.1.2: build the Bash matcher command that runs `peaks code
239
239
  * gate-step-08`. We invoke the CLI directly (not via `node -e "..."`)
240
240
  * because the CLI is the only legitimate source of the structured
241
241
  * decision + Next: slice context. Exit code is the load-bearing
@@ -246,9 +246,9 @@ export function buildClaudeSettingsLocalJson() {
246
246
  */
247
247
  function buildBashGateStep08Command() {
248
248
  // The hook receives the tool call on stdin. We ignore stdin and
249
- // delegate entirely to `peaks solo gate-step-08`, which reads
249
+ // delegate entirely to `peaks code gate-step-08`, which reads
250
250
  // .peaks/_runtime/<sessionId>/job-shape.json and last-prompt.txt.
251
251
  // `${CLAUDE_PROJECT_DIR}` resolves to the consumer project's root
252
252
  // (Claude Code's standard convention).
253
- return 'peaks solo gate-step-08 --project "${CLAUDE_PROJECT_DIR}"';
253
+ return 'peaks code gate-step-08 --project "${CLAUDE_PROJECT_DIR}"';
254
254
  }
@@ -1 +1 @@
1
- export declare const CLI_VERSION = "4.0.0-beta";
1
+ export declare const CLI_VERSION = "4.0.0-beta.3";
@@ -1 +1 @@
1
- export const CLI_VERSION = "4.0.0-beta";
1
+ export const CLI_VERSION = "4.0.0-beta.3";
@@ -0,0 +1,57 @@
1
+ # peaks-loop video demo
2
+
3
+ Remotion-based 30-second brand walk-through for peaks-loop 4.0. Mirrors `README.md`.
4
+
5
+ ## Composition
6
+
7
+ - Two compositions, one per locale:
8
+ - `peaks-loop-demo` — 30 seconds @ 30fps (900 frames), 1920×1080 — Chinese primary.
9
+ - `peaks-loop-demo-en` — same frame budget, English primary.
10
+ - Scene timeline (frozen in `src/Root.tsx`):
11
+ - 0–90 — **TitleScene** (`peaks-loop`, no ·, no emoji)
12
+ - 90–240 — **PhilosophyScene** — 5 hero philosophy items, bilingual
13
+ - 240–540 — **DemoScene × 3** — `写长任务代码` / `修 bug 当天发` / `接一个长跑的需求`
14
+ - 540–780 — **SedimentScene** — 3-beat `NL → MANIFEST → BEE`
15
+ - 780–900 — **ClosingScene** — `npm i -g peaks-loop` + repo-name vs skill-name arc + 5,439 tests stats
16
+
17
+ ## Visual style
18
+
19
+ - Background: `#0f172a` (slate-900) via `bg-brand-bg`
20
+ - Primary text: `#f8fafc` (slate-50) via `text-brand-fg`
21
+ - Accent: `#6366f1` (indigo-500) via `text-brand-accent`
22
+ - Stable badge: `#22c55e` (green-500)
23
+ - Mono font for kickers / install chip / chat bubbles; sans font for headlines
24
+
25
+ ## Public preview files (tracked)
26
+
27
+ The READMEs embed `<video>` tags that point at:
28
+
29
+ - `preview/peaks-loop-demo.mp4` (zh, 4.9 MB)
30
+ - `preview/peaks-loop-demo-en.mp4` (en, 5.0 MB)
31
+
32
+ These are produced by the render command below and committed to git so a clone (and the GitHub rendering) sees the same path. The shell snippet under **Render** keeps `preview/` in sync after a fresh build.
33
+
34
+ ## Render
35
+
36
+ ```bash
37
+ cd examples/video-demo
38
+ pnpm install
39
+ npx remotion render peaks-loop-demo out/peaks-loop-demo.mp4
40
+ npx remotion render peaks-loop-demo-en out/peaks-loop-demo-en.mp4
41
+
42
+ mkdir -p preview
43
+ cp out/peaks-loop-demo.mp4 preview/peaks-loop-demo.mp4
44
+ cp out/peaks-loop-demo-en.mp4 preview/peaks-loop-demo-en.mp4
45
+ ```
46
+
47
+ Fallback (no Chromium available):
48
+
49
+ ```bash
50
+ npx remotion still peaks-loop-demo out/still.png --frame=120
51
+ ```
52
+
53
+ ## Preview during dev
54
+
55
+ ```bash
56
+ npx remotion studio # http://localhost:3000
57
+ ```