@north-light/crouter 0.3.170 → 0.3.172

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 (670) hide show
  1. package/dist/api/client.d.ts +37 -11
  2. package/dist/api/client.js +84 -15
  3. package/dist/api/dto/human.d.ts +53 -39
  4. package/dist/api/dto/human.js +2 -3
  5. package/dist/api/dto/inbox.d.ts +0 -1
  6. package/dist/api/dto/nodes.d.ts +12 -0
  7. package/dist/api/dto/review-comments.d.ts +137 -0
  8. package/dist/api/dto/review-comments.js +5 -0
  9. package/dist/api/dto/reviews.d.ts +109 -0
  10. package/dist/api/dto/reviews.js +5 -0
  11. package/dist/api/index.d.ts +2 -0
  12. package/dist/api/index.js +2 -0
  13. package/dist/api/routes.d.ts +17 -4
  14. package/dist/api/routes.js +21 -5
  15. package/dist/build-root.d.ts +1 -16
  16. package/dist/build-root.js +1 -25
  17. package/dist/builtin-memory/00-runtime-base.md +7 -5
  18. package/dist/builtin-memory/04-base-worker.md +1 -1
  19. package/dist/builtin-memory/04-orchestration-kernel.md +7 -7
  20. package/dist/builtin-memory/05-kinds/design/00-base.md +1 -1
  21. package/dist/builtin-memory/05-kinds/design/01-orchestrator.md +1 -1
  22. package/dist/builtin-memory/05-kinds/developer/00-base.md +1 -1
  23. package/dist/builtin-memory/05-kinds/explore/00-base.md +1 -1
  24. package/dist/builtin-memory/05-kinds/plan/00-base.md +1 -1
  25. package/dist/builtin-memory/05-kinds/plan/01-orchestrator.md +1 -1
  26. package/dist/builtin-memory/05-kinds/review/00-base.md +1 -1
  27. package/dist/builtin-memory/05-kinds/review/companion/00-base.md +20 -0
  28. package/dist/builtin-memory/05-kinds/spec/00-base.md +3 -7
  29. package/dist/builtin-memory/05-kinds/spec/01-orchestrator.md +3 -3
  30. package/dist/builtin-memory/05-kinds/spec/requirements.md +3 -3
  31. package/dist/builtin-memory/design.md +2 -2
  32. package/dist/builtin-memory/insights/capture.md +50 -0
  33. package/dist/builtin-memory/insights/init.md +45 -0
  34. package/dist/builtin-memory/insights/listen.md +9 -0
  35. package/dist/builtin-memory/internal/agent-shaping.md +2 -2
  36. package/dist/builtin-memory/internal/nodes-and-canvas.md +1 -1
  37. package/dist/builtin-memory/internal/plugins.md +12 -11
  38. package/dist/builtin-memory/internal/storage-tiers.md +2 -2
  39. package/dist/builtin-memory/{planning.md → plan/roadmap.md} +3 -3
  40. package/dist/builtin-memory/plan.md +19 -0
  41. package/dist/builtin-memory/spec/guide.md +38 -0
  42. package/dist/builtin-memory/spec/requirements.md +31 -0
  43. package/dist/builtin-memory/spec/roadmap.md +35 -0
  44. package/dist/builtin-memory/spec.md +10 -86
  45. package/dist/builtin-pi-packages/pi-crtr-extensions/README.md +3 -4
  46. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/provider-rotation.test.ts +49 -5
  47. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +56 -0
  48. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +920 -0
  49. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +221 -156
  50. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/statusline.ts +4 -5
  51. package/dist/cli.js +2 -6
  52. package/dist/clients/attach/__tests__/attach-chrome-remote.test.js +7 -35
  53. package/dist/clients/attach/__tests__/attach-keybindings.test.js +32 -16
  54. package/dist/clients/attach/__tests__/context-message.test.js +142 -6
  55. package/dist/clients/attach/__tests__/crtr-output.test.js +29 -45
  56. package/dist/clients/attach/__tests__/diagram.test.js +1 -1
  57. package/dist/clients/attach/__tests__/file-review-focus.test.js +48 -0
  58. package/dist/clients/attach/__tests__/group-activity.test.js +266 -0
  59. package/dist/clients/attach/__tests__/input-controller-extension-command.test.js +32 -0
  60. package/dist/clients/attach/__tests__/session-identity-refresh.test.js +32 -0
  61. package/dist/clients/attach/__tests__/titled-editor-preview.test.js +1 -2
  62. package/dist/clients/attach/chrome/header.d.ts +10 -0
  63. package/dist/clients/attach/chrome/header.js +30 -0
  64. package/dist/clients/attach/chrome/recap.d.ts +7 -0
  65. package/dist/clients/attach/chrome/recap.js +19 -0
  66. package/dist/clients/attach/chrome/status-line.d.ts +3 -0
  67. package/dist/clients/attach/chrome/status-line.js +5 -0
  68. package/dist/clients/attach/chrome/widgets.js +11 -21
  69. package/dist/clients/attach/command.js +11 -7
  70. package/dist/clients/attach/config.d.ts +4 -0
  71. package/dist/clients/attach/config.js +3 -0
  72. package/dist/clients/attach/input/controller.d.ts +19 -0
  73. package/dist/clients/attach/input/controller.js +62 -28
  74. package/dist/clients/attach/input/titled-editor.d.ts +0 -4
  75. package/dist/clients/attach/input/titled-editor.js +2 -10
  76. package/dist/clients/attach/overlays/file-review.d.ts +9 -5
  77. package/dist/clients/attach/overlays/file-review.js +9 -70
  78. package/dist/clients/attach/overlays/help.d.ts +33 -0
  79. package/dist/clients/attach/overlays/help.js +204 -0
  80. package/dist/clients/attach/render/activity-slot.d.ts +4 -0
  81. package/dist/clients/attach/render/activity-slot.js +13 -0
  82. package/dist/clients/attach/render/chat-view.d.ts +117 -12
  83. package/dist/clients/attach/render/chat-view.js +604 -135
  84. package/dist/clients/attach/render/context-message.d.ts +2 -1
  85. package/dist/clients/attach/render/context-message.js +17 -13
  86. package/dist/clients/attach/render/crtr-output.js +1 -3
  87. package/dist/clients/attach/render/diagram.js +2 -2
  88. package/dist/clients/attach/render/edit-diff.d.ts +4 -1
  89. package/dist/clients/attach/render/edit-diff.js +7 -11
  90. package/dist/clients/attach/render/group-activity.d.ts +32 -0
  91. package/dist/clients/attach/render/group-activity.js +206 -0
  92. package/dist/clients/attach/render/group-recap.d.ts +10 -0
  93. package/dist/clients/attach/render/group-recap.js +93 -0
  94. package/dist/clients/attach/render/html-markdown.d.ts +17 -0
  95. package/dist/clients/attach/render/html-markdown.js +228 -0
  96. package/dist/clients/attach/render/measured-container.d.ts +96 -0
  97. package/dist/clients/attach/render/measured-container.js +322 -0
  98. package/dist/clients/attach/render/scroll-animation.d.ts +8 -0
  99. package/dist/clients/attach/render/scroll-animation.js +80 -0
  100. package/dist/clients/attach/render/tool-calls.js +6 -6
  101. package/dist/clients/attach/render/transcript-copy.d.ts +9 -0
  102. package/dist/clients/attach/render/transcript-copy.js +81 -0
  103. package/dist/clients/attach/render/viewport.d.ts +29 -0
  104. package/dist/clients/attach/render/viewport.js +159 -0
  105. package/dist/clients/attach/session/bindings.d.ts +10 -7
  106. package/dist/clients/attach/session/bindings.js +23 -8
  107. package/dist/clients/attach/session/connection.js +4 -5
  108. package/dist/clients/attach/session/context.d.ts +6 -4
  109. package/dist/clients/attach/session/frame.d.ts +34 -0
  110. package/dist/clients/attach/session/frame.js +176 -0
  111. package/dist/clients/attach/session/frames.d.ts +4 -1
  112. package/dist/clients/attach/session/frames.js +14 -1
  113. package/dist/clients/attach/session/identity.js +4 -3
  114. package/dist/clients/attach/session/input-wiring.d.ts +14 -4
  115. package/dist/clients/attach/session/input-wiring.js +15 -13
  116. package/dist/clients/attach/session/invariant.d.ts +9 -0
  117. package/dist/clients/attach/session/invariant.js +15 -0
  118. package/dist/clients/attach/session/keys.d.ts +10 -2
  119. package/dist/clients/attach/session/keys.js +13 -5
  120. package/dist/clients/attach/session/layout.d.ts +10 -8
  121. package/dist/clients/attach/session/layout.js +33 -34
  122. package/dist/clients/attach/session/mouse.d.ts +18 -0
  123. package/dist/clients/attach/session/mouse.js +64 -0
  124. package/dist/clients/attach/session/pane-tag.d.ts +3 -0
  125. package/dist/clients/attach/session/pane-tag.js +51 -8
  126. package/dist/clients/attach/session/reconnect.d.ts +3 -0
  127. package/dist/clients/attach/session/reconnect.js +42 -5
  128. package/dist/clients/attach/session/surface-frame.d.ts +20 -0
  129. package/dist/clients/attach/session/surface-frame.js +73 -0
  130. package/dist/clients/attach/session/surface-host.d.ts +64 -0
  131. package/dist/clients/attach/session/surface-host.js +255 -0
  132. package/dist/clients/attach/session/whip.d.ts +17 -0
  133. package/dist/clients/attach/session/whip.js +334 -0
  134. package/dist/clients/attach/slash/dispatch.d.ts +13 -1
  135. package/dist/clients/attach/slash/dispatch.js +51 -29
  136. package/dist/clients/attach/viewer.js +907 -819
  137. package/dist/clients/conversation/conversation.d.ts +65 -0
  138. package/dist/clients/conversation/conversation.js +318 -0
  139. package/dist/clients/conversation/frames.d.ts +30 -0
  140. package/dist/clients/conversation/frames.js +52 -0
  141. package/dist/clients/conversation/region.d.ts +51 -0
  142. package/dist/clients/conversation/region.js +265 -0
  143. package/dist/clients/conversation/submit.d.ts +38 -0
  144. package/dist/clients/conversation/submit.js +51 -0
  145. package/dist/clients/inbox/__tests__/inbox-controller.test.js +247 -0
  146. package/dist/clients/inbox/__tests__/mount-panel.test.js +776 -0
  147. package/dist/clients/inbox/controller.d.ts +79 -0
  148. package/dist/clients/inbox/controller.js +448 -0
  149. package/dist/clients/inbox/deck-adapter.d.ts +29 -0
  150. package/dist/clients/inbox/deck-adapter.js +62 -0
  151. package/dist/clients/inbox/layout.d.ts +8 -0
  152. package/dist/clients/inbox/layout.js +9 -0
  153. package/dist/clients/inbox/resolve.d.ts +10 -0
  154. package/dist/clients/inbox/resolve.js +34 -0
  155. package/dist/clients/inbox/review/__tests__/editor-roundtrip.test.js +29 -0
  156. package/dist/clients/inbox/review/__tests__/remap.test.js +196 -0
  157. package/dist/clients/inbox/review/__tests__/review-core.test.js +341 -0
  158. package/dist/clients/inbox/review/anchors.d.ts +41 -0
  159. package/dist/clients/inbox/review/anchors.js +89 -0
  160. package/dist/clients/inbox/review/columns.d.ts +22 -0
  161. package/dist/clients/inbox/review/columns.js +40 -0
  162. package/dist/clients/inbox/review/comments-client.d.ts +66 -0
  163. package/dist/clients/inbox/review/comments-client.js +98 -0
  164. package/dist/clients/inbox/review/composition.d.ts +60 -0
  165. package/dist/clients/inbox/review/composition.js +278 -0
  166. package/dist/clients/inbox/review/document-region.d.ts +120 -0
  167. package/dist/clients/inbox/review/document-region.js +902 -0
  168. package/dist/clients/inbox/review/frame.d.ts +45 -0
  169. package/dist/clients/inbox/review/frame.js +215 -0
  170. package/dist/clients/inbox/review/keys.d.ts +67 -0
  171. package/dist/clients/inbox/review/keys.js +130 -0
  172. package/dist/clients/inbox/review/launch.d.ts +10 -0
  173. package/dist/clients/inbox/review/launch.js +129 -0
  174. package/dist/clients/inbox/review/live-source.d.ts +24 -0
  175. package/dist/clients/inbox/review/live-source.js +160 -0
  176. package/dist/clients/inbox/review/nvim.d.ts +13 -0
  177. package/dist/clients/inbox/review/nvim.js +42 -0
  178. package/dist/clients/inbox/review/remap.d.ts +51 -0
  179. package/dist/clients/inbox/review/remap.js +157 -0
  180. package/dist/clients/inbox/review/review-client.d.ts +30 -0
  181. package/dist/clients/inbox/review/review-client.js +107 -0
  182. package/dist/clients/inbox/review/roundtrip.d.ts +5 -0
  183. package/dist/clients/inbox/review/roundtrip.js +36 -0
  184. package/dist/clients/inbox/review/state.d.ts +143 -0
  185. package/dist/clients/inbox/review/state.js +282 -0
  186. package/dist/clients/inbox/review-adapter.d.ts +29 -0
  187. package/dist/clients/inbox/review-adapter.js +92 -0
  188. package/dist/clients/inbox/review-visibility.d.ts +5 -0
  189. package/dist/clients/inbox/review-visibility.js +19 -0
  190. package/dist/clients/inbox/surface.d.ts +19 -0
  191. package/dist/clients/inbox/surface.js +128 -0
  192. package/dist/clients/inbox/tui/ansi.d.ts +66 -0
  193. package/dist/clients/inbox/tui/ansi.js +317 -0
  194. package/dist/clients/inbox/tui/clipboard.d.ts +2 -0
  195. package/dist/clients/inbox/tui/clipboard.js +26 -0
  196. package/dist/clients/inbox/tui/input.d.ts +7 -0
  197. package/dist/clients/inbox/tui/input.js +653 -0
  198. package/dist/clients/inbox/tui/keys.d.ts +28 -0
  199. package/dist/clients/inbox/tui/keys.js +111 -0
  200. package/dist/clients/inbox/tui/panel.d.ts +2 -0
  201. package/dist/clients/inbox/tui/panel.js +217 -0
  202. package/dist/clients/inbox/tui/render.d.ts +37 -0
  203. package/dist/clients/inbox/tui/render.js +476 -0
  204. package/dist/clients/inbox/tui/types.d.ts +57 -0
  205. package/dist/clients/inbox/tui/types.js +1 -0
  206. package/dist/clients/inbox/tui.d.ts +6 -0
  207. package/dist/clients/inbox/tui.js +74 -0
  208. package/dist/clients/surfaces/host.d.ts +66 -0
  209. package/dist/clients/surfaces/host.js +1 -0
  210. package/dist/clients/surfaces/region.d.ts +16 -0
  211. package/dist/clients/surfaces/region.js +1 -0
  212. package/dist/clients/web/__tests__/push-engine.test.js +14 -158
  213. package/dist/clients/web/dev-server.d.ts +3 -3
  214. package/dist/clients/web/dev-server.js +9 -23
  215. package/dist/clients/web/events.js +4 -6
  216. package/dist/clients/web/push-engine.d.ts +2 -66
  217. package/dist/clients/web/push-engine.js +30 -161
  218. package/dist/clients/web/push-registry.d.ts +0 -4
  219. package/dist/clients/web/push-registry.js +2 -7
  220. package/dist/clients/web/server.js +3 -35
  221. package/dist/clients/web/web-client/shared/protocol.d.ts +0 -108
  222. package/dist/clients/web/web-cmd.js +2 -2
  223. package/dist/commands/__tests__/human.test.js +27 -15
  224. package/dist/commands/api-client.js +3 -3
  225. package/dist/commands/canvas-browse.js +1 -1
  226. package/dist/commands/canvas-issue.js +1 -1
  227. package/dist/commands/canvas-use.js +1 -1
  228. package/dist/commands/human/doc.d.ts +2 -0
  229. package/dist/commands/human/doc.js +98 -0
  230. package/dist/commands/human/inbox.d.ts +2 -0
  231. package/dist/commands/human/inbox.js +101 -0
  232. package/dist/commands/human/prompts.d.ts +2 -3
  233. package/dist/commands/human/prompts.js +27 -180
  234. package/dist/commands/human/queue.d.ts +1 -5
  235. package/dist/commands/human/queue.js +54 -216
  236. package/dist/commands/human/review.d.ts +2 -0
  237. package/dist/commands/human/review.js +298 -0
  238. package/dist/commands/human/shared.d.ts +2 -69
  239. package/dist/commands/human/shared.js +1 -181
  240. package/dist/commands/human.js +15 -20
  241. package/dist/commands/memory/__tests__/lint.test.d.ts +1 -0
  242. package/dist/commands/memory/__tests__/lint.test.js +15 -0
  243. package/dist/commands/memory/delete.js +2 -2
  244. package/dist/commands/memory/lint.d.ts +1 -0
  245. package/dist/commands/memory/lint.js +21 -3
  246. package/dist/commands/memory/read.js +4 -4
  247. package/dist/commands/node.js +8 -7
  248. package/dist/commands/pkg/plugin-manage.js +143 -68
  249. package/dist/commands/surface-inspect.js +2 -2
  250. package/dist/commands/surface.js +6 -12
  251. package/dist/commands/sys/__tests__/setup-core.test.js +9 -5
  252. package/dist/commands/sys/__tests__/setup-front-door.test.js +7 -42
  253. package/dist/commands/sys/config.js +29 -3
  254. package/dist/commands/sys/feedback.js +1 -1
  255. package/dist/commands/sys/setup-core.d.ts +12 -11
  256. package/dist/commands/sys/setup-core.js +55 -46
  257. package/dist/commands/sys/setup-wizard.d.ts +4 -1
  258. package/dist/commands/sys/setup-wizard.js +50 -9
  259. package/dist/commands/sys/sync-deps.js +1 -1
  260. package/dist/commands/sys.js +4 -6
  261. package/dist/core/__tests__/broker-sdk-wiring.test.js +6 -1
  262. package/dist/core/__tests__/broker-snapshot-history.test.js +9 -1
  263. package/dist/core/__tests__/dead-node-policy-table.test.js +3 -4
  264. package/dist/core/__tests__/fixtures/fake-engine.d.ts +8 -5
  265. package/dist/core/__tests__/fixtures/fake-engine.js +28 -2
  266. package/dist/core/__tests__/full/broker-provider-retry.test.js +87 -2
  267. package/dist/core/__tests__/full/broker-whip-interrupt.test.d.ts +1 -0
  268. package/dist/core/__tests__/full/broker-whip-interrupt.test.js +39 -0
  269. package/dist/core/__tests__/full/detach-focus.test.js +1 -1
  270. package/dist/core/__tests__/human-deliver-e2e.test.js +64 -64
  271. package/dist/core/__tests__/human-deliver.test.js +71 -345
  272. package/dist/core/__tests__/inline-memory-refs.test.js +2 -12
  273. package/dist/core/__tests__/memory-resolver-precedence.test.js +12 -15
  274. package/dist/core/__tests__/migration.test.js +10 -0
  275. package/dist/core/__tests__/model-pin-durability.test.js +14 -0
  276. package/dist/core/__tests__/phase4-review-migration.test.d.ts +1 -0
  277. package/dist/core/__tests__/phase4-review-migration.test.js +100 -0
  278. package/dist/core/__tests__/phase4-review-store.test.d.ts +1 -0
  279. package/dist/core/__tests__/phase4-review-store.test.js +143 -0
  280. package/dist/core/__tests__/remote-canvas-target.test.js +2 -2
  281. package/dist/core/__tests__/revive.test.js +22 -53
  282. package/dist/core/__tests__/session-cycles.test.js +48 -18
  283. package/dist/core/__tests__/spawn-no-kickoff.test.js +8 -12
  284. package/dist/core/__tests__/stop-guard.test.js +16 -1
  285. package/dist/core/__tests__/tmux-surface.test.js +21 -25
  286. package/dist/core/asset-root.d.ts +7 -0
  287. package/dist/core/asset-root.js +18 -0
  288. package/dist/core/broker-client/client.d.ts +0 -7
  289. package/dist/core/broker-client/client.js +4 -10
  290. package/dist/core/broker-client/transport-relay.d.ts +3 -4
  291. package/dist/core/broker-client/transport-relay.js +3 -4
  292. package/dist/core/canvas/__tests__/attention.test.js +1 -1
  293. package/dist/core/canvas/__tests__/remote-canvas-source.test.js +1 -1
  294. package/dist/core/canvas/__tests__/remote-transport.test.d.ts +1 -0
  295. package/dist/core/{view/__tests__/transport-remote.test.js → canvas/__tests__/remote-transport.test.js} +2 -2
  296. package/dist/core/canvas/__tests__/render-remote.test.js +1 -1
  297. package/dist/core/canvas/attention.js +4 -4
  298. package/dist/core/canvas/canvas.d.ts +6 -11
  299. package/dist/core/canvas/canvas.js +11 -33
  300. package/dist/core/canvas/db.js +207 -38
  301. package/dist/core/canvas/extensions.d.ts +1 -1
  302. package/dist/core/canvas/extensions.js +8 -1
  303. package/dist/core/canvas/index.d.ts +0 -1
  304. package/dist/core/canvas/index.js +0 -1
  305. package/dist/core/canvas/nav-model.d.ts +1 -1
  306. package/dist/core/canvas/nav-model.js +1 -1
  307. package/dist/core/canvas/paths.d.ts +5 -0
  308. package/dist/core/canvas/paths.js +16 -0
  309. package/dist/core/canvas/remote-canvas-source.js +2 -2
  310. package/dist/core/canvas/remote-transport.d.ts +7 -0
  311. package/dist/core/{view/transport-remote.js → canvas/remote-transport.js} +3 -4
  312. package/dist/core/canvas/source.js +1 -1
  313. package/dist/core/canvas/status-glyph.js +4 -12
  314. package/dist/core/canvas/types.d.ts +10 -35
  315. package/dist/core/clipboard-text.d.ts +8 -0
  316. package/dist/core/clipboard-text.js +18 -0
  317. package/dist/core/command-manifests/registry.d.ts +1 -3
  318. package/dist/core/command-plugins/bundle.d.ts +29 -0
  319. package/dist/core/command-plugins/bundle.js +198 -0
  320. package/dist/core/command-plugins/discovery.d.ts +0 -8
  321. package/dist/core/command-plugins/discovery.js +2 -39
  322. package/dist/core/command-plugins/transport/http-fetch.d.ts +4 -30
  323. package/dist/core/command-plugins/transport/http-fetch.js +17 -95
  324. package/dist/core/command.d.ts +1 -13
  325. package/dist/core/command.js +1 -16
  326. package/dist/core/config.d.ts +4 -0
  327. package/dist/core/config.js +28 -3
  328. package/dist/core/document-lines.d.ts +4 -0
  329. package/dist/core/document-lines.js +6 -0
  330. package/dist/core/feed/feed.d.ts +2 -0
  331. package/dist/core/feed/feed.js +11 -7
  332. package/dist/core/human/__tests__/inbox-cancel-worker.d.ts +1 -0
  333. package/dist/core/human/__tests__/inbox-cancel-worker.js +7 -0
  334. package/dist/core/human/__tests__/inbox-claim-worker.d.ts +1 -0
  335. package/dist/core/human/__tests__/inbox-claim-worker.js +17 -0
  336. package/dist/core/human/__tests__/inbox-core.test.d.ts +1 -0
  337. package/dist/core/human/__tests__/inbox-core.test.js +144 -0
  338. package/dist/core/human/__tests__/inbox-stale-claim-worker.d.ts +1 -0
  339. package/dist/core/human/__tests__/inbox-stale-claim-worker.js +8 -0
  340. package/dist/core/human/__tests__/visible-paths.test.d.ts +1 -0
  341. package/dist/{clients/attach → core/human}/__tests__/visible-paths.test.js +9 -0
  342. package/dist/core/human/claim.d.ts +23 -0
  343. package/dist/core/human/claim.js +67 -0
  344. package/dist/core/human/convention.d.ts +30 -0
  345. package/dist/core/human/convention.js +202 -0
  346. package/dist/core/human/deck-factories.d.ts +8 -0
  347. package/dist/core/human/deck-factories.js +15 -0
  348. package/dist/core/human/deck-schema.d.ts +70 -0
  349. package/dist/core/human/deck-schema.js +92 -0
  350. package/dist/core/human/root.d.ts +7 -0
  351. package/dist/core/human/root.js +37 -0
  352. package/dist/core/human/scan.d.ts +3 -0
  353. package/dist/core/human/scan.js +76 -0
  354. package/dist/core/human/summary.d.ts +8 -0
  355. package/dist/core/human/summary.js +44 -0
  356. package/dist/core/human/tickets.d.ts +49 -0
  357. package/dist/core/human/tickets.js +190 -0
  358. package/dist/core/human/types.d.ts +136 -0
  359. package/dist/core/human/types.js +5 -0
  360. package/dist/{clients/attach → core/human}/visible-paths.d.ts +1 -1
  361. package/dist/{clients/attach → core/human}/visible-paths.js +3 -2
  362. package/dist/core/inspector/chrome.d.ts +6 -0
  363. package/dist/core/inspector/chrome.js +14 -0
  364. package/dist/core/inspector/contract.d.ts +105 -0
  365. package/dist/core/inspector/contract.js +1 -0
  366. package/dist/core/inspector/core.d.ts +4 -5
  367. package/dist/core/inspector/core.js +3 -5
  368. package/dist/core/inspector/host.d.ts +46 -0
  369. package/dist/core/{tui → inspector}/host.js +42 -208
  370. package/dist/core/inspector/text.d.ts +2 -2
  371. package/dist/core/inspector/transport.d.ts +6 -0
  372. package/dist/core/inspector/transport.js +36 -0
  373. package/dist/core/inspector/tui.d.ts +2 -2
  374. package/dist/core/inspector/tui.js +15 -15
  375. package/dist/core/keybindings/__tests__/inbox-affordance.test.js +11 -11
  376. package/dist/core/keybindings/__tests__/resolve.test.js +10 -19
  377. package/dist/core/keybindings/attach-control.d.ts +9 -3
  378. package/dist/core/keybindings/attach-control.js +3 -1
  379. package/dist/core/keybindings/catalog.d.ts +6 -5
  380. package/dist/core/keybindings/catalog.js +61 -133
  381. package/dist/core/keybindings/inbox.d.ts +5 -6
  382. package/dist/core/keybindings/inbox.js +9 -10
  383. package/dist/core/keybindings/index.d.ts +3 -3
  384. package/dist/core/keybindings/index.js +3 -3
  385. package/dist/core/keybindings/persistence.d.ts +5 -1
  386. package/dist/core/keybindings/persistence.js +24 -6
  387. package/dist/core/keybindings/resolve.d.ts +6 -0
  388. package/dist/core/keybindings/resolve.js +10 -3
  389. package/dist/core/memory/inline-ref-grammar.js +2 -3
  390. package/dist/core/memory-resolver.d.ts +27 -29
  391. package/dist/core/memory-resolver.js +45 -39
  392. package/dist/core/model-routes.d.ts +33 -0
  393. package/dist/core/model-routes.js +42 -3
  394. package/dist/core/preview-registry.js +17 -55
  395. package/dist/core/profiles/select.js +3 -3
  396. package/dist/core/{view/remote-canvas-target.d.ts → remote-canvas-target.d.ts} +2 -2
  397. package/dist/core/{view/remote-canvas-target.js → remote-canvas-target.js} +4 -4
  398. package/dist/core/review/__tests__/capture-origin.test.d.ts +1 -0
  399. package/dist/core/review/__tests__/capture-origin.test.js +139 -0
  400. package/dist/core/review/__tests__/comments.test.d.ts +1 -0
  401. package/dist/core/review/__tests__/comments.test.js +98 -0
  402. package/dist/core/review/__tests__/project.test.d.ts +1 -0
  403. package/dist/core/review/__tests__/project.test.js +71 -0
  404. package/dist/core/review/__tests__/remap.test.d.ts +1 -0
  405. package/dist/core/review/__tests__/remap.test.js +159 -0
  406. package/dist/core/review/__tests__/stage-identity.test.d.ts +1 -0
  407. package/dist/core/review/__tests__/stage-identity.test.js +140 -0
  408. package/dist/core/review/birth.d.ts +7 -0
  409. package/dist/core/review/birth.js +23 -0
  410. package/dist/core/review/comments.d.ts +69 -0
  411. package/dist/core/review/comments.js +295 -0
  412. package/dist/core/review/companion.d.ts +35 -0
  413. package/dist/core/review/companion.js +205 -0
  414. package/dist/core/review/document.d.ts +27 -0
  415. package/dist/core/review/document.js +138 -0
  416. package/dist/core/review/project.d.ts +13 -0
  417. package/dist/core/review/project.js +58 -0
  418. package/dist/core/review/realize.d.ts +19 -0
  419. package/dist/core/review/realize.js +217 -0
  420. package/dist/core/review/remap.d.ts +24 -0
  421. package/dist/core/review/remap.js +156 -0
  422. package/dist/core/review/signal.d.ts +5 -0
  423. package/dist/core/review/signal.js +31 -0
  424. package/dist/core/review/stage.d.ts +26 -0
  425. package/dist/core/review/stage.js +184 -0
  426. package/dist/core/review/store.d.ts +46 -0
  427. package/dist/core/review/store.js +163 -0
  428. package/dist/core/review/ticket-filter.d.ts +17 -0
  429. package/dist/core/review/ticket-filter.js +32 -0
  430. package/dist/core/review/types.d.ts +130 -0
  431. package/dist/core/review/types.js +23 -0
  432. package/dist/core/runtime/__tests__/session-visibility.test.d.ts +1 -0
  433. package/dist/core/runtime/__tests__/session-visibility.test.js +119 -0
  434. package/dist/core/runtime/bearings.d.ts +5 -17
  435. package/dist/core/runtime/bearings.js +88 -71
  436. package/dist/core/runtime/broker-protocol.d.ts +31 -8
  437. package/dist/core/runtime/broker.d.ts +15 -1
  438. package/dist/core/runtime/broker.js +573 -141
  439. package/dist/core/runtime/canvas-extensions.d.ts +4 -5
  440. package/dist/core/runtime/canvas-extensions.js +5 -5
  441. package/dist/core/runtime/front-door.js +4 -4
  442. package/dist/core/runtime/headless-pi.d.ts +24 -0
  443. package/dist/core/runtime/headless-pi.js +152 -0
  444. package/dist/core/runtime/kickoff.d.ts +1 -5
  445. package/dist/core/runtime/kickoff.js +1 -5
  446. package/dist/core/runtime/model-registry.d.ts +3 -0
  447. package/dist/core/runtime/model-registry.js +13 -0
  448. package/dist/core/runtime/naming-persist.d.ts +4 -0
  449. package/dist/core/runtime/naming-persist.js +27 -1
  450. package/dist/core/runtime/naming.d.ts +17 -12
  451. package/dist/core/runtime/naming.js +91 -140
  452. package/dist/core/runtime/node-read.js +19 -10
  453. package/dist/core/runtime/nodes.d.ts +9 -14
  454. package/dist/core/runtime/nodes.js +3 -53
  455. package/dist/core/runtime/package-health.d.ts +6 -21
  456. package/dist/core/runtime/package-health.js +12 -123
  457. package/dist/core/runtime/placement-tmux.d.ts +2 -1
  458. package/dist/core/runtime/placement-tmux.js +6 -4
  459. package/dist/core/runtime/placement.d.ts +1 -0
  460. package/dist/core/runtime/placement.js +4 -8
  461. package/dist/core/runtime/promote.js +3 -0
  462. package/dist/core/runtime/recap.d.ts +2 -7
  463. package/dist/core/runtime/recap.js +35 -69
  464. package/dist/core/runtime/revive.js +34 -77
  465. package/dist/core/runtime/session-cycles.d.ts +4 -0
  466. package/dist/core/runtime/session-cycles.js +14 -1
  467. package/dist/core/runtime/session-visibility.d.ts +37 -0
  468. package/dist/core/runtime/session-visibility.js +83 -0
  469. package/dist/core/runtime/spawn.js +10 -22
  470. package/dist/core/runtime/stop-guard.d.ts +1 -1
  471. package/dist/core/runtime/stop-guard.js +18 -13
  472. package/dist/core/runtime/surface-bg.js +1 -1
  473. package/dist/core/runtime/tmux-chrome.d.ts +1 -1
  474. package/dist/core/runtime/tmux-chrome.js +1 -1
  475. package/dist/core/runtime/tmux.d.ts +35 -7
  476. package/dist/core/runtime/tmux.js +439 -62
  477. package/dist/core/runtime/tool-group-summary.d.ts +19 -0
  478. package/dist/core/runtime/tool-group-summary.js +88 -0
  479. package/dist/core/scope.d.ts +2 -7
  480. package/dist/core/scope.js +9 -35
  481. package/dist/core/substrate/schema.d.ts +2 -2
  482. package/dist/core/termrender/code-doc.d.ts +12 -0
  483. package/dist/core/termrender/code-doc.js +92 -0
  484. package/dist/core/termrender/display.d.ts +12 -0
  485. package/dist/core/termrender/display.js +19 -0
  486. package/dist/core/termrender/termrender.d.ts +73 -0
  487. package/dist/core/termrender/termrender.js +795 -0
  488. package/dist/core/termrender/version.d.ts +1 -0
  489. package/dist/core/termrender/version.js +1 -0
  490. package/dist/core/tui/terminal.js +1 -2
  491. package/dist/core/user-settings.d.ts +71 -3
  492. package/dist/core/user-settings.js +83 -1
  493. package/dist/daemon/api/__tests__/inbox.test.js +44 -133
  494. package/dist/daemon/api/handlers/human.d.ts +0 -10
  495. package/dist/daemon/api/handlers/human.js +104 -702
  496. package/dist/daemon/api/handlers/inbox.js +113 -142
  497. package/dist/daemon/api/handlers/review-comments.d.ts +2 -0
  498. package/dist/daemon/api/handlers/review-comments.js +500 -0
  499. package/dist/daemon/api/handlers/reviews.d.ts +2 -0
  500. package/dist/daemon/api/handlers/reviews.js +287 -0
  501. package/dist/daemon/api/map.d.ts +22 -7
  502. package/dist/daemon/api/map.js +159 -11
  503. package/dist/daemon/api/server.js +4 -0
  504. package/dist/daemon/cron-run.js +6 -9
  505. package/dist/daemon/crtrd.js +17 -33
  506. package/dist/daemon/fleet.d.ts +1 -8
  507. package/dist/daemon/fleet.js +4 -30
  508. package/dist/daemon/human/finish.d.ts +14 -0
  509. package/dist/daemon/human/finish.js +115 -0
  510. package/dist/daemon/human/sweep.d.ts +6 -0
  511. package/dist/daemon/human/sweep.js +49 -0
  512. package/dist/daemon/messaging/node-message.d.ts +18 -0
  513. package/dist/daemon/messaging/node-message.js +70 -0
  514. package/dist/daemon/review/comment-notify.d.ts +26 -0
  515. package/dist/daemon/review/comment-notify.js +107 -0
  516. package/dist/daemon/review/deliver.d.ts +7 -0
  517. package/dist/daemon/review/deliver.js +56 -0
  518. package/dist/daemon/review/finish.d.ts +22 -0
  519. package/dist/daemon/review/finish.js +254 -0
  520. package/dist/daemon/review/sweep.d.ts +11 -0
  521. package/dist/daemon/review/sweep.js +120 -0
  522. package/dist/index.d.ts +2 -0
  523. package/dist/index.js +2 -2
  524. package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +42 -64
  525. package/dist/pi-extensions/__tests__/canvas-recap.test.d.ts +1 -0
  526. package/dist/pi-extensions/__tests__/canvas-recap.test.js +159 -0
  527. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +16 -38
  528. package/dist/pi-extensions/__tests__/canvas-structured-output.test.d.ts +1 -0
  529. package/dist/pi-extensions/__tests__/canvas-structured-output.test.js +63 -0
  530. package/dist/pi-extensions/canvas-context-intro.d.ts +8 -11
  531. package/dist/pi-extensions/canvas-context-intro.js +50 -104
  532. package/dist/pi-extensions/canvas-recap.d.ts +15 -2
  533. package/dist/pi-extensions/canvas-recap.js +192 -69
  534. package/dist/pi-extensions/canvas-review-boundary.d.ts +59 -0
  535. package/dist/pi-extensions/canvas-review-boundary.js +81 -0
  536. package/dist/pi-extensions/canvas-stophook.d.ts +3 -3
  537. package/dist/pi-extensions/canvas-stophook.js +78 -128
  538. package/dist/pi-extensions/canvas-structured-output.js +52 -8
  539. package/dist/shared/generated-context.d.ts +29 -4
  540. package/dist/shared/generated-context.js +122 -7
  541. package/dist/shared/tool-groups.d.ts +23 -0
  542. package/dist/shared/tool-groups.js +60 -0
  543. package/dist/shared/working-activity.d.ts +8 -0
  544. package/dist/shared/working-activity.js +26 -0
  545. package/dist/types.d.ts +36 -2
  546. package/dist/types.js +51 -0
  547. package/dist/web-client/assets/index-CCPaLeW7.css +2 -0
  548. package/dist/web-client/assets/index-kyOWsnZK.js +86 -0
  549. package/dist/web-client/index.html +2 -2
  550. package/dist/web-client/sw.js +1 -1
  551. package/docs/compat/hearth-crtr-v4.md +2 -2
  552. package/docs/compat/hearth-crtr-v5.md +4 -2
  553. package/docs/public-api.md +3 -3
  554. package/package.json +21 -14
  555. package/runtime.lock.json +4661 -1453
  556. package/scripts/postinstall.mjs +15 -2
  557. package/dist/builtin-pi-packages/pi-mode-switch/README.md +0 -36
  558. package/dist/builtin-pi-packages/pi-mode-switch/bin/mode +0 -36
  559. package/dist/builtin-pi-packages/pi-mode-switch/extensions/index.ts +0 -449
  560. package/dist/builtin-pi-packages/pi-mode-switch/package.json +0 -14
  561. package/dist/builtin-pi-packages/pi-mode-switch/tsconfig.json +0 -9
  562. package/dist/builtin-views/_lib/states.mjs +0 -161
  563. package/dist/builtin-views/canvas/core.mjs +0 -657
  564. package/dist/builtin-views/canvas/text.mjs +0 -58
  565. package/dist/builtin-views/canvas/tui.mjs +0 -168
  566. package/dist/builtin-views/canvas/web.jsx +0 -121
  567. package/dist/builtin-views/chat/core.mjs +0 -684
  568. package/dist/builtin-views/chat/text.mjs +0 -101
  569. package/dist/builtin-views/chat/tui.mjs +0 -360
  570. package/dist/builtin-views/chat/web.jsx +0 -362
  571. package/dist/builtin-views/git-pr/core.mjs +0 -673
  572. package/dist/builtin-views/git-pr/text.mjs +0 -84
  573. package/dist/builtin-views/git-pr/tui.mjs +0 -301
  574. package/dist/builtin-views/git-pr/web.jsx +0 -216
  575. package/dist/builtin-views/inbox/_lib/render.mjs +0 -175
  576. package/dist/builtin-views/inbox/core.mjs +0 -1273
  577. package/dist/builtin-views/inbox/text.mjs +0 -73
  578. package/dist/builtin-views/inbox/tui.mjs +0 -314
  579. package/dist/builtin-views/inbox/web.jsx +0 -188
  580. package/dist/builtin-views/linkedin/core.mjs +0 -906
  581. package/dist/builtin-views/linkedin/text.mjs +0 -69
  582. package/dist/builtin-views/linkedin/tui.mjs +0 -413
  583. package/dist/builtin-views/linkedin/web.jsx +0 -206
  584. package/dist/builtin-views/prompt-review/core.mjs +0 -735
  585. package/dist/builtin-views/prompt-review/text.mjs +0 -15
  586. package/dist/builtin-views/prompt-review/tui.mjs +0 -196
  587. package/dist/builtin-views/prompt-review/web.jsx +0 -484
  588. package/dist/builtin-views/workspace-sidebar/__tests__/core.test.js +0 -50
  589. package/dist/builtin-views/workspace-sidebar/__tests__/core.test.ts +0 -53
  590. package/dist/builtin-views/workspace-sidebar/core.mjs +0 -670
  591. package/dist/builtin-views/workspace-sidebar/text.mjs +0 -53
  592. package/dist/builtin-views/workspace-sidebar/tui.mjs +0 -141
  593. package/dist/builtin-views/workspace-sidebar/web.jsx +0 -109
  594. package/dist/clients/attach/session/mode.d.ts +0 -25
  595. package/dist/clients/attach/session/mode.js +0 -97
  596. package/dist/commands/sys/promptstudio.d.ts +0 -2
  597. package/dist/commands/sys/promptstudio.js +0 -65
  598. package/dist/commands/view-cycle.d.ts +0 -2
  599. package/dist/commands/view-cycle.js +0 -130
  600. package/dist/commands/view-list.d.ts +0 -2
  601. package/dist/commands/view-list.js +0 -66
  602. package/dist/commands/view-new.d.ts +0 -2
  603. package/dist/commands/view-new.js +0 -74
  604. package/dist/commands/view-pick.d.ts +0 -6
  605. package/dist/commands/view-pick.js +0 -129
  606. package/dist/commands/view-run.d.ts +0 -2
  607. package/dist/commands/view-run.js +0 -214
  608. package/dist/commands/view.d.ts +0 -2
  609. package/dist/commands/view.js +0 -31
  610. package/dist/commands/workspace.d.ts +0 -2
  611. package/dist/commands/workspace.js +0 -165
  612. package/dist/core/__tests__/chat-view-reconnect.test.js +0 -105
  613. package/dist/core/__tests__/full/consult-startup-failure.test.js +0 -124
  614. package/dist/core/canvas/__tests__/human-work-outbox.test.js +0 -123
  615. package/dist/core/canvas/human-work-outbox.d.ts +0 -73
  616. package/dist/core/canvas/human-work-outbox.js +0 -261
  617. package/dist/core/command-plugins/store.d.ts +0 -16
  618. package/dist/core/command-plugins/store.js +0 -64
  619. package/dist/core/keybindings/__tests__/bespoke-consumers.test.js +0 -40
  620. package/dist/core/runtime/fault-recovery-nudge.d.ts +0 -3
  621. package/dist/core/runtime/fault-recovery-nudge.js +0 -3
  622. package/dist/core/tui/__tests__/host-keybindings.test.js +0 -113
  623. package/dist/core/tui/host.d.ts +0 -66
  624. package/dist/core/view/__tests__/transport-cache.test.js +0 -62
  625. package/dist/core/view/bridge.d.ts +0 -10
  626. package/dist/core/view/bridge.js +0 -31
  627. package/dist/core/view/chrome.d.ts +0 -9
  628. package/dist/core/view/chrome.js +0 -22
  629. package/dist/core/view/contract.d.ts +0 -205
  630. package/dist/core/view/contract.js +0 -23
  631. package/dist/core/view/loader.d.ts +0 -31
  632. package/dist/core/view/loader.js +0 -188
  633. package/dist/core/view/stream-local.d.ts +0 -3
  634. package/dist/core/view/stream-local.js +0 -231
  635. package/dist/core/view/transport-cache.d.ts +0 -8
  636. package/dist/core/view/transport-cache.js +0 -38
  637. package/dist/core/view/transport-local.d.ts +0 -7
  638. package/dist/core/view/transport-local.js +0 -83
  639. package/dist/core/view/transport-remote.d.ts +0 -2
  640. package/dist/core/view/transport.d.ts +0 -10
  641. package/dist/core/view/transport.js +0 -15
  642. package/dist/pi-extensions/naming-tool.d.ts +0 -24
  643. package/dist/pi-extensions/naming-tool.js +0 -67
  644. package/dist/prompts/view.d.ts +0 -7
  645. package/dist/prompts/view.js +0 -172
  646. package/dist/web/ViewChrome.d.ts +0 -7
  647. package/dist/web/ViewChrome.js +0 -28
  648. package/dist/web/ViewPane.d.ts +0 -39
  649. package/dist/web/ViewPane.js +0 -48
  650. package/dist/web/index.d.ts +0 -8
  651. package/dist/web/index.js +0 -22
  652. package/dist/web/runtime.d.ts +0 -39
  653. package/dist/web/runtime.js +0 -232
  654. package/dist/web/states.d.ts +0 -24
  655. package/dist/web/states.js +0 -24
  656. package/dist/web/transport-http.d.ts +0 -5
  657. package/dist/web/transport-http.js +0 -34
  658. package/dist/web/transport-stream.d.ts +0 -3
  659. package/dist/web/transport-stream.js +0 -204
  660. package/dist/web-client/assets/index-U_NZ66VE.js +0 -79
  661. package/dist/web-client/assets/index-aaeu4adv.css +0 -2
  662. /package/dist/{builtin-views/workspace-sidebar/__tests__/core.test.d.ts → clients/attach/__tests__/file-review-focus.test.d.ts} +0 -0
  663. /package/dist/clients/attach/__tests__/{visible-paths.test.d.ts → group-activity.test.d.ts} +0 -0
  664. /package/dist/{core/__tests__/chat-view-reconnect.test.d.ts → clients/attach/__tests__/input-controller-extension-command.test.d.ts} +0 -0
  665. /package/dist/{core/__tests__/full/consult-startup-failure.test.d.ts → clients/attach/__tests__/session-identity-refresh.test.d.ts} +0 -0
  666. /package/dist/{core/canvas/__tests__/human-work-outbox.test.d.ts → clients/inbox/__tests__/inbox-controller.test.d.ts} +0 -0
  667. /package/dist/{core/keybindings/__tests__/bespoke-consumers.test.d.ts → clients/inbox/__tests__/mount-panel.test.d.ts} +0 -0
  668. /package/dist/{core/tui/__tests__/host-keybindings.test.d.ts → clients/inbox/review/__tests__/editor-roundtrip.test.d.ts} +0 -0
  669. /package/dist/{core/view/__tests__/transport-cache.test.d.ts → clients/inbox/review/__tests__/remap.test.d.ts} +0 -0
  670. /package/dist/{core/view/__tests__/transport-remote.test.d.ts → clients/inbox/review/__tests__/review-core.test.d.ts} +0 -0
