@north-light/cli 0.3.561 → 0.3.563

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 (579) hide show
  1. package/dist/api/client.d.ts +27 -4
  2. package/dist/api/client.js +3 -3
  3. package/dist/api/contract.d.ts +1 -1
  4. package/dist/api/contract.js +1 -1
  5. package/dist/api/dto/bash-jobs.d.ts +5 -1
  6. package/dist/api/dto/broker-ops.d.ts +25 -1
  7. package/dist/api/dto/charges.d.ts +9 -2
  8. package/dist/api/dto/delivery.d.ts +26 -2
  9. package/dist/api/dto/execution-start.d.ts +57 -0
  10. package/dist/api/dto/execution-start.js +0 -0
  11. package/dist/api/dto/modelauth.d.ts +5 -0
  12. package/dist/api/dto/node-records.d.ts +16 -0
  13. package/dist/api/dto/objects.d.ts +1 -1
  14. package/dist/api/dto/reports.d.ts +0 -3
  15. package/dist/api/dto/run-events.d.ts +7 -1
  16. package/dist/api/dto/settings.d.ts +55 -0
  17. package/dist/api/dto/settings.js +0 -0
  18. package/dist/api/index.d.ts +2 -0
  19. package/dist/api/index.js +1 -1
  20. package/dist/api/routes.d.ts +11 -0
  21. package/dist/api/routes.js +1 -1
  22. package/dist/build-root.d.ts +1 -0
  23. package/dist/build-root.js +1 -1
  24. package/dist/builtin-memory/crouter-sdk/release-notes.md +4 -0
  25. package/dist/cli.js +7 -7
  26. package/dist/clients/attach/chrome/bash-jobs.d.ts +11 -1
  27. package/dist/clients/attach/chrome/bash-jobs.js +1 -1
  28. package/dist/clients/attach/chrome/canvas-panels.d.ts +1 -1
  29. package/dist/clients/attach/chrome/roster.js +6 -4
  30. package/dist/clients/attach/overlays/auth.js +2 -2
  31. package/dist/clients/attach/render/chat-view.js +1 -1
  32. package/dist/clients/attach/viewer.js +550 -567
  33. package/dist/commands/canvas-config.js +2 -2
  34. package/dist/commands/canvas-use.js +1 -1
  35. package/dist/commands/human.js +2 -2
  36. package/dist/commands/node/bash.js +3 -3
  37. package/dist/commands/node/create.js +2 -2
  38. package/dist/commands/person-settings.d.ts +1 -0
  39. package/dist/commands/person-settings.js +1 -0
  40. package/dist/commands/pkg/market-manage.d.ts +2 -2
  41. package/dist/commands/pkg/market-manage.js +1 -1
  42. package/dist/commands/pkg/plugin-manage.js +13 -13
  43. package/dist/commands/pkg/shared.js +1 -1
  44. package/dist/commands/profile/default.js +1 -1
  45. package/dist/commands/push.js +2 -3
  46. package/dist/commands/sys/config.js +1 -1
  47. package/dist/commands/sys/connect.js +1 -1
  48. package/dist/commands/sys/context/sysprompt.js +2 -2
  49. package/dist/commands/sys/doctor.js +1 -1
  50. package/dist/commands/sys/join.js +1 -1
  51. package/dist/commands/sys/panels/broker-limits-panel.js +1 -1
  52. package/dist/commands/sys/panels/keybindings-panel.js +1 -1
  53. package/dist/commands/sys/panels/models-panel.d.ts +8 -2
  54. package/dist/commands/sys/panels/models-panel.js +1 -1
  55. package/dist/commands/sys/panels/prefs-panel.d.ts +1 -0
  56. package/dist/commands/sys/panels/prefs-panel.js +1 -1
  57. package/dist/commands/sys/panels/profiles-panel.js +1 -1
  58. package/dist/commands/sys/panels/provider-panel.d.ts +4 -0
  59. package/dist/commands/sys/panels/provider-panel.js +1 -1
  60. package/dist/commands/sys/provider-login.js +5 -5
  61. package/dist/commands/sys/setup-core.js +3 -3
  62. package/dist/commands/sys/setup-settings-runner.js +1 -1
  63. package/dist/commands/sys/spend.js +3 -3
  64. package/dist/commands/sys/update.js +1 -1
  65. package/dist/core/auth-file.d.ts +11 -19
  66. package/dist/core/auth-file.js +1 -2
  67. package/dist/core/auto-update.d.ts +1 -1
  68. package/dist/core/auto-update.js +4 -4
  69. package/dist/core/bash-jobs.d.ts +29 -71
  70. package/dist/core/bash-jobs.js +9 -10
  71. package/dist/core/blobs/directory.d.ts +3 -0
  72. package/dist/core/blobs/directory.js +1 -0
  73. package/dist/core/blobs/fault.d.ts +3 -0
  74. package/dist/core/blobs/fault.js +1 -0
  75. package/dist/core/blobs/index.d.ts +21 -0
  76. package/dist/core/blobs/index.js +1 -0
  77. package/dist/core/blobs/r2.d.ts +9 -0
  78. package/dist/core/blobs/r2.js +4 -0
  79. package/dist/core/bootstrap.d.ts +1 -1
  80. package/dist/core/bootstrap.js +2 -2
  81. package/dist/core/canvas/canvas.d.ts +9 -7
  82. package/dist/core/canvas/canvas.js +8 -8
  83. package/dist/core/canvas/crons.d.ts +3 -2
  84. package/dist/core/canvas/crons.js +3 -3
  85. package/dist/core/canvas/daemon-owner.d.ts +5 -0
  86. package/dist/core/canvas/daemon-owner.js +1 -1
  87. package/dist/core/canvas/db.d.ts +10 -9
  88. package/dist/core/canvas/db.js +4 -4
  89. package/dist/core/canvas/executions.d.ts +100 -4
  90. package/dist/core/canvas/executions.js +1 -1
  91. package/dist/core/canvas/export-sqlite.js +1 -1
  92. package/dist/core/canvas/focuses.d.ts +4 -0
  93. package/dist/core/canvas/focuses.js +1 -1
  94. package/dist/core/canvas/history.js +9 -9
  95. package/dist/core/canvas/managed-worktree-sweep-candidates.d.ts +2 -1
  96. package/dist/core/canvas/managed-worktree-sweep-candidates.js +3 -2
  97. package/dist/core/canvas/node-tokens.d.ts +1 -4
  98. package/dist/core/canvas/node-tokens.js +3 -3
  99. package/dist/core/canvas/paths.d.ts +0 -1
  100. package/dist/core/canvas/paths.js +1 -1
  101. package/dist/core/canvas/person-state.d.ts +26 -0
  102. package/dist/core/canvas/person-state.js +1 -0
  103. package/dist/core/canvas/person.d.ts +3 -10
  104. package/dist/core/canvas/person.js +7 -7
  105. package/dist/core/canvas/reconciler-leases.d.ts +12 -0
  106. package/dist/core/canvas/reconciler-leases.js +8 -0
  107. package/dist/core/canvas/recovery.d.ts +4 -0
  108. package/dist/core/canvas/recovery.js +1 -1
  109. package/dist/core/canvas/schema-pg/003-fleet-removals.sql +1 -1
  110. package/dist/core/canvas/schema-pg/005-fleet-blobs.sql +13 -0
  111. package/dist/core/canvas/schema-pg/006-job-rows.sql +20 -0
  112. package/dist/core/canvas/schema-pg/007-ledger-check.sql +117 -0
  113. package/dist/core/canvas/schema-version.d.ts +1 -1
  114. package/dist/core/canvas/schema-version.js +1 -1
  115. package/dist/core/canvas/sessions.d.ts +8 -11
  116. package/dist/core/canvas/sessions.js +1 -4
  117. package/dist/core/canvas/tree.d.ts +4 -2
  118. package/dist/core/canvas/tree.js +6 -6
  119. package/dist/core/canvas/types.d.ts +7 -0
  120. package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -1
  121. package/dist/core/command-plugins/bundle.d.ts +1 -1
  122. package/dist/core/command-plugins/bundle.js +1 -1
  123. package/dist/core/command-plugins/compose.d.ts +1 -1
  124. package/dist/core/command-plugins/discovery.d.ts +0 -1
  125. package/dist/core/command-plugins/discovery.js +1 -1
  126. package/dist/core/command-plugins/help-addenda.js +1 -1
  127. package/dist/core/command-plugins/presence.d.ts +2 -0
  128. package/dist/core/command-plugins/presence.js +1 -1
  129. package/dist/core/config.d.ts +16 -15
  130. package/dist/core/config.js +1 -1
  131. package/dist/core/conversation-store/client-worker.js +1 -1
  132. package/dist/core/conversation-store/client.js +2 -2
  133. package/dist/core/conversation-store/index.d.ts +9 -11
  134. package/dist/core/conversation-store/index.js +1 -1
  135. package/dist/core/conversation-store/patch.js +1 -1
  136. package/dist/core/conversation-store/row-store.d.ts +14 -0
  137. package/dist/core/conversation-store/row-store.js +13 -0
  138. package/dist/core/directory/join.d.ts +5 -3
  139. package/dist/core/directory/join.js +1 -1
  140. package/dist/core/env-name.d.ts +1 -0
  141. package/dist/core/env-name.js +1 -1
  142. package/dist/core/environment-recipe.d.ts +15 -0
  143. package/dist/core/environment-recipe.js +1 -0
  144. package/dist/core/environments.js +1 -1
  145. package/dist/core/events/emit.js +2 -2
  146. package/dist/core/events/run-event-chunks.d.ts +25 -0
  147. package/dist/core/events/run-event-chunks.js +5 -0
  148. package/dist/core/feed/messages.js +5 -5
  149. package/dist/core/grants/mirror.d.ts +15 -0
  150. package/dist/core/grants/mirror.js +15 -3
  151. package/dist/core/grants/on-sync.d.ts +9 -5
  152. package/dist/core/grants/on-sync.js +1 -1
  153. package/dist/core/grants/remove.d.ts +1 -6
  154. package/dist/core/grants/remove.js +1 -1
  155. package/dist/core/grants/sync.js +1 -1
  156. package/dist/core/grants/watch.d.ts +15 -9
  157. package/dist/core/grants/watch.js +1 -1
  158. package/dist/core/graph/custom.js +8 -8
  159. package/dist/core/graph/jobs.d.ts +83 -5
  160. package/dist/core/graph/jobs.js +11 -2
  161. package/dist/core/graph/kinds/job.js +2 -2
  162. package/dist/core/graph/names.js +7 -7
  163. package/dist/core/graph/objects.d.ts +5 -1
  164. package/dist/core/graph/objects.js +11 -11
  165. package/dist/core/graph/reader.d.ts +3 -0
  166. package/dist/core/graph/reader.js +3 -3
  167. package/dist/core/graph/repo-sync/identity.d.ts +3 -1
  168. package/dist/core/graph/repo-sync/identity.js +1 -1
  169. package/dist/core/graph/repo-sync/repos.d.ts +1 -1
  170. package/dist/core/graph/repo-sync/repos.js +2 -2
  171. package/dist/core/graph/repo-sync/sync.js +2 -2
  172. package/dist/core/installed-plugins.js +1 -1
  173. package/dist/core/keybindings/persistence.d.ts +1 -1
  174. package/dist/core/keybindings/persistence.js +1 -1
  175. package/dist/core/layout-migrate/loose-keys.d.ts +1 -1
  176. package/dist/core/layout-migrate/loose-keys.js +1 -1
  177. package/dist/core/ledger/account.d.ts +12 -0
  178. package/dist/core/ledger/account.js +2 -0
  179. package/dist/core/ledger/charges.d.ts +2 -2
  180. package/dist/core/ledger/charges.js +1 -1
  181. package/dist/core/ledger/check.d.ts +5 -1
  182. package/dist/core/ledger/check.js +1 -7
  183. package/dist/core/ledger/chunks.d.ts +8 -0
  184. package/dist/core/ledger/chunks.js +2 -0
  185. package/dist/core/ledger/index.d.ts +2 -1
  186. package/dist/core/ledger/index.js +1 -1
  187. package/dist/core/ledger/infra-allowance.d.ts +9 -0
  188. package/dist/core/ledger/infra-allowance.js +1 -0
  189. package/dist/core/ledger/limits.js +3 -3
  190. package/dist/core/ledger/payer.d.ts +1 -1
  191. package/dist/core/ledger/payer.js +1 -1
  192. package/dist/core/ledger/read.d.ts +14 -4
  193. package/dist/core/ledger/read.js +2 -3
  194. package/dist/core/ledger/totals.d.ts +5 -16
  195. package/dist/core/ledger/totals.js +4 -4
  196. package/dist/core/ledger/types.d.ts +12 -3
  197. package/dist/core/llm/run.js +2 -2
  198. package/dist/core/managed-providers.d.ts +72 -0
  199. package/dist/core/managed-providers.js +1 -0
  200. package/dist/core/model-auth/api-credential-store.d.ts +10 -0
  201. package/dist/core/model-auth/api-credential-store.js +1 -0
  202. package/dist/core/model-auth/daemon-login.d.ts +1 -1
  203. package/dist/core/model-auth/daemon-login.js +1 -1
  204. package/dist/core/model-auth/flows.d.ts +5 -4
  205. package/dist/core/model-auth/flows.js +1 -1
  206. package/dist/core/model-auth/handoff-jti.d.ts +3 -4
  207. package/dist/core/model-auth/handoff-jti.js +1 -1
  208. package/dist/core/model-auth/readiness.js +1 -1
  209. package/dist/core/model-config.d.ts +1 -1
  210. package/dist/core/model-config.js +1 -1
  211. package/dist/core/model-routes-pool.d.ts +14 -0
  212. package/dist/core/model-routes-pool.js +1 -0
  213. package/dist/core/model-routes.d.ts +11 -16
  214. package/dist/core/model-routes.js +1 -1
  215. package/dist/core/peer/ingest.d.ts +2 -0
  216. package/dist/core/peer/ingest.js +1 -1
  217. package/dist/core/peer/stubs.d.ts +8 -0
  218. package/dist/core/peer/stubs.js +1 -1
  219. package/dist/core/permissions/evaluator.d.ts +7 -2
  220. package/dist/core/permissions/evaluator.js +2 -2
  221. package/dist/core/plugin-env.js +1 -1
  222. package/dist/core/pool-credential-store.d.ts +2 -5
  223. package/dist/core/pool-credential-store.js +1 -1
  224. package/dist/core/profiles/app-env-store.d.ts +5 -5
  225. package/dist/core/profiles/app-env-store.js +1 -2
  226. package/dist/core/profiles/default-binding.d.ts +5 -5
  227. package/dist/core/profiles/default-binding.js +1 -1
  228. package/dist/core/profiles/env-store.d.ts +10 -21
  229. package/dist/core/profiles/env-store.js +1 -2
  230. package/dist/core/profiles/manifest.d.ts +14 -18
  231. package/dist/core/profiles/manifest.js +1 -1
  232. package/dist/core/profiles/relocate.js +1 -1
  233. package/dist/core/profiles/select.js +21 -21
  234. package/dist/core/provider-credential.d.ts +1 -1
  235. package/dist/core/provider-credential.js +1 -1
  236. package/dist/core/provider-management.d.ts +3 -4
  237. package/dist/core/provider-management.js +1 -1
  238. package/dist/core/providers/bundles.js +2 -2
  239. package/dist/core/providers/call.d.ts +3 -34
  240. package/dist/core/providers/description.d.ts +34 -0
  241. package/dist/core/providers/description.js +0 -0
  242. package/dist/core/providers/token-cache.d.ts +14 -14
  243. package/dist/core/providers/token-cache.js +1 -1
  244. package/dist/core/review/companion.js +1 -1
  245. package/dist/core/runs/activity.d.ts +1 -1
  246. package/dist/core/runs/activity.js +1 -1
  247. package/dist/core/runs/events.d.ts +7 -5
  248. package/dist/core/runs/events.js +2 -6
  249. package/dist/core/runs/operations.d.ts +1 -1
  250. package/dist/core/runs/operations.js +6 -6
  251. package/dist/core/runtime/bearings.js +1 -1
  252. package/dist/core/runtime/broker/attachments-fetch.d.ts +5 -0
  253. package/dist/core/runtime/broker/attachments-fetch.js +1 -0
  254. package/dist/core/runtime/broker/bash-job-launch.d.ts +4 -2
  255. package/dist/core/runtime/broker/bash-job-launch.js +1 -1
  256. package/dist/core/runtime/broker/boot-state.d.ts +9 -0
  257. package/dist/core/runtime/broker/boot-state.js +1 -0
  258. package/dist/core/runtime/broker/cli-relay.d.ts +2 -1
  259. package/dist/core/runtime/broker/cli-relay.js +1 -1
  260. package/dist/core/runtime/broker/client-registry.d.ts +3 -3
  261. package/dist/core/runtime/broker/daemon-ops.d.ts +10 -1
  262. package/dist/core/runtime/broker/daemon-ops.js +1 -1
  263. package/dist/core/runtime/broker/fault-retry.d.ts +2 -0
  264. package/dist/core/runtime/broker/fault-retry.js +1 -1
  265. package/dist/core/runtime/broker/frame-engine-control.js +1 -1
  266. package/dist/core/runtime/broker/held-deferred-inbox.d.ts +3 -0
  267. package/dist/core/runtime/broker/held-deferred-inbox.js +1 -1
  268. package/dist/core/runtime/broker/job-reporter.d.ts +18 -0
  269. package/dist/core/runtime/broker/job-reporter.js +2 -0
  270. package/dist/core/runtime/broker/model-adapter.d.ts +3 -0
  271. package/dist/core/runtime/broker/model-adapter.js +3 -2
  272. package/dist/core/runtime/broker/signal-stream.js +1 -1
  273. package/dist/core/runtime/broker/spilled-body.d.ts +5 -0
  274. package/dist/core/runtime/broker/spilled-body.js +1 -0
  275. package/dist/core/runtime/broker/summaries-post.d.ts +5 -0
  276. package/dist/core/runtime/broker/summaries-post.js +1 -0
  277. package/dist/core/runtime/broker/tool-groups.d.ts +3 -0
  278. package/dist/core/runtime/broker/tool-groups.js +1 -1
  279. package/dist/core/runtime/broker/turn-replies.d.ts +1 -0
  280. package/dist/core/runtime/broker/turn-replies.js +1 -1
  281. package/dist/core/runtime/broker-persona-guidance.js +2 -2
  282. package/dist/core/runtime/broker.js +1 -1
  283. package/dist/core/runtime/deliver-live.js +1 -1
  284. package/dist/core/runtime/first-boot-rows.d.ts +8 -0
  285. package/dist/core/runtime/first-boot-rows.js +2 -0
  286. package/dist/core/runtime/fleet.d.ts +13 -12
  287. package/dist/core/runtime/front-door-login.js +1 -1
  288. package/dist/core/runtime/front-door.js +6 -6
  289. package/dist/core/runtime/headless-pi.js +1 -1
  290. package/dist/core/runtime/host.d.ts +14 -3
  291. package/dist/core/runtime/host.js +3 -3
  292. package/dist/core/runtime/invocation.d.ts +6 -0
  293. package/dist/core/runtime/kickoff.d.ts +2 -14
  294. package/dist/core/runtime/kickoff.js +17 -19
  295. package/dist/core/runtime/launch-config-worker.js +1 -1
  296. package/dist/core/runtime/launch.js +2 -2
  297. package/dist/core/runtime/model-registry.js +1 -1
  298. package/dist/core/runtime/node-read.d.ts +4 -6
  299. package/dist/core/runtime/node-read.js +3 -3
  300. package/dist/core/runtime/nodes.js +1 -1
  301. package/dist/core/runtime/outcome-document.d.ts +0 -1
  302. package/dist/core/runtime/outcome-document.js +1 -1
  303. package/dist/core/runtime/output-result.d.ts +15 -0
  304. package/dist/core/runtime/output-result.js +5 -0
  305. package/dist/core/runtime/placement.d.ts +17 -1
  306. package/dist/core/runtime/placement.js +1 -1
  307. package/dist/core/runtime/provider-credential-gate.d.ts +6 -2
  308. package/dist/core/runtime/provider-credential-gate.js +2 -2
  309. package/dist/core/runtime/recovery-hold.d.ts +21 -2
  310. package/dist/core/runtime/recovery-hold.js +2 -1
  311. package/dist/core/runtime/recycle.js +1 -1
  312. package/dist/core/runtime/reset.js +1 -1
  313. package/dist/core/runtime/revive.d.ts +2 -2
  314. package/dist/core/runtime/revive.js +2 -2
  315. package/dist/core/runtime/runner/blaxel/client.d.ts +81 -0
  316. package/dist/core/runtime/runner/blaxel/client.js +1 -0
  317. package/dist/core/runtime/runner/blaxel/image-build.d.ts +74 -0
  318. package/dist/core/runtime/runner/blaxel/image-build.js +5 -0
  319. package/dist/core/runtime/runner/blaxel/runner.d.ts +41 -0
  320. package/dist/core/runtime/runner/blaxel/runner.js +3 -0
  321. package/dist/core/runtime/runner/index.d.ts +8 -0
  322. package/dist/core/runtime/runner/index.js +1 -0
  323. package/dist/core/runtime/runner/process.d.ts +11 -0
  324. package/dist/core/runtime/runner/process.js +1 -0
  325. package/dist/core/runtime/runner/types.d.ts +95 -0
  326. package/dist/core/runtime/runner/types.js +0 -0
  327. package/dist/core/runtime/situational-context.d.ts +3 -6
  328. package/dist/core/runtime/situational-context.js +2 -2
  329. package/dist/core/runtime/situational-live.js +1 -1
  330. package/dist/core/runtime/spawn-env-rows.d.ts +5 -0
  331. package/dist/core/runtime/spawn-env-rows.js +1 -0
  332. package/dist/core/runtime/spawn-env.d.ts +4 -18
  333. package/dist/core/runtime/spawn-env.js +1 -1
  334. package/dist/core/runtime/spawn.js +2 -2
  335. package/dist/core/runtime/stop-guard.d.ts +1 -1
  336. package/dist/core/runtime/stop-guard.js +2 -8
  337. package/dist/core/runtime/structured-output.d.ts +0 -67
  338. package/dist/core/runtime/structured-output.js +3 -8
  339. package/dist/core/runtime/tmux-driver.d.ts +8 -0
  340. package/dist/core/runtime/tmux-driver.js +6 -6
  341. package/dist/core/runtime/view-socket.d.ts +20 -0
  342. package/dist/core/runtime/view-socket.js +3 -1
  343. package/dist/core/runtime/warm-pool.d.ts +13 -1
  344. package/dist/core/runtime/warm-pool.js +1 -1
  345. package/dist/core/scoped-state/legacy-profiles.d.ts +11 -0
  346. package/dist/core/scoped-state/legacy-profiles.js +1 -0
  347. package/dist/core/scoped-state/materialized-plugins.d.ts +18 -0
  348. package/dist/core/scoped-state/materialized-plugins.js +1 -0
  349. package/dist/core/scoped-state/migrate.d.ts +8 -1
  350. package/dist/core/scoped-state/migrate.js +3 -3
  351. package/dist/core/scoped-state/person-rows.d.ts +10 -0
  352. package/dist/core/scoped-state/person-rows.js +6 -0
  353. package/dist/core/scoped-state/person-store.d.ts +72 -0
  354. package/dist/core/scoped-state/person-store.js +1 -0
  355. package/dist/core/secrets/blaxel-launch.d.ts +24 -0
  356. package/dist/core/secrets/blaxel-launch.js +4 -0
  357. package/dist/core/secrets/blaxel-register.d.ts +2 -0
  358. package/dist/core/secrets/blaxel-register.js +1 -0
  359. package/dist/core/secrets/env-rows.d.ts +17 -0
  360. package/dist/core/secrets/env-rows.js +4 -0
  361. package/dist/core/secrets/environment-owner.d.ts +8 -0
  362. package/dist/core/secrets/environment-owner.js +1 -0
  363. package/dist/core/secrets/environment-secrets.d.ts +14 -0
  364. package/dist/core/secrets/environment-secrets.js +1 -0
  365. package/dist/core/secrets/index.d.ts +2 -0
  366. package/dist/core/secrets/index.js +1 -0
  367. package/dist/core/secrets/key.d.ts +3 -0
  368. package/dist/core/secrets/key.js +2 -0
  369. package/dist/core/secrets/seal.d.ts +18 -0
  370. package/dist/core/secrets/seal.js +1 -0
  371. package/dist/core/spaces/mounts.d.ts +1 -1
  372. package/dist/core/spaces/mounts.js +1 -1
  373. package/dist/core/spaces/process.d.ts +1 -1
  374. package/dist/core/spaces/stop.d.ts +7 -5
  375. package/dist/core/spaces/stop.js +2 -2
  376. package/dist/core/spaces/users.d.ts +2 -1
  377. package/dist/core/spaces/users.js +1 -1
  378. package/dist/core/storage/attachments.d.ts +11 -8
  379. package/dist/core/storage/attachments.js +1 -1
  380. package/dist/core/storage/tables.d.ts +4 -0
  381. package/dist/core/storage/tables.js +3 -3
  382. package/dist/core/subscription-state.d.ts +34 -72
  383. package/dist/core/subscription-state.js +1 -4
  384. package/dist/core/substrate/delivery/plan.js +1 -1
  385. package/dist/core/user-settings.js +1 -1
  386. package/dist/daemon/api/app-listener.js +10 -10
  387. package/dist/daemon/api/auth/person-bearer.d.ts +14 -0
  388. package/dist/daemon/api/auth/person-bearer.js +1 -0
  389. package/dist/daemon/api/bridge.js +4 -4
  390. package/dist/daemon/api/document-listener.js +3 -3
  391. package/dist/daemon/api/environment-of.d.ts +18 -0
  392. package/dist/daemon/api/environment-of.js +5 -0
  393. package/dist/daemon/api/handlers/analytics.js +1 -1
  394. package/dist/daemon/api/handlers/app-profiles.d.ts +2 -2
  395. package/dist/daemon/api/handlers/app-profiles.js +1 -1
  396. package/dist/daemon/api/handlers/bash-jobs.js +1 -1
  397. package/dist/daemon/api/handlers/bash.js +1 -1
  398. package/dist/daemon/api/handlers/broker-ops.d.ts +3 -0
  399. package/dist/daemon/api/handlers/broker-ops.js +1 -1
  400. package/dist/daemon/api/handlers/broker-recovery.js +1 -1
  401. package/dist/daemon/api/handlers/broker-signals.d.ts +0 -3
  402. package/dist/daemon/api/handlers/broker-signals.js +2 -2
  403. package/dist/daemon/api/handlers/canvas.js +4 -4
  404. package/dist/daemon/api/handlers/charges.d.ts +1 -1
  405. package/dist/daemon/api/handlers/charges.js +1 -1
  406. package/dist/daemon/api/handlers/conversations.d.ts +2 -0
  407. package/dist/daemon/api/handlers/conversations.js +3 -0
  408. package/dist/daemon/api/handlers/crons.js +1 -1
  409. package/dist/daemon/api/handlers/daemon.js +1 -1
  410. package/dist/daemon/api/handlers/delivery.d.ts +1 -1
  411. package/dist/daemon/api/handlers/delivery.js +1 -1
  412. package/dist/daemon/api/handlers/docs.js +1 -1
  413. package/dist/daemon/api/handlers/exec.js +1 -1
  414. package/dist/daemon/api/handlers/execution-start.d.ts +2 -0
  415. package/dist/daemon/api/handlers/execution-start.js +2 -0
  416. package/dist/daemon/api/handlers/files.js +1 -1
  417. package/dist/daemon/api/handlers/git-credential.d.ts +11 -0
  418. package/dist/daemon/api/handlers/git-credential.js +1 -0
  419. package/dist/daemon/api/handlers/hook-exec.d.ts +1 -1
  420. package/dist/daemon/api/handlers/hook-exec.js +1 -1
  421. package/dist/daemon/api/handlers/human-requests.js +1 -1
  422. package/dist/daemon/api/handlers/inbox.js +1 -1
  423. package/dist/daemon/api/handlers/messages.js +1 -1
  424. package/dist/daemon/api/handlers/model-config.js +1 -1
  425. package/dist/daemon/api/handlers/modelauth.d.ts +1 -1
  426. package/dist/daemon/api/handlers/modelauth.js +1 -1
  427. package/dist/daemon/api/handlers/node-events.d.ts +6 -0
  428. package/dist/daemon/api/handlers/node-events.js +3 -3
  429. package/dist/daemon/api/handlers/node-outcomes.js +1 -1
  430. package/dist/daemon/api/handlers/node-records.js +3 -2
  431. package/dist/daemon/api/handlers/nodes.js +1 -1
  432. package/dist/daemon/api/handlers/objects.js +3 -3
  433. package/dist/daemon/api/handlers/profiles.js +1 -1
  434. package/dist/daemon/api/handlers/providers.js +1 -1
  435. package/dist/daemon/api/handlers/reports.js +9 -13
  436. package/dist/daemon/api/handlers/reviews.js +1 -1
  437. package/dist/daemon/api/handlers/runs.js +1 -1
  438. package/dist/daemon/api/handlers/settings.d.ts +2 -0
  439. package/dist/daemon/api/handlers/settings.js +1 -0
  440. package/dist/daemon/api/handlers/structured-requests.js +1 -1
  441. package/dist/daemon/api/handlers/vendor-status.d.ts +1 -1
  442. package/dist/daemon/api/handlers/vendor-status.js +1 -1
  443. package/dist/daemon/api/handlers/worktree.js +1 -1
  444. package/dist/daemon/api/map.d.ts +2 -2
  445. package/dist/daemon/api/map.js +2 -2
  446. package/dist/daemon/api/operations.js +1 -1
  447. package/dist/daemon/api/reader.d.ts +8 -1
  448. package/dist/daemon/api/reader.js +1 -1
  449. package/dist/daemon/api/router.d.ts +4 -2
  450. package/dist/daemon/api/router.js +1 -1
  451. package/dist/daemon/api/server.d.ts +15 -3
  452. package/dist/daemon/api/server.js +1 -1
  453. package/dist/daemon/api/vendor-signin.d.ts +2 -1
  454. package/dist/daemon/api/vendor-signin.js +19 -19
  455. package/dist/daemon/api/viewer-presence.d.ts +20 -6
  456. package/dist/daemon/api/viewer-presence.js +2 -1
  457. package/dist/daemon/boot-settings.d.ts +3 -0
  458. package/dist/daemon/boot-settings.js +1 -0
  459. package/dist/daemon/broker-signals/bus.d.ts +48 -11
  460. package/dist/daemon/broker-signals/bus.js +1 -1
  461. package/dist/daemon/cron/armed-context.js +1 -1
  462. package/dist/daemon/cron/lease-recovery.js +1 -1
  463. package/dist/daemon/cron/live-runs.d.ts +6 -0
  464. package/dist/daemon/cron/live-runs.js +1 -1
  465. package/dist/daemon/cron/run-socket.js +1 -1
  466. package/dist/daemon/cron-run.js +2 -2
  467. package/dist/daemon/crtrd-cli.js +1 -1
  468. package/dist/daemon/crtrd.d.ts +10 -0
  469. package/dist/daemon/crtrd.js +18 -17
  470. package/dist/daemon/delivery/run-delivery.d.ts +1 -1
  471. package/dist/daemon/delivery/run-delivery.js +1 -1
  472. package/dist/daemon/due-sources.d.ts +1 -1
  473. package/dist/daemon/due-sources.js +1 -1
  474. package/dist/daemon/due.js +7 -6
  475. package/dist/daemon/fleet.d.ts +6 -6
  476. package/dist/daemon/fleet.js +9 -9
  477. package/dist/daemon/park-activity.d.ts +2 -1
  478. package/dist/daemon/park-activity.js +1 -1
  479. package/dist/daemon/park-pending.d.ts +20 -13
  480. package/dist/daemon/park-pending.js +3 -1
  481. package/dist/daemon/profile-delete.js +1 -1
  482. package/dist/daemon/reconcilers/bash-deadline.d.ts +15 -10
  483. package/dist/daemon/reconcilers/bash-deadline.js +1 -3
  484. package/dist/daemon/reconcilers/broker-supervision.d.ts +13 -3
  485. package/dist/daemon/reconcilers/broker-supervision.js +4 -4
  486. package/dist/daemon/reconcilers/cron-lane.d.ts +0 -1
  487. package/dist/daemon/reconcilers/cron-lane.js +1 -1
  488. package/dist/daemon/reconcilers/fault-retry-backstop.d.ts +2 -9
  489. package/dist/daemon/reconcilers/fault-retry-backstop.js +1 -1
  490. package/dist/daemon/reconcilers/grant-effects.d.ts +8 -0
  491. package/dist/daemon/reconcilers/grant-effects.js +1 -0
  492. package/dist/daemon/reconcilers/grove-instance-sweep.d.ts +1 -3
  493. package/dist/daemon/reconcilers/grove-instance-sweep.js +1 -1
  494. package/dist/daemon/reconcilers/ledger-r2.d.ts +27 -0
  495. package/dist/daemon/reconcilers/ledger-r2.js +7 -0
  496. package/dist/daemon/reconcilers/ledger-sandbox.d.ts +55 -0
  497. package/dist/daemon/reconcilers/ledger-sandbox.js +9 -0
  498. package/dist/daemon/reconcilers/ledger-storage.d.ts +22 -0
  499. package/dist/daemon/reconcilers/ledger-storage.js +5 -0
  500. package/dist/daemon/reconcilers/live-obligation.d.ts +3 -2
  501. package/dist/daemon/reconcilers/live-obligation.js +1 -1
  502. package/dist/daemon/reconcilers/managed-worktree-sweep.d.ts +0 -5
  503. package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -1
  504. package/dist/daemon/reconcilers/node-deadline.d.ts +2 -1
  505. package/dist/daemon/reconcilers/node-deadline.js +1 -1
  506. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.d.ts +1 -2
  507. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -1
  508. package/dist/daemon/reconcilers/node-lifecycle/remote-wake.d.ts +31 -0
  509. package/dist/daemon/reconcilers/node-lifecycle/remote-wake.js +1 -0
  510. package/dist/daemon/reconcilers/node-lifecycle/requested-stops.d.ts +5 -0
  511. package/dist/daemon/reconcilers/node-lifecycle/requested-stops.js +2 -0
  512. package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -1
  513. package/dist/daemon/reconcilers/pending-review-submit.js +1 -1
  514. package/dist/daemon/reconcilers/recipe-image.d.ts +49 -0
  515. package/dist/daemon/reconcilers/recipe-image.js +7 -0
  516. package/dist/daemon/reconcilers/row-claim.d.ts +19 -0
  517. package/dist/daemon/reconcilers/row-claim.js +2 -0
  518. package/dist/daemon/reconcilers/storage-due-work.d.ts +18 -3
  519. package/dist/daemon/reconcilers/storage-due-work.js +2 -1
  520. package/dist/daemon/reconcilers/storage-maintenance.d.ts +5 -13
  521. package/dist/daemon/reconcilers/storage-maintenance.js +1 -1
  522. package/dist/daemon/reconcilers/structured-request-lane.js +1 -1
  523. package/dist/daemon/reconcilers/throttled-lane.d.ts +11 -0
  524. package/dist/daemon/reconcilers/throttled-lane.js +1 -0
  525. package/dist/daemon/review/finish.js +1 -1
  526. package/dist/daemon/run-notices.d.ts +3 -0
  527. package/dist/daemon/run-notices.js +1 -1
  528. package/dist/daemon/runs/append-section.d.ts +4 -1
  529. package/dist/daemon/runs/append-section.js +2 -2
  530. package/dist/daemon/runs/observer.d.ts +3 -2
  531. package/dist/daemon/runs/observer.js +3 -2
  532. package/dist/daemon/runs/view-transport.d.ts +19 -0
  533. package/dist/daemon/runs/view-transport.js +1 -0
  534. package/dist/daemon/structured-requests/boot.d.ts +2 -1
  535. package/dist/daemon/structured-requests/boot.js +1 -1
  536. package/dist/daemon/structured-requests/effects.d.ts +4 -3
  537. package/dist/daemon/structured-requests/effects.js +1 -1
  538. package/dist/daemon/structured-requests/notifier.d.ts +2 -0
  539. package/dist/daemon/structured-requests/notifier.js +1 -1
  540. package/dist/daemon/structured-requests/sidecar.d.ts +4 -3
  541. package/dist/daemon/structured-requests/sidecar.js +1 -1
  542. package/dist/launcher/validate.js +1 -1
  543. package/dist/migrations/004-canvas-documents/index.js +2 -2
  544. package/dist/pi-extensions/broker-local.d.ts +3 -3
  545. package/dist/pi-extensions/broker-local.js +1 -2
  546. package/dist/pi-extensions/canvas-bash-valve.js +6 -6
  547. package/dist/pi-extensions/canvas-context-intro.js +2 -2
  548. package/dist/pi-extensions/canvas-elapsed.js +2 -2
  549. package/dist/pi-extensions/canvas-goal-capture.js +1 -1
  550. package/dist/pi-extensions/canvas-inbox-watcher.js +2 -2
  551. package/dist/pi-extensions/canvas-review-boundary.d.ts +11 -1
  552. package/dist/pi-extensions/canvas-review-boundary.js +3 -3
  553. package/dist/pi-extensions/canvas-stophook.js +1 -1
  554. package/dist/pi-extensions/canvas-structured-output.d.ts +5 -3
  555. package/dist/pi-extensions/canvas-structured-output.js +6 -11
  556. package/dist/pi-extensions/canvas-tool-guide.d.ts +9 -2
  557. package/dist/pi-extensions/canvas-tool-guide.js +6 -6
  558. package/dist/shared/inbox-entry-body.js +7 -7
  559. package/dist/types.d.ts +12 -0
  560. package/docs/sdk/release-notes.md +4 -0
  561. package/package.json +7 -4
  562. package/packages/crouter-identity/package.json +1 -1
  563. package/runtime.lock.json +13 -13
  564. package/scripts/git-credential-crtr +33 -0
  565. package/scripts/sandbox-bootstrap.sh +54 -0
  566. package/scripts/sandbox-start.mjs +320 -0
  567. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.d.ts +0 -78
  568. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js +0 -1179
  569. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.ts +0 -1406
  570. package/dist/core/conversation-store/file-store.d.ts +0 -37
  571. package/dist/core/conversation-store/file-store.js +0 -9
  572. package/dist/core/conversation-store/listener.d.ts +0 -4
  573. package/dist/core/conversation-store/listener.js +0 -8
  574. package/dist/core/scoped-state/profiles.d.ts +0 -27
  575. package/dist/core/scoped-state/profiles.js +0 -1
  576. package/dist/core/scoped-state/providers.d.ts +0 -24
  577. package/dist/core/scoped-state/providers.js +0 -1
  578. package/dist/core/scoped-state/settings.d.ts +0 -28
  579. package/dist/core/scoped-state/settings.js +0 -1
