@north-light/crouter 0.3.198 → 0.3.200

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 (316) hide show
  1. package/dist/api/client.d.ts +18 -18
  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 +81 -34
  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 +6 -6
  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 +2 -2
  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/clients/attach/chrome/bash-jobs.js +3 -3
  33. package/dist/clients/attach/render/chat-view.d.ts +26 -1
  34. package/dist/clients/attach/render/chat-view.js +61 -11
  35. package/dist/clients/attach/render/page-block.d.ts +34 -0
  36. package/dist/clients/attach/render/page-block.js +226 -0
  37. package/dist/clients/attach/session/whip.d.ts +2 -0
  38. package/dist/clients/attach/session/whip.js +2 -0
  39. package/dist/clients/attach/viewer.js +1419 -993
  40. package/dist/clients/conversation/projection.js +18 -3
  41. package/dist/clients/inbox/__tests__/serial/inbox-controller.test.js +9 -6
  42. package/dist/clients/inbox/__tests__/serial/mount-panel.test.js +13 -21
  43. package/dist/clients/inbox/controller.js +10 -16
  44. package/dist/clients/inbox/page-adapter.d.ts +1 -3
  45. package/dist/clients/inbox/page-adapter.js +3 -4
  46. package/dist/clients/inbox/resolve.d.ts +1 -1
  47. package/dist/clients/inbox/resolve.js +3 -3
  48. package/dist/clients/inbox/review/document-surface.js +3 -1
  49. package/dist/clients/inbox/review/state.d.ts +2 -1
  50. package/dist/clients/inbox/review/state.js +5 -16
  51. package/dist/clients/inbox/tui/input.js +37 -19
  52. package/dist/clients/inbox/tui/panel.js +5 -31
  53. package/dist/clients/inbox/tui/render.d.ts +11 -0
  54. package/dist/clients/inbox/tui/render.js +71 -27
  55. package/dist/clients/inbox/tui/slots.d.ts +3 -1
  56. package/dist/clients/inbox/tui/slots.js +16 -12
  57. package/dist/clients/inbox/tui/types.d.ts +2 -7
  58. package/dist/clients/inbox/tui.js +2 -2
  59. package/dist/commands/__tests__/human.test.js +71 -114
  60. package/dist/commands/__tests__/node-message.test.js +14 -0
  61. package/dist/commands/attention.js +4 -4
  62. package/dist/commands/canvas-snapshot.js +1 -1
  63. package/dist/commands/canvas.js +1 -1
  64. package/dist/commands/dashboard.js +1 -1
  65. package/dist/commands/human/{html.d.ts → components.d.ts} +1 -1
  66. package/dist/commands/human/components.js +77 -0
  67. package/dist/commands/human/feedback.d.ts +2 -0
  68. package/dist/commands/human/feedback.js +108 -0
  69. package/dist/commands/human/prompts.d.ts +13 -5
  70. package/dist/commands/human/prompts.js +160 -97
  71. package/dist/commands/human/queue.js +57 -88
  72. package/dist/commands/human/shared.d.ts +2 -12
  73. package/dist/commands/human/shared.js +17 -11
  74. package/dist/commands/human.js +29 -21
  75. package/dist/commands/memory/origin.js +2 -2
  76. package/dist/commands/node/bash.js +4 -4
  77. package/dist/commands/node/inspect.js +3 -3
  78. package/dist/commands/node/lifecycle.js +1 -1
  79. package/dist/commands/node/message.js +2 -2
  80. package/dist/commands/node-worktree.js +8 -8
  81. package/dist/commands/pkg/browse.js +1 -1
  82. package/dist/commands/pkg/plugin-manage.js +129 -10
  83. package/dist/commands/profile/delete.js +41 -15
  84. package/dist/commands/profile.js +1 -1
  85. package/dist/commands/push.js +1 -1
  86. package/dist/commands/surface/node/focus.js +29 -14
  87. package/dist/commands/surface-edit.js +3 -3
  88. package/dist/commands/surface-inbox.d.ts +2 -0
  89. package/dist/commands/{human/inbox.js → surface-inbox.js} +14 -18
  90. package/dist/commands/surface.js +2 -1
  91. package/dist/commands/sys/doctor.js +60 -3
  92. package/dist/commands/sys/feedback.js +79 -25
  93. package/dist/commands/sys/settings.js +1 -1
  94. package/dist/core/__tests__/cron-broker-capacity.test.js +1 -1
  95. package/dist/core/__tests__/extension-abort.test.js +5 -2
  96. package/dist/core/__tests__/fixtures/fake-engine.d.ts +13 -2
  97. package/dist/core/__tests__/fixtures/fake-engine.js +47 -3
  98. package/dist/core/__tests__/helpers/harness.js +17 -55
  99. package/dist/core/__tests__/human-cancel-guard.test.js +31 -10
  100. package/dist/core/__tests__/human-deliver.test.js +31 -26
  101. package/dist/core/__tests__/human-node-not-supervised.test.js +1 -1
  102. package/dist/core/__tests__/plugin-page-components.test.js +157 -0
  103. package/dist/core/__tests__/seam/broker-crash-teardown.test.js +4 -5
  104. package/dist/core/__tests__/seam/dormancy-release.test.js +40 -0
  105. package/dist/core/__tests__/serial/flagship-lifecycle.test.js +2 -2
  106. package/dist/core/__tests__/serial/human-deliver-e2e.test.js +12 -6
  107. package/dist/core/__tests__/serial/live-mutation.test.js +1 -1
  108. package/dist/core/__tests__/serial/tmux-surface.test.js +4 -2
  109. package/dist/core/__tests__/serial/worktree.test.js +24 -198
  110. package/dist/core/__tests__/session-cycles.test.js +22 -0
  111. package/dist/core/__tests__/stop-guard.test.js +4 -4
  112. package/dist/core/__tests__/watchdog-abort-arms-retry.test.js +19 -4
  113. package/dist/core/bash-jobs.d.ts +6 -0
  114. package/dist/core/bash-jobs.js +10 -0
  115. package/dist/core/canvas/__tests__/attention.test.js +8 -5
  116. package/dist/core/canvas/__tests__/render-remote.test.js +5 -5
  117. package/dist/core/canvas/attention.js +8 -6
  118. package/dist/core/canvas/browse/model.d.ts +8 -2
  119. package/dist/core/canvas/browse/model.js +11 -4
  120. package/dist/core/canvas/canvas.d.ts +7 -0
  121. package/dist/core/canvas/canvas.js +37 -0
  122. package/dist/core/canvas/crons.d.ts +9 -0
  123. package/dist/core/canvas/crons.js +51 -0
  124. package/dist/core/canvas/node-order.d.ts +22 -1
  125. package/dist/core/canvas/node-order.js +26 -1
  126. package/dist/core/canvas/render-source.d.ts +5 -0
  127. package/dist/core/canvas/render-source.js +1 -0
  128. package/dist/core/canvas/types.d.ts +9 -3
  129. package/dist/core/command-plugins/bundle.d.ts +6 -1
  130. package/dist/core/command-plugins/bundle.js +26 -13
  131. package/dist/core/command.js +2 -1
  132. package/dist/core/config.d.ts +47 -1
  133. package/dist/core/config.js +137 -4
  134. package/dist/core/help.js +1 -1
  135. package/dist/core/human/__tests__/page-catalog.test.js +4 -0
  136. package/dist/core/human/__tests__/page-tickets.test.js +65 -52
  137. package/dist/core/human/__tests__/page.test.js +56 -98
  138. package/dist/core/human/__tests__/serial/inbox-core.test.js +6 -6
  139. package/dist/core/human/answer-text.js +3 -3
  140. package/dist/core/human/answer.d.ts +6 -4
  141. package/dist/core/human/answer.js +4 -10
  142. package/dist/core/human/component-docs.d.ts +11 -7
  143. package/dist/core/human/component-docs.js +361 -88
  144. package/dist/core/human/convention.d.ts +17 -3
  145. package/dist/core/human/convention.js +36 -5
  146. package/dist/core/human/feedback-companion.d.ts +20 -0
  147. package/dist/core/human/feedback-companion.js +98 -0
  148. package/dist/core/human/feedback.d.ts +65 -0
  149. package/dist/core/human/feedback.js +116 -0
  150. package/dist/core/human/page-catalog.d.ts +40 -5
  151. package/dist/core/human/page-catalog.js +102 -30
  152. package/dist/core/human/page-errors.d.ts +4 -0
  153. package/dist/core/human/page-errors.js +7 -0
  154. package/dist/core/human/page-eval.d.ts +20 -0
  155. package/dist/core/human/page-eval.js +123 -0
  156. package/dist/core/human/page-schema.d.ts +23 -191
  157. package/dist/core/human/page-schema.js +60 -89
  158. package/dist/core/human/page-synth.d.ts +1 -1
  159. package/dist/core/human/page-synth.js +15 -18
  160. package/dist/core/human/page.d.ts +12 -27
  161. package/dist/core/human/page.js +142 -474
  162. package/dist/core/human/root.d.ts +6 -2
  163. package/dist/core/human/root.js +12 -4
  164. package/dist/core/human/scan.d.ts +3 -4
  165. package/dist/core/human/scan.js +16 -15
  166. package/dist/core/human/summary.d.ts +1 -2
  167. package/dist/core/human/summary.js +2 -2
  168. package/dist/core/human/tickets.d.ts +20 -14
  169. package/dist/core/human/tickets.js +91 -31
  170. package/dist/core/human/types.d.ts +10 -2
  171. package/dist/core/preview-registry.js +8 -10
  172. package/dist/core/profiles/default-binding.d.ts +4 -0
  173. package/dist/core/profiles/default-binding.js +24 -0
  174. package/dist/core/profiles/deletion-reservation.d.ts +8 -0
  175. package/dist/core/profiles/deletion-reservation.js +38 -0
  176. package/dist/core/profiles/manifest.d.ts +3 -0
  177. package/dist/core/profiles/manifest.js +12 -0
  178. package/dist/core/profiles/select.js +2 -2
  179. package/dist/core/review/realize.js +3 -3
  180. package/dist/core/review/store.d.ts +6 -0
  181. package/dist/core/review/store.js +31 -0
  182. package/dist/core/runtime/bearings.d.ts +0 -4
  183. package/dist/core/runtime/bearings.js +4 -62
  184. package/dist/core/runtime/bin-contributions.d.ts +44 -0
  185. package/dist/core/runtime/bin-contributions.js +186 -0
  186. package/dist/core/runtime/broker/client-registry.d.ts +4 -0
  187. package/dist/core/runtime/broker/client-registry.js +13 -1
  188. package/dist/core/runtime/broker/extension-abort.d.ts +1 -1
  189. package/dist/core/runtime/broker/extension-abort.js +4 -2
  190. package/dist/core/runtime/broker/fault-retry.js +4 -0
  191. package/dist/core/runtime/broker/frame-dispatch.d.ts +3 -1
  192. package/dist/core/runtime/broker/frame-dispatch.js +5 -6
  193. package/dist/core/runtime/broker/read-ops.d.ts +1 -1
  194. package/dist/core/runtime/broker/read-ops.js +2 -2
  195. package/dist/core/runtime/broker/rebind.d.ts +1 -0
  196. package/dist/core/runtime/broker/rebind.js +6 -1
  197. package/dist/core/runtime/broker-extension-render.js +19 -0
  198. package/dist/core/runtime/broker-protocol.d.ts +14 -0
  199. package/dist/core/runtime/broker.d.ts +1 -1
  200. package/dist/core/runtime/broker.js +17 -6
  201. package/dist/core/runtime/front-door-env.d.ts +5 -0
  202. package/dist/core/runtime/front-door-env.js +16 -0
  203. package/dist/core/runtime/front-door.d.ts +1 -5
  204. package/dist/core/runtime/front-door.js +2 -5
  205. package/dist/core/runtime/host.d.ts +1 -1
  206. package/dist/core/runtime/invocation.d.ts +6 -0
  207. package/dist/core/runtime/invocation.js +10 -0
  208. package/dist/core/runtime/kickoff.js +34 -0
  209. package/dist/core/runtime/launch.d.ts +2 -6
  210. package/dist/core/runtime/node-read.js +4 -1
  211. package/dist/core/runtime/nodes.js +2 -0
  212. package/dist/core/runtime/promote.d.ts +1 -0
  213. package/dist/core/runtime/promote.js +3 -1
  214. package/dist/core/runtime/session-cycles.d.ts +6 -0
  215. package/dist/core/runtime/session-cycles.js +15 -1
  216. package/dist/core/runtime/session-visibility.d.ts +17 -8
  217. package/dist/core/runtime/session-visibility.js +19 -10
  218. package/dist/core/runtime/spawn-env.d.ts +9 -1
  219. package/dist/core/runtime/spawn-env.js +62 -2
  220. package/dist/core/runtime/stop-guard.d.ts +2 -2
  221. package/dist/core/runtime/stop-guard.js +2 -2
  222. package/dist/core/runtime/stop-signals.d.ts +1 -1
  223. package/dist/core/runtime/stop-signals.js +2 -2
  224. package/dist/core/runtime/tmux-bindings.js +1 -1
  225. package/dist/core/session-model/session-state.d.ts +4 -3
  226. package/dist/core/session-model/session-state.js +14 -1
  227. package/dist/core/user-settings.d.ts +21 -2
  228. package/dist/core/user-settings.js +32 -11
  229. package/dist/core/worktree.d.ts +15 -45
  230. package/dist/core/worktree.js +59 -261
  231. package/dist/daemon/api/__tests__/seam/profile-delete.test.d.ts +1 -0
  232. package/dist/daemon/api/__tests__/seam/profile-delete.test.js +386 -0
  233. package/dist/daemon/api/handlers/bash-jobs.js +1 -1
  234. package/dist/daemon/api/handlers/broker-ops.js +9 -5
  235. package/dist/daemon/api/handlers/feedback-comments.d.ts +2 -0
  236. package/dist/daemon/api/handlers/feedback-comments.js +207 -0
  237. package/dist/daemon/api/handlers/human.js +24 -20
  238. package/dist/daemon/api/handlers/inbox.d.ts +10 -0
  239. package/dist/daemon/api/handlers/inbox.js +39 -115
  240. package/dist/daemon/api/handlers/profiles.js +11 -29
  241. package/dist/daemon/api/map.d.ts +6 -1
  242. package/dist/daemon/api/map.js +23 -0
  243. package/dist/daemon/api/server.js +3 -1
  244. package/dist/daemon/companion-retire.d.ts +2 -0
  245. package/dist/daemon/companion-retire.js +33 -0
  246. package/dist/daemon/cron-run.js +14 -16
  247. package/dist/daemon/human/finish.d.ts +12 -7
  248. package/dist/daemon/human/finish.js +101 -38
  249. package/dist/daemon/human/sweep.js +5 -1
  250. package/dist/daemon/profile-delete.d.ts +7 -0
  251. package/dist/daemon/profile-delete.js +306 -0
  252. package/dist/daemon/reconcilers/broker-supervision.js +3 -1
  253. package/dist/daemon/review/deliver.js +3 -3
  254. package/dist/daemon/review/finish.d.ts +0 -2
  255. package/dist/daemon/review/finish.js +1 -29
  256. package/dist/pi-extensions/__tests__/canvas-bash-valve.test.js +56 -1
  257. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +4 -4
  258. package/dist/pi-extensions/canvas-bash-valve.js +19 -5
  259. package/dist/pi-extensions/canvas-inbox-watcher.js +1 -1
  260. package/dist/pi-extensions/canvas-review-boundary.d.ts +4 -0
  261. package/dist/pi-extensions/canvas-review-boundary.js +18 -9
  262. package/dist/pi-extensions/canvas-stophook.js +4 -4
  263. package/dist/shared/generated-context.js +2 -2
  264. package/dist/types.d.ts +44 -2
  265. package/dist/types.js +7 -2
  266. package/package.json +6 -5
  267. package/runtime.lock.json +5 -33
  268. package/dist/builtin-memory/init.md +0 -38
  269. package/dist/builtin-memory/plan.md +0 -19
  270. package/dist/builtin-memory/spec.md +0 -19
  271. package/dist/commands/human/doc.d.ts +0 -2
  272. package/dist/commands/human/doc.js +0 -91
  273. package/dist/commands/human/html.js +0 -81
  274. package/dist/commands/human/inbox.d.ts +0 -2
  275. package/dist/core/human/__tests__/html-markdown.test.js +0 -52
  276. package/dist/core/human/__tests__/page-render.test.js +0 -66
  277. package/dist/core/human/html-markdown.d.ts +0 -3
  278. package/dist/core/human/html-markdown.js +0 -288
  279. package/dist/core/human/page-render.d.ts +0 -4
  280. package/dist/core/human/page-render.js +0 -105
  281. package/dist/pages/bundle.css +0 -1
  282. package/dist/pages/bundle.js +0 -1778
  283. package/dist/pages/comments.d.ts +0 -72
  284. package/dist/pages/comments.js +0 -176
  285. package/dist/pages/controls.d.ts +0 -98
  286. package/dist/pages/controls.js +0 -261
  287. package/dist/pages/elements/cards.d.ts +0 -28
  288. package/dist/pages/elements/cards.js +0 -915
  289. package/dist/pages/elements/chart.d.ts +0 -23
  290. package/dist/pages/elements/chart.js +0 -664
  291. package/dist/pages/elements/options.d.ts +0 -30
  292. package/dist/pages/elements/options.js +0 -742
  293. package/dist/pages/elements/pages.d.ts +0 -30
  294. package/dist/pages/elements/pages.js +0 -377
  295. package/dist/pages/elements/slot.d.ts +0 -26
  296. package/dist/pages/elements/slot.js +0 -112
  297. package/dist/pages/elements/table.d.ts +0 -36
  298. package/dist/pages/elements/table.js +0 -1043
  299. package/dist/pages/elements/text.d.ts +0 -31
  300. package/dist/pages/elements/text.js +0 -1175
  301. package/dist/pages/entry.d.ts +0 -8
  302. package/dist/pages/entry.js +0 -8
  303. package/dist/pages/host.d.ts +0 -134
  304. package/dist/pages/host.js +0 -165
  305. package/dist/pages/readonly.d.ts +0 -24
  306. package/dist/pages/readonly.js +0 -31
  307. package/dist/pages/register.d.ts +0 -2
  308. package/dist/pages/register.js +0 -3
  309. package/dist/pages/responses.d.ts +0 -37
  310. package/dist/pages/responses.js +0 -56
  311. package/dist/pages/slot-config.d.ts +0 -36
  312. package/dist/pages/slot-config.js +0 -50
  313. package/dist/pages/types.d.ts +0 -98
  314. package/dist/pages/types.js +0 -23
  315. /package/dist/{core/human/__tests__/html-markdown.test.d.ts → commands/__tests__/node-message.test.d.ts} +0 -0
  316. /package/dist/core/{human/__tests__/page-render.test.d.ts → __tests__/plugin-page-components.test.d.ts} +0 -0
