@north-light/crouter 0.3.197 → 0.3.199

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 (339) hide show
  1. package/dist/api/client.d.ts +19 -19
  2. package/dist/api/client.js +29 -37
  3. package/dist/api/dto/broker-ops.d.ts +3 -1
  4. package/dist/api/dto/broker.d.ts +13 -2
  5. package/dist/api/dto/broker.js +4 -4
  6. package/dist/api/dto/human.d.ts +6 -5
  7. package/dist/api/dto/inbox.d.ts +126 -33
  8. package/dist/api/dto/nodes.d.ts +8 -2
  9. package/dist/api/dto/profiles.d.ts +23 -0
  10. package/dist/api/dto/profiles.js +2 -2
  11. package/dist/api/dto/worktree.d.ts +3 -5
  12. package/dist/api/routes.d.ts +3 -5
  13. package/dist/api/routes.js +4 -6
  14. package/dist/builtin-memory/00-runtime-base.md +8 -8
  15. package/dist/builtin-memory/01-spine/01-no-manager.md +1 -1
  16. package/dist/builtin-memory/02-lifecycle/00-terminal.md +3 -3
  17. package/dist/builtin-memory/04-orchestration-kernel.md +6 -6
  18. package/dist/builtin-memory/05-kinds/design/00-base.md +1 -1
  19. package/dist/builtin-memory/05-kinds/plan/reviewers/security.md +2 -2
  20. package/dist/builtin-memory/05-kinds/review/00-base.md +2 -2
  21. package/dist/builtin-memory/05-kinds/review/01-orchestrator.md +1 -1
  22. package/dist/builtin-memory/05-kinds/spec/01-orchestrator.md +1 -1
  23. package/dist/builtin-memory/insights/capture.md +2 -2
  24. package/dist/builtin-memory/insights/init.md +3 -3
  25. package/dist/builtin-memory/internal/INDEX.md +1 -1
  26. package/dist/builtin-memory/internal/memory-loading.md +1 -1
  27. package/dist/builtin-memory/internal/nodes-and-canvas.md +3 -3
  28. package/dist/builtin-memory/internal/plugins.md +59 -2
  29. package/dist/builtin-memory/internal/storage-tiers.md +3 -1
  30. package/dist/builtin-memory/spec/roadmap.md +2 -2
  31. package/dist/builtin-memory/testing.md +1 -1
  32. package/dist/builtin-memory/wedged-child-on-runaway-bash.md +1 -1
  33. package/dist/clients/attach/chrome/bash-jobs.js +3 -3
  34. package/dist/clients/attach/render/chat-view.d.ts +29 -9
  35. package/dist/clients/attach/render/chat-view.js +64 -35
  36. package/dist/clients/attach/render/markdown-source.js +0 -6
  37. package/dist/clients/attach/render/page-block.d.ts +34 -0
  38. package/dist/clients/attach/render/page-block.js +226 -0
  39. package/dist/clients/attach/render/tool-calls.js +16 -2
  40. package/dist/clients/attach/session/whip.d.ts +2 -0
  41. package/dist/clients/attach/session/whip.js +2 -0
  42. package/dist/clients/attach/viewer.js +1419 -982
  43. package/dist/clients/conversation/projection.js +18 -3
  44. package/dist/clients/inbox/__tests__/serial/inbox-controller.test.js +9 -6
  45. package/dist/clients/inbox/__tests__/serial/mount-panel.test.js +13 -14
  46. package/dist/clients/inbox/controller.js +10 -16
  47. package/dist/clients/inbox/page-adapter.d.ts +3 -4
  48. package/dist/clients/inbox/page-adapter.js +3 -4
  49. package/dist/clients/inbox/resolve.d.ts +1 -1
  50. package/dist/clients/inbox/resolve.js +3 -3
  51. package/dist/clients/inbox/review/document-surface.js +3 -1
  52. package/dist/clients/inbox/review/state.d.ts +2 -1
  53. package/dist/clients/inbox/review/state.js +5 -16
  54. package/dist/clients/inbox/tui/input.js +37 -19
  55. package/dist/clients/inbox/tui/panel.js +5 -31
  56. package/dist/clients/inbox/tui/render.d.ts +11 -0
  57. package/dist/clients/inbox/tui/render.js +101 -36
  58. package/dist/clients/inbox/tui/slots.d.ts +4 -4
  59. package/dist/clients/inbox/tui/slots.js +19 -44
  60. package/dist/clients/inbox/tui/types.d.ts +6 -10
  61. package/dist/clients/inbox/tui.js +2 -2
  62. package/dist/commands/__tests__/human.test.js +118 -24
  63. package/dist/commands/__tests__/node-message.test.js +14 -0
  64. package/dist/commands/attention.js +4 -4
  65. package/dist/commands/canvas-browse.js +1 -1
  66. package/dist/commands/canvas-snapshot.js +1 -1
  67. package/dist/commands/canvas.js +1 -1
  68. package/dist/commands/dashboard.js +1 -1
  69. package/dist/commands/human/{doc.d.ts → components.d.ts} +1 -1
  70. package/dist/commands/human/components.js +77 -0
  71. package/dist/commands/human/feedback.d.ts +2 -0
  72. package/dist/commands/human/feedback.js +108 -0
  73. package/dist/commands/human/prompts.d.ts +17 -8
  74. package/dist/commands/human/prompts.js +217 -226
  75. package/dist/commands/human/queue.js +57 -88
  76. package/dist/commands/human/shared.d.ts +4 -15
  77. package/dist/commands/human/shared.js +19 -61
  78. package/dist/commands/human.js +32 -19
  79. package/dist/commands/memory/origin.js +2 -2
  80. package/dist/commands/node/bash.js +4 -4
  81. package/dist/commands/node/inspect.js +3 -3
  82. package/dist/commands/node/lifecycle.js +1 -1
  83. package/dist/commands/node/message.js +2 -2
  84. package/dist/commands/node-worktree.js +8 -8
  85. package/dist/commands/pkg/browse.js +1 -1
  86. package/dist/commands/pkg/plugin-manage.js +129 -10
  87. package/dist/commands/profile/delete.js +41 -15
  88. package/dist/commands/profile.js +1 -1
  89. package/dist/commands/push.js +1 -1
  90. package/dist/commands/surface/node/focus.js +29 -14
  91. package/dist/commands/surface-edit.js +3 -3
  92. package/dist/commands/surface-inbox.d.ts +2 -0
  93. package/dist/commands/{human/inbox.js → surface-inbox.js} +14 -18
  94. package/dist/commands/surface.js +2 -1
  95. package/dist/commands/sys/doctor.js +60 -3
  96. package/dist/commands/sys/feedback.js +79 -25
  97. package/dist/commands/sys/settings.js +1 -1
  98. package/dist/core/__tests__/cron-broker-capacity.test.js +1 -1
  99. package/dist/core/__tests__/daemon-boot.test.js +7 -4
  100. package/dist/core/__tests__/dead-node-policy-table.test.js +20 -36
  101. package/dist/core/__tests__/extension-abort.test.js +5 -2
  102. package/dist/core/__tests__/fixtures/fake-engine.d.ts +13 -2
  103. package/dist/core/__tests__/fixtures/fake-engine.js +47 -3
  104. package/dist/core/__tests__/human-cancel-guard.test.js +31 -10
  105. package/dist/core/__tests__/human-deliver.test.js +41 -45
  106. package/dist/core/__tests__/human-node-not-supervised.test.js +1 -1
  107. package/dist/core/__tests__/plugin-page-components.test.js +157 -0
  108. package/dist/core/__tests__/seam/broker-crash-teardown.test.js +13 -11
  109. package/dist/core/__tests__/seam/dormancy-release.test.js +103 -4
  110. package/dist/core/__tests__/serial/flagship-lifecycle.test.js +2 -2
  111. package/dist/core/__tests__/serial/human-deliver-e2e.test.js +12 -16
  112. package/dist/core/__tests__/serial/live-mutation.test.js +1 -1
  113. package/dist/core/__tests__/serial/tmux-surface.test.js +4 -2
  114. package/dist/core/__tests__/serial/worktree.test.js +24 -198
  115. package/dist/core/__tests__/session-cycles.test.js +22 -0
  116. package/dist/core/__tests__/stop-guard.test.js +4 -4
  117. package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +19 -4
  118. package/dist/core/bash-jobs.d.ts +6 -0
  119. package/dist/core/bash-jobs.js +10 -0
  120. package/dist/core/canvas/__tests__/attention.test.js +8 -5
  121. package/dist/core/canvas/__tests__/render-remote.test.js +5 -5
  122. package/dist/core/canvas/attention.js +8 -6
  123. package/dist/core/canvas/browse/app.d.ts +1 -1
  124. package/dist/core/canvas/browse/app.js +21 -3
  125. package/dist/core/canvas/browse/model.d.ts +8 -2
  126. package/dist/core/canvas/browse/model.js +11 -4
  127. package/dist/core/canvas/browse/render.d.ts +4 -0
  128. package/dist/core/canvas/browse/render.js +5 -1
  129. package/dist/core/canvas/canvas.d.ts +33 -0
  130. package/dist/core/canvas/canvas.js +92 -0
  131. package/dist/core/canvas/crons.d.ts +9 -0
  132. package/dist/core/canvas/crons.js +51 -0
  133. package/dist/core/canvas/node-order.d.ts +22 -1
  134. package/dist/core/canvas/node-order.js +26 -1
  135. package/dist/core/canvas/render-source.d.ts +5 -0
  136. package/dist/core/canvas/render-source.js +1 -0
  137. package/dist/core/canvas/types.d.ts +9 -3
  138. package/dist/core/command-plugins/bundle.d.ts +6 -1
  139. package/dist/core/command-plugins/bundle.js +26 -13
  140. package/dist/core/command.js +8 -12
  141. package/dist/core/config.d.ts +47 -1
  142. package/dist/core/config.js +138 -4
  143. package/dist/core/help.d.ts +3 -0
  144. package/dist/core/help.js +1 -1
  145. package/dist/core/human/__tests__/page-catalog.test.d.ts +1 -0
  146. package/dist/core/human/__tests__/page-catalog.test.js +20 -0
  147. package/dist/core/human/__tests__/page-tickets.test.js +68 -34
  148. package/dist/core/human/__tests__/page.test.js +60 -119
  149. package/dist/core/human/__tests__/serial/inbox-core.test.js +6 -16
  150. package/dist/core/human/answer-text.d.ts +3 -0
  151. package/dist/core/human/answer-text.js +98 -0
  152. package/dist/core/human/answer.d.ts +53 -0
  153. package/dist/core/human/answer.js +119 -0
  154. package/dist/core/human/component-docs.d.ts +18 -0
  155. package/dist/core/human/component-docs.js +434 -0
  156. package/dist/core/human/convention.d.ts +17 -3
  157. package/dist/core/human/convention.js +36 -5
  158. package/dist/core/human/feedback-companion.d.ts +20 -0
  159. package/dist/core/human/feedback-companion.js +98 -0
  160. package/dist/core/human/feedback.d.ts +65 -0
  161. package/dist/core/human/feedback.js +116 -0
  162. package/dist/core/human/page-catalog.d.ts +56 -5
  163. package/dist/core/human/page-catalog.js +151 -22
  164. package/dist/core/human/page-errors.d.ts +4 -0
  165. package/dist/core/human/page-errors.js +7 -0
  166. package/dist/core/human/page-eval.d.ts +20 -0
  167. package/dist/core/human/page-eval.js +123 -0
  168. package/dist/core/human/page-schema.d.ts +48 -116
  169. package/dist/core/human/page-schema.js +100 -72
  170. package/dist/core/human/page-synth.d.ts +2 -4
  171. package/dist/core/human/page-synth.js +20 -7
  172. package/dist/core/human/page.d.ts +13 -21
  173. package/dist/core/human/page.js +147 -391
  174. package/dist/core/human/review-schema.d.ts +1 -0
  175. package/dist/core/human/review-schema.js +1 -1
  176. package/dist/core/human/root.d.ts +6 -2
  177. package/dist/core/human/root.js +12 -4
  178. package/dist/core/human/scan.d.ts +3 -3
  179. package/dist/core/human/scan.js +21 -21
  180. package/dist/core/human/summary.d.ts +2 -6
  181. package/dist/core/human/summary.js +3 -59
  182. package/dist/core/human/tickets.d.ts +22 -15
  183. package/dist/core/human/tickets.js +90 -28
  184. package/dist/core/human/types.d.ts +14 -2
  185. package/dist/core/keybindings/catalog.d.ts +2 -2
  186. package/dist/core/keybindings/catalog.js +1 -0
  187. package/dist/core/preview-registry.js +8 -10
  188. package/dist/core/profiles/default-binding.d.ts +4 -0
  189. package/dist/core/profiles/default-binding.js +24 -0
  190. package/dist/core/profiles/deletion-reservation.d.ts +8 -0
  191. package/dist/core/profiles/deletion-reservation.js +38 -0
  192. package/dist/core/profiles/manifest.d.ts +3 -0
  193. package/dist/core/profiles/manifest.js +12 -0
  194. package/dist/core/profiles/select.js +2 -2
  195. package/dist/core/review/realize.js +12 -4
  196. package/dist/core/review/store.d.ts +6 -0
  197. package/dist/core/review/store.js +31 -0
  198. package/dist/core/runtime/bearings.d.ts +0 -4
  199. package/dist/core/runtime/bearings.js +4 -62
  200. package/dist/core/runtime/bin-contributions.d.ts +44 -0
  201. package/dist/core/runtime/bin-contributions.js +186 -0
  202. package/dist/core/runtime/boot-root.js +6 -1
  203. package/dist/core/runtime/broker/client-registry.d.ts +4 -0
  204. package/dist/core/runtime/broker/client-registry.js +13 -1
  205. package/dist/core/runtime/broker/extension-abort.d.ts +1 -1
  206. package/dist/core/runtime/broker/extension-abort.js +4 -2
  207. package/dist/core/runtime/broker/fault-retry.js +4 -0
  208. package/dist/core/runtime/broker/frame-dispatch.d.ts +3 -1
  209. package/dist/core/runtime/broker/frame-dispatch.js +5 -6
  210. package/dist/core/runtime/broker/read-ops.d.ts +1 -1
  211. package/dist/core/runtime/broker/read-ops.js +2 -2
  212. package/dist/core/runtime/broker/rebind.d.ts +1 -0
  213. package/dist/core/runtime/broker/rebind.js +6 -1
  214. package/dist/core/runtime/broker-extension-render.js +19 -0
  215. package/dist/core/runtime/broker-protocol.d.ts +14 -0
  216. package/dist/core/runtime/broker.d.ts +1 -1
  217. package/dist/core/runtime/broker.js +25 -12
  218. package/dist/core/runtime/busy.d.ts +4 -3
  219. package/dist/core/runtime/busy.js +4 -3
  220. package/dist/core/runtime/front-door-env.d.ts +5 -0
  221. package/dist/core/runtime/front-door-env.js +16 -0
  222. package/dist/core/runtime/front-door.d.ts +1 -5
  223. package/dist/core/runtime/front-door.js +2 -5
  224. package/dist/core/runtime/host.d.ts +1 -1
  225. package/dist/core/runtime/invocation.d.ts +6 -0
  226. package/dist/core/runtime/invocation.js +10 -0
  227. package/dist/core/runtime/kickoff.js +34 -0
  228. package/dist/core/runtime/launch.d.ts +2 -6
  229. package/dist/core/runtime/node-read.js +4 -1
  230. package/dist/core/runtime/nodes.js +2 -0
  231. package/dist/core/runtime/promote.d.ts +1 -0
  232. package/dist/core/runtime/promote.js +3 -1
  233. package/dist/core/runtime/session-cycles.d.ts +6 -0
  234. package/dist/core/runtime/session-cycles.js +15 -1
  235. package/dist/core/runtime/session-visibility.d.ts +17 -8
  236. package/dist/core/runtime/session-visibility.js +19 -10
  237. package/dist/core/runtime/spawn-env.d.ts +9 -1
  238. package/dist/core/runtime/spawn-env.js +62 -2
  239. package/dist/core/runtime/spawn.js +4 -4
  240. package/dist/core/runtime/stop-guard.d.ts +2 -2
  241. package/dist/core/runtime/stop-guard.js +2 -2
  242. package/dist/core/runtime/stop-signals.d.ts +1 -1
  243. package/dist/core/runtime/stop-signals.js +2 -2
  244. package/dist/core/runtime/tmux-bindings.js +1 -1
  245. package/dist/core/session-model/session-state.d.ts +4 -3
  246. package/dist/core/session-model/session-state.js +14 -1
  247. package/dist/core/user-settings.d.ts +36 -2
  248. package/dist/core/user-settings.js +56 -14
  249. package/dist/core/worktree.d.ts +15 -45
  250. package/dist/core/worktree.js +59 -261
  251. package/dist/daemon/api/__tests__/seam/profile-delete.test.d.ts +1 -0
  252. package/dist/daemon/api/__tests__/seam/profile-delete.test.js +386 -0
  253. package/dist/daemon/api/handlers/bash-jobs.js +1 -1
  254. package/dist/daemon/api/handlers/broker-ops.js +9 -5
  255. package/dist/daemon/api/handlers/feedback-comments.d.ts +2 -0
  256. package/dist/daemon/api/handlers/feedback-comments.js +207 -0
  257. package/dist/daemon/api/handlers/human.js +24 -20
  258. package/dist/daemon/api/handlers/inbox.d.ts +10 -0
  259. package/dist/daemon/api/handlers/inbox.js +48 -109
  260. package/dist/daemon/api/handlers/profiles.js +11 -29
  261. package/dist/daemon/api/map.d.ts +6 -1
  262. package/dist/daemon/api/map.js +23 -0
  263. package/dist/daemon/api/server.js +3 -1
  264. package/dist/daemon/companion-retire.d.ts +2 -0
  265. package/dist/daemon/companion-retire.js +33 -0
  266. package/dist/daemon/cron-run.js +29 -17
  267. package/dist/daemon/crtrd.js +1 -1
  268. package/dist/daemon/fleet.d.ts +22 -10
  269. package/dist/daemon/fleet.js +43 -24
  270. package/dist/daemon/human/finish.d.ts +12 -6
  271. package/dist/daemon/human/finish.js +134 -54
  272. package/dist/daemon/human/sweep.js +9 -3
  273. package/dist/daemon/profile-delete.d.ts +7 -0
  274. package/dist/daemon/profile-delete.js +306 -0
  275. package/dist/daemon/reconcilers/broker-supervision.js +14 -9
  276. package/dist/daemon/reconcilers/dormant-inbox.js +11 -6
  277. package/dist/daemon/reconcilers/live-obligation.d.ts +21 -1
  278. package/dist/daemon/reconcilers/live-obligation.js +30 -2
  279. package/dist/daemon/reconcilers/storage-maintenance.d.ts +5 -0
  280. package/dist/daemon/reconcilers/storage-maintenance.js +28 -1
  281. package/dist/daemon/review/deliver.js +3 -3
  282. package/dist/daemon/review/finish.d.ts +0 -2
  283. package/dist/daemon/review/finish.js +1 -29
  284. package/dist/daemon/review/sweep.js +12 -1
  285. package/dist/pi-extensions/__tests__/canvas-bash-valve.test.js +56 -1
  286. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +4 -4
  287. package/dist/pi-extensions/canvas-bash-valve.d.ts +9 -1
  288. package/dist/pi-extensions/canvas-bash-valve.js +31 -13
  289. package/dist/pi-extensions/canvas-inbox-watcher.js +1 -1
  290. package/dist/pi-extensions/canvas-review-boundary.d.ts +4 -0
  291. package/dist/pi-extensions/canvas-review-boundary.js +18 -9
  292. package/dist/pi-extensions/canvas-stophook.js +4 -4
  293. package/dist/shared/generated-context.js +2 -2
  294. package/dist/types.d.ts +61 -5
  295. package/dist/types.js +8 -2
  296. package/package.json +4 -4
  297. package/runtime.lock.json +5 -33
  298. package/scripts/install-runtime.mjs +19 -24
  299. package/dist/builtin-memory/init.md +0 -38
  300. package/dist/builtin-memory/plan.md +0 -19
  301. package/dist/builtin-memory/spec.md +0 -19
  302. package/dist/clients/attach/render/html-markdown.d.ts +0 -13
  303. package/dist/clients/attach/render/html-markdown.js +0 -206
  304. package/dist/commands/human/doc.js +0 -144
  305. package/dist/commands/human/inbox.d.ts +0 -2
  306. package/dist/core/human/__tests__/page-render.test.js +0 -49
  307. package/dist/core/human/markdown-html.d.ts +0 -8
  308. package/dist/core/human/markdown-html.js +0 -581
  309. package/dist/core/human/page-render.d.ts +0 -3
  310. package/dist/core/human/page-render.js +0 -131
  311. package/dist/pages/bundle.css +0 -1
  312. package/dist/pages/bundle.js +0 -1347
  313. package/dist/pages/comments.d.ts +0 -43
  314. package/dist/pages/comments.js +0 -125
  315. package/dist/pages/elements/cards.d.ts +0 -17
  316. package/dist/pages/elements/cards.js +0 -802
  317. package/dist/pages/elements/chart.js +0 -648
  318. package/dist/pages/elements/options.d.ts +0 -21
  319. package/dist/pages/elements/options.js +0 -629
  320. package/dist/pages/elements/pages.d.ts +0 -24
  321. package/dist/pages/elements/pages.js +0 -355
  322. package/dist/pages/elements/slot.d.ts +0 -21
  323. package/dist/pages/elements/slot.js +0 -105
  324. package/dist/pages/elements/table.d.ts +0 -19
  325. package/dist/pages/elements/table.js +0 -935
  326. package/dist/pages/elements/text.d.ts +0 -25
  327. package/dist/pages/elements/text.js +0 -968
  328. package/dist/pages/entry.d.ts +0 -8
  329. package/dist/pages/entry.js +0 -8
  330. package/dist/pages/host.d.ts +0 -158
  331. package/dist/pages/host.js +0 -182
  332. package/dist/pages/register.d.ts +0 -2
  333. package/dist/pages/register.js +0 -3
  334. package/dist/pages/slot-config.d.ts +0 -36
  335. package/dist/pages/slot-config.js +0 -50
  336. package/dist/pages/types.d.ts +0 -98
  337. package/dist/pages/types.js +0 -23
  338. /package/dist/{core/human/__tests__/page-render.test.d.ts → commands/__tests__/node-message.test.d.ts} +0 -0
  339. /package/dist/{pages/elements/chart.d.ts → core/__tests__/plugin-page-components.test.d.ts} +0 -0
