@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
@@ -0,0 +1,198 @@
1
+ import { Parser } from 'tar';
2
+ import { validateCommandManifest } from '../command-manifests/manifest.js';
3
+ function issue(code, message, received, expected, next, path) {
4
+ return { code, message, received, expected, next, ...(path !== undefined ? { path } : {}) };
5
+ }
6
+ function bundleInvalid(message, received, expected, next, path) {
7
+ return issue('plugin_bundle_invalid', message, received, expected, next, path);
8
+ }
9
+ function archiveEnvelopeIssue(archive) {
10
+ // tar v7's Parser always sniffs gzip, even when passed gzip: false. Reject
11
+ // its unambiguous magic bytes before parsing so archive plugins stay tar-only.
12
+ if (archive[0] === 0x1f && archive[1] === 0x8b) {
13
+ return bundleInvalid('bundle archive must be uncompressed tar data', 'gzip-compressed archive', 'an uncompressed tar archive', 'Serve the archive without compression.');
14
+ }
15
+ if (archive.length === 0 || archive.length % 512 !== 0) {
16
+ return bundleInvalid('bundle archive must be a non-empty whole number of 512-byte tar blocks', `${archive.length} bytes`, 'a non-empty tar stream with a 512-byte block length', 'Serve one complete uncompressed tar archive.');
17
+ }
18
+ if (archive.length < 1024 || !archive.subarray(-1024).every((byte) => byte === 0)) {
19
+ return bundleInvalid('bundle archive is missing the required two zero-block terminator', 'archive tail is not 1024 zero bytes', 'a complete tar stream ending in two 512-byte zero blocks', 'Serve the complete uncompressed tar archive.');
20
+ }
21
+ return undefined;
22
+ }
23
+ function validateMemberName(path, type) {
24
+ if (path.length === 0 || path.includes('\u0000') || path.includes('\\') || path.startsWith('/') || /^[A-Za-z]:($|\/)/.test(path)) {
25
+ return bundleInvalid('bundle member path must be a safe relative POSIX path', path, 'a relative path without absolute, drive-letter, backslash, or NUL forms', 'Use a safe relative POSIX member path.', path);
26
+ }
27
+ if (type === 'file' && path.endsWith('/')) {
28
+ return bundleInvalid('only directory members may have a trailing slash', path, 'a regular-file path without a trailing slash', 'Emit this member as a regular file path.', path);
29
+ }
30
+ const segments = (type === 'directory' && path.endsWith('/') ? path.slice(0, -1) : path).split('/');
31
+ if (segments.some((segment) => segment === '' || segment === '.' || segment === '..')) {
32
+ return bundleInvalid('bundle member path contains an unsafe segment', path, 'non-empty segments other than . or ..', 'Use a safe relative POSIX member path.', path);
33
+ }
34
+ return undefined;
35
+ }
36
+ function validateMemberShape(path, type) {
37
+ if (type === 'file') {
38
+ if (path === 'bundle.json' || path === 'commands.json' || (path.startsWith('memory/') && path.endsWith('.md')))
39
+ return undefined;
40
+ return bundleInvalid('bundle contains an unsupported file member', path, 'bundle.json, commands.json, or memory/**/*.md', 'Remove unsupported members from the archive.', path);
41
+ }
42
+ if (path === 'memory' || path.startsWith('memory/'))
43
+ return undefined;
44
+ return bundleInvalid('bundle contains an unsupported directory member', path, 'memory or a directory below memory/', 'Remove unsupported directory members from the archive.', path);
45
+ }
46
+ /** A member path as it will exist on disk: directories carry no trailing slash. */
47
+ function materializedPath(member) {
48
+ return member.type === 'directory' && member.path.endsWith('/') ? member.path.slice(0, -1) : member.path;
49
+ }
50
+ /** Reject member sets that cannot become one filesystem tree — a path claimed as
51
+ * both a file and a directory, the same path twice after directory
52
+ * normalization, or a file that another member nests beneath. */
53
+ function validateMemberTree(members) {
54
+ const claimed = new Map();
55
+ for (const member of members) {
56
+ const path = materializedPath(member);
57
+ const existing = claimed.get(path);
58
+ if (existing !== undefined) {
59
+ return bundleInvalid(existing === member.type
60
+ ? 'bundle contains a duplicate member'
61
+ : 'bundle claims one path as both a file and a directory', `${path} (${existing} and ${member.type})`, 'each materialized path exactly once, with one type', 'Emit each archive path once, as a single member type.', path);
62
+ }
63
+ claimed.set(path, member.type);
64
+ }
65
+ for (const [path, type] of claimed) {
66
+ if (type !== 'file')
67
+ continue;
68
+ for (const other of claimed.keys()) {
69
+ if (other.startsWith(`${path}/`)) {
70
+ return bundleInvalid('bundle nests a member beneath a regular-file path', `${other} beneath file ${path}`, 'members nested only beneath directory paths', 'Emit the parent path as a directory or remove the nested member.', other);
71
+ }
72
+ }
73
+ }
74
+ return undefined;
75
+ }
76
+ async function parseArchive(archive) {
77
+ const members = [];
78
+ const seen = new Set();
79
+ let memberIssue;
80
+ await new Promise((resolve, reject) => {
81
+ const parser = new Parser({
82
+ strict: true,
83
+ maxMetaEntrySize: Number.MAX_SAFE_INTEGER,
84
+ gzip: false,
85
+ brotli: false,
86
+ zstd: false,
87
+ onReadEntry: (entry) => {
88
+ const path = entry.path;
89
+ const type = entry.type === 'File' || entry.type === 'OldFile'
90
+ ? 'file'
91
+ : entry.type === 'Directory'
92
+ ? 'directory'
93
+ : undefined;
94
+ if (type === undefined || entry.unsupported || entry.ignore || entry.linkpath !== undefined) {
95
+ memberIssue ??= bundleInvalid('bundle member must be a regular file or directory without a link target', `${path} (${entry.type})`, 'a regular file or directory member without link metadata', 'Remove links and unsupported member types from the archive.', path);
96
+ entry.resume();
97
+ return;
98
+ }
99
+ memberIssue ??= validateMemberName(path, type);
100
+ memberIssue ??= validateMemberShape(path, type);
101
+ if (seen.has(path)) {
102
+ memberIssue ??= bundleInvalid('bundle contains a duplicate member', path, 'each member path exactly once', 'Emit each archive member only once.', path);
103
+ }
104
+ seen.add(path);
105
+ const chunks = [];
106
+ entry.on('data', (chunk) => chunks.push(chunk));
107
+ entry.on('end', () => {
108
+ if (memberIssue === undefined)
109
+ members.push({ path, type, bytes: new Uint8Array(Buffer.concat(chunks)) });
110
+ });
111
+ },
112
+ });
113
+ parser.on('ignoredEntry', (entry) => {
114
+ const path = entry.path;
115
+ memberIssue ??= bundleInvalid('bundle contains an ignored or unsupported archive member', `${path} (${entry.type})`, 'only supported regular file or directory members', 'Remove ignored or unsupported members from the archive.', path);
116
+ entry.resume();
117
+ });
118
+ parser.once('error', reject);
119
+ parser.once('end', resolve);
120
+ try {
121
+ parser.end(Buffer.from(archive));
122
+ }
123
+ catch (error) {
124
+ reject(error);
125
+ }
126
+ }).catch((error) => {
127
+ memberIssue ??= bundleInvalid('bundle archive could not be parsed', error instanceof Error ? error.message : String(error), 'a valid complete uncompressed tar archive', 'Fix the archive format and serve it again.');
128
+ });
129
+ return memberIssue === undefined ? { members } : { issue: memberIssue };
130
+ }
131
+ function parseBundleMetadata(bytes) {
132
+ let raw;
133
+ try {
134
+ raw = JSON.parse(Buffer.from(bytes).toString('utf8'));
135
+ }
136
+ catch {
137
+ return bundleInvalid('bundle.json is not valid JSON', 'invalid JSON', '{"bundleVersion":1}', 'Write valid bundle metadata.', 'bundle.json');
138
+ }
139
+ if (typeof raw !== 'object' || raw === null || Array.isArray(raw) || Object.keys(raw).length !== 1 || raw['bundleVersion'] !== 1) {
140
+ return bundleInvalid('bundle.json must contain exactly {"bundleVersion":1}', JSON.stringify(raw), 'an object with only bundleVersion set to 1', 'Set bundle.json to {"bundleVersion":1}.', 'bundle.json');
141
+ }
142
+ return undefined;
143
+ }
144
+ function parseCommands(bytes, reservedCoreNames) {
145
+ let raw;
146
+ try {
147
+ raw = JSON.parse(Buffer.from(bytes).toString('utf8'));
148
+ }
149
+ catch {
150
+ return {
151
+ issues: [bundleInvalid('commands.json is not valid JSON', 'invalid JSON', 'a valid command-manifest JSON object', 'Regenerate commands.json.', 'commands.json')],
152
+ };
153
+ }
154
+ const validation = validateCommandManifest(raw, { transport: 'http', reservedCoreNames });
155
+ return {
156
+ ...(validation.manifest !== undefined ? { commands: validation.manifest } : {}),
157
+ issues: validation.issues,
158
+ };
159
+ }
160
+ /** Validate a Core-served plugin directory archive entirely in memory. */
161
+ export async function validatePluginBundle(archive, options) {
162
+ const envelope = archiveEnvelopeIssue(archive);
163
+ if (envelope !== undefined)
164
+ return { issues: [envelope] };
165
+ const parsed = await parseArchive(archive);
166
+ if (parsed.issue !== undefined || parsed.members === undefined)
167
+ return { issues: [parsed.issue] };
168
+ const treeIssue = validateMemberTree(parsed.members);
169
+ if (treeIssue !== undefined)
170
+ return { issues: [treeIssue] };
171
+ const bundle = parsed.members.find((member) => member.path === 'bundle.json' && member.type === 'file');
172
+ const commands = parsed.members.find((member) => member.path === 'commands.json' && member.type === 'file');
173
+ if (bundle === undefined || commands === undefined) {
174
+ return {
175
+ issues: [bundleInvalid('bundle must contain exactly one bundle.json and one commands.json regular file', `bundle.json=${bundle !== undefined}, commands.json=${commands !== undefined}`, 'one regular bundle.json and one regular commands.json member', 'Add the required metadata members to the archive.')],
176
+ };
177
+ }
178
+ const metadataIssue = parseBundleMetadata(bundle.bytes);
179
+ if (metadataIssue !== undefined)
180
+ return { issues: [metadataIssue] };
181
+ const commandValidation = parseCommands(commands.bytes, options.reservedCoreNames);
182
+ if (commandValidation.commands === undefined)
183
+ return { issues: commandValidation.issues };
184
+ return {
185
+ bundle: {
186
+ bundleVersion: 1,
187
+ commands: commandValidation.commands,
188
+ commandsBytes: commands.bytes,
189
+ directories: parsed.members
190
+ .filter((member) => member.type === 'directory')
191
+ .map((member) => ({ path: member.path })),
192
+ memory: parsed.members
193
+ .filter((member) => member.type === 'file' && member.path.startsWith('memory/'))
194
+ .map((member) => ({ path: member.path, bytes: member.bytes })),
195
+ },
196
+ issues: [],
197
+ };
198
+ }
@@ -2,7 +2,6 @@ import type { InstalledPlugin, PluginTransport } from '../../types.js';
2
2
  import { type ValidatedCommandManifest } from '../command-manifests/manifest.js';