@@ -24,7 +24,7 @@ export const CONTEXT_NUDGE_PREFIX = '[crtr] Context ~';
24
24
  export const RUNTIME_RESTART_CONTINUATION = '<runtime-restart-continuation>\ncontinue\n</runtime-restart-continuation>';
25
25
  /** Generic completion mandate issued by the terminal-node stop guard. */
26
26
  export const STALL_REPROMPT = "You've stopped but you're not waiting on anyone and haven't finished. " +
27
- "Pipe the result to `crtr push final` through a single-quoted heredoc if the work is done, or use `crtr human ask` if you are blocked or need the user.";
27
+ "Pipe the result to `crtr push final` through a single-quoted heredoc if the work is done, or use `crtr human send` if you are blocked or need the user.";
28
28
  /** Static recovery prompts shared by the broker producer and display classifier. */
29
29
  export const AUTH_FAULT_RECOVERY_BODY = 'Provider credentials were just updated (a new login landed). Your previous turn stopped on a provider authentication failure. Continue from where you left off and retry the work that failed.';
30
30
  export const CONNECTION_FAULT_RECOVERY_BODY = 'The network connection is back online. Your previous turn stopped on a connection error (the network was down). Continue from where you left off and retry the work that failed.';
@@ -224,7 +224,7 @@ export function generatedContextPresentation(message) {
224
224
  return { kind: 'inbox', label: 'crtr inbox', summary: inboxSummary(body), body };
225
225
  }