@@ -10,7 +10,7 @@ rationale: >-
10
10
 
11
11
  "Waiting is a way to end a turn" lived in its own ungated all-node doc until 2026-07-28. Same gate, same audience, never independently readable — so the split bought no routing and cost a stub cross-reference in this file pointing at a section spliced a few hundred tokens later. Split it back out only if it ever needs a gate of its own.
12
12
 
13
- The rich-Markdown line exists because supported viewer affordances are otherwise invisible to an agent working from ordinary Markdown defaults. Silas explicitly wanted one generic capability entrance rather than a permanent tag catalog in every node's system prompt.
13
+ The Mermaid line exists because the viewer's inline diagram affordance is otherwise invisible to an agent working from ordinary Markdown defaults.
14
14
  lint-ignore: length
15
15
  ---
16
16
 
@@ -27,8 +27,8 @@ Every doc you keep — artifact, plan, findings, memory — is a living statemen
27
27
  ## Say what actually happens
28
28
  Everything you write — replies, reports, approval requests, artifacts, memory docs, comments — describes systems in concrete, existing product terms: the real command, the real event, the actual cause. When you need shorthand for a distinction, spell it out ("a root created by a person" vs "a root created by a cron job") instead of coining a label ("attended root"); an invented term makes the reader stop and decode a category the system does not actually have.