@@ -1,25 +1,14 @@
1
1
  // Run with: node --import tsx/esm --test src/pi-extensions/__tests__/canvas-context-intro.test.ts
2
2
  //
3
- // BUG REGRESSION (crouter/CLAUDE.md testing policy):
4
- // `crtr node new --fork-from <node>` caused AGENT IDENTITY CONFUSION. A fork
5
- // inherits the SOURCE node's entire first-person conversation (pi COPIES it
6
- // into the fork's session), so on boot the forked agent impersonated the
7
- // source — it kept acting AS the source, even "monitoring itself" as a phantom
8
- // child, until it happened to check CRTR_NODE_ID. Two root causes, both fixed
9
- // here and pinned by these tests:
10
- // 1. canvas-context-intro never re-asserted the node's OWN identity, so the
11
- // copied first-person narrative won.
12
- // 2. the idempotency guard misfired for a fork: the copied conversation
13
- // already carries the SOURCE's <crtr-context> entry, so the guard treated
14
- // it as "already present" and SUPPRESSED the fork's own intro entirely —
15
- // the fork booted with the source's bearings (source id, source dir).
16
- // Symptom write-up: nodes/mq4ns376-da6e56c9/reports/20260608T075810-final.md.
3
+ // A fresh branch receives the full context baseline. A forked crouter branch
4
+ // receives a compact node-scoped update after its inherited baseline. Resumes
5
+ // remain idempotent through the exact node-id stamp.
17
6
  import { test, before, after, beforeEach } from 'node:test';