3
3
  import type { CommandManifestIssue, DeclBranch as DeclBranchGeneric, DeclLeaf as DeclLeafGeneric } from '../command-manifests/schema.js';
4
4
  import type { CommandRegistrySnapshot } from '../command-manifests/registry.js';
5
- import type { HttpPluginManifestStore } from './store.js';
6
5
  export interface CommandDiscoveryIssue extends CommandManifestIssue {
7
6
  plugin: string;
8
7
  }
@@ -22,12 +21,6 @@ export interface PluginCommandValidation {
22
21
  transport?: PluginTransport;
23
22
  contributions: ValidatedContribution[];
24
23
  issues: CommandDiscoveryIssue[];
25
- absentStore?: boolean;
26
- httpManifestStore?: HttpPluginManifestStore;
27
- }
28
- export interface AbsentStoreHydration {
29
- hydratedAny: boolean;
30
- diagnostics: string[];
31
24
  }
32
25
  export declare function effectiveCommandPlugins(startDir?: string, profileId?: string | null): InstalledPlugin[];
33
26
  export declare function validatePluginCommands(plugin: InstalledPlugin, reservedNames?: ReadonlySet<string>): PluginCommandValidation;
@@ -38,4 +31,3 @@ export declare function discoverCommandContributions(reservedNames: ReadonlySet<
38
31
  issues: CommandDiscoveryIssue[];
39
32
  };