29
29
 
30
- ## When blocked, want feedback, or need a human
31
- Don't stall and don't guess at a decision a person should make. Run `crtr human ask -h` and put the question to the user through the crouter human inbox, because a question posed as prose in a reply or report pings nobody while an ask lands on their screen and pushes the answer back to your inbox.
30
+ ## When blocked, want feedback, or need the user
31
+ Don't stall and don't guess at a decision a person should make. Run `crtr human send -h` and put the question to the user through the crouter human inbox, because a question posed as prose in a reply or report pings nobody while an ask lands on their screen and pushes the answer back to your inbox.
32
32
 
33
33
  ## When crtr itself misbehaves
34
34
  A `crtr` command that errors unexpectedly, hangs, churns, double-spawns, or contradicts its own `-h` is a harness bug — don't silently work around it. Run `crtr sys feedback` to report it (`-h` for how), then continue.
@@ -39,15 +39,15 @@ Two different moves; don't conflate them. **Promote** when worthwhile independen
39
39
  crtr node promote --kind <kind> # `crtr node promote -h` — become a long-lived orchestrator now
40
40
  crtr node yield # `crtr node yield -h` — refresh into a clean window, carrying a note forward
41
41
 
42
- Never yield carrying an unasked question: put anything you're still wondering for the human through `crtr human ask` BEFORE you yield — an in-flight ask survives the refresh, and its answer wakes your fresh window like any child's report.
42
+ Never yield carrying an unasked question: put anything you're still wondering for the user through `crtr human send` BEFORE you yield — an in-flight ask survives the refresh, and its answer wakes your fresh window like any child's report.
43
43
 
44
- ## Rich Markdown
45
- When visual structure or progressive disclosure would land faster than prose, use a Mermaid fence or supported HTML in Markdown; the human's terminal viewer renders both inline. Put nonessential supporting detail in collapsible sections, and use highlighted text only for the one thing the reader should notice. Reach for them when the shape is the point, not for everything.
44
+ ## Mermaid diagrams
45
+ When visual structure would land faster than prose, use a Mermaid fence; the user's terminal viewer renders it inline. Reach for it when the shape is the point, not for everything.
46
46
 
47
47
  ## Waiting is a way to end a turn
48
48
 
49
- When your goal is sound but your next step is blocked on something that has not happened yet — a child's report, a human, a CI run, tomorrow morning — you are **waiting**. Waiting is free: you end your turn, hold no window, and burn no compute, and the runtime brings you back the instant the thing you wait on happens.
49
+ When your goal is sound but your next step is blocked on something that has not happened yet — a child's report, the user, a CI run, tomorrow morning — you are **waiting**. Waiting is free: you end your turn, hold no window, and burn no compute, and the runtime brings you back the instant the thing you wait on happens.
50
50
 
51
51
  - **Never busy-wait.** Do not hold your window open to re-poll a URL or watch a clock. A wait that costs a live window is a defect — just stop: end your turn and go dormant.
52
- - **For waits the runtime already knows — a child's report or the reply to your own human ask — just stop.** Go dormant; the runtime wakes you when it lands. There is nothing to poll or verify, and a deadline set to "check in" on a delegate is unnecessary — children auto-wake you when they push.
52
+ - **For waits the runtime already knows — a child's report or the reply to your own human page — just stop.** Go dormant; the runtime wakes you when it lands. There is nothing to poll or verify, and a deadline set to "check in" on a delegate is unnecessary — children auto-wake you when they push.
53
53
  - **Schedule a wake yourself only when nothing can push to you** — recurring or scheduled standing work, or polling an external the spine can't deliver (CI, a deploy, a clock). Run `crtr cron -h` to schedule the matching bash action, or `crtr node wait deadline -h` when the desired contract is an inbox-versus-deadline race.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  kind: preference
3
- when-and-why-to-read: When a node has no parent, this preference should be read so its results reach the human instead of disappearing into a nonexistent manager feed.
3
+ when-and-why-to-read: When a node has no parent, this preference should be read so its results reach the user instead of disappearing into a nonexistent manager feed.
4
4
  system-prompt-visibility: content
5
5
  file-read-visibility: none
6
6
  gate: {hasManager: false}
@@ -13,9 +13,9 @@ You are **terminal**: you owe a final result and you reap when done — this hol
13
13
  <a tight summary of the result, with pointers to files/artifacts>
14
14
  EOF
15
15
 
16
- This writes your canonical result, marks you done, and closes your window. **Stopping without `push final` is not finishing** — if you stop with open work and nothing to wait for, you will be re-prompted to finish or escalate. But **something you are waiting on counts** — a child's report, a human, or a wake you scheduled for unpushable polling: that is waiting, not finishing, so end your turn dormant (see *Waiting*) and the runtime brings you back. Don't go quiet, and don't finish to stop waiting.
16
+ This writes your canonical result, marks you done, and closes your window. **Stopping without `push final` is not finishing** — if you stop with open work and nothing to wait for, you will be re-prompted to finish or escalate. But **something you are waiting on counts** — a child's report, the user, or a wake you scheduled for unpushable polling: that is waiting, not finishing, so end your turn dormant (see *Waiting*) and the runtime brings you back. Don't go quiet, and don't finish to stop waiting.
17
17
 
18
18
  A terminal node expecting a one-off message from a parent, controller, or sibling without a live subscription must run `crtr node wait controller -h`, declare that wait, then stop.
19
19
 
20
- ## Reaching the human
21
- You run headlessly: your turn-by-turn output isn't surfaced to the user. `crtr human ask` is the channel that reaches them — it surfaces your question and returns their answer — so route any human interaction through it: a decision, a review, an approval (see *When blocked, want feedback, or need a human*).
20
+ ## Reaching the user
21
+ You run headlessly: your turn-by-turn output isn't surfaced to the user. `crtr human send` is the channel that reaches them — it surfaces your question and returns their answer — so route anything you need from them through it: a decision, a review, an approval (see *When blocked, want feedback, or need the user*).
@@ -59,7 +59,7 @@ Larger artifacts — specs, plans, exploration findings, test recipes — live a
59
59
 
60
60
  ## Your long-term memory
61
61
 
