@printpractical/cruze 0.0.12 → 0.0.14

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 (297) hide show
  1. package/README.md +61 -118
  2. package/dist/adapters/inbound/cli/cli_context.js +0 -27
  3. package/dist/adapters/inbound/cli/commands/code.js +5 -18
  4. package/dist/adapters/inbound/cli/commands/documents.js +11 -37
  5. package/dist/adapters/inbound/cli/commands/init.js +1 -1
  6. package/dist/adapters/inbound/cli/commands/review.js +2 -9
  7. package/dist/adapters/inbound/cli/commands/status.js +16 -63
  8. package/dist/adapters/inbound/cli/commands.js +10 -37
  9. package/dist/adapters/inbound/cli/parse_command.js +0 -54
  10. package/dist/adapters/outbound/git_repository.js +2 -71
  11. package/dist/app/ports/repository.js +0 -12
  12. package/dist/app/project_context.js +15 -25
  13. package/dist/app/use_cases/approve_document.js +29 -0
  14. package/dist/app/use_cases/check_code.js +21 -56
  15. package/dist/app/use_cases/new_document.js +25 -0
  16. package/dist/app/use_cases/project_status.js +43 -67
  17. package/dist/app/use_cases/run_review.js +11 -30
  18. package/dist/app/use_cases/validate_project.js +4 -4
  19. package/dist/domain/approvals.js +51 -0
  20. package/dist/domain/check/check_source.js +2 -31
  21. package/dist/domain/config.js +8 -84
  22. package/dist/domain/hashing.js +16 -30
  23. package/dist/domain/ids.js +13 -27
  24. package/dist/domain/next_step.js +41 -0
  25. package/dist/domain/project/features.js +71 -0
  26. package/dist/domain/project/layout.js +11 -27
  27. package/dist/domain/project/project_docs.js +48 -0
  28. package/dist/domain/project/release.js +30 -0
  29. package/dist/domain/scaffold.js +0 -1
  30. package/dist/domain/skill_budget.js +4 -4
  31. package/dist/domain/trace.js +8 -25
  32. package/dist/domain/validation/document_rules.js +70 -0
  33. package/dist/domain/validation/release_rules.js +45 -0
  34. package/dist/domain/validation/validate_project.js +20 -27
  35. package/dist/domain/versions/cruze_version.js +3 -9
  36. package/dist/main.js +1 -1
  37. package/package.json +1 -1
  38. package/skills/asking/SKILL.md +51 -0
  39. package/skills/behavioural-testing/SKILL.md +14 -16
  40. package/skills/behavioural-testing/examples.md +1 -2
  41. package/skills/behavioural-testing/fakes.md +2 -2
  42. package/skills/build/SKILL.md +34 -38
  43. package/skills/dependency-approval/SKILL.md +34 -31
  44. package/skills/envision/SKILL.md +23 -18
  45. package/skills/envision/architecture.md +16 -0
  46. package/skills/envision/breakdown.md +14 -0
  47. package/skills/envision/possibilities.md +6 -7
  48. package/skills/fix/SKILL.md +34 -0
  49. package/skills/formats/SKILL.md +39 -87
  50. package/skills/formats/config.md +47 -0
  51. package/skills/formats/templates/architecture.md +18 -74
  52. package/skills/formats/templates/feature.md +18 -34
  53. package/skills/formats/templates/vision.md +15 -27
  54. package/skills/hexagonal-design/SKILL.md +11 -11
  55. package/skills/hexagonal-design/contracts.md +3 -3
  56. package/skills/hexagonal-design/fundamentals.md +1 -1
  57. package/skills/hexagonal-design/languages/cpp.md +1 -1
  58. package/skills/hexagonal-design/languages/rust.md +1 -1
  59. package/skills/hexagonal-design/languages/swift.md +2 -2
  60. package/skills/hexagonal-design/runtime.md +2 -2
  61. package/skills/research/SKILL.md +4 -4
  62. package/skills/research/evaluation.md +1 -1
  63. package/skills/review/SKILL.md +27 -0
  64. package/skills/roles/SKILL.md +8 -59
  65. package/skills/roles/code-reviewer.md +21 -32
  66. package/skills/roles/researcher.md +3 -3
  67. package/skills/shape/SKILL.md +37 -0
  68. package/skills/shape/self-check.md +12 -0
  69. package/src/adapters/inbound/cli/cli_context.ts +0 -27
  70. package/src/adapters/inbound/cli/commands/code.ts +5 -18
  71. package/src/adapters/inbound/cli/commands/documents.ts +11 -37
  72. package/src/adapters/inbound/cli/commands/init.ts +1 -1
  73. package/src/adapters/inbound/cli/commands/review.ts +2 -9
  74. package/src/adapters/inbound/cli/commands/status.ts +16 -63
  75. package/src/adapters/inbound/cli/commands.ts +10 -37
  76. package/src/adapters/inbound/cli/parse_command.ts +0 -54
  77. package/src/adapters/outbound/git_repository.ts +2 -71
  78. package/src/app/ports/repository.ts +0 -12
  79. package/src/app/project_context.ts +15 -25
  80. package/src/app/use_cases/approve_document.ts +29 -0
  81. package/src/app/use_cases/check_code.ts +21 -56
  82. package/src/app/use_cases/new_document.ts +25 -0
  83. package/src/app/use_cases/project_status.ts +49 -73
  84. package/src/app/use_cases/run_review.ts +11 -30
  85. package/src/app/use_cases/validate_project.ts +4 -4
  86. package/src/domain/approvals.ts +51 -0
  87. package/src/domain/check/check_source.ts +2 -31
  88. package/src/domain/config.ts +9 -85
  89. package/src/domain/hashing.ts +16 -30
  90. package/src/domain/ids.ts +13 -27
  91. package/src/domain/next_step.ts +41 -0
  92. package/src/domain/project/features.ts +71 -0
  93. package/src/domain/project/layout.ts +11 -27
  94. package/src/domain/project/project_docs.ts +48 -0
  95. package/src/domain/project/release.ts +30 -0
  96. package/src/domain/scaffold.ts +0 -1
  97. package/src/domain/skill_budget.ts +4 -4
  98. package/src/domain/trace.ts +8 -25
  99. package/src/domain/validation/document_rules.ts +70 -0
  100. package/src/domain/validation/release_rules.ts +45 -0
  101. package/src/domain/validation/validate_project.ts +21 -28
  102. package/src/domain/versions/cruze_version.ts +3 -9
  103. package/src/main.ts +1 -1
  104. package/templates/init/AGENTS.md +4 -12
  105. package/templates/init/ci.yml +3 -3
  106. package/templates/init/config.yaml +8 -17
  107. package/templates/init/review/claude.yaml +2 -2
  108. package/dist/adapters/inbound/cli/argument_files.js +0 -29
  109. package/dist/adapters/inbound/cli/commands/diff.js +0 -23
  110. package/dist/adapters/inbound/cli/commands/journal.js +0 -32
  111. package/dist/adapters/inbound/cli/commands/progress.js +0 -55
  112. package/dist/adapters/inbound/cli/commands/realign.js +0 -28
  113. package/dist/adapters/inbound/cli/commands/show.js +0 -96
  114. package/dist/app/use_cases/abandon_work.js +0 -42
  115. package/dist/app/use_cases/approve_artifact.js +0 -197
  116. package/dist/app/use_cases/journal_events.js +0 -64
  117. package/dist/app/use_cases/land_change.js +0 -134
  118. package/dist/app/use_cases/new_project_doc.js +0 -48
  119. package/dist/app/use_cases/new_work_item.js +0 -75
  120. package/dist/app/use_cases/realign_done.js +0 -45
  121. package/dist/app/use_cases/realign_status.js +0 -106
  122. package/dist/app/use_cases/record_progress.js +0 -118
  123. package/dist/app/use_cases/show_elements.js +0 -18
  124. package/dist/app/use_cases/show_notes.js +0 -11
  125. package/dist/app/use_cases/show_scope.js +0 -51
  126. package/dist/app/use_cases/upstream_diff.js +0 -55
  127. package/dist/domain/approvals/agent_approval.js +0 -68
  128. package/dist/domain/approvals/evaluate.js +0 -36
  129. package/dist/domain/approvals/fingerprint.js +0 -52
  130. package/dist/domain/approvals/rebase.js +0 -39
  131. package/dist/domain/approvals/records.js +0 -50
  132. package/dist/domain/approvals/upstream_text.js +0 -36
  133. package/dist/domain/architecture_sections.js +0 -23
  134. package/dist/domain/check/decision_comments.js +0 -38
  135. package/dist/domain/decision_citations.js +0 -62
  136. package/dist/domain/edits/agents_file.js +0 -58
  137. package/dist/domain/edits/managed_tables.js +0 -60
  138. package/dist/domain/edits/progress_block.js +0 -33
  139. package/dist/domain/edits/status_lines.js +0 -52
  140. package/dist/domain/elements.js +0 -126
  141. package/dist/domain/journal.js +0 -109
  142. package/dist/domain/land/bookkeeping.js +0 -54
  143. package/dist/domain/land/merge_plan.js +0 -137
  144. package/dist/domain/land/text_ops.js +0 -66
  145. package/dist/domain/line_diff.js +0 -56
  146. package/dist/domain/project/artifact_ref.js +0 -42
  147. package/dist/domain/project/deltas.js +0 -49
  148. package/dist/domain/project/element_lookup.js +0 -124
  149. package/dist/domain/project/living_model.js +0 -55
  150. package/dist/domain/project/new_items.js +0 -48
  151. package/dist/domain/project/notes.js +0 -74
  152. package/dist/domain/project/plan_parts.js +0 -111
  153. package/dist/domain/project/progress.js +0 -43
  154. package/dist/domain/project/project_view.js +0 -72
  155. package/dist/domain/project/roadmap.js +0 -43
  156. package/dist/domain/project/scope_view.js +0 -134
  157. package/dist/domain/project/work_items.js +0 -68
  158. package/dist/domain/status/next_step.js +0 -181
  159. package/dist/domain/status/pending_rethink.js +0 -22
  160. package/dist/domain/status/verification.js +0 -29
  161. package/dist/domain/status/work_status.js +0 -125
  162. package/dist/domain/validation/decision_rules.js +0 -76
  163. package/dist/domain/validation/delta_rules.js +0 -81
  164. package/dist/domain/validation/element_rules.js +0 -104
  165. package/dist/domain/validation/future_rules.js +0 -40
  166. package/dist/domain/validation/living_rules.js +0 -99
  167. package/dist/domain/validation/plan_rules.js +0 -124
  168. package/dist/domain/validation/project_rules.js +0 -115
  169. package/dist/domain/validation/size_rules.js +0 -45
  170. package/dist/domain/validation/vision_rules.js +0 -41
  171. package/dist/domain/validation/work_item_rules.js +0 -175
  172. package/dist/domain/versions/realign_notes.js +0 -72
  173. package/dist/domain/versions/rule_versions.js +0 -29
  174. package/dist/domain/versions/scheduled_exceptions.js +0 -41
  175. package/skills/about/SKILL.md +0 -21
  176. package/skills/architect/SKILL.md +0 -49
  177. package/skills/architect/feature.md +0 -40
  178. package/skills/architect/project.md +0 -58
  179. package/skills/architect/tweak.md +0 -22
  180. package/skills/architect/walkthrough.md +0 -35
  181. package/skills/domain-language/SKILL.md +0 -37
  182. package/skills/envision/feature.md +0 -25
  183. package/skills/envision/intake.md +0 -28
  184. package/skills/envision/project.md +0 -24
  185. package/skills/explore/SKILL.md +0 -39
  186. package/skills/formats/reference/architecture.md +0 -84
  187. package/skills/formats/reference/config.md +0 -80
  188. package/skills/formats/reference/durable-docs.md +0 -74
  189. package/skills/formats/reference/specs.md +0 -65
  190. package/skills/formats/reference/work-items.md +0 -100
  191. package/skills/formats/templates/adr.md +0 -7
  192. package/skills/formats/templates/change.md +0 -29
  193. package/skills/formats/templates/glossary.md +0 -8
  194. package/skills/formats/templates/roadmap.md +0 -32
  195. package/skills/formats/templates/spec.md +0 -11
  196. package/skills/formats/templates/standalone-change.md +0 -46
  197. package/skills/grilling/SKILL.md +0 -90
  198. package/skills/grilling/illustrating.md +0 -38
  199. package/skills/improve/SKILL.md +0 -51
  200. package/skills/land/SKILL.md +0 -48
  201. package/skills/next/SKILL.md +0 -31
  202. package/skills/plan/SKILL.md +0 -62
  203. package/skills/plan/tasks.md +0 -35
  204. package/skills/plan/test-plan.md +0 -14
  205. package/skills/realign/SKILL.md +0 -37
  206. package/skills/realign/notes/0.0.10.md +0 -131
  207. package/skills/realign/notes/0.0.11.md +0 -15
  208. package/skills/realign/notes/0.0.12.md +0 -31
  209. package/skills/realign/notes/0.0.2.md +0 -69
  210. package/skills/realign/notes/0.0.3.md +0 -11
  211. package/skills/realign/notes/0.0.4.md +0 -27
  212. package/skills/realign/notes/0.0.5.md +0 -38
  213. package/skills/realign/notes/0.0.6.md +0 -44
  214. package/skills/realign/notes/0.0.7.md +0 -11
  215. package/skills/realign/notes/0.0.8.md +0 -97
  216. package/skills/realign/notes/0.0.9.md +0 -59
  217. package/skills/realign/notes.md +0 -39
  218. package/skills/rethink/SKILL.md +0 -62
  219. package/skills/rethink/levels.md +0 -54
  220. package/skills/roadmap/SKILL.md +0 -54
  221. package/skills/roles/auditor.md +0 -35
  222. package/skills/roles/design-reviewer.md +0 -43
  223. package/skills/roles/design-rubric.md +0 -41
  224. package/skills/roles/plan-rubric.md +0 -11
  225. package/skills/roles/surveyor.md +0 -41
  226. package/skills/roles/verifier.md +0 -42
  227. package/skills/triage/SKILL.md +0 -37
  228. package/skills/verify/SKILL.md +0 -45
  229. package/skills/verify/manual-test.md +0 -23
  230. package/src/adapters/inbound/cli/argument_files.ts +0 -29
  231. package/src/adapters/inbound/cli/commands/diff.ts +0 -23
  232. package/src/adapters/inbound/cli/commands/journal.ts +0 -32
  233. package/src/adapters/inbound/cli/commands/progress.ts +0 -55
  234. package/src/adapters/inbound/cli/commands/realign.ts +0 -28
  235. package/src/adapters/inbound/cli/commands/show.ts +0 -96
  236. package/src/app/use_cases/abandon_work.ts +0 -42
  237. package/src/app/use_cases/approve_artifact.ts +0 -197
  238. package/src/app/use_cases/journal_events.ts +0 -64
  239. package/src/app/use_cases/land_change.ts +0 -134
  240. package/src/app/use_cases/new_project_doc.ts +0 -48
  241. package/src/app/use_cases/new_work_item.ts +0 -75
  242. package/src/app/use_cases/realign_done.ts +0 -45
  243. package/src/app/use_cases/realign_status.ts +0 -106
  244. package/src/app/use_cases/record_progress.ts +0 -118
  245. package/src/app/use_cases/show_elements.ts +0 -18
  246. package/src/app/use_cases/show_notes.ts +0 -11
  247. package/src/app/use_cases/show_scope.ts +0 -51
  248. package/src/app/use_cases/upstream_diff.ts +0 -55
  249. package/src/domain/approvals/agent_approval.ts +0 -68
  250. package/src/domain/approvals/evaluate.ts +0 -36
  251. package/src/domain/approvals/fingerprint.ts +0 -52
  252. package/src/domain/approvals/rebase.ts +0 -39
  253. package/src/domain/approvals/records.ts +0 -50
  254. package/src/domain/approvals/upstream_text.ts +0 -36
  255. package/src/domain/architecture_sections.ts +0 -23
  256. package/src/domain/check/decision_comments.ts +0 -38
  257. package/src/domain/decision_citations.ts +0 -62
  258. package/src/domain/edits/agents_file.ts +0 -58
  259. package/src/domain/edits/managed_tables.ts +0 -60
  260. package/src/domain/edits/progress_block.ts +0 -33
  261. package/src/domain/edits/status_lines.ts +0 -52
  262. package/src/domain/elements.ts +0 -126
  263. package/src/domain/journal.ts +0 -109
  264. package/src/domain/land/bookkeeping.ts +0 -54
  265. package/src/domain/land/merge_plan.ts +0 -137
  266. package/src/domain/land/text_ops.ts +0 -66
  267. package/src/domain/line_diff.ts +0 -56
  268. package/src/domain/project/artifact_ref.ts +0 -42
  269. package/src/domain/project/deltas.ts +0 -49
  270. package/src/domain/project/element_lookup.ts +0 -124
  271. package/src/domain/project/living_model.ts +0 -55
  272. package/src/domain/project/new_items.ts +0 -48
  273. package/src/domain/project/notes.ts +0 -74
  274. package/src/domain/project/plan_parts.ts +0 -111
  275. package/src/domain/project/progress.ts +0 -43
  276. package/src/domain/project/project_view.ts +0 -72
  277. package/src/domain/project/roadmap.ts +0 -43
  278. package/src/domain/project/scope_view.ts +0 -134
  279. package/src/domain/project/work_items.ts +0 -68
  280. package/src/domain/status/next_step.ts +0 -181
  281. package/src/domain/status/pending_rethink.ts +0 -22
  282. package/src/domain/status/verification.ts +0 -29
  283. package/src/domain/status/work_status.ts +0 -125
  284. package/src/domain/validation/decision_rules.ts +0 -76
  285. package/src/domain/validation/delta_rules.ts +0 -81
  286. package/src/domain/validation/element_rules.ts +0 -104
  287. package/src/domain/validation/future_rules.ts +0 -40
  288. package/src/domain/validation/living_rules.ts +0 -99
  289. package/src/domain/validation/plan_rules.ts +0 -124
  290. package/src/domain/validation/project_rules.ts +0 -115
  291. package/src/domain/validation/size_rules.ts +0 -45
  292. package/src/domain/validation/vision_rules.ts +0 -41
  293. package/src/domain/validation/work_item_rules.ts +0 -175
  294. package/src/domain/versions/realign_notes.ts +0 -72
  295. package/src/domain/versions/rule_versions.ts +0 -29
  296. package/src/domain/versions/scheduled_exceptions.ts +0 -41
  297. package/templates/init/gitattributes +0 -2