40
33
  export declare function buildExternalCommandSnapshot(reservedCoreNames: ReadonlySet<string>): CommandRegistrySnapshot;
41
- export declare function hydrateAbsentHttpPlugins(): Promise<AbsentStoreHydration>;
@@ -6,8 +6,6 @@ import { validateCommandManifest } from '../command-manifests/manifest.js';
6
6
  import { resolveCommandRegistry } from '../command-manifests/registry.js';
7
7
  import { adaptPluginContributions } from './compose.js';
8
8
  import { validateHttpPluginTransport } from './endpoint.js';
9
- import { readHttpPluginManifest, resolveHttpPluginManifestStore, writeHttpPluginManifest } from './store.js';
10
- import { fetchHttpPluginManifest } from './transport/http-fetch.js';
11
9
  export function effectiveCommandPlugins(startDir = process.cwd(), profileId) {
12
10
  const seen = new Set();
13
11
  const result = [];
@@ -97,10 +95,7 @@ export function validatePluginCommands(plugin, reservedNames = new Set()) {
97
95
  const transport = transportFor(plugin, issues);
98
96
  if (transport === undefined)
99
97
  return { plugin, manifestPath, contributions: [], issues };
100
- const httpManifestStore = transport.kind === 'http'
101
- ? resolveHttpPluginManifestStore({ root: plugin.root, commands }) ?? undefined
102
- : undefined;
103
- const safe = transport.kind === 'http' ? httpManifestStore?.path ?? null : safePath(plugin.root, commands);
98
+ const safe = safePath(plugin.root, commands);
104
99
  if (safe === null) {
105
100
  issues.push({ code: 'command_path_unsafe', plugin: plugin.name, message: 'commands pointer escapes the plugin root or is not a regular file', received: commands, expected: 'a relative path to a regular file inside the plugin root', next: 'Fix plugin.json.commands.', path: 'commands' });
106
101
  return { plugin, manifestPath, transport, contributions: [], issues };
@@ -108,14 +103,12 @@ export function validatePluginCommands(plugin, reservedNames = new Set()) {
108
103
  manifestPath = safe;
109
104
  let bytes;
110
105
  try {
111
- bytes = transport.kind === 'http' ? readHttpPluginManifest(httpManifestStore) : readFileSync(safe);
106
+ bytes = readFileSync(safe);
112
107
  }
113
108
  catch {
114
109
  bytes = null;
115
110
  }
116
111
  if (bytes === null) {
117
- if (transport.kind === 'http')
118
- return { plugin, manifestPath, transport, contributions: [], issues, absentStore: true, httpManifestStore };
119
112
  issues.push({ code: 'command_manifest_unreadable', plugin: plugin.name, message: 'commands.json is missing or unreadable', received: safe, expected: 'a readable JSON file', next: 'Reinstall or update the plugin.' });
120
113
  return { plugin, manifestPath, transport, contributions: [], issues };
121
114
  }
@@ -124,8 +117,6 @@ export function validatePluginCommands(plugin, reservedNames = new Set()) {
124
117
  raw = JSON.parse(Buffer.from(bytes).toString('utf8'));
125
118
  }
126
119
  catch {
127
- if (transport.kind === 'http')
128
- return { plugin, manifestPath, transport, contributions: [], issues, absentStore: true, httpManifestStore };
129
120
  issues.push({ code: 'command_manifest_invalid', plugin: plugin.name, message: 'commands.json is not valid JSON', received: safe, expected: 'a JSON object', next: 'Regenerate commands.json.' });
130
121
  return { plugin, manifestPath, transport, contributions: [], issues };
131
122
  }
@@ -171,31 +162,3 @@ export function buildExternalCommandSnapshot(reservedCoreNames) {
171
162
  const resolved = resolveCommandRegistry(candidates, reservedCoreNames);
172
163
  return { contributions: resolved.contributions, issues: [...validations.flatMap((validation) => validation.issues.map((issue) => contributorIssue(validation.plugin, issue))), ...resolved.issues] };
173
164
  }
174
- export async function hydrateAbsentHttpPlugins() {
175
- let hydratedAny = false;
176
- const diagnostics = [];
177
- for (const validation of discoverPluginCommandCandidates()) {
178
- if (validation.transport?.kind !== 'http')
179
- continue;
180
- const unsafePath = validation.issues.find((issue) => issue.code === 'command_path_unsafe');
181
- if (unsafePath !== undefined) {
182
- diagnostics.push(`HTTP plugin "${validation.plugin.name}": ${unsafePath.code}: ${unsafePath.message} — ${unsafePath.next}`);
183
- continue;
184
- }
185
- if (!validation.absentStore || validation.httpManifestStore === undefined)
186
- continue;
187
- try {
188
- const result = await fetchHttpPluginManifest({ name: validation.plugin.name, endpoint: validation.transport.endpoint, ...(validation.transport.authEnv !== undefined ? { authEnv: validation.transport.authEnv } : {}) });
189
- if (result.status === 200) {
190
- writeHttpPluginManifest(validation.httpManifestStore, result.raw);
191
- hydratedAny = true;
192
- }
193
- else
194
- diagnostics.push(`HTTP plugin "${validation.plugin.name}": ${result.message} — run \`crtr pkg plugin update --name ${validation.plugin.name}\``);
195
- }
196
- catch (error) {
197
- diagnostics.push(`HTTP plugin "${validation.plugin.name}": ${error.message} — run \`crtr pkg plugin update --name ${validation.plugin.name}\``);
198
- }
199
- }
200
- return { hydratedAny, diagnostics };
201
- }
@@ -1,42 +1,16 @@
1
1
  import type { HttpPluginFetchTarget } from '../endpoint.js';
2
- import type { HttpPluginManifestStore } from '../store.js';
3
- /** Result of a successful manifest fetch. */
2
+ /** Exact archive bytes returned by a successful authenticated bundle fetch. */
4
3
  export interface FetchSuccess {
5
4
  status: 200;
6
5
  raw: Uint8Array;
7
6
  }
8
- /** Typed failures from manifest fetch. */
9
7
  export type FetchResult = FetchSuccess | FetchFailure;
10
8
  export interface FetchFailure {
11
9
  status: 'auth_env_missing' | 'cli_unreachable' | 'cli_protocol_error';
12
10
  message: string;
13
11
  }
14
12
  /**
15
- * Fetch a HTTP-transport plugin manifest from the registered endpoint.
16
- *
17
- * Implements the core authenticated GET primitive for T0/T2/T4 fetches:
18
- * - Reads bearer token from `authEnv` env var at invocation time
19
- * - Fails with `auth_env_missing` USAGE before network if env var is named but empty
20
- * - Performs one GET request with `Accept: application/json` header
21
- * - Attaches `Authorization: Bearer <token>` header when auth var is configured
22
- * - A single 10-second socket-inactivity timeout (Node's `timeout` option) covers
23
- * the whole request — there is no separate connect clock and no 30s total cap;
24
- * that two-clock model belongs to the invoker's per-leaf HTTP calls (§6.6), not
25
- * this simpler manifest-fetch primitive.
26
- * - Returns exact response bytes on 2xx success
27
- * - Returns typed `cli_unreachable` NETWORK on transport/timeout failures
28
- * - Returns typed `cli_protocol_error` GENERAL on non-2xx without parseable error body
29
- *
30
- * No retries, no conditional request (ETag/If-None-Match), no 304 handling.
13
+ * One authenticated GET for a plugin directory archive. It has one ten-second
14
+ * inactivity timeout and never retries or conditionally revalidates.
31
15
  */
32
- export declare function fetchHttpPluginManifest(registration: HttpPluginFetchTarget): Promise<FetchResult>;
33
- /**
34
- * Explicit refresh: unconditional fetch and replace stored manifest.
35
- *
36
- * Called when user runs `crtr pkg plugin update <name>`. Always fetches
37
- * regardless of stored-manifest state, and replaces it on success.
38
- * On failure, preserves existing manifest bytes and throws CrtrError.
39
- *
40
- * Returns the raw manifest bytes on success.
41
- */
42
- export declare function refreshHttpPlugin(target: HttpPluginFetchTarget, store: HttpPluginManifestStore): Promise<Uint8Array>;
16
+ export declare function fetchHttpPluginBundle(registration: HttpPluginFetchTarget): Promise<FetchResult>;
@@ -1,31 +1,11 @@
1
1
  import { URL } from 'node:url';
2
2
  import { request as httpsRequest } from 'node:https';
3
3
  import { request as httpRequest } from 'node:http';
4
- import { writeHttpPluginManifest } from '../store.js';
5
- import { general, network, usage } from '../../errors.js';
6
- // ---------------------------------------------------------------------------
7
- // Core fetch primitive
8
- // ---------------------------------------------------------------------------
9
4
  /**
10
- * Fetch a HTTP-transport plugin manifest from the registered endpoint.
11
- *
12
- * Implements the core authenticated GET primitive for T0/T2/T4 fetches:
13
- * - Reads bearer token from `authEnv` env var at invocation time
14
- * - Fails with `auth_env_missing` USAGE before network if env var is named but empty
15
- * - Performs one GET request with `Accept: application/json` header
16
- * - Attaches `Authorization: Bearer <token>` header when auth var is configured
17
- * - A single 10-second socket-inactivity timeout (Node's `timeout` option) covers
18
- * the whole request — there is no separate connect clock and no 30s total cap;
19
- * that two-clock model belongs to the invoker's per-leaf HTTP calls (§6.6), not
20
- * this simpler manifest-fetch primitive.
21
- * - Returns exact response bytes on 2xx success
22
- * - Returns typed `cli_unreachable` NETWORK on transport/timeout failures
23
- * - Returns typed `cli_protocol_error` GENERAL on non-2xx without parseable error body
24
- *
25
- * No retries, no conditional request (ETag/If-None-Match), no 304 handling.
5
+ * One authenticated GET for a plugin directory archive. It has one ten-second
6
+ * inactivity timeout and never retries or conditionally revalidates.
26
7
  */
27
- export async function fetchHttpPluginManifest(registration) {
28
- // Check auth env var and fail before network if named but empty
8
+ export async function fetchHttpPluginBundle(registration) {
29
9
  let token;
30
10
  if (registration.authEnv) {
31
11
  token = process.env[registration.authEnv];
@@ -36,101 +16,43 @@ export async function fetchHttpPluginManifest(registration) {
36
16
  };
37
17
  }
38
18
  }
39
- // Parse endpoint URL
40
19
  let url;
41
20
  try {
42
21
  url = new URL(registration.endpoint);
43
22
  }
44
- catch (err) {
23
+ catch {
45
24
  return {
46
25
  status: 'cli_protocol_error',
47
26
  message: `Invalid endpoint URL: ${registration.endpoint}`,
48
27
  };
49
28
  }
50
- // Prepare request headers
51
- const headers = {
52
- 'Accept': 'application/json',
53
- };
54
- if (token) {
29
+ const headers = { Accept: 'application/x-tar' };
30
+ if (token)
55
31
  headers['Authorization'] = `Bearer ${token}`;
56
- }
57
- // Perform the GET request
58
32
  return new Promise((resolve) => {
59
33
  const request = url.protocol === 'https:' ? httpsRequest : httpRequest;
60
- const options = {
61
- method: 'GET',
62
- headers,
63
- timeout: 10_000, // 10 second manifest fetch timeout per spec §6.6
64
- };
65
- const req = request(url, options, (res) => {
34
+ const req = request(url, { method: 'GET', headers, timeout: 10_000 }, (res) => {
66
35
  let body = Buffer.alloc(0);
67
- res.on('data', (chunk) => {
68
- body = Buffer.concat([body, chunk]);
69
- });
36
+ res.on('data', (chunk) => { body = Buffer.concat([body, chunk]); });
70
37
  res.on('end', () => {
71
38
  if (!res.statusCode) {
72
- resolve({
73
- status: 'cli_protocol_error',
74
- message: 'No HTTP status code received.',
75
- });
76
- return;
39
+ resolve({ status: 'cli_protocol_error', message: 'No HTTP status code received.' });
77
40
  }
78
- // Success: 2xx status
79
- if (res.statusCode >= 200 && res.statusCode < 300) {
80
- resolve({
81
- status: 200,
82
- raw: new Uint8Array(body),
83
- });
84
- return;
41
+ else if (res.statusCode >= 200 && res.statusCode < 300) {
42
+ resolve({ status: 200, raw: new Uint8Array(body) });
43
+ }
44
+ else {
45
+ resolve({ status: 'cli_protocol_error', message: `HTTP ${res.statusCode} from ${registration.endpoint}` });
85
46
  }
86
- // Non-2xx failure
87
- resolve({
88
- status: 'cli_protocol_error',
89
- message: `HTTP ${res.statusCode} from ${registration.endpoint}`,
90
- });
91
47
  });
92
48
  });
93
49
  req.on('timeout', () => {
94
50
  req.destroy();
95
- resolve({
96
- status: 'cli_unreachable',
97
- message: `Request timeout (10s) fetching ${registration.endpoint}`,
98
- });
51
+ resolve({ status: 'cli_unreachable', message: `Request timeout (10s) fetching ${registration.endpoint}` });
99
52
  });
100
- req.on('error', (err) => {
101
- resolve({
102
- status: 'cli_unreachable',
103
- message: `Network error fetching ${registration.endpoint}: ${err.message}`,
104
- });
53
+ req.on('error', (error) => {
54
+ resolve({ status: 'cli_unreachable', message: `Network error fetching ${registration.endpoint}: ${error.message}` });
105
55
  });
106
56
  req.end();
107
57
  });
108
58
  }
109
- // ---------------------------------------------------------------------------
110
- // Store-integrated helpers
111
- // ---------------------------------------------------------------------------
112
- /**
113
- * Explicit refresh: unconditional fetch and replace stored manifest.
114
- *
115
- * Called when user runs `crtr pkg plugin update <name>`. Always fetches
116
- * regardless of stored-manifest state, and replaces it on success.
117
- * On failure, preserves existing manifest bytes and throws CrtrError.
118
- *
119
- * Returns the raw manifest bytes on success.
120
- */
121
- export async function refreshHttpPlugin(target, store) {
122
- // Unconditional fetch
123
- const result = await fetchHttpPluginManifest(target);
124
- if (result.status !== 200) {
125
- if (result.status === 'auth_env_missing') {
126
- throw usage(result.message);
127
- }
128
- if (result.status === 'cli_unreachable') {
129
- throw network(result.message);
130
- }
131
- throw general(result.message);
132
- }
133
- // Write to the resolved HTTP manifest store.
134
- writeHttpPluginManifest(store, result.raw);
135
- return result.raw;
136
- }
@@ -166,17 +166,5 @@ export interface ParseArgvOptions {
166
166
  * Returns a plain object whose keys are camelCase parameter names.
167
167
  * Optionally tracks which parameters were explicitly provided via a callback. */
168
168
  export declare function parseArgv(params: InputParam[], tokens: string[], options?: ParseArgvOptions): Promise<Record<string, unknown>>;
169
- /** Optional seams for `runCli`. */
170
- export interface RunCliOptions {
171
- /** The one unknown-first-token retry seam. Called exactly once only when an
172
- * unknown first token misses at root (walk stopped at root, `path` empty,
173
- * on a real non-help token), where absent HTTP-plugin stores may hydrate.
174
- * A deeper unknown token under a known command (`path` non-empty) never
175
- * calls it. It returns a freshly rebuilt root when hydration produced new
176
- * commands to re-walk the original argv against, otherwise undefined to
177
- * surface the plain `unknown_path` error. crtr's core fast path passes no
178
- * options, so a recognized core first token has zero HTTP-plugin I/O. */
179
- onUnknownFirstTokenMiss?: () => Promise<RootDef | undefined>;
180
- }
181
- export declare function runCli(root: RootDef, argv: string[], options?: RunCliOptions): Promise<void>;
169
+ export declare function runCli(root: RootDef, argv: string[]): Promise<void>;
182
170
  export {};
@@ -547,7 +547,7 @@ export async function parseArgv(params, tokens, options) {
547
547
  }
548
548
  return result;
549
549
  }
550
- export async function runCli(root, argv, options) {
550
+ export async function runCli(root, argv) {
551
551
  // argv is process.argv — strip node binary + script path. `--json` is a
552
552
  // global: pull it out anywhere it appears so the rest of argv parses against
553
553
  // the leaf schema unchanged, and switch stdout from rendered prose to raw
@@ -570,21 +570,6 @@ export async function runCli(root, argv, options) {
570
570
  }
571
571
  let { node, path, remaining } = walk(root, tokens);
572
572
  try {
573
- // An unknown first token that misses at root is the only site absent
574
- // HTTP-plugin stores may hydrate. A deeper unknown token under a known
575
- // command never triggers it. Invoke the seam once; if it hydrated commands,
576
- // re-walk the original argv against the rebuilt root. Keeping it inside the
577
- // try sends any seam failure through the ordinary error handler.
578
- if (options?.onUnknownFirstTokenMiss !== undefined &&
579
- node.kind === 'root' &&
580
- path.length === 0 &&
581
- remaining.length > 0 &&
582
- remaining[0] !== '-h' &&
583
- remaining[0] !== '--help') {
584
- const rebuilt = await options.onUnknownFirstTokenMiss();
585
- if (rebuilt !== undefined)
586
- ({ node, path, remaining } = walk(rebuilt, tokens));
587
- }
588
573
  // Passthrough branches (e.g. `crtr capture`) opt out of the tree model
589
574
  // entirely: forward every token after the branch verbatim to an external
590
575
  // binary before any of the normal unknown-path / help / dispatch logic
@@ -1,4 +1,5 @@
1
1
  import type { Scope, ScopeConfig, ScopeState, KindConfig, ModelLaddersConfig, ModelProvider, ModelStrength, ModelRouteConfig, ModelRoutingConfig } from '../types.js';
2
+ import { type BindingId } from './keybindings/catalog.js';
2
3
  export declare function configPath(scope: Scope): string | null;
3
4
  export declare function statePath(scope: Scope): string | null;
4
5
  export declare function readConfig(scope: Scope): ScopeConfig;
@@ -22,6 +23,9 @@ export declare function writeConfig(scope: Scope, config: ScopeConfig): void;
22
23
  export declare function writeRawConfig(scope: Scope, config: Partial<ScopeConfig>): void;
23
24
  export declare function writeState(scope: Scope, state: ScopeState): void;
24
25
  export declare function ensureScopeInitialized(scope: Scope, root: string): void;
26
+ /** Normalize the user-owned list of attach actions allowed to bridge through an
27
+ * occupied tmux root binding. Unknown and non-attach ids have no effect. */
28
+ export declare function normalizeTmuxPassthrough(raw: unknown): BindingId[];
25
29
  /** Raw (un-defaulted) partial config for one scope, or null if the scope has
26
30
  * no root or no config.json. Used by `readMergedLaunchConfig` to layer
27
31
  * scopes onto each other WITHOUT each scope's own default-fill masking a
@@ -1,12 +1,14 @@
1
1
  import { mkdirSync, rmSync } from 'node:fs';
2
2
  import { dirname, join } from 'node:path';
3
3
  import { isDeepStrictEqual } from 'node:util';
4
- import { CONFIG_FILE, STATE_FILE, CONDENSED_HISTORY_MODES, defaultScopeConfig, defaultScopeState, defaultModelLaddersConfig, defaultKindsConfig, defaultRemoteCanvasConfig } from '../types.js';
4
+ import { CONFIG_FILE, STATE_FILE, CONDENSED_HISTORY_MODES, MOUSE_MODE_DEFAULTS, DEFAULT_WHIP_MESSAGES, defaultScopeConfig, defaultScopeState, defaultModelLaddersConfig, defaultKindsConfig, defaultRemoteCanvasConfig } from '../types.js';
5
+ import { BINDING_CATALOG, BINDING_IDS, isAttachPaneBinding } from './keybindings/catalog.js';
5
6
  import { emitEvent } from './events/emit.js';
6
7
  import { atomicWriteJson, readJsonIfExists, writeJson, ensureDir } from './fs-utils.js';
7
8
  import { scopeRoot, requireScopeRoot, findProjectScopeRoots } from './scope.js';
8
9
  import { profileRoot } from './profiles/manifest.js';
9
10
  import { SCOPE_CONFIG_KEYS } from './user-settings.js';
11
+ import { normalizeWorkingGerunds } from '../shared/working-activity.js';
10
12
  function configPathFor(root) {
11
13
  return join(root, CONFIG_FILE);
12
14
  }
@@ -132,7 +134,7 @@ export function ensureScopeInitialized(scope, root) {
132
134
  // a missing `modelLadders` from whatever build is CURRENTLY running, and an explicit
133
135
  // user override (`sys config set modelLadders...`) still persists and still wins.
134
136
  // Keybindings are sparse user overrides, so an untouched scope omits that member too.
135
- const { modelLadders: _omittedModelLadders, keybindings: _omittedKeybindings, brokerThresholds, ...rest } = defaultScopeConfig();
137
+ const { modelLadders: _omittedModelLadders, keybindings: _omittedKeybindings, tmux_passthrough: _omittedTmuxPassthrough, brokerThresholds, ...rest } = defaultScopeConfig();
136
138
  // Broker thresholds are host-wide daemon policy, so only user scope
137
139
  // persists them. Project config must never acquire a machine setting.
138
140
  atomicWriteJson(cfgPath, scope === 'user' ? { ...rest, brokerThresholds } : rest);
@@ -149,6 +151,14 @@ function normalizeKeybindings(raw) {
149
151
  }
150
152
  return out;
151
153
  }
154
+ const ATTACH_PANE_BINDING_IDS = new Set(BINDING_CATALOG.filter(isAttachPaneBinding).map((definition) => definition.id));
155
+ /** Normalize the user-owned list of attach actions allowed to bridge through an
156
+ * occupied tmux root binding. Unknown and non-attach ids have no effect. */
157
+ export function normalizeTmuxPassthrough(raw) {
158
+ if (!Array.isArray(raw))
159
+ return [];
160
+ return [...new Set(raw.filter((id) => typeof id === 'string' && BINDING_IDS.has(id) && ATTACH_PANE_BINDING_IDS.has(id)))];
161
+ }
152
162
  function mergeModelLadders(raw, base = defaultModelLaddersConfig()) {
153
163
  const defaults = base;
154
164
  if (raw === null || typeof raw !== 'object')
@@ -414,6 +424,12 @@ function mergeBrokerThresholds(raw, defaults) {
414
424
  ? { warning, automaticReviveCap }
415
425
  : { ...defaults };
416
426
  }
427
+ function normalizeWhipMessages(raw) {
428
+ if (!Array.isArray(raw))
429
+ return [...DEFAULT_WHIP_MESSAGES];
430
+ const messages = raw.filter((message) => typeof message === 'string' && message.trim() !== '').map((message) => message.trim());
431
+ return messages.length > 0 ? messages : [...DEFAULT_WHIP_MESSAGES];
432
+ }
417
433
  function mergeConfig(partial) {
418
434
  const defaults = defaultScopeConfig();
419
435
  const schema_version = defaults.schema_version;
@@ -436,19 +452,28 @@ function mergeConfig(partial) {
436
452
  : defaults.auto_open_child_viewers;
437
453
  const brokerThresholds = mergeBrokerThresholds(partial.brokerThresholds, defaults.brokerThresholds);
438
454
  const completion_bell = typeof partial.completion_bell === 'boolean' ? partial.completion_bell : defaults.completion_bell;
455
+ const working_gerunds = normalizeWorkingGerunds(partial.working_gerunds);
456
+ const whip_mode = typeof partial.whip_mode === 'boolean' ? partial.whip_mode : defaults.whip_mode;
457
+ const whip_messages = normalizeWhipMessages(partial.whip_messages);
458
+ const mouse_mode_default = MOUSE_MODE_DEFAULTS.includes(partial.mouse_mode_default)
459
+ ? partial.mouse_mode_default
460
+ : defaults.mouse_mode_default;
439
461
  const live_cycles = normalizePositiveInteger(partial.live_cycles, defaults.live_cycles);
440
462
  const condensed_history = CONDENSED_HISTORY_MODES.includes(partial.condensed_history)
441
463
  ? partial.condensed_history
442
464
  : defaults.condensed_history;
443
465
  const fold_finished_tools = typeof partial.fold_finished_tools === 'boolean' ? partial.fold_finished_tools : defaults.fold_finished_tools;
466
+ const summarize_tool_calls = typeof partial.summarize_tool_calls === 'boolean' ? partial.summarize_tool_calls : defaults.summarize_tool_calls;
467
+ const detailed_tool_recaps = typeof partial.detailed_tool_recaps === 'boolean' ? partial.detailed_tool_recaps : defaults.detailed_tool_recaps;
444
468
  const keybindings = normalizeKeybindings(partial.keybindings);
469
+ const tmux_passthrough = normalizeTmuxPassthrough(partial.tmux_passthrough);
445
470
  const modelLadders = mergeModelLadders(partial.modelLadders);
446
471
  const modelRoutes = mergeModelRoutes(partial.modelRoutes);
447
472
  const modelRouting = mergeModelRouting(partial.modelRouting, undefined);
448
473
  const kinds = mergeKinds(partial.kinds);
449
474
  const remoteCanvas = mergeRemoteCanvas(partial.remoteCanvas);
450
475
  const spawnEnv = mergeSpawnEnv(partial.spawnEnv, defaults.spawnEnv?.allow);
451
- return { schema_version, marketplaces, plugins, auto_update, max_panes_per_window, auto_open_child_viewers, brokerThresholds, completion_bell, live_cycles, condensed_history, fold_finished_tools, keybindings, modelLadders, ...(Object.keys(modelRoutes).length > 0 ? { modelRoutes } : {}), ...(modelRouting !== undefined ? { modelRouting } : {}), kinds, remoteCanvas, spawnEnv };
476
+ return { schema_version, marketplaces, plugins, auto_update, max_panes_per_window, auto_open_child_viewers, brokerThresholds, completion_bell, working_gerunds, whip_mode, whip_messages, mouse_mode_default, live_cycles, condensed_history, fold_finished_tools, summarize_tool_calls, detailed_tool_recaps, keybindings, tmux_passthrough, modelLadders, ...(Object.keys(modelRoutes).length > 0 ? { modelRoutes } : {}), ...(modelRouting !== undefined ? { modelRouting } : {}), kinds, remoteCanvas, spawnEnv };
452
477
  }
453
478
  /** Raw (un-defaulted) partial config for one scope, or null if the scope has
454
479
  * no root or no config.json. Used by `readMergedLaunchConfig` to layer