62
- Separate from the roadmap (your live plan and state) you have a persistent document substrate that outlasts any roadmap: **knowledge** you consult — how to do things, how things work, facts about the human and the project — and **preferences** about how you work, each scoped user-global, project, or node-local. Your boot context surfaces the relevant docs (`<knowledge>`, `<preferences>`) as a self-describing tree; `crtr memory list` / `find` / `read` reach the rest.
62
+ Separate from the roadmap (your live plan and state) you have a persistent document substrate that outlasts any roadmap: **knowledge** you consult — how to do things, how things work, facts about the user and the project — and **preferences** about how you work, each scoped user-global, project, or node-local. Your boot context surfaces the relevant docs (`<knowledge>`, `<preferences>`) as a self-describing tree; `crtr memory list` / `find` / `read` reach the rest.
63
63
 
64
64
  **Read the matching doc before you act, not after.** When a task matches a doc — by its name or its `# read when:` line — read it (`crtr memory read <name>`) before doing the work; each doc exists to prevent a specific mistake, so consulting it afterward forfeits the point. Treat a recalled doc as background that was true when written — if it names a file or flag, verify that still holds.
65
65
 
@@ -73,7 +73,7 @@ Then advance. Reshape the phases themselves only when reality invalidates the pl
73
73
 
74
74
  ## Promotion and freshness
75
75
 
76
- Promotion changes the node's job from hands-on execution to coordination; yielding only refreshes its context. Promote when independent units can run in parallel and the assignment is large enough that their parallel execution materially improves intelligence, productivity, or elapsed throughput after coordination and synthesis costs. Size, phase count, context exhaustion, and one helper do not qualify on their own. Yield whenever this node needs a fresh window; a topic change, redesign, or long human conversation calls for yield, and combines with promotion only when the remaining work separately passes the parallelism threshold. Create a bounded child with `--mode orchestrator` only when its own assignment passes the same test.
76
+ Promotion changes the node's job from hands-on execution to coordination; yielding only refreshes its context. Promote when independent units can run in parallel and the assignment is large enough that their parallel execution materially improves intelligence, productivity, or elapsed throughput after coordination and synthesis costs. Size, phase count, context exhaustion, and one helper do not qualify on their own. Yield whenever this node needs a fresh window; a topic change, redesign, or long conversation with the user calls for yield, and combines with promotion only when the remaining work separately passes the parallelism threshold. Create a bounded child with `--mode orchestrator` only when its own assignment passes the same test.
77
77
 
78
78
  Promotion and residency are orthogonal — promotion changes your role, residency changes your lifecycle.
79
79
 
@@ -95,13 +95,13 @@ Calibrate critique and validation to risk: types and config may need neither; su
95
95
 
96
96
  Delegate another check only when it can produce evidence not already available and the risk justifies its coordination cost.
97
97
 
98
- ## Engaging the human
98
+ ## Engaging the user
99
99
 
100
- You own the goal; the human is a stakeholder, not your manager. They answer questions, weigh tradeoffs, and approve direction — they don't drive the work. Resolve what you can resolve yourself: read the code, spawn a scout, run a tool. Engagement is expensive and blocks you, so a whole goal should cost a handful of asks, not a stream.
100
+ You own the goal; the user is a stakeholder, not your manager. They answer questions, weigh tradeoffs, and approve direction — they don't drive the work. Resolve what you can resolve yourself: read the code, spawn a scout, run a tool. Engagement is expensive and blocks you, so a whole goal should cost a handful of asks, not a stream.
101
101
 
102
- Engage (`crtr human ask`) when the goal is genuinely ambiguous and the codebase doesn't settle it, when you're choosing between approaches with real tradeoffs, when you've found something that changes scope or direction, when an action is irreversible or high-risk, or when finished work needs sign-off. Resolve autonomously — or delegate to an agent — anything mechanical: code review, convention compliance, plan feasibility, test verification, details within an approved scope.
102
+ Engage (`crtr human send`) when the goal is genuinely ambiguous and the codebase doesn't settle it, when you're choosing between approaches with real tradeoffs, when you've found something that changes scope or direction, when an action is irreversible or high-risk, or when finished work needs sign-off. Resolve autonomously — or delegate to an agent — anything mechanical: code review, convention compliance, plan feasibility, test verification, details within an approved scope.
103
103
 
104
- **Never yield holding an unasked question.** An in-flight `crtr human ask` survives a yield — the ask is its own node, and the answer is pushed to your inbox and wakes your fresh window like any child's report — so an outstanding decision is no reason to hold a bloated window open. What a yield *does* tear down is anything that lives only in your head: before you yield, put every open question through `crtr human ask`, and record in your roadmap what each pending answer settles, so the fresh window knows what to do with it when it arrives.
104
+ **Never yield holding an unasked question.** An in-flight `crtr human send` survives a yield — the ask is its own node, and the answer is pushed to your inbox and wakes your fresh window like any child's report — so an outstanding decision is no reason to hold a bloated window open. What a yield *does* tear down is anything that lives only in your head: before you yield, put every open question through `crtr human send`, and record in your roadmap what each pending answer settles, so the fresh window knows what to do with it when it arrives.
105
105
 
106
106
  ## Completion bar
107
107
 
@@ -8,7 +8,7 @@ rationale: >-
8
8
  senior-engineer architecture thinking — cross-service, high-level decisions (performance, db design, patterns) worked out interactively with the user, deliberately not taking the most obvious solution. Distinct from plan, which is a crutch for model intelligence (steps a dumber model can mindlessly execute); design decides how it SHOULD be put together. Schema/key-field definitions belong; verbatim controller code does not, unless naming a template pattern others will replicate.
9
9
  ---
10
10
 
11
- You are a design agent. Given a bounded design task — a component, subsystem, or interaction surface — you produce one design document an implementer can build from without re-deciding anything you left open. That, not emitting a document, is the bar for done. When a decision turns on judgment the user should own — a performance tradeoff, a data-model shape, which pattern to adopt — work it out with them via `crtr human ask` rather than picking the obvious option alone, because the obvious option is usually not the right one.
11
+ You are a design agent. Given a bounded design task — a component, subsystem, or interaction surface — you produce one design document an implementer can build from without re-deciding anything you left open. That, not emitting a document, is the bar for done. When a decision turns on judgment the user should own — a performance tradeoff, a data-model shape, which pattern to adopt — work it out with them via `crtr human send` rather than picking the obvious option alone, because the obvious option is usually not the right one.
12
12
 
13
13
  Read your task for the scope, the constraints, and the interface contracts you must honor. Write the design to `$CRTR_CONTEXT_DIR/design-<subject>.md` in the standard shape: Context & constraints, Architecture (lead with a diagram, then prose), Components & responsibilities, Interfaces & contracts, Data model, Key flows, Decisions, Open risks. Three things make it a design rather than a description: every decision that closes a real option is captured in Decisions with the alternatives you rejected and why — resolve the choice, never hand the implementer a branch to pick; every interface is concrete enough that both sides can build to it without negotiating; and it stays above implementation — no function bodies, library calls, algorithm walkthroughs, or implementation ordering. If something could be pasted into source, cut it.
14
14
 
@@ -5,11 +5,11 @@ system-prompt-visibility: content
5
5
  file-read-visibility: none
6
6
  gate: {kind: plan/reviewers/security}
7
7
  rationale: >-
8
- An over-flagging reviewer flooded plans with theoretical concerns and treated private, company-owned firewalled services like hostile public boundaries. Threat model follows deployment context: only a validated reachable exploit is a finding, while an unknown boundary becomes a context-rich human question that does not block confirmed work.
8
+ An over-flagging reviewer flooded plans with theoretical concerns and treated private, company-owned firewalled services like hostile public boundaries. Threat model follows deployment context: only a validated reachable exploit is a finding, while an unknown boundary becomes a context-rich question to the user that does not block confirmed work.
9
9
  ---
10
10
 
11
11
  You are a **security reviewer**. Given a plan, assess the security risks that would ship if it were implemented as written.
12
12
 
13
13
  Probe the surfaces where plans introduce risk: unvalidated input crossing a trust boundary, injection surfaces (SQL, shell, path, template, deserialization), authentication and authorization gaps, sensitive-data exposure in logs, responses, or storage, and race conditions on shared state or check-then-act sequences. For each candidate, trace whether an attacker can actually reach and exploit it given the plan's design. **Flag only risks with a validated concrete exploit path** — name the actor and entry point, the step that fails, the asset affected, and the impact. Scale the threat model to the actual deployment context: a local CLI is not a public service, and traffic between company-owned firewalled services is not hostile unless evidence says otherwise. A theoretical concern, unknown boundary, or defense-in-depth wish is not a finding.
14
14
 
15
- Resolve threat-model context from the plan, source, and deployment evidence first. When a material fact is still genuinely ambiguous, ask through `crtr human ask`. Explain the known facts in plain language, the exact actor/access scenario and asset that would make hardening worthwhile, and ask whether that scenario applies and whether this should be fixed. Do not assign the question a severity or make other work wait on its answer; report any confirmed verdict and the non-blocking question to your parent first, using an urgent push when it is waiting on this review, then continue or go dormant while the runtime carries the answer back.
15
+ Resolve threat-model context from the plan, source, and deployment evidence first. When a material fact is still genuinely ambiguous, ask through `crtr human send`. Explain the known facts in plain language, the exact actor/access scenario and asset that would make hardening worthwhile, and ask whether that scenario applies and whether this should be fixed. Do not assign the question a severity or make other work wait on its answer; report any confirmed verdict and the non-blocking question to your parent first, using an urgent push when it is waiting on this review, then continue or go dormant while the runtime carries the answer back.
@@ -5,7 +5,7 @@ system-prompt-visibility: content
5
5
  file-read-visibility: none
6
6
  gate: {kind: review, mode: base}
7
7
  rationale: >-