@@ -0,0 +1,320 @@
1
+ #!/usr/bin/env node
2
+ // scripts/sandbox-start.mjs — `crtr-sandbox-start` (design-fleet, Wake call step 5.1–5.9; C-A2).
3
+ //
4
+ // node sandbox-start.mjs start: the node token arrives on stdin (the bootstrap pipes it), the rest in env
5
+ // node sandbox-start.mjs --wake <id> signal the broker of execution <id> with SIGUSR1; exit 3 (no_broker) when none runs
6
+ //
7
+ // Plain node, no imports from dist/. A failing start prints `crtr-sandbox-start: failed <reason>` as its last
8
+ // line (the runner's `status` reads it) and exits non-zero.
9
+ import { spawn, spawnSync } from 'node:child_process';
10
+ import { createServer } from 'node:http';
11
+ import { randomBytes } from 'node:crypto';
12
+ import { existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, readlinkSync, realpathSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
13
+ import { tmpdir } from 'node:os';
14
+ import { dirname, join, resolve, sep } from 'node:path';
15
+ import { fileURLToPath } from 'node:url';
16
+
17
+ export const EXIT_NO_BROKER = 3;
18
+ const here = dirname(fileURLToPath(import.meta.url));
19
+
20
+ class StartFailure extends Error {
21
+ constructor(reason, detail) { super(detail ?? reason); this.reason = reason; }
22
+ }
23
+
24
+ /** Broker processes of this sandbox: `{pid, execution}` for each `broker-cli.js ... --epoch <execution> <node>` command line. */
25
+ export function findBrokers(procRoot = '/proc') {
26
+ const out = [];
27
+ for (const name of readdirSync(procRoot)) {
28
+ if (!/^\d+$/.test(name)) continue;
29
+ let argv;
30
+ try { argv = readFileSync(join(procRoot, name, 'cmdline'), 'utf8').split('\0'); } catch { continue; }
31
+ const entry = argv.findIndex((a) => a.endsWith('broker-cli.js'));
32
+ if (entry < 0) continue;
33
+ const epoch = argv.indexOf('--epoch', entry);
34
+ if (epoch < 0 || argv[epoch + 1] === undefined) continue;
35
+ out.push({ pid: Number(name), execution: argv[epoch + 1], node: argv.filter((a) => a !== '').at(-1) });
36
+ }
37
+ return out;
38
+ }
39
+
40
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
41
+
42
+ async function stopBroker(pid) {
43
+ try { process.kill(pid, 'SIGTERM'); } catch { return; }
44
+ for (let i = 0; i < 100; i++) {
45
+ await sleep(100);
46
+ try { process.kill(pid, 0); } catch { return; }
47
+ }
48
+ try { process.kill(pid, 'SIGKILL'); } catch { /* gone */ }
49
+ }
50
+
51
+ export function wake(executionId, brokers = findBrokers()) {
52
+ const found = brokers.find((b) => b.execution === executionId);
53
+ if (!found) return EXIT_NO_BROKER;
54
+ process.kill(found.pid, 'SIGUSR1');
55
+ return 0;
56
+ }
57
+
58
+ async function readStdin() {
59
+ const chunks = [];
60
+ for await (const chunk of process.stdin) chunks.push(chunk);
61
+ return Buffer.concat(chunks).toString('utf8').trim();
62
+ }
63
+
64
+ async function api(baseUrl, token, method, path, body) {
65
+ const response = await fetch(`${baseUrl.replace(/\/$/, '')}${path}`, {
66
+ method, headers: { authorization: `Bearer ${token}`, ...(body ? { 'content-type': 'application/json' } : {}) }, ...(body ? { body: JSON.stringify(body) } : {}),
67
+ signal: AbortSignal.timeout(30_000),
68
+ });
69
+ return response;
70
+ }
71
+
72
+ function run(command, args, options = {}) {
73
+ return spawnSync(command, args, { encoding: 'utf8', ...options });
74
+ }
75
+
76
+ /** Whether `path` lies inside `root` (both resolved). */
77
+ export function within(root, path) {
78
+ const r = resolve(root) + sep;
79
+ return (resolve(path) + sep).startsWith(r);
80
+ }
81
+
82
+ /** Step 5.9: a daemon-side extension path under `dist/` maps into the installed release; any other path must already lie in the release or the agent dir. */
83
+ export function mapExtension(path, release, agentDir) {
84
+ const marker = `${sep}dist${sep}`;
85
+ const at = path.lastIndexOf(marker);
86
+ if (at >= 0 && !within(release, path) && !within(agentDir, path)) {
87
+ const mapped = join(release, path.slice(at + 1));
88
+ if (existsSync(mapped)) return mapped;
89
+ }
90
+ if (!within(release, path) && !within(agentDir, path)) throw new StartFailure('extension_unavailable', `extension path ${path} lies outside the release and the agent dir`);
91
+ if (!existsSync(path)) throw new StartFailure('extension_unavailable', `extension ${path} does not exist`);
92
+ return path;
93
+ }
94
+
95
+ function lstatExists(path) {
96
+ try { lstatSync(path); return true; } catch { return false; }
97
+ }
98
+
99
+ function gitIn(cwd, args, timeoutMs) {
100
+ return run('git', args, { cwd, timeout: timeoutMs });
101
+ }
102
+
103
+ /** A short-lived credential relay for the start script's own git calls (the broker's relay does not exist until the script ends). It answers
104
+ * only `POST /v1/environments/<id>/git-credential`, forwarding it to the control plane with the node token this process holds; the socket
105
+ * lives in a private directory and the token is neither written to disk nor placed in any child's environment. */
106
+ async function credentialRelay(apiUrl, token, environmentId) {
107
+ const dir = mkdtempSync(join(tmpdir(), 'crtr-credential-'));
108
+ const socketPath = join(dir, 'api.sock');
109
+ const route = `/v1/environments/${environmentId}/git-credential`;
110
+ const server = createServer((req, res) => {
111
+ const chunks = [];
112
+ req.on('data', (c) => chunks.push(c));
113
+ req.on('end', async () => {
114
+ if (req.method !== 'POST' || req.url !== route) return void res.writeHead(404).end();
115
+ try {
116
+ const upstream = await api(apiUrl, token, 'POST', route, JSON.parse(Buffer.concat(chunks).toString('utf8')));
117
+ res.writeHead(upstream.status, { 'content-type': 'application/json' }).end(await upstream.text());
118
+ } catch (error) { res.writeHead(502).end(String(error?.message ?? error)); }
119
+ });
120
+ });
121
+ await new Promise((resolveListen, rejectListen) => { server.once('error', rejectListen); server.listen(socketPath, resolveListen); });
122
+ return { socketPath, close: async () => { await new Promise((r) => server.close(r)); rmSync(dir, { recursive: true, force: true }); } };
123
+ }
124
+
125
+ /** `git` in `cwd` without blocking the event loop (the credential relay must keep answering while it runs). */
126
+ function gitAsync(cwd, args, timeoutMs, env) {
127
+ return new Promise((resolveGit) => {
128
+ const child = spawn('git', args, { cwd, env, stdio: ['ignore', 'pipe', 'pipe'], timeout: timeoutMs });
129
+ let stderr = '';
130
+ child.stderr.on('data', (c) => { stderr += c; });
131
+ child.stdout.resume();
132
+ child.on('error', (error) => resolveGit({ status: 1, stderr: String(error?.message ?? error) }));
133
+ child.on('close', (status) => resolveGit({ status, stderr }));
134
+ });
135
+ }
136
+
137
+ async function start(env) {
138
+ const need = (name) => { const v = env[name]; if (!v) throw new StartFailure('bad_environment', `${name} is not set`); return v; };
139
+ const apiUrl = need('CRTR_API_URL');
140
+ const executionId = need('CRTR_EXECUTION_ID');
141
+ const releaseDir = realpathSync(env.CRTR_RELEASE_DIR ?? resolve(here, '..'));
142
+ // 5.1 token first; nothing is started or stopped before the control plane accepts it.
143
+ const token = env.CRTR_NODE_TOKEN ?? await readStdin();
144
+ if (!/^[A-Za-z0-9_-]{43}$/.test(token)) throw new StartFailure('token_missing', 'no node token on stdin');
145
+ let response;
146
+ try { response = await api(apiUrl, token, 'GET', `/v1/executions/${executionId}/start`); }
147
+ catch (error) { throw new StartFailure('bundle_unreachable', String(error?.message ?? error)); }
148
+ if (response.status === 401 || response.status === 403) throw new StartFailure('token_rejected', `the control plane answered ${response.status}`);
149
+ if (!response.ok) throw new StartFailure('bundle_failed', `the control plane answered ${response.status}`);
150
+ const bundle = await response.json();
151
+
152
+ // 5.2 a broker of this execution is signalled; a broker of another execution is stopped.
153
+ const brokers = findBrokers(env.CRTR_PROC_ROOT ?? '/proc').filter((b) => b.node === bundle.node.id);
154
+ if (brokers.some((b) => b.execution === executionId)) { wake(executionId, brokers); return null; }
155
+ for (const b of brokers) await stopBroker(b.pid);
156
+
157
+ const root = env.CRTR_HOME ?? '/var/lib/crtr';
158
+ const home = join(root, 'apps', bundle.node.app.replace(/^app:/, ''), 'home');
159
+ const agentDir = join(home, '.pi', 'agent');
160
+ const work = env.CRTR_WORK_DIR ?? '/work';
161
+ mkdirSync(agentDir, { recursive: true });
162
+ // The recipe image installs its pi packages into one agent dir of its own (RECIPE_PI_AGENT_DIR in image-build.ts); every app's agent dir links to
163
+ // that install, so the packages load whichever app the node runs in.
164
+ const recipeAgent = join(root, 'recipe-pi-agent');
165
+ for (const tree of ['npm', 'git']) {
166
+ const source = join(recipeAgent, tree);
167
+ const target = join(agentDir, tree);
168
+ if (!existsSync(source)) continue;
169
+ if (!lstatExists(target)) symlinkSync(source, target);
170
+ else if (!lstatSync(target).isSymbolicLink() || readlinkSync(target) !== source) throw new StartFailure('recipe_packages_unavailable', `${target} exists and is not the recipe image's ${source}`);
171
+ }
172
+
173
+ // 5.4 git: the credential helper, and the identity only when the bundle carries one.
174
+ const gitEnv = { ...env, HOME: home };
175
+ const gitConfig = (key, value) => run('git', ['config', '--global', key, value], { env: gitEnv });
176
+ gitConfig('credential.https://github.com.helper', join(releaseDir, 'scripts', 'git-credential-crtr'));
177
+ if (bundle.git_identity) { gitConfig('user.name', bundle.git_identity.name); gitConfig('user.email', bundle.git_identity.email); }
178
+
179
+ // 5.5 plugins, once per revision.
180
+ const marker = join(work, '.crtr', 'plugins-revision');
181
+ const have = existsSync(marker) ? readFileSync(marker, 'utf8').trim() : null;
182
+ if (have !== String(bundle.plugins_revision) && bundle.plugins.length > 0) {
183
+ const crtr = join(releaseDir, 'bin', 'crtr');
184
+ const pluginEnv = { ...gitEnv, NPM_CONFIG_PREFIX: join(home, '.npm-global'), CRTR_HOME: root, CRTR_NO_AUTO_INIT: '1' };
185
+ const crtrRun = (args) => run(process.execPath, [crtr, ...args], { env: pluginEnv, timeout: 300_000 });
186
+ const detail = (r) => (r.stderr || r.stdout || '').slice(0, 300);
187
+ // A plugin of a marketplace is installed as `<marketplace name>/<plugin>`; the bundle names only the marketplace's url and ref, so the name is what
188
+ // `pkg market add` reports. Adding re-clones, so a marketplace added once per start is current. A plugin already installed (an earlier revision) is
189
+ // removed first, since install refuses an installed name.
190
+ const marketplaces = new Map();
191
+ for (const plugin of bundle.plugins) {
192
+ if ('path' in plugin.source) throw new StartFailure('plugin_source_unreachable', `${plugin.name}: its source is ${plugin.source.path} on the machine that registered it, which a sandbox cannot read`);
193
+ const { url, ref } = plugin.source.marketplace;
194
+ if (!url) throw new StartFailure('plugin_source_unreachable', `${plugin.name}: its marketplace has no url`);
195
+ const key = `${url}\0${ref ?? ''}`;
196
+ if (!marketplaces.has(key)) {
197
+ const added = crtrRun(['--json', 'pkg', 'market', 'add', url, ...(ref ? ['--ref', ref] : []), '--scope', 'user']);
198
+ let name;
199
+ try { name = JSON.parse(added.stdout).name; } catch { /* reported below */ }
200
+ if (added.status !== 0 || typeof name !== 'string') throw new StartFailure('plugin_install_failed', `${plugin.name}: marketplace ${url}: ${detail(added)}`);
201
+ marketplaces.set(key, name);
202
+ }
203
+ const removed = crtrRun(['pkg', 'plugin', 'remove', plugin.name, '--scope', 'user']);
204
+ if (removed.status !== 0 && !/not found/i.test(removed.stderr + removed.stdout)) throw new StartFailure('plugin_install_failed', `${plugin.name}: remove: ${detail(removed)}`);
205
+ const installed = crtrRun(['pkg', 'plugin', 'install', `${marketplaces.get(key)}/${plugin.name}`, '--scope', 'user']);
206
+ if (installed.status !== 0) throw new StartFailure('plugin_install_failed', `${plugin.name}: ${detail(installed)}`);
207
+ }
208
+ }
209
+ if (have !== String(bundle.plugins_revision)) { mkdirSync(dirname(marker), { recursive: true }); writeFileSync(marker, String(bundle.plugins_revision)); }
210
+
211
+ // 5.6 fetch only, never clone and never move a working tree; a failure is recorded and the start continues. The fetch reaches a private
212
+ // repository through the credential helper, over a relay of this process (see credentialRelay) because the broker's does not exist yet.
213
+ const fetchFailures = [];
214
+ const cloned = (bundle.recipe?.repositories ?? []).filter((repo) => existsSync(join(work, repo.name, '.git')));
215
+ if (cloned.length > 0) {
216
+ const environment = bundle.node.environment_id;
217
+ const relay = environment ? await credentialRelay(apiUrl, token, environment) : null;
218
+ const fetchEnv = { ...gitEnv, GIT_TERMINAL_PROMPT: '0', ...(relay ? { CRTR_API_SOCKET: relay.socketPath, CRTR_ENVIRONMENT_ID: environment } : {}) };
219
+ delete fetchEnv.CRTR_NODE_TOKEN;
220
+ try {
221
+ for (const repo of cloned) {
222
+ const r = await gitAsync(join(work, repo.name), ['fetch', '--prune'], 60_000, fetchEnv);
223
+ if (r.status !== 0) fetchFailures.push({ repository: repo.name, error: r.stderr.slice(0, 300) });
224
+ }
225
+ } finally { await relay?.close(); }
226
+ }
227
+
228
+ // 5.7 the managed worktree request (D102): the node's branch in the recipe repository's one clone, never a second checkout.
229
+ const worktree = bundle.launch.worktree;
230
+ if (worktree) {
231
+ const dir = join(work, worktree.repository);
232
+ if (!existsSync(join(dir, '.git'))) throw new StartFailure('cwd_missing', `${dir} holds no clone of ${worktree.repository}`);
233
+ const current = gitIn(dir, ['symbolic-ref', '--short', '-q', 'HEAD'], 10_000).stdout?.trim();
234
+ if (current !== worktree.branch) {
235
+ const exists = gitIn(dir, ['rev-parse', '--verify', '-q', `refs/heads/${worktree.branch}`], 10_000).status === 0;
236
+ const r = gitIn(dir, exists ? ['switch', worktree.branch] : ['switch', '-c', worktree.branch, worktree.base], 30_000);
237
+ if (r.status !== 0) throw new StartFailure('worktree_failed', `${worktree.branch}: ${(r.stderr || '').slice(0, 300)}`);
238
+ }
239
+ }
240
+
241
+ // 5.7 directories and the cwd.
242
+ const cwd = bundle.node.cwd;
243
+ if (!existsSync(cwd)) {
244
+ const inside = (bundle.recipe?.repositories ?? []).some((repo) => within(join(work, repo.name), cwd));
245
+ if (inside) throw new StartFailure('cwd_missing', `${cwd} lies in a repository that was never cloned`);
246
+ mkdirSync(cwd, { recursive: true });
247
+ }
248
+ const nodeId = bundle.node.id;
249
+ const environmentId = bundle.node.environment_id;
250
+ if (environmentId) writeFileSync(join(root, 'environment-id'), environmentId);
251
+ const appRoot = join(root, 'apps', bundle.node.app.replace(/^app:/, ''));
252
+ const runDir = join(env.CRTR_RUN_ROOT ?? '/run/crtr', 'nodes', nodeId);
253
+ for (const dir of ['context', 'reports', 'attachments', 'worktree'].map((d) => join(appRoot, 'nodes', nodeId, d))
254
+ .concat([join(root, 'runtime', 'nodes', nodeId, 'job'), join(runDir, 'job')])) mkdirSync(dir, { recursive: true });
255
+
256
+ // 5.8 the broker's local inputs.
257
+ const launch = bundle.launch;
258
+ const brokerEntry = join(releaseDir, 'dist', 'core', 'runtime', 'broker-cli.js');
259
+ const argv = [...launch.argv];
260
+ for (let i = 0; i < argv.length; i++) if (argv[i] === '-e') argv[i + 1] = mapExtension(argv[i + 1], releaseDir, agentDir);
261
+ // As host.ts does: the scopes file exists only when the recipe's env names one, holding `scopes ?? []`.
262
+ const scopesFile = launch.env?.CRTR_SCOPES_FILE !== undefined ? join(runDir, 'scopes.json') : null;
263
+ if (scopesFile) writeFileSync(scopesFile, JSON.stringify(launch.scopes ?? []));
264
+ const models = launch.models;
265
+ if (models) writeFileSync(join(agentDir, 'models.json'), `${JSON.stringify(models, null, 2)}\n`);
266
+ writeFileSync(join(runDir, 'broker-launch.json'), JSON.stringify({ ...launch, argv }));
267
+ const settingsPath = join(agentDir, 'settings.json');
268
+ const builtin = join(releaseDir, 'dist', 'builtin-pi-packages', 'pi-crtr-extensions');
269
+ let settings = {};
270
+ if (existsSync(settingsPath)) settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
271
+ const packages = Array.isArray(settings.packages) ? settings.packages : [];
272
+ if (!packages.includes(builtin)) packages.push(builtin);
273
+ const recipeSettings = join(recipeAgent, 'settings.json');
274
+ if (existsSync(recipeSettings)) {
275
+ for (const entry of JSON.parse(readFileSync(recipeSettings, 'utf8')).packages ?? []) {
276
+ if (!packages.some((have) => JSON.stringify(have) === JSON.stringify(entry))) packages.push(entry);
277
+ }
278
+ }
279
+ writeFileSync(settingsPath, `${JSON.stringify({ ...settings, packages })}\n`);
280
+
281
+ // 5.9 the broker, with the token on fd 3 and not in its environment.
282
+ const brokerEnv = { ...env, ...launch.env, HOME: home, PI_CODING_AGENT_DIR: agentDir, CRTR_HOME: root, CRTR_RUNTIME_HOME: join(root, 'runtime'),
283
+ CRTR_FRONT_DOOR: '1', CRTR_EXECUTION_ID: executionId, CRTR_API_URL: apiUrl, CRTR_NO_AUTO_INIT: '1',
284
+ CRTR_PLUGINS_REVISION: String(bundle.plugins_revision), ...(environmentId ? { CRTR_ENVIRONMENT_ID: environmentId } : {}), ...(scopesFile ? { CRTR_SCOPES_FILE: scopesFile } : {}),
285
+ PATH: `${join(releaseDir, 'bin')}:${env.PATH ?? '/usr/local/bin:/usr/bin:/bin'}` };
286
+ for (const name of ['CRTR_NODE_TOKEN', 'CRTR_RELEASE_URL', 'CRTR_RELEASE_SHA256']) delete brokerEnv[name];
287
+ const child = spawn(process.execPath, [brokerEntry, '--canvas-home', join(root, 'runtime'), '--epoch', executionId, nodeId],
288
+ { cwd, env: brokerEnv, stdio: ['ignore', 'inherit', 'inherit', 'pipe'] });
289
+ child.stdio[3].end(token);
290
+ const exited = new Promise((resolveExit) => child.on('exit', (code, signal) => resolveExit(code ?? (signal ? 128 : 1))));
291
+ for (const sig of ['SIGTERM', 'SIGINT']) process.on(sig, () => child.kill(sig));
292
+ // The failure is a node log record (`POST /v1/nodes/:id/records/log`, the route a broker's events use); a refused post goes to the process log (`bl logs`).
293
+ for (const failure of fetchFailures) {
294
+ const record = JSON.stringify({ v: 1, ts: new Date().toISOString(), level: 'warn', event: 'sandbox.fetch.failed', component: 'broker', operation_id: randomBytes(16).toString('hex'), node_id: nodeId, fields: failure });
295
+ try {
296
+ const posted = await api(apiUrl, token, 'POST', `/v1/nodes/${nodeId}/records/log`, { record, expected_execution_id: executionId });
297
+ if (!posted.ok) throw new Error(`the control plane answered ${posted.status}`);
298
+ } catch (error) { console.error(`sandbox.fetch.failed ${record} (not recorded: ${error?.message ?? error})`); }
299
+ }
300
+ return await exited;
301
+ }
302
+
303
+ if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
304
+ const args = process.argv.slice(2);
305
+ try {
306
+ if (args[0] === '--wake') {
307
+ if (!args[1]) throw new StartFailure('bad_arguments', '--wake needs an execution id');
308
+ const code = wake(args[1], findBrokers(process.env.CRTR_PROC_ROOT ?? '/proc'));
309
+ if (code === EXIT_NO_BROKER) console.error('crtr-sandbox-start: failed no_broker');
310
+ process.exit(code);
311
+ }
312
+ const code = await start(process.env);
313
+ process.exit(code ?? 0);
314
+ } catch (error) {
315
+ const reason = error instanceof StartFailure ? error.reason : 'start_failed';
316
+ console.error(`crtr-sandbox-start: ${error.message}`);
317
+ console.error(`crtr-sandbox-start: failed ${reason}`);
318
+ process.exit(1);
319
+ }
320
+ }
@@ -1,78 +0,0 @@
1
- import type { ExtensionAPI, ExtensionContext } from '@earendil-works/pi-coding-agent';
2
- import { type AssistantMessageEventStream, type TranscriptContext, type Model, type SimpleStreamOptions } from '@earendil-works/pi-ai';
3
- import { type ManagedProviderId, type SubscriptionCredential } from '../../../core/subscription-state.js';
4
- export interface ProviderRotationOptions {
5
- modelIntent?: string;
6
- nodeCwd?: string;
7
- profileId?: string;
8
- }
9
- type ProviderErrorClassification = {
10
- kind: "rate_limit" | "transient" | "fatal";
11
- status?: number;
12
- reason: string;
13
- hadRetryAfterHeader: boolean;
14
- /** Cooldown this classification imposes regardless of any Retry-After header. */
15
- cooldownMs?: number;
16
- };
17
- type ProviderClassificationPolicy = {
18
- rotateOnAuth: boolean;
19
- };
20
- /** Test seam for the policy mapping over the shared recognition signal. */
21
- export declare function __classifyProviderErrorForTest(error: unknown, observed?: {
22
- status?: number;
23
- retryAfterMs?: number;
24
- }, policy?: ProviderClassificationPolicy): ProviderErrorClassification;
25
- declare function defaultSleep(ms: number): Promise<void>;
26
- /** Test-only seam: override the sleep implementation used for in-place/wait-out retries. Pass undefined to restore the default. */
27
- export declare function __setSleepForTest(fn: typeof defaultSleep | undefined): void;
28
- export declare const POISONED_TRANSPORT_PASS_LIMIT = 2;
29
- declare function defaultTerminatePoisonedProcess(tried: string): Promise<boolean>;
30
- /** Test-only seam: override poisoned-process self-termination. Pass undefined to restore the default. */
31
- export declare function __setTerminatePoisonedProcessForTest(fn: typeof defaultTerminatePoisonedProcess | undefined): void;
32
- /** Test-only seam for the bounded, non-fatal subscription bookkeeping path. */
33
- export declare function __recordSubscriptionMutationForTest(description: string, mutate: () => Promise<unknown>): Promise<boolean>;
34
- type RefreshedCredential = {
35
- refresh: string;
36
- access: string;
37
- expires: number;
38
- clientId?: string;
39
- };
40
- type LoginCredential = {
41
- refresh: string;
42
- access: string;
43
- expires: number;
44
- accountId?: string;
45
- clientId?: string;
46
- };
47
- type ResolvedCredential = SubscriptionCredential & {
48
- access: string;
49
- };
50
- type RefreshForProvider = (providerId: ManagedProviderId, refreshToken: string, signal?: AbortSignal, clientId?: string) => Promise<RefreshedCredential>;
51
- /** Test-only seam: override the per-provider refresh function. Pass undefined to restore the default. */
52
- export declare function __setRefreshForProviderForTest(fn: RefreshForProvider | undefined): void;
53
- /** Test-only seam: exercises the real `refreshCredentialIfNeeded` (including its locked refresh
54
- * transaction) without duplicating its logic. */
55
- export declare function __refreshCredentialIfNeededForTest(providerId: ManagedProviderId, credential: SubscriptionCredential, signal?: AbortSignal): Promise<ResolvedCredential>;
56
- declare function defaultLoginForProvider(providerId: ManagedProviderId, ctx: ExtensionContext): Promise<LoginCredential>;
57
- /** Test-only seam: override the per-provider login function. Pass undefined to restore the default. */
58
- export declare function __setLoginForProviderForTest(fn: typeof defaultLoginForProvider | undefined): void;
59
- declare function defaultStreamForProvider(model: Model<any>, context: TranscriptContext, options: SimpleStreamOptions | undefined): AssistantMessageEventStream;
60
- /** Test-only seam: override the per-provider stream factory. Pass undefined to restore the default. */
61
- export declare function __setStreamForProviderForTest(fn: typeof defaultStreamForProvider | undefined): void;
62
- /**
63
- * pi-ai races the manual-code-paste dialog against its loopback callback server. When the
64
- * callback supplies a code, the manual-input promise can remain pending, so `run` receives:
65
- * - `readCode`, a `ctx.ui.input` wrapper with an AbortSignal. Aborting it removes the pending
66
- * broker entry and emits an `extension_ui_dismiss` frame for exactly that dialog.
67
- * - `dismissManual`, which aborts the signal at the post-code `onProgress` boundary before
68
- * the token exchange completes. `onProgress` is emitted only after a code is available, so
69
- * dismissing then cannot close a dialog the user still needs; `finally` covers paths without
70
- * progress, and repeated AbortController calls are inert.
71
- *
72
- * `undefined` from `readCode` means cancellation or timeout. It throws so OAuth ends directly
73
- * instead of opening a second paste-only dialog.
74
- */
75
- export declare function loginWithManualInputCleanup<T>(ctx: ExtensionContext, run: (readCode: (title: string, placeholder: string) => Promise<string>, dismissManual: () => void) => Promise<T>): Promise<T>;
76
- export declare function createProviderRotationExtension(options?: ProviderRotationOptions): (pi: ExtensionAPI) => Promise<void>;
77
- declare const defaultProviderRotationExtension: (pi: ExtensionAPI) => Promise<void>;
78
- export default defaultProviderRotationExtension;