package/README.md CHANGED
@@ -4,25 +4,38 @@
4
4
  <img src="docs/assets/cruze-logo.jpg" alt="Cruze" width="720">
5
5
  </p>
6
6
 
7
- Cruze is a spec-driven development framework for coding agents. It keeps one living model of your system (vision, glossary, architecture and behaviour specs) and delivers work as small changes against that model. Each change is merged back into the model when it lands, so the architecture an agent reads on the tenth change is as current as it was on the first.
7
+ Cruze is a lightweight spec-driven workflow for coding agents. You and the agent put the product's vision and future features on paper, break the release into features, and agree on an architecture map. Then, one feature at a time, you agree on what it does and what its public API looks like, and the agent builds it test-first with ports and adapters, reviews it in a fresh context, and opens a pull request.
8
8
 
9
- It works with any agent that supports the [Agent Skills](https://agentskills.io) format. It ships as one npm package: a `cruze` CLI that owns every deterministic step (IDs, approvals, checks, merges) and a set of skills that guide the agent through design and delivery.
9
+ It works with any agent that supports the [Agent Skills](https://agentskills.io) format. It ships as one npm package: a small `cruze` CLI for the deterministic parts (approvals, the next step, scenario-to-test tracing, layer rules) and a set of skills that guide the agent.
10
10
 
11
11
  ## Status
12
12
 
13
- Version 0.0.12 is the twelfth preview. Designs are easier to see and keep lean: the walkthrough shows the types each caller passes and the decisions you didn't make, reviews cut fields nothing reads, questions use plain words and explain a part before asking about it, and a rethink designs for the features ahead. Early development. The CLI is complete for the V1 lifecycle. The document formats ship as the `cruze-formats` skill, the standards an agent designs and codes to ship as knowledge skills, and the whole workflow, from explore to land, ships as workflow skills. Claude Code is the agent tested so far.
13
+ Version 0.0.14 is a rewrite. The earlier previews ran thirteen steps with design reviews, plans, verifiers, journals and merged living specs. Measured across nine projects, they took about twice the time of a plain design doc and plan for code of the same quality, and asked the user so many questions that most answers were a bare "agree". This version keeps what paid off and drops the rest. Nothing is compatible with 0.0.13 projects. Claude Code is the agent tested so far.
14
14
 
15
- ## Why
15
+ ## The flow
16
16
 
17
- Spec-driven workflows tend to fail in the same few ways:
17
+ ```
18
+ envision ──► shape ──► build ──► review ──► pull request
19
+ (project start or a major shift)
20
+
21
+ fix: reproduce ──► failing test ──► fix ──► review ──► pull request
22
+ ```
18
23
 
19
- - The architecture drifts after a few changes, because design decisions die with the change that made them.
20
- - Stepping back to fix a design mid-implementation breaks the workflow's state.
21
- - Code lands in a handful of oversized files, because nothing owns module structure before code is written.
22
- - Everything is "fully specified", yet the result fails when a person actually uses it.
23
- - Review loops keep finding new things to change and never converge.
24
+ | Step | Who | What comes out | Your part |
25
+ | --- | --- | --- | --- |
26
+ | `envision` | you and the agent | `docs/vision.md`: the problem, users, the release's features and what each needs, future features and what must stay possible. `docs/architecture.md`: ports, adapters, runtime, technology, layers | Answer one round of questions, approve both documents |
27
+ | `shape` | you and the agent | `docs/features/<slug>.md`: behaviour as scenarios, the public API as code, a sketch of how it crosses the stack, the decisions the agent took | Approve it, or say what to change |
28
+ | `build` | the agent | Code built test-first, one scenario at a time; the first feature also sets up CI with a coverage gate | Nothing, unless a scenario or the public API has to change; then you see the change and approve again |
29
+ | `review` | a fresh-context reviewer | Fixes for what it finds, a note on how to try the feature, a pull request | Decide only findings that would change what you approved |
30
+ | `fix` | the agent | A failing test that reproduces the bug, the fix, a review, a pull request | Nothing, unless the right behaviour is your call |
24
31
 
25
- Cruze answers each of these with a specific mechanism. A living `docs/architecture.md` is read at every step and updated by every change. Approvals are bound to document content, so stepping back is just editing. Every task names the file it touches, and `cruze check` enforces layer rules. Scenarios are traced to behavioural tests, and the system is actually run. Reviews use a closed rubric with a hard limit of two rounds, and bring you only the findings that are yours to decide: changes to behaviour or to the designed contracts.
32
+ What it holds to:
33
+
34
+ - **You decide behaviour and public APIs; the agent decides the rest.** The agent asks at most one round of questions per step, and lists the choices it made in the document you approve, so nothing about the stack surprises you at the end.
35
+ - **The architecture is designed for what's coming.** Future features shape the boundaries, such as where a port goes, but nothing is built for them until they join a release.
36
+ - **Ports and adapters.** `cruze check` enforces the layer rules in CI.
37
+ - **Behavioural tests.** Every scenario has a test carrying its ID, and `cruze trace` fails CI when one is missing.
38
+ - **Approvals follow the text.** An approved feature edited later shows as edited until you approve it again.
26
39
 
27
40
  ## Quick start
28
41
 
@@ -32,10 +45,10 @@ Requires Node.js 22.18 or later, and git.
32
45
 
33
46
  The skills run `cruze` commands, so the agent needs `cruze` on its path. Install it globally, in one of three ways. `cruze --version` confirms which version you have.
34
47
 
35
- From a GitHub Release, without npm. Each release attaches the packed package:
48
+ From a GitHub Release, without npm:
36
49
 
37
50
  ```sh
38
- npm install -g https://github.com/PrintPractical/cruze/releases/download/v0.0.12/printpractical-cruze-0.0.12.tgz
51
+ npm install -g https://github.com/PrintPractical/cruze/releases/download/v0.0.14/printpractical-cruze-0.0.14.tgz
39
52
  ```
40
53
 
41
54
  From npm, once a version is published there:
@@ -44,10 +57,10 @@ From npm, once a version is published there:
44
57
  npm install -g @printpractical/cruze
45
58
  ```
46
59
 
47
- From the git repository, at a tag or `#main`. This needs git and access to the repository. npm 11 needs `--install-links` for a global git install, and the first `cruze` command builds the CLI, which takes a moment:
60
+ From the git repository, at a tag or `#main`. npm 11 needs `--install-links` for a global git install, and the first `cruze` command builds the CLI:
48
61
 
49
62
  ```sh
50
- npm install -g --install-links github:PrintPractical/cruze#v0.0.12
63
+ npm install -g --install-links github:PrintPractical/cruze#v0.0.14
51
64
  ```
52
65
 
53
66
  ### 2. Set up a repository
@@ -58,129 +71,59 @@ In the root of the repository:
58
71
  cruze init
59
72
  ```
60
73
 
61
- When you didn't install from npm, tell `init` where Cruze came from, so the CI it writes runs the same source instead of the npm package:
74
+ When you didn't install from npm, tell `init` where Cruze came from, so the CI it writes runs the same source:
62
75
 
63
76
  ```sh
64
- cruze init --package https://github.com/PrintPractical/cruze/releases/download/v0.0.12/printpractical-cruze-0.0.12.tgz
77
+ cruze init --package https://github.com/PrintPractical/cruze/releases/download/v0.0.14/printpractical-cruze-0.0.14.tgz
65
78
  ```
66
79
 
67
- `init` asks for the project name, and which coding agent you use: `claude` for Claude Code, or `other` for any agent that reads `AGENTS.md` and `.agents/skills/`, such as Codex or OpenCode. It doesn't ask when you pass `--agent claude` or `--agent other`, or when the repository already has `CLAUDE.md` or `.claude/`. With `--yes`, or without a terminal, it sets up Claude Code. Then it creates:
68
-
69
- | Path | Purpose |
70
- | --- | --- |
71
- | `README.md` | Titled with the project name |
72
- | `CHANGELOG.md` | In [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format |
73
- | `AGENTS.md` | Agent instructions; Cruze keeps its managed sections current |
74
- | `CLAUDE.md` | For Claude Code only: a link to `AGENTS.md` |
75
- | `.cruze/config.yaml` | Project configuration, including the Cruze version whose skills the project uses, and for Claude Code the command `cruze review` runs |
76
- | `.github/workflows/ci.yml` | CI that runs `cruze validate`, `check` and `trace`; the walking-skeleton change adds the language's build and test steps |
77
- | `.gitattributes` | Merges Cruze's journals line by line, so parallel branches don't conflict on them |
78
- | `.agents/skills/cruze-*` | The Cruze skills, also linked into `.claude/skills/` for Claude Code |
80
+ `init` asks for the project name and your coding agent: `claude` for Claude Code, or `other` for any agent that reads `AGENTS.md` and `.agents/skills/`. It creates `README.md`, `CHANGELOG.md`, `AGENTS.md` (and `CLAUDE.md` for Claude Code), `.cruze/config.yaml`, a CI workflow that runs `cruze validate`, `check` and `trace`, and the skills in `.agents/skills/`, linked into `.claude/skills/` for Claude Code. It never overwrites an existing file.
79
81
 
80
- Existing files are never overwritten, so it is safe to run in an existing repository.
82
+ ### 3. Start
81
83
 
82
- The CLI writes its result to stdout: JSON when stdout isn't a terminal, and text on a terminal. Pass `--json` to get JSON on a terminal, or `--text` to get text through a pipe, as in `cruze journal list --text | grep review`. Errors and notes go to stderr.
84
+ Ask your agent to envision the project, and give it whatever you have: a sentence, a design document, a conversation. From then on, `cruze next` says what comes next.
83
85
 
84
86
  ## Upgrading
85
87
 
86
- A repository runs three copies of Cruze: the CLI on your path, the skills in `.agents/skills/`, and the CLI that CI runs. `.cruze/config.yaml` records the version the skills came from, as `cruze: "0.0.2"`. When the CLI you run differs from it, every `cruze` command says so in a note on stderr, and `cruze validate` reports it as a `cruze-version` warning.
87
-
88
- It also records `standards:`, the version whose expectations the code meets. A release can expect more of existing code, such as where tests live. Its new rules report on your code right away, but they fail CI only once you realign to that release, so upgrading never turns CI red.
89
-
90
- 1. **Upgrade the CLI** the same way you installed it, naming the new version, then check it with `cruze --version`:
91
-
92
- ```sh
93
- npm install -g https://github.com/PrintPractical/cruze/releases/download/v<version>/printpractical-cruze-<version>.tgz
94
- npm install -g @printpractical/cruze@<version>
95
- npm install -g --install-links github:PrintPractical/cruze#v<version>
96
- ```
97
-
98
- 2. **Update each repository.** In its root, run:
88
+ 1. Upgrade the CLI the same way you installed it, naming the new version.
89
+ 2. In each repository, run `cruze install`. It replaces the Cruze skills (those named `cruze-*`) and leaves your own alone, records the version in `.cruze/config.yaml`, and moves the CI workflow to the new version when CI runs a published package, a release tarball or a release tag.
90
+ 3. Commit the skills, the config and the CI workflow together.
99
91
 
100
- ```sh
101
- cruze install
102
- ```
103
-
104
- `install` does three things:
105
- - It replaces the Cruze skills (those named `cruze-*`) and leaves your own skills alone. Pass `--agent claude` to link them for Claude Code in a repository without `CLAUDE.md` or `.claude/`.
106
- - It records the new version in `.cruze/config.yaml`.
107
- - It moves `.github/workflows/ci.yml` to the new version when CI runs the npm package, a release tarball or a release tag. It names any other source, such as a branch, for you to update by hand.
108
-
109
- 3. **Commit** the skills, the config and the CI workflow together, with a message such as `chore: upgrade Cruze to <version>`, so CI runs the version the skills were written for.
110
-
111
- 4. **Realign the code** when it suits you, with the `realign` skill. `cruze realign status` lists what each release since `standards:` expects of existing code: what its CLI rules find, and the questions a fresh-context auditor answers. You decide each finding: fix it in a prefactor change, waive it for good, or defer it. `cruze realign done` then moves `standards:` up. Findings still waiting for their prefactor are listed under `check.exceptions` until it lands, so CI stays green. Add `--full` to audit against every release, such as for a project that adopted Cruze partway. `cruze next` suggests realigning when nothing else is due.
112
-
113
- An older CLI refuses to install over a repository that already moved to a newer version, so a stale CLI on another machine can't roll it back. To go back on purpose, set `cruze:` in `.cruze/config.yaml` to the older version first, then run that version's `cruze install`.
92
+ When the CLI you run differs from the version the project records, every command notes it on stderr, and `cruze validate` warns.
114
93
 
115
94
  ## Commands
116
95
 
117
- Skills call these at fixed points, and CI runs `check` and `trace` on every push. Run `cruze help` for every option.
118
-
119
96
  | Command | What it does |
120
97
  | --- | --- |
121
- | `cruze validate` | Checks every document against the formats: IDs, elements, deltas, scope rules, task lines, test plans, roadmap and config, and warns when a change falls outside the size band in `changes:` or a document cites a decision recorded elsewhere |
122
- | `cruze approve <doc>` | Records an approval as a fingerprint: the document's design hash plus the hash of every upstream element it cites. `--replan` sets built elements a rethink changed back to planned; `--rebase` accepts living text a feature must now build on. `--by-agent` approves a change for you once its plan review has closed, and `--restamp-unchanged` re-stamps work a rethink didn't change; both record that the agent gave the approval |
123
- | `cruze next` | Names the step to run next on this branch, and why, from computed status: for stale work, whether a re-stamp or a rebase is due |
124
- | `cruze show <ref>` | Prints the design a change builds, or a feature's delta: each element's full body, the delivered scenarios, what they cite with where to find it, the settled decisions and the item's dispositions, so a step reads its scope instead of the whole architecture |
125
- | `cruze show <ID>...` | Prints the chosen elements' bodies, with each in-flight delta's version beside the living one |
126
- | `cruze show --notes [<target>]` | Lists every note with its kind and what it is about, and the parts of the user's input envision handed to each step or feature; with a target, such as `architect` or a feature slug, only those for it |
127
- | `cruze show --index [<context>]` | Lists every element of the architecture and specs on one line, with its status, module and the work in flight that changes it, or one context or capability in full, and gives the size of the living docs |
128
- | `cruze status` | Computes each document's state (approved, edited, upstream changed or unapproved) from content, never from stored state, and counts the findings waiting on a rethink |
129
- | `cruze diff <ref>` | Shows what changed upstream of a document since its approval, each element's approved text against its current text, and whether the work's delta needs a rebase |
130
- | `cruze status --gate build` | Passes only when this branch's change, its feature and the architecture are approved and current, and no finding on them waits on a rethink |
131
- | `cruze status --overlap` | Lists changes on other branches that touch the same elements as this branch's change |
132
- | `cruze new <kind>` | Creates a project document (`vision`, `glossary`, `architecture`, `roadmap`) or work (`feature`, `change`, `adr`, `note`) from its template, with a dated ID that is never reused; a note says its kind and what it is about (`--kind`, `--about`) |
133
- | `cruze task done <T#>` | Ticks a task with its commit; `cruze task reopen` unticks one a rethink changed, and `cruze task deviation` records a small departure from the plan |
134
- | `cruze features <add\|update\|drop>` | Edits the feature map: adds or drops a future feature, or corrects a summary |
135
- | `cruze roadmap prune` | Clears landed items from the roadmap's status when a release closes |
136
- | `cruze trace` | Fails when a delivered scenario has no test carrying its ID; `--all` checks every built scenario |
137
- | `cruze check` | Enforces the layer rules and the file budgets, and warns on decision numbers in code comments; `--ci` also fails on warnings |
138
- | `cruze review <role>` | Runs a role (design reviewer, code reviewer, verifier, researcher or auditor) in a fresh agent context, through the command in `.cruze/config.yaml`. When no command is set, or its program isn't installed, it prints the role's prompt for the agent to run in a helper of its own |
139
- | `cruze land` | Merges a verified change into the living docs, re-stamps the approvals the merge would make stale, fills the Commands and Layout sections of `AGENTS.md`, and archives finished work |
140
- | `cruze realign status` | Lists what the installed Cruze expects of existing code since its `standards:` version, with what the CLI rules find now; `--full` covers every release |
141
- | `cruze realign done` | Moves `standards:` up once every finding is fixed, waived or scheduled in a change named with `--change` |
142
- | `cruze abandon <ref>` | Archives a feature or standalone change that stops for good, with its reason, and puts a feature back on the future list |
143
- | `cruze journal add <event>` | Records a rethink, review round, disposition, verification, override, bug or lesson; `cruze journal list` reads the work in flight's entries, or landed work's too with `--all`; `cruze feedback export` bundles the journal for improving Cruze itself |
144
-
145
- Stepping back is editing: change an upstream document and every approval that cites a changed element shows as stale, with the element named. Re-approving is the rewind; there are no phases to reset.
98
+ | `cruze init` | Sets up the repository and installs the skills |
99
+ | `cruze install` | Installs or updates the skills |
100
+ | `cruze new vision\|architecture\|feature <slug>` | Starts a document from its template |
101
+ | `cruze validate` | Checks the documents: required sections, scenario IDs, the release's features and needs, size, leftover template text |
102
+ | `cruze approve <vision\|architecture\|slug>` | Records that you approved a document as it reads now |
103
+ | `cruze status` | Each document's approval and each feature's progress, in release order, and the next step |
104
+ | `cruze next` | The step to run next, and why |
105
+ | `cruze trace [<slug>]` | Fails when a built feature's scenario has no test carrying its ID, or a test names a scenario no feature defines |
106
+ | `cruze check [<file>...] [--ci]` | Enforces the layer rules, and warns on file budgets (fails on them with `--ci`) |
107
+ | `cruze review code-reviewer --feature <slug> --base <commit>` | Runs the code reviewer in a fresh agent context, through the command in `.cruze/config.yaml` |
108
+
109
+ Every command prints JSON when stdout isn't a terminal, and text on a terminal; `--json` and `--text` choose. Errors and notes go to stderr.
146
110
 
147
111
  ## Skills
148
112
 
149
- `cruze init` and `cruze install` put these into `.agents/skills/`. Agents load them when a situation calls for them, and the workflow skills will load them by path at the step that needs them.
150
-
151
113
  | Skill | What it holds |
152
114
  | --- | --- |
153
- | `cruze-explore` | Optional thinking partner before any step: options and trade-offs, captured as a note only when you ask |
154
- | `cruze-envision` | The what: the project's vision, goals, principles, what must stay possible later and feature map, asking about the capabilities the product may grow into, or one feature's intent and requirements with scenarios |
155
- | `cruze-architect` | The how: the architecture, a feature's architecture delta and its changes, or a tweak; ends with a design review and a walkthrough for your approval |
156
- | `cruze-roadmap` | Orders the release into phases with blocking edges and goal coverage, and closes a release |
157
- | `cruze-plan` | Turns a change into a test plan and ordered tasks with file targets, reviewed in a fresh context and approved once the review closes |
158
- | `cruze-build` | Builds the change task by task, each test-first, checked and committed, and stops to rethink when the design is wrong |
159
- | `cruze-verify` | Runs the checks, a fresh-context verifier that uses the real system, a two-lane code review and a manual test script, then asks you to accept |
160
- | `cruze-land` | Merges the change into the living docs and updates the changelog, README and `AGENTS.md`; also lands bug fixes |
161
- | `cruze-triage` | Reproduces a bug, finds its root cause against the living docs, and fixes it test-first or routes it to architect or rethink |
162
- | `cruze-rethink` | Steps back to the level a discovery touches, keeps completed work, re-approves what went stale and records why |
163
- | `cruze-realign` | Brings existing code up to what a new Cruze expects: audits it against each release's notes, decides every finding with you, and schedules the fixes as prefactor changes |
164
- | `cruze-improve` | Restructures existing code to meet today's standards: surveys it for structure that departs from them or keeps causing friction, lets you pick any or all of the candidates, and schedules the moves as prefactor changes |
165
- | `cruze-next` | Says which step to run next and why |
166
- | `cruze-roles` | The fresh-context design reviewer, code reviewer, verifier, researcher, auditor and surveyor, and how a review runs to a disposition for every finding |
167
- | `cruze-formats` | The format of every Cruze document, with templates |
168
- | `cruze-hexagonal-design` | Ports and adapters with domain-driven design: who owns each rule, dependency direction, many small modules, contracts, runtime ownership, layouts by kind of system, and notes for Rust, Swift and C++ |
169
- | `cruze-behavioural-testing` | Which tests to write and at which seam, fakes instead of mocks, and protecting approved scenarios' tests |
170
- | `cruze-grilling` | Interviewing the user in rounds until decisions settle, and challenging once before deferring |
171
- | `cruze-domain-language` | Building the glossary and using its words in documents, IDs and code |
172
- | `cruze-dependency-approval` | No new dependency without your explicit approval, and where approvals are recorded |
173
- | `cruze-research` | Adopting a mature library before building, and answering questions from primary sources at the right version |
174
-
175
- ## Reporting back
176
-
177
- Cruze improves from what goes wrong in real projects. Every rethink, review finding, bug and override is recorded in the project's journal, along with each repeated lesson about Cruze's own steps. To send them back, with the `## Known pitfalls` of `AGENTS.md`:
178
-
179
- ```sh
180
- cruze feedback export --out cruze-feedback.json
181
- ```
182
-
183
- The export replaces the project name, and the name of whoever approved or recorded each entry, with placeholders. Read it before sharing: summaries can still mention your domain or people. Attach it to an issue at https://github.com/PrintPractical/cruze/issues. Maintainers turn it into changes with the `cruze-retro` skill in this repository.
115
+ | `cruze-envision` | The vision with future features, the release broken into features with their needs, and the architecture map |
116
+ | `cruze-shape` | One feature's behaviour, public API and stack sketch, self-checked and approved by you |
117
+ | `cruze-build` | Building an approved feature test-first, scenario by scenario, and the foundation's CI |
118
+ | `cruze-review` | The fresh-context code review, fixes, and the pull request |
119
+ | `cruze-fix` | A bug from report to reviewed fix |
120
+ | `cruze-asking` | When to ask you and when to decide, and how to show a question with code and diagrams |
121
+ | `cruze-formats` | The format of each document, with templates |
122
+ | `cruze-hexagonal-design` | Ports and adapters with domain-driven design, contracts, runtime ownership, layouts by kind of system, and notes for Rust, Swift and C++ |
123
+ | `cruze-behavioural-testing` | Which tests to write and at which seam, and fakes instead of mocks |
124
+ | `cruze-dependency-approval` | Adopt libraries freely; ask only for significant ones |
125
+ | `cruze-research` | Adopting a mature library before building, and answering questions from primary sources |
126
+ | `cruze-roles` | The fresh-context code reviewer and researcher, and how to run them |
184
127
 
185
128
  ## Development
186
129
 
@@ -1,32 +1,19 @@
1
1
  import { posix } from "node:path";
2
2
  import { checkCode, traceTests } from "../../../../app/use_cases/check_code.js";
3
- import { landChange } from "../../../../app/use_cases/land_change.js";
4
3
 
5
4
 
6
5
  export async function runCheck(context , args , options ) {
7
- const files = [...options.file, ...args].map((file) => posix.normalize(posix.join(context.workingDirectory, file)));
6
+ const files = args.map((file) => posix.normalize(posix.join(context.workingDirectory, file)));
8
7
  const report = await checkCode(context, { ci: options.ci, ...(files.length === 0 ? {} : { files }) });
9
- const lines = report.findings.map((f) => `${f.severity} ${f.path}${f.line === undefined ? "" : `:${f.line}`} ${f.message} [${f.rule}]${f.pending === true ? " (pending realign)" : ""}`);
8
+ const lines = report.findings.map((f) => `${f.severity} ${f.path}${f.line === undefined ? "" : `:${f.line}`} ${f.message} [${f.rule}]`);
10
9
  lines.push(`Checked ${report.checked} file(s): ${report.passed ? "passed" : "failed"}.`);
11
10
  return { json: report, human: lines.join("\n"), failed: !report.passed };
12
11
  }
13
12
 
14
- export async function runTrace(context , _args , options ) {
15
- const report = await traceTests(context, { all: options.all, ...(options.change === undefined ? {} : { change: options.change }) });
13
+ export async function runTrace(context , args ) {
14
+ const report = await traceTests(context, args[0]);
16
15
  const lines = report.missing.map((id) => `missing test for ${id}`);
17
- lines.push(...report.unknown.map((u) => `${u.path}:${u.line} cites ${u.id}, which no spec or delta defines`));
16
+ lines.push(...report.unknown.map((u) => `${u.path}:${u.line} cites ${u.id}, which no feature defines`));
18
17
  lines.push(`Traced ${report.scenarios.length} scenario(s) for ${report.scope}: ${report.passed ? "passed" : "failed"}.`);
19
18
  return { json: report, human: lines.join("\n"), failed: !report.passed };
20
19
  }
21
-
22
- export async function runLand(context , args , options ) {
23
- const report = await landChange(context, args[0], options.override === undefined ? {} : { override: options.override });
24
- const lines = [`Landed ${report.change}.`];
25
- if (report.merged.length > 0) lines.push(`Merged into the living docs: ${report.merged.join(", ")}`);
26
- if (report.built.length > 0) lines.push(`Now built: ${report.built.join(", ")}`);
27
- if (report.removed.length > 0) lines.push(`Removed: ${report.removed.join(", ")}`);
28
- if (report.restamped.length > 0) lines.push(`Re-stamped approvals: ${report.restamped.join(", ")}`);
29
- if (report.unexcepted.length > 0) lines.push(`CI checks these again, now that the change realign scheduled them in has landed: ${report.unexcepted.join(", ")}`);
30
- if (report.archivedTo !== undefined) lines.push(`Finished; archived to ${report.archivedTo}.`);
31
- return { json: report, human: lines.join("\n") };
32
- }
@@ -1,9 +1,8 @@
1
- import { approveArtifact } from "../../../../app/use_cases/approve_artifact.js";
2
- import { PROJECT_DOC_KINDS, createNote, createProjectDoc, } from "../../../../app/use_cases/new_project_doc.js";
3
- import { createWorkItem, } from "../../../../app/use_cases/new_work_item.js";
1
+ import { approveDocument } from "../../../../app/use_cases/approve_document.js";
2
+ import { DOCUMENT_KINDS, createDocument, } from "../../../../app/use_cases/new_document.js";
4
3
  import { validate } from "../../../../app/use_cases/validate_project.js";
5
4
 
6
- import { UsageError, requireArgs, requireOption, } from "../cli_context.js";
5
+ import { UsageError, requireArgs, } from "../cli_context.js";
7
6
 
8
7
  export async function runValidate(context ) {
9
8
  const report = await validate(context);
@@ -11,44 +10,19 @@ export async function runValidate(context ) {
11
10
  return { json: report, human: [...report.problems.map(formatProblem), summary].join("\n"), failed: !report.valid };
12
11
  }
13
12
 
14
- export async function runApprove(context , args , options ) {
13
+ export async function runApprove(context , args ) {
15
14
  requireArgs(args, ["document"]);
16
- if (options.byAgent && options.restampUnchanged) throw new UsageError("--by-agent and --restamp-unchanged are alternatives");
17
- const agent = options.byAgent ? "plan-review" : options.restampUnchanged ? "rethink" : undefined;
18
- const report = await approveArtifact(context, args[0] ?? "", { replan: options.replan, rebase: options.rebase, ...(agent === undefined ? {} : { agent }) });
19
- const lines = [`Approved ${report.artifact} (${report.hash.slice(0, 19)}), pinned to ${report.upstream.length} upstream element(s).`];
20
- if (report.basis === "plan-review") lines.push("Approved for the user: its plan review closed with no blocker open.");
21
- if (report.restamped !== undefined) lines.push(`Re-stamped for the user: its own design is unchanged, and only ${report.restamped.join(", ")} changed.`);
22
- if (report.stamped.length > 0) lines.push(`Marked ${report.stamped.length} element(s) planned.`);
23
- if (report.bound !== undefined) lines.push(`Bound the change to branch ${report.bound}.`);
24
- if (report.replanned.length > 0) lines.push(`Set back to planned: ${report.replanned.join(", ")}.`);
25
- if (report.rebased.length > 0) lines.push(`Accepted the current living text of: ${report.rebased.join(", ")}.`);
26
- return { json: report, human: lines.join("\n") };
15
+ const record = await approveDocument(context, args[0] ?? "");
16
+ return { json: record, human: `Approved ${record.path} (${record.hash.slice(0, 19)}).` };
27
17
  }
28
18
 
29
19
  export async function runNew(context , args , options ) {
30
20
  requireArgs(args, ["kind"]);
31
- if (PROJECT_DOC_KINDS.includes(args[0] )) {
32
- const report = await createProjectDoc(context, args[0] );
33
- return { json: report, human: `Created ${report.path}` };
34
- }
35
- requireArgs(args, ["kind", "slug"]);
36
- if (args[0] === "note") {
37
- const report = await createNote(context, args[1] ?? "", requireOption(options.title, "--title"), requireOption(options.kind, "--kind"), requireOption(options.about, "--about"));
38
- return { json: report, human: `Created ${report.path}` };
39
- }
40
- const kind = args[0] ;
41
- if (!["feature", "change", "adr"].includes(kind)) {
42
- throw new UsageError(`cruze new takes ${PROJECT_DOC_KINDS.join(", ")}, feature, change, adr or note, not "${args[0]}"`);
43
- }
44
- const report = await createWorkItem(context, {
45
- kind,
46
- slug: args[1] ?? "",
47
- title: requireOption(options.title, "--title"),
48
- ...(options.feature === undefined ? {} : { feature: options.feature }),
49
- ...(options.roadmap === undefined ? {} : { roadmap: options.roadmap }),
50
- });
51
- return { json: report, human: `Created ${report.kind} ${report.ref} at ${report.path}` };
21
+ const kind = args[0] ;
22
+ if (!DOCUMENT_KINDS.includes(kind)) throw new UsageError(`cruze new takes ${DOCUMENT_KINDS.join(", ")}, not "${args[0]}"`);
23
+ if (kind === "feature") requireArgs(args, ["kind", "slug"]);
24
+ const report = await createDocument(context, kind, args[1], options.title);
25
+ return { json: report, human: `Created ${report.path}` };
52
26
  }
53
27
 
54
28
  export function formatProblem(problem ) {
@@ -18,6 +18,6 @@ export async function runInit(context , _args , options
18
18
  if (report.created.length > 0) lines.push(`Created: ${report.created.join(", ")}`);
19
19
  if (report.skipped.length > 0) lines.push(`Left untouched (already present): ${report.skipped.join(", ")}`);
20
20
  lines.push(...describeSkillInstall(report.skills));
21
- lines.push("Next: open your coding agent in this repository and ask it what Cruze can do.");
21
+ lines.push("Next: open your coding agent in this repository and ask it to envision the project, with whatever you have: a sentence, a design document, notes.");
22
22
  return { json: report, human: lines.join("\n") };
23
23
  }
@@ -1,18 +1,11 @@
1
1
  import { runReview } from "../../../../app/use_cases/run_review.js";
2
- import { readArgumentFile } from "../argument_files.js";
3
- import { UsageError, requireArgs, } from "../cli_context.js";
2
+ import { requireArgs, } from "../cli_context.js";
4
3
 
5
4
  export async function runReviewCommand(context , args , options ) {
6
5
  requireArgs(args, ["role"]);
7
- const round = options.round === undefined ? undefined : Number(options.round);
8
- if (round !== undefined && round !== 1 && round !== 2) throw new UsageError("--round is 1 or 2");
9
- if (options.blockers !== undefined && round !== 2) throw new UsageError("--blockers goes with --round 2");
10
- const blockers = options.blockers === undefined ? undefined : await readArgumentFile(options.blockers);
11
6
  const report = await runReview(context, {
12
7
  role: args[0] ?? "",
13
- ...(options.item === undefined ? {} : { item: options.item }),
14
- ...(round === undefined ? {} : { round }),
15
- ...(blockers === undefined ? {} : { blockers }),
8
+ ...(options.feature === undefined ? {} : { item: options.feature }),
16
9
  ...(options.base === undefined ? {} : { base: options.base }),
17
10
  });
18
11
  return { json: report, human: report.status === "reported" ? report.report : `${report.instruction}\n\n${report.prompt}` };
@@ -1,71 +1,24 @@
1
- import { checkBuildGate, findOverlaps, showStatus, suggestNext } from "../../../../app/use_cases/project_status.js";
2
-
3
- import { UsageError, } from "../cli_context.js";
1
+ import { showStatus, suggestNext } from "../../../../app/use_cases/project_status.js";
2
+
3
+
4
4
 
5
- export async function runStatus(context , _args , options ) {
6
- if (options.override !== undefined && options.gate === undefined) throw new UsageError("--override goes with --gate build");
7
- if (options.change !== undefined && !options.overlap) throw new UsageError("--change goes with --overlap");
8
- if (options.gate !== undefined && options.overlap) throw new UsageError("--gate and --overlap are alternatives");
9
- if (options.gate !== undefined) {
10
- if (options.gate !== "build") throw new UsageError(`unknown gate "${options.gate}"; the only gate is build`);
11
- const report = await checkBuildGate(context, options.override);
12
- const human = report.passed
13
- ? report.overridden ? `Build gate overridden and journaled:\n ${report.reasons.join("\n ")}` : "Build gate passed."
14
- : `Build gate blocked:\n ${report.reasons.join("\n ")}`;
15
- return { json: report, human, failed: !report.passed };
16
- }
17
- if (options.overlap) {
18
- const report = await findOverlaps(context, options.change);
19
- const human = report.overlaps.length === 0
20
- ? `No other branch touches what ${report.change} touches.`
21
- : report.overlaps.map((o) => `${o.branch}: ${o.item} also touches ${o.shared.join(", ")}`).join("\n");
22
- return { json: report, human };
23
- }
5
+ export async function runStatus(context ) {
24
6
  const report = await showStatus(context);
25
- const lines = [`Branch: ${report.branch ?? "(none)"}${report.active === undefined ? "" : `, building ${report.active}`}`];
26
- for (const doc of report.documents) lines.push(describe(doc.artifact, doc));
27
- for (const feature of report.features) {
28
- lines.push(`${describe(`feature ${feature.ref}`, feature.approval)}${pendingNote(feature.rethinkPending)}`);
29
- for (const change of feature.changes) {
30
- const name = change.ref.split("/")[1] ?? change.ref;
31
- lines.push(change.landed !== undefined ? ` ${name}: landed ${change.landed}` : ` ${describe(name, change.approval)}, tasks ${change.tasksDone}/${change.tasksTotal}${pendingNote(change.rethinkPending)}`);
32
- }
7
+ const lines = report.documents.map((d) => `${d.path}: ${d.state}`);
8
+ for (const f of report.features) {
9
+ const needs = f.needs.length === 0 ? "" : `, needs ${f.needs.join(", ")}`;
10
+ const approval = f.approval === "missing" ? "" : `, ${f.approval}`;
11
+ lines.push(`${f.slug}: ${f.status}${approval}${f.scenarios === 0 ? "" : `, ${f.scenarios} scenario(s)`}${needs}${f.inRelease ? "" : " (not in the release)"}`);
33
12
  }
34
- for (const change of report.standalone) lines.push(`${describe(`change ${change.ref}`, change.approval)}, tasks ${change.tasksDone}/${change.tasksTotal}${pendingNote(change.rethinkPending)}`);
35
- const json = {
36
- ...report,
37
- documents: report.documents.map(compact),
38
- features: report.features.map((f) => ({ ...f, approval: compact(f.approval), changes: f.changes.map((c) => ({ ...c, approval: compact(c.approval) })) })),
39
- standalone: report.standalone.map((c) => ({ ...c, approval: compact(c.approval) })),
40
- };
41
- return { json, human: lines.join("\n") };
42
- }
43
-
44
- /** The state without the record's hashes: an agent reads status often, and the hashes were a third of each read. */
45
- function compact(status ) {
46
- const { record, ...rest } = status;
47
- if (record === undefined) return rest;
48
- return { ...rest, approvedAt: record.approvedAt, by: record.by, ...(record.basis === undefined ? {} : { basis: record.basis }) };
49
- }
50
-
51
- function pendingNote(findings ) {
52
- return findings === undefined ? "" : `, ${findings.length} finding(s) waiting on a rethink`;
13
+ lines.push(`Next: ${describe(report.next)}`);
14
+ return { json: report, human: lines.join("\n") };
53
15
  }
54
16
 
55
- /** Every step starts a new session: one session that ran plan, build, verify and land reached 745k tokens of context. */
56
- const FRESH_SESSION = "Run it in a new session, so its context starts empty.";
57
-
58
- const BASIS = { "plan-review": " (by the agent, after its plan review)", rethink: " (re-stamped by the agent after a rethink)" };
59
-
60
- function describe(label , status ) {
61
- const byAgent = status.state === "approved" ? BASIS[status.record?.basis ?? ""] ?? "" : "";
62
- const detail = status.changed.length > 0 ? ` (${status.changed.join(", ")})` : status.unjournaled === true ? " (no journal entry)" : byAgent;
63
- return `${label}: ${status.state}${detail}`;
17
+ export async function runNext(context ) {
18
+ const next = await suggestNext(context);
19
+ return { json: next, human: `Next: ${describe(next)}` };
64
20
  }
65
21
 
66
- export async function runNext(context ) {
67
- const report = await suggestNext(context);
68
- const describe = (s ) => `${s.step}${s.target === undefined ? "" : ` ${s.target}`}: ${s.reason}`;
69
- const lines = [`Next: ${describe(report.next)}`, ...report.also.map((s) => `Also: ${describe(s)}`), FRESH_SESSION];
70
- return { json: { ...report, session: FRESH_SESSION }, human: lines.join("\n") };
22
+ function describe(step ) {
23
+ return `${step.step}${step.target === undefined ? "" : ` ${step.target}`}: ${step.reason}`;
71
24
  }