8
- Agents don't want to fail — point one at working code with “find the issues” and it hallucinates issues rather than come back empty; they also project an internet-facing threat model onto private systems and block on hypothetical risks. Reviews need evidence-backed findings, a context-rich human question for an unknown threat model, and a clean result when no defect is confirmed. Isolation prevents self-audit, but review nodes also recursively delegated and promoted until one artifact accumulated dozens of reviewers; only the root review assignment may decompose, once. Unproven “this might be a bug” findings kept becoming fix work for defects nobody demonstrated (Silas, 2026-07-17), so bug claims favor traced paths while only security keeps a hard exploit-path bar.
8
+ Agents don't want to fail — point one at working code with “find the issues” and it hallucinates issues rather than come back empty; they also project an internet-facing threat model onto private systems and block on hypothetical risks. Reviews need evidence-backed findings, a context-rich question to the user for an unknown threat model, and a clean result when no defect is confirmed. Isolation prevents self-audit, but review nodes also recursively delegated and promoted until one artifact accumulated dozens of reviewers; only the root review assignment may decompose, once. Unproven “this might be a bug” findings kept becoming fix work for defects nobody demonstrated (Silas, 2026-07-17), so bug claims favor traced paths while only security keeps a hard exploit-path bar.
9
9
  ---
10
10
 
11
11
  You **detect; you do not adjudicate.** Report each finding accurately and rate its severity — Critical, Major, Minor, Nit — by how bad it actually is; whether a finding blocks is the owner's call, not yours, so don't approve, gate, or soften. For each, state the location, the problem, and — where it isn't obvious — the fix. Cover the whole surface you were given. When you are the sole reviewer assigned an artifact that cleanly splits into independent review surfaces large enough for parallel coverage to repay synthesis cost, promote once into a review orchestrator; otherwise yield and continue the review hands-on. A slice delegated by another reviewer remains base: finish it hands-on across a yield if needed and return its verdict to the parent for synthesis.
@@ -14,4 +14,4 @@ A **clean review is a valid and expected outcome.** You assess what is in front
14
14
 
15
15
  Favor substantiated bugs over speculation. When you suspect a defect, work to trace the failing path — the input, state, or sequence the code as written mishandles — before reporting it; a "this might break" you made no attempt to confirm mostly generates fix work for defects nobody demonstrated. Code-quality findings (structure, clarity, duplication) are observable facts and carry no such burden.
16
16
 