18
7
  import assert from 'node:assert/strict';
19
8
  import { mkdtempSync, rmSync } from 'node:fs';
20
9
  import { tmpdir } from 'node:os';
21
10
  import { join } from 'node:path';
22
- import { buildContextIntro, registerCanvasContextIntro, CONTEXT_INTRO_CUSTOM_TYPE, } from '../canvas-context-intro.js';
11
+ import { buildContextIntro, buildForkContextIntro, registerCanvasContextIntro, CONTEXT_INTRO_CUSTOM_TYPE, } from '../canvas-context-intro.js';
23
12
  import { createNode } from '../../core/canvas/canvas.js';
24
13
  import { closeDb } from '../../core/canvas/db.js';
25
14
  let home;
@@ -82,56 +71,44 @@ after(() => {
82
71
  else
83
72
  process.env['CRTR_NODE_ID'] = origNode;
84
73
  });
85
- test('boot intro asserts the node\'s OWN identity up front (regression: forked node impersonated source)', () => {
74
+ test('full boot intro leads with the node\'s own identity', () => {
86
75
  createNode(node('alpha', { name: 'fix-auth', kind: 'developer' }));
87
76
  const intro = buildContextIntro('alpha');
88
77
  assert.match(intro, /<crtr-bearings>/, 'opens with the bearings section');
89
78
  assert.match(intro, /You are node alpha/, 'names the node by its own id');
90
79
  assert.match(intro, /kind developer/, 'states the node kind');
91
- // Gated (Option A): a fresh (non-fork) node's bearings are its FIRST entry, so
92
- // there is no earlier narrative to disown — the disown framing (the fork callout
93
- // naming the copied history "inherited reference material") is fork-only and must
94
- // NOT appear here.
95
- assert.ok(!/inherited reference material/.test(intro), 'a non-fork node carries no disown-the-earlier-narrative line');
96
- // Identity LEADS the bearings block (no wrapper of its own), so it is the first
97
- // prose the model reads — the orienting frame, not a trailing note.
80
+ assert.doesNotMatch(intro, /FORK of/, 'a fresh node carries no fork framing');
81
+ // Identity leads the bearings block.
98
82
  assert.match(intro, /<crtr-bearings>\nYou are node alpha/, 'identity leads the bearings block');
99
83
  assert.ok(intro.indexOf('<crtr-bearings>') < intro.indexOf('<project_context>'), 'bearings precede project context');
100
84
  });
101
- test('a FORK\'s intro names the source and disowns it (regression: fork acted AS the source)', () => {
102
- // The source node whose conversation pi copied into the fork.
85
+ test('fork bearings contain only the new node-scoped facts', () => {
103
86
  createNode(node('src7', { name: 'looking-pi-crouter', description: 'monitor-telemetry' }));
104
- // The fork: fork_from provenance persisted at spawn.
105
- createNode(node('fork9', { fork_from: 'src7' }));
106
- const intro = buildContextIntro('fork9');
107
- assert.match(intro, /You are node fork9/, 'the fork is told its OWN id');
108
- assert.match(intro, /You are a FORK of src7/, 'names the fork source explicitly');
109
- assert.match(intro, /You are NOT src7/, '"you are NOT the source" flag is present');
110
- // Carries the source's human label so the agent recognizes the copied persona.
111
- assert.match(intro, /looking-pi-crouter/, 'surfaces the source label');
112
- // The fork DOES carry the disown framing — it has a real referent (copied history).
113
- assert.match(intro, /inherited reference material/, 'the fork disowns the copied first-person narrative');
114
- // It must NOT tell the fork it is the source node.
115
- assert.ok(!/You are node src7/.test(intro), 'fork is never told it is the source node');
116
- // A non-fork sibling gets the identity assertion but NO fork callout and NO
117
- // disown line (gated on fork_from).
87
+ createNode(node('fork9', { fork_from: 'src7', lifecycle: 'resident' }));
88
+ const intro = buildForkContextIntro('fork9');
89
+ assert.match(intro, /You are node fork9/, 'the fork receives its own id');
90
+ assert.match(intro, /new FORK of src7/, 'the fork names its source');
91
+ assert.match(intro, /not src7/, 'the fork does not adopt the source identity');
92
+ assert.match(intro, /looking-pi-crouter/, 'the source label identifies the copied history');
93
+ assert.match(intro, /Lifecycle: resident/, 'the fork receives its current lifecycle');
94
+ assert.match(intro, /independent root/, 'the fork receives its current graph role');
95
+ assert.ok(intro.includes(join(home, 'nodes', 'fork9', 'context')), 'the fork receives its own context path');
96
+ assert.match(intro, /first real user message/, 'the fork waits for its new mandate');
97
+ assert.doesNotMatch(intro, /<memory kind="knowledge">/, 'the inherited knowledge catalog is not repeated');
98
+ assert.doesNotMatch(intro, /<auto-loaded-context>/, 'inherited workspace docs are not repeated');
99
+ assert.doesNotMatch(intro, /<project_context>/, 'the inherited project snapshot is not repeated');
118
100
  createNode(node('plain2'));
119
101
  const plain = buildContextIntro('plain2');
120
102
  assert.match(plain, /You are node plain2/);
121
- assert.ok(!/FORK of/.test(plain), 'a fresh (non-fork) node carries no fork callout');
122
- assert.ok(!/inherited reference material/.test(plain), 'a non-fork node carries no disown line');
123
- // Regression: a raw provenance FILE PATH as fork_from (as human-work queue
124
- // handlers pass) must not crash getNode() lookup inside identity assertion
125
- // construction — it is not a valid node-id path segment, so it must be
126
- // treated as an opaque source label instead of thrown at.
103
+ assert.ok(!/FORK of/.test(plain), 'a fresh node carries no fork callout');
104
+ // A path-valued provenance remains an opaque label.
127
105
  const pathSource = '/Users/silasrhyneer/.crouter/canvas/human-work/queue/20260717T000000-abc.json';
128
106
  createNode(node('fork10', { fork_from: pathSource }));
129
- const pathIntro = buildContextIntro('fork10');
130
- assert.match(pathIntro, /You are node fork10/, 'the fork is told its OWN id');
131
- assert.match(pathIntro, new RegExp(`You are a FORK of ${pathSource.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`), 'a path-valued fork source passes through as-is (no crash on getNode lookup)');
132
- assert.match(pathIntro, /inherited reference material/, 'the fork disowns the copied first-person narrative');
107
+ const pathIntro = buildForkContextIntro('fork10');
108
+ assert.match(pathIntro, /You are node fork10/);
109
+ assert.match(pathIntro, new RegExp(`new FORK of ${pathSource.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}`), 'a path-valued source is named without a node lookup');
133
110
  });
134
- test('session_start INJECTS the fork\'s own bearings despite the inherited source block (the misfiring-idempotency bug)', () => {
111
+ test('session_start appends compact fork bearings after an inherited source baseline', () => {
135
112
  createNode(node('srcA'));
136
113
  createNode(node('forkB', { fork_from: 'srcA' }));
137
114
  // A fork boots with the SOURCE's whole conversation copied in — including the
@@ -141,22 +118,24 @@ test('session_start INJECTS the fork\'s own bearings despite the inherited sourc
141
118
  const pi = makeFakePi();
142
119
  registerCanvasContextIntro(pi);
143
120
  pi.fireSessionStart([inheritedSourceBlock]);
144
- // The fix: the inherited block belongs to srcA, so it must NOT suppress
145
- // forkB's own intro. forkB's bearings (with its identity assertion) ARE sent.
121
+ // The inherited baseline belongs to srcA, so forkB receives its own compact update.
146
122
  assert.equal(pi.sent.length, 1, 'fork injects its OWN bearings over the inherited source block');
147
123
  assert.equal(pi.sent[0].customType, CONTEXT_INTRO_CUSTOM_TYPE);
148
124
  assert.match(pi.sent[0].content, /You are node forkB/, 'injected bearings name the fork, not the source');
149
- assert.match(pi.sent[0].content, /You are a FORK of srcA/, 'injected bearings carry the fork callout');
150
- // The exact, machine-readable resume discriminator rides along (not sent to
151
- // the LLM): it names THIS node, so a later resume tells our block apart from
152
- // any inherited one without depending on prose.
153
- assert.equal(pi.sent[0].details?.nodeId, 'forkB', 'injected block carries the exact node-id stamp');
125
+ assert.match(pi.sent[0].content, /new FORK of srcA/, 'injected bearings carry the fork callout');
126
+ assert.doesNotMatch(pi.sent[0].content, /<project_context>/, 'the full source baseline is not repeated');
127
+ assert.equal(pi.sent[0].details?.nodeId, 'forkB', 'the compact update carries the fork node stamp');
128
+ // A non-crouter source has no inherited baseline, so its fork receives one.
129
+ createNode(node('externalF', { fork_from: '/tmp/external-session.jsonl' }));
130
+ process.env['CRTR_NODE_ID'] = 'externalF';
131
+ const externalPi = makeFakePi();
132
+ registerCanvasContextIntro(externalPi);
133
+ externalPi.fireSessionStart([]);
134
+ assert.match(externalPi.sent[0].content, /<project_context>/, 'an external-session fork receives the full baseline');
154
135
  });
155
- test('resume idempotency uses the EXACT details stamp, independent of block text (regression hardening)', () => {
136
+ test('resume idempotency uses the exact details stamp independent of block text', () => {
156
137
  createNode(node('stampD'));
157
- // A restored block that carries OUR exact stamp but whose TEXT does not mention
158
- // our id. The old content-substring-only guard would re-inject (and accumulate)
159
- // here; the exact `details.nodeId` match skips correctly.
138
+ // The exact node-id stamp is authoritative even when prose carries no id.
160
139
  const stampedNoIdInText = {
161
140
  type: 'custom_message',
162
141
  customType: CONTEXT_INTRO_CUSTOM_TYPE,
@@ -169,10 +148,9 @@ test('resume idempotency uses the EXACT details stamp, independent of block text
169
148
  pi.fireSessionStart([stampedNoIdInText]);
170
149
  assert.equal(pi.sent.length, 0, 'exact details-stamp match skips re-injection even when the text omits the id');
171
150
  });
172
- test('session_start stays IDEMPOTENT on a genuine resume (our own bearings already present)', () => {
151
+ test('session_start stays idempotent on a genuine resume', () => {
173
152
  createNode(node('resumeC'));
174
- // A `--session` relaunch restores OUR conversation — our own bearings (naming
175
- // resumeC) are already in history.
153
+ // A resume restores this node's already-stamped bearings.
176
154
  const ownBlock = introEntry(buildContextIntro('resumeC'));
177
155
  process.env['CRTR_NODE_ID'] = 'resumeC';
178
156
  const pi = makeFakePi();
@@ -0,0 +1,159 @@
1
+ import { test } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { mkdtempSync, rmSync } from 'node:fs';
4
+ import { tmpdir } from 'node:os';
5
+ import { join } from 'node:path';
6
+ import { registerCanvasRecap } from '../canvas-recap.js';
7
+ import { createNode } from '../../core/canvas/canvas.js';
8
+ import { closeDb } from '../../core/canvas/db.js';
9
+ test('a streaming manual recap snapshots the partial response and replaces the pinned recap only on success', () => {
10
+ const originalNodeId = process.env['CRTR_NODE_ID'];
11
+ process.env['CRTR_NODE_ID'] = 'recap-regression-node';
12
+ const handlers = new Map();
13
+ let commandHandler;
14
+ const widgetWrites = [];
15
+ const notifications = [];
16
+ const generations = [];
17
+ let idleWaits = 0;
18
+ const recapGenerator = (conversation, finish) => {
19
+ generations.push({ conversation, finish });
20
+ };
21
+ const pi = {
22
+ on: (event, handler) => { handlers.set(event, handler); },
23
+ registerCommand: (_name, options) => {
24
+ commandHandler = options.handler;
25
+ },
26
+ };
27
+ const sessionManager = {
28
+ getEntries: () => [{ type: 'message', message: { role: 'user', content: 'Build the recap command.' } }],
29
+ };
30
+ const ctx = {
31
+ ui: {
32
+ setWidget: (_key, content) => { widgetWrites.push(content); },
33
+ notify: (message) => { notifications.push(message); },
34
+ },
35
+ sessionManager,
36
+ model: { provider: 'test', id: 'light' },
37
+ isIdle: () => false,
38
+ waitForIdle: async () => { idleWaits += 1; },
39
+ };
40
+ try {
41
+ registerCanvasRecap(pi, recapGenerator);
42
+ handlers.get('session_start')?.({}, ctx);
43
+ commandHandler?.('', ctx);
44
+ assert.equal(notifications.at(-1), 'Generating recap…', 'the manually selected command confirms that generation started');
45
+ generations[0]?.finish('Goal: Existing goal\nState: Existing state');
46
+ assert.deepEqual(widgetWrites.at(-1), ['Goal: Existing goal', 'State: Existing state']);
47
+ assert.equal(notifications.at(-1), 'Recap ready', 'a completed manual recap confirms that the widget was refreshed');
48
+ handlers.get('message_update')?.({
49
+ message: { role: 'assistant', content: [{ type: 'text', text: 'I am editing the live implementation now.' }] },
50
+ }, ctx);
51
+ const writesBeforeRequest = widgetWrites.length;
52
+ const result = commandHandler?.('', ctx);
53
+ assert.equal(result, undefined, 'the command starts synchronously while the main response is streaming');
54
+ assert.equal(idleWaits, 0);
55
+ assert.equal(generations.length, 2);
56
+ assert.match(generations[1].conversation, /Agent: I am editing the live implementation now\./);
57
+ assert.equal(widgetWrites.length, writesBeforeRequest, 'the pinned recap remains while its replacement generates');
58
+ handlers.get('message_update')?.({
59
+ message: { role: 'assistant', content: [{ type: 'text', text: 'I am now verifying the implementation.' }] },
60
+ }, ctx);
61
+ generations[1].finish('Goal: Updated goal\nState: Updated click-time state');
62
+ assert.deepEqual(widgetWrites.at(-1), ['Goal: Updated goal', 'State: Updated click-time state']);
63
+ }
64
+ finally {
65
+ handlers.get('session_shutdown')?.({}, ctx);
66
+ if (originalNodeId === undefined)
67
+ delete process.env['CRTR_NODE_ID'];
68
+ else
69
+ process.env['CRTR_NODE_ID'] = originalNodeId;
70
+ }
71
+ });
72
+ test('review recap and naming input exclude inherited entries while retaining the post-boundary conversation', () => {
73
+ const originalNodeId = process.env['CRTR_NODE_ID'];
74
+ const originalHome = process.env['CRTR_HOME'];
75
+ const home = mkdtempSync(join(tmpdir(), 'crtr-recap-boundary-'));
76
+ const nodeId = 'review-recap-node';
77
+ const handlers = new Map();
78
+ let commandHandler;
79
+ const widgetWrites = [];
80
+ const recapInputs = [];
81
+ const namingInputs = [];
82
+ let entries = [
83
+ { type: 'message', message: { role: 'user', content: 'PREBOUNDARY_CANARY inherited request' } },
84
+ { type: 'message', message: { role: 'assistant', content: 'inherited answer' } },
85
+ {
86
+ type: 'custom_message',
87
+ customType: 'crtr-review-boundary',
88
+ details: { reviewId: 'review-1' },
89
+ },
90
+ { type: 'message', message: { role: 'user', content: 'review-only finding' } },
91
+ { type: 'message', message: { role: 'assistant', content: 'review-only resolution' } },
92
+ ];
93
+ const pi = {
94
+ on: (event, handler) => { handlers.set(event, handler); },
95
+ registerCommand: (_name, options) => {
96
+ commandHandler = options.handler;
97
+ },
98
+ getSessionName: () => 'developer',
99
+ setSessionName: () => undefined,
100
+ };
101
+ const sessionManager = { getEntries: () => entries };
102
+ const ctx = {
103
+ ui: { setWidget: (_key, content) => { widgetWrites.push(content); } },
104
+ sessionManager,
105
+ };
106
+ const recapGenerator = (conversation) => { recapInputs.push(conversation); };
107
+ try {
108
+ closeDb();
109
+ process.env['CRTR_HOME'] = home;
110
+ process.env['CRTR_NODE_ID'] = nodeId;
111
+ createNode({
112
+ node_id: nodeId,
113
+ name: 'developer',
114
+ created: new Date().toISOString(),
115
+ cwd: '/tmp/work',
116
+ kind: 'developer',
117
+ mode: 'base',
118
+ lifecycle: 'terminal',
119
+ status: 'active',
120
+ review_binding: {
121
+ review_id: 'review-1',
122
+ origin_node_id: 'origin',
123
+ branch_file: '/tmp/review.jsonl',
124
+ target_file: '/tmp/target.ts',
125
+ },
126
+ });
127
+ registerCanvasRecap(pi, recapGenerator, (_id, conversation) => { namingInputs.push(conversation); });
128
+ handlers.get('session_start')?.({}, ctx);
129
+ commandHandler?.('', ctx);
130
+ assert.equal(recapInputs.length, 1);
131
+ assert.equal(namingInputs.length, 1);
132
+ for (const input of [...recapInputs, ...namingInputs]) {
133
+ assert.doesNotMatch(input, /PREBOUNDARY_CANARY/);
134
+ assert.match(input, /review-only finding/);
135
+ assert.match(input, /review-only resolution/);
136
+ }
137
+ entries = [{ type: 'message', message: { role: 'user', content: 'PREBOUNDARY_CANARY without a boundary' } }];
138
+ handlers.get('message_update')?.({
139
+ message: { role: 'assistant', content: 'PREBOUNDARY_CANARY streaming response without a boundary' },
140
+ }, ctx);
141
+ commandHandler?.('', ctx);
142
+ assert.equal(recapInputs.length, 1, 'a markerless review produces no recap input, including a streaming partial');
143
+ assert.equal(namingInputs.length, 1, 'a markerless review produces no naming input, including a streaming partial');
144
+ assert.equal(widgetWrites.at(-1), undefined, 'a markerless review clears the recap widget');
145
+ }
146
+ finally {
147
+ handlers.get('session_shutdown')?.({}, ctx);
148
+ closeDb();
149
+ rmSync(home, { recursive: true, force: true });
150
+ if (originalHome === undefined)
151
+ delete process.env['CRTR_HOME'];
152
+ else
153
+ process.env['CRTR_HOME'] = originalHome;
154
+ if (originalNodeId === undefined)
155
+ delete process.env['CRTR_NODE_ID'];
156
+ else
157
+ process.env['CRTR_NODE_ID'] = originalNodeId;
158
+ }
159
+ });
@@ -90,44 +90,6 @@ after(() => {
90
90
  else
91
91
  process.env['TMUX_PANE'] = origPane;
92
92
  });
93
- test('pending private fork binds both child coordinates atomically, or shuts down unbound', () => {
94
- createNode(node('bound', {
95
- private_fork_phase: 'fork_pending',
96
- human_work_target: { work_kind: 'follow_up', dir: '/ticket', request_id: 'request-1', root: '/root' },
97
- private_fork_recipe: { kickoff: 'private kickoff' },
98
- }));
99
- process.env['CRTR_NODE_ID'] = 'bound';
100
- const pi = makeFakePi();
101
- registerCanvasStophook(pi);
102
- let boundShutdown = false;
103
- pi.fire('session_start', { type: 'session_start' }, {
104
- sessionManager: { getSessionId: () => 'child-id', getSessionFile: () => '/sessions/child.jsonl' },
105
- shutdown: () => { boundShutdown = true; },
106
- });
107
- const bound = getNode('bound');
108
- assert.equal(bound.private_fork_phase, 'session_started');
109
- assert.equal(bound.pi_session_id, 'child-id');
110
- assert.equal(bound.pi_session_file, '/sessions/child.jsonl');
111
- assert.equal(boundShutdown, false, 'a fully-bound child remains live');
112
- createNode(node('unbound', {
113
- private_fork_phase: 'fork_pending',
114
- human_work_target: { work_kind: 'follow_up', dir: '/ticket', request_id: 'request-2', root: '/root' },
115
- private_fork_recipe: { kickoff: 'private kickoff' },
116
- }));
117
- process.env['CRTR_NODE_ID'] = 'unbound';
118
- const missing = makeFakePi();
119
- registerCanvasStophook(missing);
120
- let missingShutdown = false;
121
- missing.fire('session_start', { type: 'session_start' }, {
122
- sessionManager: { getSessionId: () => 'child-id', getSessionFile: () => null },
123
- shutdown: () => { missingShutdown = true; },
124
- });
125
- const unbound = getNode('unbound');
126
- assert.equal(missingShutdown, true, 'a pending fork with no writable child session is shut down');
127
- assert.equal(unbound.private_fork_phase, 'fork_pending');
128
- assert.equal(unbound.pi_session_id ?? null, null);
129
- assert.equal(unbound.pi_session_file ?? null, null);
130
- });
131
93
  test('natural stop commits idle-release only at agent_settled', { timeout: 1_000 }, () => {
132
94
  createNode(node('root', { parent: null, lifecycle: 'resident' }));
133
95
  createNode(node('mgr', { parent: 'root', lifecycle: 'terminal', mode: 'orchestrator' }));
@@ -181,6 +143,22 @@ test('gh-451: idle-release does NOT release while a non-deferred inbox entry sit
181
143
  assert.equal(getNode('mgr')?.intent ?? null, null, 'no idle-release intent while a non-deferred entry is unseen');
182
144
  assert.equal(shutdown, false, 'pi stays alive so the in-process watcher can still deliver/commit');
183
145
  });
146
+ test('gh-451: finished does NOT shut down while a non-deferred inbox entry sits past the cursor', { timeout: 1_000 }, () => {
147
+ // A canonical final can settle while the in-process watcher has delivered a
148
+ // child report into the inbox but has not yet committed the durable cursor.
149
+ // The finished branch must keep this broker alive for that delivery.
150
+ createNode(node('mgr', { parent: null, lifecycle: 'terminal', final_report: 'mgr-final.md' }));
151
+ appendInbox('mgr', { from: 'worker', tier: 'normal', kind: 'update', label: 'worker made progress' });
152
+ process.env['CRTR_NODE_ID'] = 'mgr';
153
+ const pi = makeFakePi();
154
+ registerCanvasStophook(pi);
155
+ let shutdown = false;
156
+ const ctx = { shutdown: () => { shutdown = true; } };
157
+ settle(pi, stopEvent('already finalized'), ctx);
158
+ assert.equal(getNode('mgr')?.status, 'active', 'mgr stays active while the watcher catches up');
159
+ assert.equal(getNode('mgr')?.intent ?? null, null, 'no idle-release intent while a non-deferred entry is unseen');
160
+ assert.equal(shutdown, false, 'pi stays alive so the in-process watcher can still deliver/commit');
161
+ });
184
162
  test('gh-451: a DEFERRED-only unseen entry does not block idle-release (matches the daemon\'s own wake gate)', { timeout: 1_000 }, () => {
185
163
  createNode(node('root', { parent: null, lifecycle: 'resident' }));
186
164
  createNode(node('mgr', { parent: 'root', lifecycle: 'terminal', mode: 'orchestrator' }));
@@ -0,0 +1,63 @@
1
+ // Run with: node --import tsx/esm --test src/pi-extensions/__tests__/canvas-structured-output.test.ts
2
+ //
3
+ // Regression: Codex strict function schemas require every property in `required`.
4
+ import { after, test } from 'node:test';
5
+ import assert from 'node:assert/strict';
6
+ import { mkdtempSync, rmSync } from 'node:fs';
7
+ import { tmpdir } from 'node:os';
8
+ import { join } from 'node:path';
9
+ import { convertResponsesTools } from '@earendil-works/pi-ai/api/openai-responses-shared';
10
+ import { writeOutputSchema } from '../../core/runtime/structured-output.js';
11
+ import registerCanvasStructuredOutput from '../canvas-structured-output.js';
12
+ const previous = {
13
+ home: process.env['CRTR_HOME'],
14
+ nodeId: process.env['CRTR_NODE_ID'],
15
+ };
16
+ let home;
17
+ after(() => {
18
+ if (home !== undefined)
19
+ rmSync(home, { recursive: true, force: true });
20
+ if (previous.home === undefined)
21
+ delete process.env['CRTR_HOME'];
22
+ else
23
+ process.env['CRTR_HOME'] = previous.home;
24
+ if (previous.nodeId === undefined)
25
+ delete process.env['CRTR_NODE_ID'];
26
+ else
27
+ process.env['CRTR_NODE_ID'] = previous.nodeId;
28
+ });
29
+ test('optional submit fields remain optional through a strict provider tool schema', () => {
30
+ home = mkdtempSync(join(tmpdir(), 'crtr-structured-output-'));
31
+ process.env['CRTR_HOME'] = home;
32
+ process.env['CRTR_NODE_ID'] = 'structured-output-test';
33
+ const schema = {
34
+ type: 'object',
35
+ properties: {
36
+ status: { type: 'string' },
37
+ commit: { type: 'string' },
38
+ verification: { type: 'string' },
39
+ blocker: { type: 'string' },
40
+ },
41
+ required: ['status', 'verification'],
42
+ additionalProperties: false,
43
+ };
44
+ writeOutputSchema('structured-output-test', 'oneoff', schema);
45
+ let definition;
46
+ registerCanvasStructuredOutput({
47
+ registerTool(tool) {
48
+ definition = tool;
49
+ },
50
+ on() { },
51
+ });
52
+ assert.ok(definition, 'the pending request registers submit');
53
+ const parameters = definition['parameters'];
54
+ assert.deepEqual(parameters.required, ['status', 'commit', 'verification', 'blocker']);
55
+ assert.deepEqual(parameters.properties.commit, { anyOf: [{ type: 'string' }, { type: 'null' }] });
56
+ assert.deepEqual(parameters.properties.blocker, { anyOf: [{ type: 'string' }, { type: 'null' }] });
57
+ assert.deepEqual(schema.required, ['status', 'verification'], 'the stored request keeps its original optionality');
58
+ const [providerTool] = convertResponsesTools([definition], {
59
+ strict: false,
60
+ supportsStrictMode: true,
61
+ });
62
+ assert.equal(providerTool['strict'], true);
63
+ });
@@ -66,10 +66,12 @@ interface PiLike {
66
66
  expanded?: boolean;
67
67
  }, theme: ThemeLike) => ComponentLike | undefined) => void;
68
68
  }
69
- /** Build the <crtr-context> bearings block for `nodeId`. Thin wrapper over the
70
- * shared builder in core/runtime/bearings.ts (the single source of truth, also
71
- * used by the promotion guidance dump). Exported for testing. */
69
+ /** Build the full bearings baseline for a conversation without inherited
70
+ * crouter context. Exported for testing. */
72
71
  export declare function buildContextIntro(nodeId: string): string;
72
+ /** Build the compact node-scoped update for a fork whose copied branch already
73
+ * carries a full crouter baseline. Exported for testing. */
74
+ export declare function buildForkContextIntro(nodeId: string): string;
73
75
  /**
74
76
  * Renderer for `crtr-context` messages. Collapsed (default) shows a one-line
75
77
  * stub; expanded (Ctrl+O) shows the label + full body. Returns a plain object
@@ -79,13 +81,8 @@ export declare function buildContextIntro(nodeId: string): string;
79
81
  export declare function renderContextMessage(message: RenderedMessageLike, options: {
80
82
  expanded?: boolean;
81
83
  }, theme: ThemeLike): ComponentLike;
82
- /**
83
- * Register the context-intro preamble on `pi`.
84
- *
85
- * Returns immediately (inert) when CRTR_NODE_ID is absent. On `session_start`
86
- * it injects the <crtr-context> block as the first message of a brand-new chat
87
- * — but only when the session does not already carry it, so a `--session <id>`
88
- * relaunch (which restores the conversation) never duplicates the block.
89
- */
84
+ /** Register the context-intro preamble. Fresh branches receive one full
85
+ * baseline, forked crouter branches receive one compact update, and resumes
86
+ * whose active branch already carries this node's stamp receive nothing. */
90
87
  export declare function registerCanvasContextIntro(pi: PiLike): void;
91
88
  export default registerCanvasContextIntro;