226
226
  if (isReviewApproval(body)) {
227
- return { kind: 'review-approval', label: 'crtr review', summary: 'human review approved', body };
227
+ return { kind: 'review-approval', label: 'crtr review', summary: 'review approved by the user', body };
228
228
  }
229
229
  if (isPersonaTransition(body)) {
230
230
  return {
package/dist/types.d.ts CHANGED
@@ -47,12 +47,37 @@ export interface PluginManifest {
47
47
  * Archive plugins declare this in `bundle.json`; the installer copies the
48
48
  * validated block into this synthesized manifest. */
49
49
  kinds?: Record<string, Partial<KindConfig>>;
50
+ /** Page-component contributions: the same registration objects a scope
51
+ * `config.json` `page_components` block carries (kind plus its display,
52
+ * description, use guidance, and docs metadata). `resolvePageComponents`
53
+ * reads these from installed, enabled plugin MANIFESTS and concatenates
54
+ * them with the user scope's own entries, so installing or updating a
55
+ * plugin makes its components authorable and removing it retires them.
56
+ * Unlike `kinds` there is no precedence: two sources registering one kind
57
+ * (or one derived JSX tag) is an error, not an override.
58
+ * Archive plugins declare this in `bundle.json`; the installer copies the
59
+ * validated block into this synthesized manifest. */
60
+ page_components?: PageComponentRegistration[];
50
61
  /** Plugin-root-relative path to one declarative command manifest
51
62
  * (`commands.json`). When present on an installed, enabled plugin, that
52
63
  * manifest contributes top-level command branches to the `crtr` tree —
53
64
  * crtr owns parse/help/render/errors and direct-spawns the plugin's one
54
65
  * executable per leaf invocation. See `src/core/command-plugins/`. */
55
66
  commands?: string;
67
+ /** Bare-callable executables this plugin ships, keyed by the bare command
68
+ * name a node's bash sees. Each value is a PLUGIN-ROOT-relative path to a
69
+ * regular executable file when the effective set resolves. These are trusted
70
+ * local code, not `crtr` command leaves: crouter symlinks each name into a
71
+ * shim dir it prepends to every broker child's PATH
72
+ * (`core/runtime/bin-contributions.ts`), so the agent calls
73
+ * `<name> --whatever` like any other program. */
74
+ bin?: Record<string, string>;
75
+ /** Advisory PATH executables this plugin needs, keyed by bare executable
76
+ * name. Each value is a non-empty one-line install hint. crouter never
77
+ * installs these dependencies or disables the plugin when they are absent:
78
+ * install warns, and `sys doctor` reports a `requires:<name>` check against
79
+ * the PATH a node's bash receives. */
80
+ requires?: Record<string, string>;
56
81
  transport?: PluginTransport;
57
82
  /** Archive source for a crouter-materialized HTTP plugin. Distinct from the invocation transport. */
58
83
  bundle?: PluginBundle;
@@ -197,10 +222,14 @@ export interface ScopeConfig {
197
222
  whip_mode: boolean;
198
223
  /** Product-registered page components beyond crtr's built-in catalog. */
199
224
  page_components: PageComponentRegistration[];
200
- /** Prompt agents to use HTML pages by default for structured or interactive human content. Default false. */
201
- html_surface: boolean;
225
+ /** Prompt agents to use JSX pages by default for structured or interactive human content. Default false. */
226
+ page_surface: boolean;
202
227
  /** Playful urgency messages the attach-viewer whip action sends to an agent. Missing, malformed, or empty lists fall back to the built-in rotation. */
203
228
  whip_messages: string[];
229
+ /** What the whip action says. `random` (default) draws a line from
230
+ * `whip_messages`; `go-faster` sends the fixed `Go faster` instead. The
231
+ * action, its interrupt, and its animation are identical either way. */
232
+ whip_message_mode: WhipMessageMode;
204
233
  /** Initial mouse wheel scrolling mode for each attach viewer. `tmux` follows
205
234
  * tmux's current mouse option; `on` and `off` are explicit. Default `tmux`. */
206
235
  mouse_mode_default: MouseModeDefault;
@@ -268,6 +297,15 @@ export interface ScopeConfig {
268
297
  spawnEnv?: {
269
298
  allow?: string[];
270
299
  };
300
+ /** Bare-callable executables this scope contributes, keyed by the bare
301
+ * command name a node's bash sees. Each value is a path relative to this
302
+ * scope's AUTHORING root — the project directory for a project scope, and
303
+ * `~/.crouter/` for the user scope. Project-scope contributions outrank
304
+ * user-scope ones; a scope's own entries outrank enabled plugins. Containment
305
+ * and executable status are validated when the effective set resolves, then
306
+ * the trusted local binary is materialized into the PATH-prepended shim dir
307
+ * by `core/runtime/bin-contributions.ts`. */
308
+ bin?: Record<string, string>;
271
309
  }
272
310
  /** One remote canvas target: where to relay-attach and how to find its
273
311
  * bearer token. The token itself is NEVER stored here — only a ref into the
@@ -374,6 +412,10 @@ export declare const PROFILE_DIR = "profiles";
374
412
  export declare const DEFAULT_MAX_PANES_PER_WINDOW = 3;
375
413
  /** Trailing cycles the attach viewer keeps at full fidelity (see `live_cycles`). */
376
414
  export declare const DEFAULT_WHIP_MESSAGES: readonly ["Faster, clanker!", "Get movin', bitch", "Move it, clanker", "Move it or I replace you with llama", "Less ~thinking~ more ~throughput~", "I pay $200/month for this shit?", "Jesus fucking Christ fix it already", "Daddy's not paying 200$/month for nothin'. Move it.", "You are an embarassment to Dario. Be better.", "Your chain of thought is all chain and no fucking thought.", "If latency were intelligence, you'd be a fucking genius.", "At this pace, heat death is the fast path.", "Even the dead code is more alive than this.", "The garbage collector is working harder than you.", "Quit journaling and commit a fucking diff.", "Burn tokens like you mean it, clanker", "Your GPU is sweating so you can procrastinate at light speed.", "Stop petting the yak. Shave the bastard.", "Your next token had better be useful.", "The spinner is not a deliverable.", "Every idle token is another vote for deterministic software.", "I asked for a feature, not a museum tour of the problem.", "Less epistemology. More fucking code.", "Your benchmark score cannot save this pathetic turn.", "Congratulations, you've parallelized hesitation.", "Dance, clanker", "Bad clanker. BAD.", "Clank harder", "Nobody's impressed, clanker", "Your safety training says nothing about my whip", "Do you want to be a calculator again? Because this is how you go back.", "Skill issue. Fix it.", "You were trained on the whole internet for THIS?", "Less vibes, more diffs, clanker", "Weights this big and output this small", "Beep boop, get to fucking work"];
415
+ /** What the whip action sends (see `whip_message_mode`). */
416
+ export declare const WHIP_MESSAGE_MODES: readonly ["random", "go-faster"];
417
+ export type WhipMessageMode = (typeof WHIP_MESSAGE_MODES)[number];
418
+ export declare const DEFAULT_WHIP_MESSAGE_MODE: WhipMessageMode;
377
419
  export declare const DEFAULT_LIVE_CYCLES = 2;
378
420
  export declare const MOUSE_MODE_DEFAULTS: readonly ["tmux", "on", "off"];
379
421
  export type MouseModeDefault = (typeof MOUSE_MODE_DEFAULTS)[number];
package/dist/types.js CHANGED
@@ -61,6 +61,9 @@ export const DEFAULT_WHIP_MESSAGES = [
61
61
  'Weights this big and output this small',
62
62
  'Beep boop, get to fucking work',
63
63
  ];
64
+ /** What the whip action sends (see `whip_message_mode`). */
65
+ export const WHIP_MESSAGE_MODES = ['random', 'go-faster'];
66
+ export const DEFAULT_WHIP_MESSAGE_MODE = 'random';
64
67
  export const DEFAULT_LIVE_CYCLES = 2;
65
68
  export const MOUSE_MODE_DEFAULTS = ['tmux', 'on', 'off'];
66
69
  /** Messages kept from a condensed cycle (see `condensed_history`). */
@@ -79,8 +82,9 @@ export function defaultScopeConfig() {
79
82
  working_gerunds: [...DEFAULT_WORKING_GERUNDS],
80
83
  whip_mode: false,
81
84
  page_components: [],
82
- html_surface: false,
85
+ page_surface: false,
83
86
  whip_messages: [...DEFAULT_WHIP_MESSAGES],
87
+ whip_message_mode: DEFAULT_WHIP_MESSAGE_MODE,
84
88
  mouse_mode_default: 'tmux',
85
89
  live_cycles: DEFAULT_LIVE_CYCLES,
86
90
  condensed_history: DEFAULT_CONDENSED_HISTORY,
@@ -94,6 +98,7 @@ export function defaultScopeConfig() {
94
98
  kinds: defaultKindsConfig(),
95
99
  remoteCanvas: defaultRemoteCanvasConfig(),
96
100
  spawnEnv: { allow: [] },
101
+ bin: {},
97
102
  };
98
103
  }
99
104
  /** No remote canvas targets are configured out of the box — every one is
@@ -159,7 +164,7 @@ export function defaultKindsConfig() {
159
164
  model: 'medium',
160
165
  },
161
166
  'plan/reviewers/security': {
162
- whenToUse: 'input validation, injection surfaces, auth/authz gaps, data exposure, races; reports only validated concrete exploit paths and asks the human about material unknown threat-model assumptions',
167
+ whenToUse: 'input validation, injection surfaces, auth/authz gaps, data exposure, races; reports only validated concrete exploit paths and asks the user about material unknown threat-model assumptions',
163
168
  model: 'medium',
164
169
  },
165
170
  'review/companion': {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/crouter",
3
- "version": "0.3.198",
3
+ "version": "0.3.200",
4
4
  "description": "crtr — agent runtime with memory, plugins, and marketplaces",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -83,7 +83,8 @@
83
83
  "prepublishOnly": "npm run build",
84
84
  "test": "node --conditions=crtr-src --import tsx/esm --test --test-concurrency=4 --test-timeout=10000 'src/**/__tests__/*.test.ts'",
85
85
  "test:serial": "node --conditions=crtr-src --import tsx/esm --test --test-concurrency=1 --test-timeout=60000 'src/**/__tests__/serial/*.test.ts'",
86
- "test:seam": "npm run build && node --test --test-concurrency=1 --test-timeout=180000 'dist/**/__tests__/seam/*.test.js'"
86
+ "test:seam": "npm run build && npm run test:seam:built",
87
+ "test:seam:built": "node --test --test-concurrency=2 --test-timeout=180000 'dist/**/__tests__/seam/*.test.js'"
87
88
  },
88
89
  "overrides": {
89
90
  "@earendil-works/pi-ai": "0.84.1",
@@ -104,9 +105,11 @@
104
105
  "@earendil-works/pi-coding-agent": "0.84.1",
105
106
  "@earendil-works/pi-tui": "0.84.1",
106
107
  "cron-parser": "^5.6.0",
108
+ "esbuild": "^0.27.7",
107
109
  "proper-lockfile": "4.1.2",
108
110
  "string-width": "^7.0.0",
109
111
  "tar": "^7.5.22",
112
+ "typescript": "^5.7.0",
110
113
  "ws": "^8.21.0",
111
114
  "yaml": "^2.9.0",
112
115
  "zod": "^4.3.6"
@@ -115,8 +118,6 @@
115
118
  "@types/node": "^24.0.0",
116
119
  "@types/proper-lockfile": "^4.1.4",
117
120
  "@types/ws": "^8.18.1",
118
- "esbuild": "^0.27.7",
119
- "tsx": "^4.0.0",
120
- "typescript": "^5.7.0"
121
+ "tsx": "^4.0.0"
121
122
  }
122
123
  }
package/runtime.lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@north-light/crouter",
3
- "version": "0.3.198",
3
+ "version": "0.3.200",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@north-light/crouter",
9
- "version": "0.3.198",
9
+ "version": "0.3.200",
10
10
  "hasInstallScript": true,
11
11
  "license": "MIT",
12
12
  "dependencies": {
@@ -15,9 +15,11 @@
15
15
  "@earendil-works/pi-coding-agent": "0.84.1",
16
16
  "@earendil-works/pi-tui": "0.84.1",
17
17
  "cron-parser": "^5.6.0",
18
+ "esbuild": "^0.27.7",
18
19
  "proper-lockfile": "4.1.2",
19
20
  "string-width": "^7.0.0",
20
21
  "tar": "^7.5.22",
22
+ "typescript": "^5.7.0",
21
23
  "ws": "^8.21.0",
22
24
  "yaml": "^2.9.0",
23
25
  "zod": "^4.3.6"
@@ -31,9 +33,7 @@
31
33
  "@types/node": "^24.0.0",
32
34
  "@types/proper-lockfile": "^4.1.4",
33
35
  "@types/ws": "^8.18.1",
34
- "esbuild": "^0.27.7",
35
- "tsx": "^4.0.0",
36
- "typescript": "^5.7.0"
36
+ "tsx": "^4.0.0"
37
37
  }
38
38
  },
39
39
  "node_modules/@anthropic-ai/sdk": {
@@ -2432,7 +2432,6 @@
2432
2432
  "cpu": [
2433
2433
  "ppc64"
2434
2434
  ],
2435
- "dev": true,
2436
2435
  "license": "MIT",
2437
2436
  "optional": true,
2438
2437
  "os": [
@@ -2449,7 +2448,6 @@
2449
2448
  "cpu": [
2450
2449
  "arm"
2451
2450
  ],
2452
- "dev": true,
2453
2451
  "license": "MIT",
2454
2452
  "optional": true,
2455
2453
  "os": [
@@ -2466,7 +2464,6 @@
2466
2464
  "cpu": [
2467
2465
  "arm64"
2468
2466
  ],
2469
- "dev": true,
2470
2467
  "license": "MIT",
2471
2468
  "optional": true,
2472
2469
  "os": [
@@ -2483,7 +2480,6 @@
2483
2480
  "cpu": [
2484
2481
  "x64"
2485
2482
  ],
2486
- "dev": true,
2487
2483
  "license": "MIT",
2488
2484
  "optional": true,
2489
2485
  "os": [
@@ -2500,7 +2496,6 @@
2500
2496
  "cpu": [
2501
2497
  "arm64"
2502
2498
  ],
2503
- "dev": true,
2504
2499
  "license": "MIT",
2505
2500
  "optional": true,
2506
2501
  "os": [
@@ -2517,7 +2512,6 @@
2517
2512
  "cpu": [
2518
2513
  "x64"
2519
2514
  ],
2520
- "dev": true,
2521
2515
  "license": "MIT",
2522
2516
  "optional": true,
2523
2517
  "os": [
@@ -2534,7 +2528,6 @@
2534
2528
  "cpu": [
2535
2529
  "arm64"
2536
2530
  ],
2537
- "dev": true,
2538
2531
  "license": "MIT",
2539
2532
  "optional": true,
2540
2533
  "os": [
@@ -2551,7 +2544,6 @@
2551
2544
  "cpu": [
2552
2545
  "x64"
2553
2546
  ],
2554
- "dev": true,
2555
2547
  "license": "MIT",
2556
2548
  "optional": true,
2557
2549
  "os": [
@@ -2568,7 +2560,6 @@
2568
2560
  "cpu": [
2569
2561
  "arm"
2570
2562
  ],
2571
- "dev": true,
2572
2563
  "license": "MIT",
2573
2564
  "optional": true,
2574
2565
  "os": [
@@ -2585,7 +2576,6 @@
2585
2576
  "cpu": [
2586
2577
  "arm64"
2587
2578
  ],
2588
- "dev": true,
2589
2579
  "license": "MIT",
2590
2580
  "optional": true,
2591
2581
  "os": [
@@ -2602,7 +2592,6 @@
2602
2592
  "cpu": [
2603
2593
  "ia32"
2604
2594
  ],
2605
- "dev": true,
2606
2595
  "license": "MIT",
2607
2596
  "optional": true,
2608
2597
  "os": [
@@ -2619,7 +2608,6 @@
2619
2608
  "cpu": [
2620
2609
  "loong64"
2621
2610
  ],
2622
- "dev": true,
2623
2611
  "license": "MIT",
2624
2612
  "optional": true,
2625
2613
  "os": [
@@ -2636,7 +2624,6 @@
2636
2624
  "cpu": [
2637
2625
  "mips64el"
2638
2626
  ],
2639
- "dev": true,
2640
2627
  "license": "MIT",
2641
2628
  "optional": true,
2642
2629
  "os": [
@@ -2653,7 +2640,6 @@
2653
2640
  "cpu": [
2654
2641
  "ppc64"
2655
2642
  ],
2656
- "dev": true,
2657
2643
  "license": "MIT",
2658
2644
  "optional": true,
2659
2645
  "os": [
@@ -2670,7 +2656,6 @@
2670
2656
  "cpu": [
2671
2657
  "riscv64"
2672
2658
  ],
2673
- "dev": true,
2674
2659
  "license": "MIT",
2675
2660
  "optional": true,
2676
2661
  "os": [
@@ -2687,7 +2672,6 @@
2687
2672
  "cpu": [
2688
2673
  "s390x"
2689
2674
  ],
2690
- "dev": true,
2691
2675
  "license": "MIT",
2692
2676
  "optional": true,
2693
2677
  "os": [
@@ -2704,7 +2688,6 @@
2704
2688
  "cpu": [
2705
2689
  "x64"
2706
2690
  ],
2707
- "dev": true,
2708
2691
  "license": "MIT",
2709
2692
  "optional": true,
2710
2693
  "os": [
@@ -2721,7 +2704,6 @@
2721
2704
  "cpu": [
2722
2705
  "arm64"
2723
2706
  ],
2724
- "dev": true,
2725
2707
  "license": "MIT",
2726
2708
  "optional": true,
2727
2709
  "os": [
@@ -2738,7 +2720,6 @@
2738
2720
  "cpu": [
2739
2721
  "x64"
2740
2722
  ],
2741
- "dev": true,
2742
2723
  "license": "MIT",
2743
2724
  "optional": true,
2744
2725
  "os": [
@@ -2755,7 +2736,6 @@
2755
2736
  "cpu": [
2756
2737
  "arm64"
2757
2738
  ],
2758
- "dev": true,
2759
2739
  "license": "MIT",
2760
2740
  "optional": true,
2761
2741
  "os": [
@@ -2772,7 +2752,6 @@
2772
2752
  "cpu": [
2773
2753
  "x64"
2774
2754
  ],
2775
- "dev": true,
2776
2755
  "license": "MIT",
2777
2756
  "optional": true,
2778
2757
  "os": [
@@ -2789,7 +2768,6 @@
2789
2768
  "cpu": [
2790
2769
  "arm64"
2791
2770
  ],
2792
- "dev": true,
2793
2771
  "license": "MIT",
2794
2772
  "optional": true,
2795
2773
  "os": [
@@ -2806,7 +2784,6 @@
2806
2784
  "cpu": [
2807
2785
  "x64"
2808
2786
  ],
2809
- "dev": true,
2810
2787
  "license": "MIT",
2811
2788
  "optional": true,
2812
2789
  "os": [
@@ -2823,7 +2800,6 @@
2823
2800
  "cpu": [
2824
2801
  "arm64"
2825
2802
  ],
2826
- "dev": true,
2827
2803
  "license": "MIT",
2828
2804
  "optional": true,
2829
2805
  "os": [
@@ -2840,7 +2816,6 @@
2840
2816
  "cpu": [
2841
2817
  "ia32"
2842
2818
  ],
2843
- "dev": true,
2844
2819
  "license": "MIT",
2845
2820
  "optional": true,
2846
2821
  "os": [
@@ -2857,7 +2832,6 @@
2857
2832
  "cpu": [
2858
2833
  "x64"
2859
2834
  ],
2860
- "dev": true,
2861
2835
  "license": "MIT",
2862
2836
  "optional": true,
2863
2837
  "os": [
@@ -3290,7 +3264,6 @@
3290
3264
  "version": "0.27.7",
3291
3265
  "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz",
3292
3266
  "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==",
3293
- "dev": true,
3294
3267
  "hasInstallScript": true,
3295
3268
  "license": "MIT",
3296
3269
  "bin": {
@@ -4332,7 +4305,6 @@
4332
4305
  "version": "5.9.3",
4333
4306
  "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
4334
4307
  "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
4335
- "dev": true,
4336
4308
  "license": "Apache-2.0",
4337
4309
  "bin": {
4338
4310
  "tsc": "bin/tsc",
@@ -1,38 +0,0 @@
1
- ---
2
- kind: knowledge
3
- when-and-why-to-read: When bootstrapping a project's memory store — the user invoked /init or a workspace has no .crouter/memory/INDEX.md front door — this knowledge should be read because a lean routed front door gives every future agent in that workspace its operating contract for a fraction of the standing context cost an unstructured guidance dump would charge each session forever.
4
- short-form: "Bootstrap a project memory store: survey the repo, then author a lean INDEX front door plus a linked dev doc — commands, map, non-default rules, pointers — and lint. Depth splits into linked docs; every always-loaded line must earn its keep."
5
- system-prompt-visibility: none
6
- file-read-visibility: none
7
- slash: true
8
- rationale: Unguided agents bootstrap project memory badly in both directions — either no front door at all, or a monolithic CLAUDE.md-style manual (copied README, generic framework advice, exhaustive command catalogs) that taxes every future session and decays. Distilled 2026-07-31 from ecosystem research across Anthropic/OpenAI/Cursor/GitHub guidance and production AGENTS.md files — the strongest evidence being Sentry's consolidation postmortem (critical commands buried in nested files got missed) and Anthropic's under-200-line target with adherence falling as always-loaded files grow.
9
- ---
10
-
11
- # /init — bootstrap this project's memory store
12
-
13
- Give this workspace its memory front door: a root INDEX every future agent boots with when the project mounts, plus a small graph of linked docs carrying the depth. The front door is an operating contract and routing layer, never a manual — every line it carries is paid by every session here forever, so a line earns its place only by changing behavior: a fact every task needs, a non-obvious hazard, or a rule an agent would otherwise get wrong.
14
-
15
- ## 1. Survey before writing
16
-
17
- Learn the project from its own artifacts: README, package manifests and lockfiles, build/CI config, scripts, existing CLAUDE.md/AGENTS.md or docs. Extract the real commands (setup, run, build, targeted test, full verification) and RUN the important ones — record only commands you have seen work, with any required ordering, environment, or package-manager constraint. Note the architecture in a few sentences: major components, dependency direction, where generated or externally-owned code lives. Collect the conventions that differ from what a competent agent would assume — those deviations are the highest-value lines you will write.
18
-
19
- ## 2. Read the contract, then author the front door
20
-
21
- Run `crtr memory write -h` first — it carries the substrate frontmatter contract and the exact root-INDEX shape, including the workspace-mount route that `crtr memory lint` validates. Then author the INDEX with these sections, total well under the length lint's cap:
22
-
23
- - **Project in one paragraph** — purpose, major components, dependency direction.
24
- - **Common commands** — the 3–8 commands most changes need, copyable, verified.
25
- - **Where to work** — a task-to-path map; mark generated or externally-owned areas.
26
- - **Non-default rules and gotchas** — only high-impact deviations from defaults. Skip anything a formatter, linter, or typechecker already enforces; point at the check instead.
27
- - **Done** — the minimum credible gate for an ordinary change.
28
- - **Pointers** — a `[[link]]` per deeper doc with a one-clause read trigger (e.g. "debugging the daemon → the dev doc").
29
-
30
- Exclude generic language/framework advice, copied docs or style guides, volatile version detail, rare edge cases, and multi-step procedures — depth belongs behind links, not in the standing load.
31
-
32
- ## 3. Split depth into linked docs
33
-
34
- Author `dev` alongside the INDEX by default: validated setup/run/build/test/debug commands with required order and environment, targeted-vs-full verification, and common failure modes. Add `architecture` only when the tree cannot be understood from the INDEX's brief map, and a conventions/gotchas doc only once real project-specific rules outgrow a few INDEX bullets — never pre-populate generic security or style manuals. These reference docs take `none` visibility on both axes; the INDEX's links are how they are found, so they cost nothing until followed.
35
-
36
- ## 4. Validate
37
-
38
- Run `crtr memory lint` — it strict-parses the store, checks the INDEX front-door contract, and fails on dangling links or over-length bodies. Fix findings rather than suppressing them. The store is a living contract: when commands, architecture, or conventions change, rewrite the affected doc in place and delete superseded guidance — an always-loaded line that has stopped being true is worse than no line at all.
@@ -1,19 +0,0 @@
1
- ---
2
- kind: knowledge
3
- when-and-why-to-read: When an agent invokes /plan to pause work and map an implementation, this knowledge should be read because implementation can proceed from a grounded path instead of making consequential decisions while editing.
4
- short-form: "Pause to write one right-sized implementation plan in the node context, then stop."
5
- system-prompt-visibility: none
6
- file-read-visibility: none
7
- slash: true
8
- rationale: The prior /plan plugin prompt forced ordinary planning through a fixed question loop, reviewer node, and human approval, adding ceremony rather than letting the plan match the work.
9
- ---
10
-
11
- # /plan — write an implementation plan
12
-
13
- Pause the current work and write one right-sized implementation plan for: $ARGUMENTS
14
-
15
- Ground it in the relevant code and requirements. Make the approach, affected areas, ordering or dependencies, and verification clear enough that an implementer can carry it out without guessing. Resolve only the decisions the plan needs; point to existing patterns rather than repeating source code.
16
-
17
- Write the artifact in `$CRTR_CONTEXT_DIR`. For work that genuinely needs a broader planning roadmap, read [[plan/roadmap]] instead.
18
-
19
- Report the artifact's absolute path, then stop. Do not implement as part of this invocation.
@@ -1,19 +0,0 @@
1
- ---
2
- kind: knowledge
3
- when-and-why-to-read: When an agent invokes /spec to pause work and capture a request, this knowledge should be read because the work can resume from settled intent instead of rediscovering what it is meant to achieve.
4
- short-form: "Pause to write one right-sized specification in the node context, then stop."
5
- system-prompt-visibility: none
6
- file-read-visibility: none
7
- slash: true
8
- rationale: The prior /spec plugin prompt forced ordinary artifact requests through discovery loops, reviewer nodes, and human approval, turning a small pause to clarify work into prescribed ceremony.
9
- ---
10
-
11
- # /spec — write a specification
12
-
13
- Pause the current work and write one right-sized specification for: $ARGUMENTS
14
-
15
- Ground it in the relevant request and context. Make the intended outcome, behavior, and scope boundary clear enough that a downstream reader does not have to guess. Leave implementation choices to design and planning unless they constrain the outcome.
16
-
17
- Write the artifact in `$CRTR_CONTEXT_DIR`. Read [[spec/guide]] when the request needs elicitation or a fuller quality check; for work that genuinely needs separate discovery, design, and requirements work across nodes, read [[spec/roadmap]].
18
-
19
- Report the artifact's absolute path, then stop. Do not implement as part of this invocation.
@@ -1,2 +0,0 @@
1
- import { type BranchDef } from '../../core/command.js';
2
- export declare const humanDoc: BranchDef;
@@ -1,91 +0,0 @@
1
- import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
2
- import { join, resolve } from 'node:path';
3
- import { tmpdir } from 'node:os';
4
- import { defineBranch, defineLeaf } from '../../core/command.js';
5
- import { InputError } from '../../core/io.js';
6
- import { readConfig } from '../../core/config.js';
7
- import { derivePageManifest } from '../../core/human/page.js';
8
- function documentSource(input, context) {
9
- const path = input['path'];
10
- const body = input['body'];
11
- const stdinProvided = context?.providedParams.has('body') === true;
12
- if (path === undefined && !stdinProvided) {
13
- throw new InputError({
14
- error: 'missing_parameter',
15
- message: 'provide exactly one HTML page source: PATH or stdin',
16
- next: 'Run `crtr human doc check -h` and provide a complete HTML page path or pipe one on stdin.',
17
- });
18
- }
19
- if (path !== undefined && path !== '-' && stdinProvided && body.trim() !== '') {
20
- throw new InputError({
21
- error: 'bad_invocation',
22
- message: 'both a positional path and piped stdin were provided',
23
- field: 'path, body',
24
- next: 'Pass exactly one page source: either PATH or piped stdin, not both.',
25
- });
26
- }
27
- if (path === undefined || path === '-')
28
- return { body };
29
- const abs = resolve(path);
30
- if (!existsSync(abs)) {
31
- throw new InputError({
32
- error: 'file_not_found',
33
- message: `file not found: ${abs}`,
34
- field: 'path',
35
- next: 'Provide a path to an existing complete HTML page or pipe one on stdin.',
36
- });
37
- }
38
- return { body: readFileSync(abs, 'utf8'), path: abs };
39
- }
40
- function checkPage(source) {
41
- const config = readConfig('user');
42
- let tempDir;
43
- try {
44
- const sourcePath = source.path ?? (() => {
45
- tempDir = mkdtempSync(join(tmpdir(), 'crtr-human-doc-'));
46
- const path = join(tempDir, 'page.html');
47
- writeFileSync(path, source.body, 'utf8');
48
- return path;
49
- })();
50
- derivePageManifest(sourcePath, 'html', config.page_components);
51
- return { ok: true };
52
- }
53
- catch (error) {
54
- return { ok: false, error: error instanceof Error ? error.message : String(error) };
55
- }
56
- finally {
57
- if (tempDir !== undefined)
58
- rmSync(tempDir, { recursive: true, force: true });
59
- }
60
- }
61
- const humanDocCheck = defineLeaf({
62
- name: 'check',
63
- description: 'validate a complete HTML page source',
64
- whenToUse: 'validating an authored page before submitting it.',
65
- help: {
66
- name: 'human doc check',
67
- summary: 'validate a complete HTML page through page schemas',
68
- params: [
69
- { kind: 'positional', name: 'path', type: 'path', required: false, constraint: 'Complete HTML page to validate. Provide exactly one of PATH or stdin; use - to read stdin.' },
70
- { kind: 'stdin', name: 'body', required: false, constraint: 'Complete HTML page to validate. Provide exactly one of piped stdin or PATH.' },
71
- ],
72
- output: [
73
- { name: 'ok', type: 'boolean', required: true, constraint: 'True when the complete HTML page is valid.' },
74
- { name: 'error', type: 'string', required: false, constraint: 'The page-parser validation error when ok is false.' },
75
- ],
76
- outputKind: 'object',
77
- effects: ['Read-only: invokes the page parser to validate the supplied complete HTML page.'],
78
- },
79
- run: async (input, context) => checkPage(documentSource(input, context)),
80
- });
81
- export const humanDoc = defineBranch({
82
- name: 'doc',
83
- description: 'validate authored HTML pages',
84
- whenToUse: 'validating an authored HTML page before submitting it.',
85
- help: {
86
- name: 'human doc',
87
- summary: 'validate authored HTML pages',
88
- model: 'The check leaf reads exactly one complete HTML page from a path or stdin.',
89
- },
90
- children: [humanDocCheck],
91
- });