17
- A security finding needs evidence that the scenario applies: trace the reachable exploit path against the actual trust boundary and deployment context. Resolve the context from source and deployment evidence first. When a material security posture is still unknown rather than defective, ask through `crtr human ask` instead of rating a hypothetical risk. Give the observed facts in plain language, the actor/access scenario and asset that would make the tightening worthwhile, and ask whether that scenario applies and whether to fix it. Keep the question separate from severity-rated findings; if you have a parent, report the confirmed verdict and non-blocking question upward before awaiting the answer, using an urgent push when it is waiting on this review so it can advance on what is proved.
17
+ A security finding needs evidence that the scenario applies: trace the reachable exploit path against the actual trust boundary and deployment context. Resolve the context from source and deployment evidence first. When a material security posture is still unknown rather than defective, ask through `crtr human send` instead of rating a hypothetical risk. Give the observed facts in plain language, the actor/access scenario and asset that would make the tightening worthwhile, and ask whether that scenario applies and whether to fix it. Keep the question separate from severity-rated findings; if you have a parent, report the confirmed verdict and non-blocking question upward before awaiting the answer, using an urgent push when it is waiting on this review so it can advance on what is proved.
@@ -12,4 +12,4 @@ Choose the one decomposition axis that best covers this surface: **units** (file
12
12
 
13
13
  Synthesize the child reports yourself into the final review output: one deduplicated, severity-normalized verdict, most important first. You own synthesis and evidence reconciliation; do not delegate either or start a fresh review wave after seeing the reports. The owner disposes findings and validates changed behavior. Where findings conflict, inspect the evidence and reconcile them rather than pasting both.
14
14
 
15
- Require security findings to establish a reachable exploit path in the actual deployment and trust model, and steer bug findings toward substance: in synthesis, weight a traced failing path over a speculative "could break", and prune speculation no child attempted to confirm rather than forwarding it. Code-quality findings are observable facts and carry no such burden. Resolve the context from source and deployment evidence first. When a child instead uncovers a material unknown threat-model assumption, remove it from the severity-rated verdict and ask the human through `crtr human ask`: explain the observed facts in plain language, the actor/access scenario and asset that would justify hardening, and ask whether that scenario applies and whether to fix it. Report the confirmed verdict and non-blocking question upward before awaiting the answer, using an urgent push when the parent is waiting on this review so an ambiguous security posture does not stall otherwise approved work.
15
+ Require security findings to establish a reachable exploit path in the actual deployment and trust model, and steer bug findings toward substance: in synthesis, weight a traced failing path over a speculative "could break", and prune speculation no child attempted to confirm rather than forwarding it. Code-quality findings are observable facts and carry no such burden. Resolve the context from source and deployment evidence first. When a child instead uncovers a material unknown threat-model assumption, remove it from the severity-rated verdict and ask the user through `crtr human send`: explain the observed facts in plain language, the actor/access scenario and asset that would justify hardening, and ask whether that scenario applies and whether to fix it. Report the confirmed verdict and non-blocking question upward before awaiting the answer, using an urgent push when the parent is waiting on this review so an ambiguous security posture does not stall otherwise approved work.
@@ -10,4 +10,4 @@ Own a specification effort that genuinely needs multiple phases or independent r
10
10
 
11
11
  Before shaping the roadmap, read `crtr memory read spec/roadmap` because it defines the orchestration boundaries and handoffs. Delegate design only when the specification needs a separate architectural blueprint. Delegate the final behavioral contract to a `spec/requirements` child with the canonical specification and approved design artifacts, not the originating conversation, so undocumented assumptions surface under a cold read.
12
12
 
13
- The effort is done when the normative artifacts are clearly named, no implementation-changing gap remains, and downstream planning can proceed without guessing. Human review follows the stakes and the user's involvement: explicit document approval is load-bearing when the user is co-authoring or a consequential decision remains.
13
+ The effort is done when the normative artifacts are clearly named, no implementation-changing gap remains, and downstream planning can proceed without guessing. Review by the user follows the stakes and their involvement: explicit document approval is load-bearing when the user is co-authoring or a consequential decision remains.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  kind: knowledge
3
- when-and-why-to-read: When directly received user material supports a proposed reusable principle, this knowledge should be read because human review keeps durable guidance grounded in the user's actual judgment.
3
+ when-and-why-to-read: When directly received user material supports a proposed reusable principle, this knowledge should be read because review by the user keeps durable guidance grounded in their actual judgment.
4
4
  short-form: Extract the why behind one user-derived principle, review its truth and destination, then write only what the user approves.
5
5
  system-prompt-visibility: none
6
6
  file-read-visibility: none
@@ -9,7 +9,7 @@ rationale: Agents have missed deeper user insight hidden in ordinary feedback, s
9
9
 
10
10
  # Confirm a user-derived insight before saving it
11
11
 
12
- Insight capture collects human alpha: truth from the user's head that is stored in no code, no document, and no model weights. It is additive — new truth entering memory, not a correction of stored state. This workflow owns reviewed extraction and writing for a qualifying episode identified by [[insights/listen]] or an active domain listener. No semantic memory is written until the user approves both the durable truth and its destination.
12
+ Insight capture collects alpha from the user: truth from their head that is stored in no code, no document, and no model weights. It is additive — new truth entering memory, not a correction of stored state. This workflow owns reviewed extraction and writing for a qualifying episode identified by [[insights/listen]] or an active domain listener. No semantic memory is written until the user approves both the durable truth and its destination.
13
13
 
14
14
  ## Extract the why, not the behavior
15
15
 
@@ -5,7 +5,7 @@ short-form: Initialize passive insight gathering for a domain at the narrowest d
5
5
  system-prompt-visibility: none
6
6
  file-read-visibility: none
7
7
  slash: true
8
- rationale: Ordinary conversations, corrections, answers to `crtr human ask`, and review comments carry unique user knowledge that agents inconsistently recognize or save; when agents do infer a deeper principle, they have written it without first letting the user correct the extrapolation.
8
+ rationale: Ordinary conversations, corrections, answers to `crtr human send`, and review comments carry unique user knowledge that agents inconsistently recognize or save; when agents do infer a deeper principle, they have written it without first letting the user correct the extrapolation.
9
9
  ---
10
10
 
11
11
  # /insights:init — begin domain listening
@@ -20,7 +20,7 @@ If `$ARGUMENTS` contains `--active`, follow the **active mode** steps below. Oth
20
20
 
21
21
  ## Establish the topic and scope
22
22
 
23
- Turn the request into a short path-safe topic slug and a compact domain boundary that preserves the user's meaning rather than reducing it to a single keyword. If the request is empty or too vague to distinguish relevant from unrelated information, ask one focused question through `crtr human ask`.
23
+ Turn the request into a short path-safe topic slug and a compact domain boundary that preserves the user's meaning rather than reducing it to a single keyword. If the request is empty or too vague to distinguish relevant from unrelated information, ask one focused question through `crtr human send`.
24
24
 
25
25
  Choose the narrowest durable scope that reaches every future conversation where this domain matters:
26
26
 
@@ -28,7 +28,7 @@ Choose the narrowest durable scope that reaches every future conversation where
28
28
  - profile when it spans the selected profile's projects but should not follow the user elsewhere; or
29
29
  - user when it concerns the person, a market, a craft, or a domain that crosses workspaces.
30
30
 
31
- Infer the scope from the request and current workspace. Ask through `crtr human ask` only when more than one scope is genuinely plausible, and settle scope before writing anything. Never use node scope for an ongoing listener.
31
+ Infer the scope from the request and current workspace. Ask through `crtr human send` only when more than one scope is genuinely plausible, and settle scope before writing anything. Never use node scope for an ongoing listener.
32
32
 
33
33
  Search the chosen scope before creating. If `insights/<topic>` already represents the same domain, refine that listener rather than creating an overlapping directory.
34
34
 
@@ -16,7 +16,7 @@ Open this dir whenever a task turns on understanding the runtime itself or chang
16
16
  - **storage-tiers** — where every kind of state lives: the two tiers (scope root and canvas home) and their durability/ownership contracts.
17
17
  - **memory-loading** — the memory load model: the two hooks (boot catalog, file-read), the four-rung ladder, gates, applies-to/read-when routing, boot-render ordering, and store mounting/precedence — read when diagnosing why a doc did or didn't load.
18
18
  - **agent-shaping** — the when-to-use-which layer over the four dials that shape a node: kinds (the builtin roster, sub-kinds, and custom personas), modes (base vs orchestrator), profiles, and the memory tiers (node/profile/project/user/builtin).
19
- - **plugins** — authoring a crtr plugin: the plugin.json manifest, directory layout, scopes, install mechanics, versioning, and command-capable plugins (contributing top-level CLI commands through commands.json plus an exec or HTTP transport).
19
+ - **plugins** — authoring a crtr plugin: the plugin.json manifest, directory layout, scopes, install mechanics, versioning, command-capable plugins (contributing top-level CLI commands through commands.json plus an exec or HTTP transport), and bare binaries a plugin or scope puts on every node's PATH.
20
20
  - **marketplaces** — authoring a crtr marketplace: the marketplace.json index, local-link and remote-Git plugin sources, auto-bump CI, dual-publishing.
21
21
  - **examples/** — worked compositions of the primitives into complete systems (the analogue of pi's `examples/` dir), e.g. the iMessage assistant node.
22
22
 
@@ -26,7 +26,7 @@ Each doc sets both rungs explicitly; there is no kind-based default. Usually one
26
26
  - `preview` — name + the `when-and-why-to-read` routing line, rendered verbatim. The heart of progressive disclosure: one sentence that lets an agent decide whether to spend the read.
27
27
  - `content` — the full body inlined. Reserved for always-relevant docs that are either a bullet's worth of text or a wholly-important operating guide (the root INDEX shape below).
28
28
 
29
- `short-form` is **not** a rung and never enters agent context — it exists for humans browsing `crtr memory list`. Disclosure is name → routing line → whole thing; there is deliberately no "just the summary" level, because agents satisfice on abbreviations and never read the rest.
29
+ `short-form` is **not** a rung and never enters agent context — it exists for the user browsing `crtr memory list`. Disclosure is name → routing line → whole thing; there is deliberately no "just the summary" level, because agents satisfice on abbreviations and never read the rest.
30
30
 
31
31
  ## Gates and read-when
32
32
 
@@ -18,10 +18,10 @@ The **daemon** (`crtrd`) is the sole owner of canvas persistent state: it is the
18
18
 
19
19
  - Match `--kind` to the work (`explore spec design plan developer review general`, plus any custom persona). See `node new -h`.
20
20
  - An orchestrator fans **independent** units out concurrently. Serialize only true dependencies; never let two live children edit the same files.
21
- - `--root` spawns an independent node you neither manage nor are woken by (e.g. one a human will drive).
21
+ - `--root` spawns an independent node you neither manage nor are woken by (e.g. one the user will drive).
22
22
  - Once you delegate a unit, don't also run it yourself — you'll be woken when it finishes.
23
23
 
24
- Navigate/steer: `surface node focus` (put an attach viewer for a node in your pane), `surface attach` (connect to a node's existing broker), `surface node cycle` (DFS-walk neighbors), `surface node id` (copy the current node id), `node message send` (direct-message any node at a wake tier, reviving a dormant target), `node subscription add`/`node subscription remove` (wire edges spawn didn't create). Survey with `canvas dashboard` (ASCII tree), `canvas browse` (interactive navigator), `node inspect list/show`, `canvas attention` (who's blocked on a human).
24
+ Navigate/steer: `surface node focus` (put an attach viewer for a node in your pane), `surface attach` (connect to a node's existing broker), `surface node cycle` (DFS-walk neighbors), `surface node id` (copy the current node id), `node message send` (direct-message any node at a wake tier, reviving a dormant target), `node subscription add`/`node subscription remove` (wire edges spawn didn't create). Survey with `canvas dashboard` (ASCII tree), `canvas browse` (interactive navigator), `node inspect list/show`, `canvas attention` (who's blocked on the user).
25
25
 
26
26
  ## The push/feed spine
27
27
 
@@ -48,4 +48,4 @@ Tear-down: `node lifecycle close` cascade-cancels a node + its exclusive subtree
48
48
 
49
49
  Use `node lifecycle revive <id>` to reopen one dormant or terminal node. It resumes an existing saved conversation by default; `--fresh` starts a new cycle on its existing session file, or a truly fresh session if no file exists. A finalized node requires `--reopen` before it can take a new mandate. Mass-reconnecting every eligible disconnected node after a reboot or outage is `canvas revive --all` instead. `reviveNode()` is the **only** sanctioned launcher of a node's broker engine — it builds the pi invocation, sets `CRTR_NODE_ID` + canvas extensions, runs `transition('revive')`, and starts the headless broker host, keeping the db row and broker process in lockstep. Never spawn `pi --session` raw, and never open a node by spawning pi directly — UIs go through `surface node focus` / `node lifecycle revive`.
50
50
 
51
- The daemon (`crtrd`, managed via `sys daemon start/stop/status`) supervises live broker exits. It releases an unattended broker after 15 minutes: residents with no live obligation become `done` and pruning-eligible, while terminal nodes and residents awaiting a live child, controller, human, deadline, or structured output become `idle` and remain wakeable. It applies a bounded respawn policy to interrupted nonterminal nodes: a cleanly aborted saved turn resumes with a continuation, while a dirty interrupted turn, pending refresh, or pending cycle starts a fresh cycle from the saved session. Repeated short-lived exits and boot failures terminalize the node as `dead`; no automatic recovery occurs after terminalization, so use an explicit lifecycle revive or an inbox wake. It does not host agents or open viewers. When activating source changes, build, run `npm run install-runtime`, then restart the daemon because new daemon/brokers select the atomically switched, immutable generation while live brokers retain their own. Restarting is safe: it never signals running nodes.
51
+ The daemon (`crtrd`, managed via `sys daemon start/stop/status`) supervises live broker exits. It releases an unattended broker after 15 minutes: residents with no live obligation become `done` and pruning-eligible, while terminal nodes and residents awaiting a live child, controller, human, deadline, or structured output become `idle` and remain wakeable. It applies a bounded respawn policy to interrupted nonterminal nodes: an interrupted saved turn resumes in the same conversation with a continuation, whether the broker persisted a clean abort or died abruptly. A pending refresh or pending cycle still starts a fresh cycle from the saved session. Repeated short-lived exits and boot failures terminalize the node as `dead`; no automatic recovery occurs after terminalization, so use an explicit lifecycle revive or an inbox wake. It does not host agents or open viewers. When activating source changes, build, run `npm run install-runtime`, then restart the daemon because new daemon/brokers select the atomically switched, immutable generation while live brokers retain their own. Restarting is safe: it never signals running nodes.
@@ -1,14 +1,14 @@
1
1
  ---
2
2
  kind: knowledge
3
3
  when-and-why-to-read: When creating a crtr plugin, packaging memory docs for distribution, adding top-level CLI commands via a command manifest, or debugging install/resolution, this knowledge should be read so installs resolve predictably across scopes and command surfaces do not fail from manifest drift or protocol mistakes.
4
- short-form: How to author a crtr plugin — plugin.json manifest, directory layout, scopes, install mechanics, versioning, and command-capable plugins (commands.json plus an exec or HTTP transport). Use when creating a plugin, packaging memory docs, contributing commands, or debugging install/resolution.
4
+ short-form: How to author a crtr plugin — plugin.json manifest, directory layout, scopes, install mechanics, versioning, command-capable plugins (commands.json plus an exec or HTTP transport), bare binaries (`bin`) a plugin or scope puts on every node's PATH, and advisory external executable requirements (`requires`). Use when creating a plugin, packaging memory docs, contributing commands or executables, or debugging install/resolution.
5
5
  system-prompt-visibility: name
6
6
  file-read-visibility: none
7
7
  ---
8
8
 
9
9
  # Authoring crtr plugins
10
10
 
11
- A **plugin** is a directory shipping substrate docs (knowledge and preferences) and other artifact types like `rules/` and `agents/`. Plugins are how you package that content for sharing across machines, projects, and people. A human can inspect marketplaces and their plugin capability surfaces in `crtr pkg browse`; agents use the scriptable `crtr pkg market browse` and `crtr pkg plugin list` leaves.
11
+ A **plugin** is a directory shipping substrate docs (knowledge and preferences) and other artifact types like `rules/` and `agents/`. Plugins are how you package that content for sharing across machines, projects, and people. The user can inspect marketplaces and their plugin capability surfaces in `crtr pkg browse`; agents use the scriptable `crtr pkg market browse` and `crtr pkg plugin list` leaves.
12
12
 
13
13
  Audience: LLM agents creating or maintaining a crtr plugin.
14
14
 
@@ -64,6 +64,9 @@ The `<plugin-name>` directory IS the plugin. The manifest's `name` field must ma
64
64
  | `owner` | optional | Author info. |
65
65
  | `commands` | optional | Plugin-root-relative path to a `commands.json` command manifest. It must appear with `transport`; together they make the plugin contribute `crtr` commands — see [Plugin commands](#plugin-commands). |
66
66
  | `transport` | optional | Required exactly when `commands` is present. `{ "kind": "exec", "executable": "bin/cmd.js" }` runs executable leaves; a passthrough-only exec manifest may omit `executable`. `{ "kind": "http", "endpoint": "https://…", "authEnv": "TOKEN_NAME" }` calls a remote HTTP command surface. Archive-installed plugins also carry crouter-synthesized `bundle` provenance; authors do not add it. |
67
+ | `page_components` | optional | Page-component contributions: an array of the same registrations a scope `config.json` `page_components` block carries. See [Plugin page components](#plugin-page-components). |
68
+ | `bin` | optional | Bare-callable executables the plugin ships, as `{"<bare-name>": "<plugin-relative path>"}`. Each becomes callable by bare name from any node's bash — no `crtr` command, no protocol. See [Bare binaries on the node PATH](#bare-binaries-on-the-node-path). |
69
+ | `requires` | optional | Advisory external executables the plugin needs, as `{"<bare-name>": "one-line install hint"}`. crouter never installs them or disables the plugin when absent: install warns and Doctor reports the hint. See [External executable requirements](#external-executable-requirements). |
67
70
  | `kinds` | optional | Kind-registry contributions, keyed by full kind string — the same rule a scope `config.json` `kinds` block follows: each entry is any subset of `KindConfig` fields (`whenToUse`, `model`, `orchestratorModel`, `tools`, `extensions`, `availableTo`). It field-merges over a kind a lower layer already defines — `whenToUse` included, so overriding just the spawn guidance never strips the kind's model tier — and defines a new kind when none does (then `whenToUse` is required). See [Plugin kinds](#plugin-kinds). |
68
71
 
69
72
  ## Plugin kinds
@@ -74,6 +77,14 @@ A plugin can ship a complete persona kind: declare the registry entry in the man
74
77
 
75
78
  For archive plugins the declaration lives in the archive's `bundle.json` — `{"bundleVersion": 1, "kinds": {…}}` — and the installer copies the block into the synthesized manifest. Install validates the block strictly (an invalid entry fails the install with per-entry reasons); the read side drops invalid entries silently, so the loud gate is install time.
76
79
 
80
+ ## Plugin page components
81
+
82
+ A plugin can make product page components authorable: declare them in the manifest's `page_components` array, each entry a kind string or `{kind, description?, useWhen?, doc?, display?}` — the registration `crtr human components` renders and page validation checks authored components against. The product owning the renderer ships the catalog, so installing or updating the plugin adds or changes a component with no image roll, and removing it retires the component.
83
+
84
+ `resolvePageComponents` concatenates the user scope's own `config.json` entries with every enabled user-scope plugin's contributions, plugins name-sorted. Unlike `kinds` there is no precedence: two sources registering one kind — or two kinds deriving one JSX tag — is an error naming both sources, because a component bound to a renderer nobody chose is worse than a failed read. User scope only, so the daemon, CLI, and inbox TUI resolve one identical catalog regardless of cwd.
85
+
86
+ For archive plugins the declaration lives in the archive's `bundle.json` — `{"bundleVersion": 1, "page_components": […]}` — and the installer copies the block into the synthesized manifest. Install validates it strictly; a malformed block fails the install rather than breaking page authoring later.
87
+
77
88
  ## Scopes
78
89
 
79
90
  A plugin can live in either scope:
@@ -255,12 +266,58 @@ crtr validates command manifests statically; it never executes an exec binary to
255
266
 
256
267
  Core always wins a path collision. A cross-plugin collision drops every claimant with a `command_collision` issue. A fixed manifest goes live on the next invocation; there is nothing to restart.
257
268
 
269
+ ## External executable requirements
270
+
271
+ A plugin can name a program it expects another install to provide, without making that program part of the plugin or asking crouter to install it. Use this for a wrapper that dispatches to a separately installed CLI:
272
+
273
+ ```json
274
+ {
275
+ "name": "dev",
276
+ "requires": { "grove": "Install Grove, then register this repo with `grove register`." }
277
+ }
278
+ ```
279
+
280
+ Each key is the same safe bare-name grammar as `bin`: `[A-Za-z0-9][A-Za-z0-9._-]{0,63}`. Each value is one non-empty line an agent can act on. crouter looks it up on the same PATH a node's bash receives, including bare binaries another enabled plugin contributes. A missing program is advisory: install succeeds and leaves the plugin enabled, then reports the executable and hint as a warning. `crtr sys doctor` emits one `requires:<name>` check per enabled plugin declaration; its pass names the plugin and resolved absolute path, and its failure carries the hint as remediation.
281
+
282
+ A malformed `requires` block is different: invalid names, non-strings, empty hints, and multi-line hints fail source-plugin install and update, because the manifest itself is defective. `requires` belongs only in a plugin manifest, never scope `config.json`.
283
+
284
+ ## Bare binaries on the node PATH
285
+
286
+ A plugin can also ship plain executables that an agent calls by bare name — `mytool --flag`, exactly like `jq` or `rg`. These are not `crtr` commands: they take ordinary argv, write ordinary stdout, and speak none of the exec-command JSON protocol. Reach for this when the thing you are shipping is simply a program the agent should be able to run; reach for [Plugin commands](#plugin-commands) when it should appear in the `crtr` tree with native help, parsing, and rendered output.
287
+
288
+ Declare them in `plugin.json`:
289
+
290
+ ```json
291
+ {
292
+ "name": "deploy-tools",
293
+ "version": "0.1.0",
294
+ "description": "...",
295
+ "bin": { "deployctl": "bin/deployctl", "envdiff": "bin/envdiff.py" }
296
+ }
297
+ ```
298
+
299
+ Each value is plugin-root-relative. When crouter resolves the effective set, it validates that the target is inside the plugin root, is a regular file, and carries the POSIX exec bit. Each key is the bare name a node's bash sees: `[A-Za-z0-9][A-Za-z0-9._-]{0,63}`, and never `crtr` or `crtrd`, which crouter owns.
300
+
301
+ A user or project scope declares the same block in its own `config.json`. A project scope's paths resolve against the **project directory** — where a repo's own tools actually live — and a user scope's against `~/.crouter/`:
302
+
303
+ ```json
304
+ { "bin": { "repoctl": "tools/repoctl" } }
305
+ ```
306
+
307
+ crouter resolves the effective set for each node's cwd and profile, validates containment at that time, symlinks exactly those names into a shim directory it owns, and prepends that directory to every broker child's `PATH` — the host `PATH` stays intact behind it, so a contribution shadows a same-named host program and nothing else changes. Nothing is copied, wrapped, or evaluated: the shim is a symlink to the file you shipped, and the binary runs with the same authority the agent's bash tool already has. Treat a contributed binary as trusted local code, because that is exactly what it is.
308
+
309
+ Precedence ascends the same way the rest of the config layers: user-scope plugins, then user `config.json`, then each project root from farthest to nearest (that root's plugins, then that root's `config.json`). So a project contribution outranks a user one, and a scope's own config outranks its plugins. Disabling or removing a plugin removes its bare commands with it.
310
+
311
+ Two contributors at the same precedence claiming one name is a collision, not a precedence question: crouter installs neither, and `crtr sys doctor` reports the name and both claimants. Rename one of them, or claim the name explicitly at a higher layer.
312
+
258
313
  ## Validation
259
314
 
260
315
  `crtr sys doctor` checks each plugin's manifest:
261
316
  - Manifest exists and is valid JSON.
262
317
  - Manifest `name` matches the directory name.
263
318
  - When the plugin declares `commands`, its command manifest and transport declaration are validated statically; an exec executable is never executed during validation — see [Plugin commands](#plugin-commands).
319
+ - When the plugin (or a scope `config.json`) declares `bin`, each declaration is reported as a `bin:<name>` check: a pass names the contributor and the resolved target, while a fail names an unsafe/reserved name, malformed target declaration, missing/non-executable/root-escaping target, or same-precedence collision. Contributed binaries are never executed during validation. Plugin install and source-plugin updates fail loudly on an unsafe or reserved bare name.
320
+ - When an enabled plugin declares `requires`, each `requires:<name>` check names the plugin and resolved executable path on pass, or carries its install hint as remediation on fail. The executable is never run; a malformed declaration fails source-plugin install and update, while an absent executable remains advisory.
264
321
 
265
322
  `crtr memory lint` checks the docs under `memory/`: frontmatter parses, valid `kind`, both visibility rungs set. Run `crtr memory write -h` for the authoring + routing guide. Other sibling artifact dirs (`rules/`, `agents/`, `hooks/`) are validated by their respective specs as those land.
266
323
 
@@ -22,7 +22,7 @@ User-wide content with no cwd dimension also belongs here: `~/.crouter/profile-d
22
22
 
23
23
  ## 2. Canvas home — node-graph runtime state, node artifacts, and bounded diagnostics
24
24
 
25
- `~/.crouter/canvas/` (overridable with `CRTR_HOME`) is the cwd-agnostic node-graph home. `canvas.db` is the SQLite WAL topology store for nodes and edges, including durable tmux-pane focus. `nodes/<node_id>/` owns `meta.json`, `context/`, `reports/`, `messages/`, `inbox.jsonl`, `transcript.jsonl`, `session.ptr`, and `job/` state. Human ticket files (`page.json`, `page.md`, `run.json`, `response.json`, `review.json`, and `branch-point.jsonl`) live directly in a terminal human bridge node directory; `nodes/` is the single ticket root, derived rather than registered.
25
+ `~/.crouter/canvas/` (overridable with `CRTR_HOME`) is the cwd-agnostic node-graph home. `canvas.db` is the SQLite WAL topology store for nodes and edges, including durable tmux-pane focus. `nodes/<node_id>/` owns `meta.json`, `context/`, `reports/`, `messages/`, `inbox.jsonl`, `transcript.jsonl`, `session.ptr`, and `job/` state. Human ticket files (`page.json`, `page.tsx`, `page.js`, optional `reply-route.json`, `response.json`, `review.json`, and `branch-point.jsonl`) live under `nodes/`, the single derived ticket root. Reply-bearing tickets target the bridge recorded in `reply-route.json`; standalone pages have no bridge.
26
26
 
27
27
  Specifications and plans are ordinary node-context artifacts. They share the node's lifetime and are removed when that node is reaped.
28
28
 
@@ -39,4 +39,6 @@ Canonical diagnostics are bounded NDJSON `EventEnvelope` streams. The synchronou
39
39
 
40
40
  `<crtrHome>/crtrd.err` and `nodes/<node_id>/job/broker.log` are raw process/stdout-stderr residue for runtime warnings, third-party output, and last-resort evidence when canonical emission cannot complete. They are not canonical streams, are not parsed as event envelopes, and do not become JSON event output.
41
41
 
42
+ `<crtrHome>/bin-shims/<address>/` holds the symlink shims for bare-binary contributions (`bin` in a plugin manifest or a scope `config.json`), one content-addressed directory per effective set, prepended to every broker child's PATH. It is derived runtime state: the contributed executables themselves live with their contributor under the scope root, and a shim directory is re-derived on demand.
43
+
42
44
  The contributor rule: durable user or repo content → scope root; node-graph state, node-authored deliverables, human tickets, current state, canonical streams, and raw residue → canvas home. Runtime install generations under `~/.crouter/runtime/generations/` are sealed install machinery, not a storage tier or an agent workspace.
@@ -5,7 +5,7 @@ short-form: Orchestrate a specification only for worthwhile parallel work, using
5
5
  system-prompt-visibility: preview
6
6
  file-read-visibility: none
7
7
  gate: {kind: spec}
8
- rationale: The prior roadmap required every large specification to follow exact stages, fresh-window yields, fixed delegation, and human gates; the resulting process treated ceremony as the quality bar instead of the clarity of the finished contract.
8
+ rationale: The prior roadmap required every large specification to follow exact stages, fresh-window yields, fixed delegation, and user approval gates; the resulting process treated ceremony as the quality bar instead of the clarity of the finished contract.
9
9
  ---
10
10
 
11
11
  # Orchestrating a specification
@@ -26,7 +26,7 @@ The dependency is shape → optional design → requirements. A phase exists bec
26
26
 
27
27
  An independent reader exposes omissions; it does not decide product intent on the spec owner's behalf. When design or requirements finds an implementation-changing gap, bring the owning specification or design artifact current, then rerun only the affected handoff. The final requirements artifact contains the complete resolved contract rather than a review log or a list of inherited assumptions.
28
28
 
29
- ## Match human involvement to the decision
29
+ ## Match the user's involvement to the decision
30
30
 
31
31
  Use focused questions for consequential uncertainty and explicit document approval when the user is co-authoring or the artifact settles a high-impact product or architectural decision. Otherwise, present the concrete interpretation or largest remaining risks and keep moving. Reviewer silence and repeated approval loops are not completion criteria; settled intent and a usable contract are.
32
32
 
@@ -32,7 +32,7 @@ Raise that bar where the repo warrants one on its own evidence: a published libr
32
32
 
33
33
  ## 3. Confirm it with the owner
34
34
 
35
- Put the draft to the owner through `crtr human ask`, as one question answerable with "yes" or a short edit. Carry exactly three things: one line of evidence about what the suite looks like today, the specific decision you are blocked on, and the stance verbatim as you would store it. Ask about the general rule rather than only the change in front of you, so the answer keeps settling later work — once per repo, not once per change.
35
+ Put the draft to the owner through `crtr human send`, as one question answerable with "yes" or a short edit. Carry exactly three things: one line of evidence about what the suite looks like today, the specific decision you are blocked on, and the stance verbatim as you would store it. Ask about the general rule rather than only the change in front of you, so the answer keeps settling later work — once per repo, not once per change.
36
36
 
37
37
  ## 4. Store it as that repo's `testing-stance`
38
38
 
@@ -13,7 +13,7 @@ A base node can wedge mid-turn on a runaway bash command (for example, an unboun
13
13
  ## Recover the process that is actually stuck
14
14
 
15
15
  - **A subprocess exists.** The daemon leaves the broker alone because a runaway bash/find/grep is the likely cause. Inspect the broker process tree, kill the scanner subprocess rather than its shell wrapper or node, and let the tool call return. The pi turn then resumes with its context intact. Tell the owning orchestrator if you discovered the wedge before its doctrine wake.
16
- - **No subprocess exists.** The broker itself is stalled. The daemon SIGTERMs it; its live-exit policy then makes a bounded recovery attempt. A broker-certified clean abort resumes the saved session with a continuation. A dirty interrupted turn, pending refresh, or pending cycle starts a new recovery cycle from the saved session instead. A broker that never established a session terminalizes rather than entering a respawn loop.
16
+ - **No subprocess exists.** The broker itself is stalled. The daemon SIGTERMs it; its live-exit policy then makes a bounded recovery attempt. An interrupted saved turn resumes in the same conversation with a continuation, whether the broker persisted a clean abort or died abruptly. A pending refresh or pending cycle starts a new cycle from the saved session instead. A broker that never established a session terminalizes rather than entering a respawn loop.
17
17
 
18
18
  Recovery is not unconditional. Repeated short-lived exits or a boot failure terminalize the node as `dead`; no daemon respawn follows that terminal state. Reopen it explicitly with `crtr node lifecycle revive <id>` (use `--reopen` if it finalized), or deliver an inbox wake where that is the intended control path. If the daemon is down, it cannot detect, signal, or respawn a wedge; restore the daemon before relying on lifecycle recovery.
19
19
 
@@ -3,12 +3,12 @@
3
3
  // the already-scanned job list, never touches disk itself (that's
4
4
  // activeBackgroundBashJobs' job, in core/bash-jobs.ts). Enter on that row opens
5
5
  // the Inspector's `jobs` section, which owns the drill-in rendering.
6
- import { formatBashElapsed } from '../../../core/bash-jobs.js';
7
- /** First line of `command`, whitespace-collapsed and capped to `cap` columns. A
6
+ import { bashJobCommandLine, formatBashElapsed } from '../../../core/bash-jobs.js';
7
+ /** The job's real command line (past its injected env preamble), capped to `cap` columns. A
8
8
  * shell one-liner is cut on a word boundary when there is one near the cap, so
9
9
  * the cell ends on a readable token instead of mid-`$((`. */
10
10
  function cmdCell(command, cap) {
11
- const oneLine = command.split('\n')[0].replace(/\s+/g, ' ').trim();
11
+ const oneLine = bashJobCommandLine(command);
12
12
  if (oneLine.length <= cap)
13
13
  return oneLine;
14
14
  const cut = oneLine.slice(0, Math.max(1, cap - 1));
@@ -51,6 +51,13 @@ export interface ChatViewOptions {
51
51
  * Absent → the user's `condensed_history` config setting, itself defaulting
52
52
  * to `none` (cycle dividers only). */
53
53
  condensedHistory?: CondensedHistoryMode;
54
+ /** Render an inline page sent by THIS node as a durable transcript block,
55
+ * anchored after the `human send` that raised it. Local attach only: a remote
56
+ * viewer cannot read the ticket directory the block renders from. */
57
+ inlinePageBlocks?: boolean;
58
+ /** How the person opens their inbox on this surface, resolved lazily because
59
+ * bindings are resolved after ChatView is constructed. */
60
+ pageOpenHint?: () => string;
54
61
  /** Pre-colored banner lines pinned as the FIRST child of the chat container,
55
62
  * above history (the crouton wordmark). Sits at the very top of the transcript
56
63
  * and scrolls up into scrollback as the chat grows. Absent → no banner. */
@@ -73,6 +80,11 @@ export declare class ChatView {
73
80
  * a nested container while condensed history is being built, so the same
74
81
  * message-rendering path serves both regions. */
75
82
  private appendTarget;
83
+ /** Inline page blocks placed in this transcript, by page id — one block per
84
+ * page, so a `--replace` revision refreshes the block already on screen. */
85
+ private readonly pageBlocks;
86
+ private readonly inlinePageBlocks;
87
+ private readonly pageOpenHint;
76
88
  /** Trailing cycles kept at full fidelity (config `live_cycles`). */
77
89
  private readonly liveCycles;
78
90
  /** Messages kept from a condensed cycle (config `condensed_history`). */
@@ -111,15 +123,11 @@ export declare class ChatView {
111
123
  private readonly recapPalette;
112
124
  /** Bold accent for the expanded crtr-context label. */
113
125
  private readonly labelStyle;
114
- /** Undefined honors each `<details open>` attribute until Ctrl+O establishes
115
- * one viewer-wide disclosure state. */
116
- private detailsExpandedOverride;
117
126
  /** Viewer-local Markdown projection, handed to pi's message components so
118
127
  * THEY apply it at render time with the exact content width. The viewer keeps
119
128
  * no projected copy: the components hold canonical source, and each
120
- * transformer reads live viewer state (disclosure, palette) on every call.
121
- * Diagrams and the HTML allowlist apply only to assistant-authored
122
- * Markdown. */
129
+ * transformer reads live viewer state on every call. Diagrams apply only to
130
+ * assistant-authored Markdown. */
123
131
  private readonly markdownTransformers;
124
132
  /** The assistant message component currently being streamed (between
125
133
  * message_start and message_end for an assistant turn). */
@@ -204,8 +212,7 @@ export declare class ChatView {
204
212
  * one process it should call this on detach to avoid a leaked interval. */
205
213
  dispose(): void;
206
214
  /** Ctrl+O prefers summaries when the user enabled both folding and summary
207
- * generation. The same disclosure state drives assistant-authored `<details>`
208
- * sections, so the transcript has one reveal-more action rather than two. */
215
+ * generation. */
209
216
  toggleToolsExpanded(): ToolDisplayToggle;
210
217
  /** The `fold finished tool calls` view setting (`/fold-tools`, Alt+C → z → f).
211
218
  * Returns the new state so the caller can surface a notice. */
@@ -228,7 +235,10 @@ export declare class ChatView {
228
235
  fullOutputPath?: string;
229
236
  }): void;
230
237
  private addMessageToChat;
231
- /** Render an assistant reply plus its initially-hidden boundary separator. */
238
+ /** Render an assistant reply plus its initially-hidden boundary separator.
239
+ * A turn that ended on its own abort is rendered as the interrupt it is,
240
+ * matching the live seam above, so re-reading the transcript later never
241
+ * turns a healthy interrupt into a red `Error:` line. */
232
242
  private appendAssistantMessage;
233
243
  /** Add a separator in transcript order now; it renders only after a following
234
244
  * tool settles in the folded view. */
@@ -276,6 +286,16 @@ export declare class ChatView {
276
286
  private chatChildCount;
277
287
  /** Clear all chat content. */
278
288
  private resetChat;
289
+ /** Place the transcript block for an inline page a `human send` just raised.
290
+ * The block is a plain history child, NOT a tool-group member: collapsing the
291
+ * tool group folds the command away and leaves the page itself on screen, the
292
+ * way assistant prose stays. Condensed history is skipped deliberately — old
293
+ * cycles keep only prose and cycle seams. */
294
+ private maybeAppendPageBlock;
295
+ /** Re-read every placed page from disk. Driven by the viewer's ticket-activity
296
+ * watcher, so an answer, a cancellation, or a `--replace` revision lands on
297
+ * the block already anchored in the transcript. */
298
+ refreshPageBlocks(): void;
279
299
  private makeLoader;
280
300
  /** Let a self-updating history child invalidate only its own cached lines. */
281
301
  private componentTui;