@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
@@ -1,28 +1,26 @@
1
- var M=Object.defineProperty;var r=(t,n)=>M(t,"name",{value:n,configurable:!0});import{join as b}from"node:path";import{getNode as R,subscriptionsOf as A,subscribersOf as N}from"../canvas/index.js";import{contextDir as h,nodeAgentDir as l}from"../canvas/node-agent-paths.js";import{hasReportDocuments as E}from"../feed/reports.js";import{readdirBeneath as T,readTextBeneathIfExists as x,unlinkBeneath as D,writeFileBeneath as $}from"../spaces/open-beneath.js";import{activeBackgroundBashJobs as I,bashJobCommandLine as G,formatBashElapsed as O}from"../bash-jobs.js";import{readRoadmap as _}from"./roadmap.js";import{buildWakeBearings as Y}from"./bearings.js";import{personaDrift as C}from"./persona.js";import{coalesce as L,nodeMailEntry as U}from"../feed/inbox.js";import{claimKickoffMail as J}from"../canvas/deliveries.js";import{formatCard as k}from"../../shared/generated-context.js";import{mapAsync as j}from"../async-array.js";const dt=k("restart-continuation",{},"continue");async function y(t){return b(await h(t),"initial-prompt.md")}r(y,"goalPath");async function v(t){return x(await l(t),await y(t))}r(v,"readGoal");async function P(t,n){const e=n.trim();e!==""&&$(await l(t),await y(t),e+`
2
- `)}r(P,"writeGoal");async function lt(t,n){const e=await v(t);if(e!==null&&e.trim()!=="")return!1;const o=n.trim();return o===""?!1:(await P(t,o),!0)}r(lt,"captureGoalIfAbsent");async function g(t){return b(await h(t),"yield-message.md")}r(g,"yieldMessagePath");async function ft(t,n){const e=n.trim();e!==""&&$(await l(t),await g(t),e+`
3
- `)}r(ft,"writeYieldMessage");async function F(t){const n=x(await l(t),await g(t))?.trim()??"";return n!==""?n:null}r(F,"readYieldMessage");async function ht(t){try{D(await l(t),await g(t))}catch{}}r(ht,"clearYieldMessage");async function K(t){return(await q(t,await h(t))).sort()}r(K,"listContextDir");async function S(t){return await E(t)}r(S,"hasRetainedReports");async function q(t,n){try{return T(await l(t),n).map(e=>e.name)}catch(e){if(e.code==="ENOENT")return[];throw e}}r(q,"agentDirNames");async function mt(t,n){const e=t.node_id,o=await F(e),a=t.run_id?[]:await J(e,n),i=a.map(s=>s.message.messageId),f=a.map(U);let u=null;if(f.length>0){const s=r(c=>{const p=c.data?.cards;return Array.isArray(p)?p.filter(B=>typeof B=="string"):[]},"cardsFor"),m=[];for(const c of f)(s(c).length>0||m.length===0)&&m.push([]),m.at(-1).push(c);u=(await j(m,async c=>[...s(c[0]),(await L(c)).map(p=>p.text).join(`
1
+ var E=Object.defineProperty;var r=(t,e)=>E(t,"name",{value:e,configurable:!0});import{join as _}from"node:path";import{getNode as $,subscriptionsOf as R,subscribersOf as j}from"../canvas/index.js";import{contextDir as w,nodeAgentDir as k}from"../canvas/node-agent-paths.js";import{hasReportDocuments as x}from"../feed/reports.js";import{readdirBeneath as T}from"../spaces/open-beneath.js";import{openDb as c}from"../canvas/db.js";import{bashJobCommandLine as A,bashJobPaths as D,formatBashElapsed as I}from"../bash-jobs.js";import{runningJobs as N}from"../graph/jobs.js";import{readRoadmap as v}from"./roadmap.js";import{buildWakeBearings as M}from"./bearings.js";import{personaDrift as L}from"./persona.js";import{coalesce as O,nodeMailEntry as U}from"../feed/inbox.js";import{claimKickoffMail as B}from"../canvas/deliveries.js";import{formatCard as y}from"../../shared/generated-context.js";import{mapAsync as g}from"../async-array.js";const dt=y("restart-continuation",{},"continue");async function S(t){return _(await w(t),"initial-prompt.md")}r(S,"goalPath");async function G(t){return(await(await c()).prepare("SELECT initial_prompt FROM nodes WHERE node_id = ?").get(t))?.initial_prompt??null}r(G,"readGoal");async function ut(t,e){const n=e.trim();n!==""&&await(await c()).prepare("UPDATE nodes SET initial_prompt = ? WHERE node_id = ?").run(n+`
2
+ `,t)}r(ut,"writeGoal");async function ct(t,e){const n=e.trim();return n===""?!1:(await(await c()).prepare("UPDATE nodes SET initial_prompt = ? WHERE node_id = ? AND (initial_prompt IS NULL OR trim(initial_prompt) = '')").run(n+`
3
+ `,t)).changes===1}r(ct,"captureGoalIfAbsent");async function lt(t,e){const n=e.trim();n!==""&&await(await c()).prepare("UPDATE nodes SET yield_note = ? WHERE node_id = ?").run(n+`
4
+ `,t)}r(lt,"writeYieldMessage");async function W(t){return(await(await c()).prepare("SELECT yield_note FROM nodes WHERE node_id = ?").get(t))?.yield_note?.trim()||null}r(W,"readYieldMessage");async function pt(t){await(await c()).prepare("UPDATE nodes SET yield_note = NULL WHERE node_id = ?").run(t)}r(pt,"clearYieldMessage");async function ft(t){return(await H(t,await w(t))).sort()}r(ft,"listContextDir");async function C(t){return await x(t)}r(C,"hasRetainedReports");async function H(t,e){try{return T(await k(t),e).map(n=>n.name)}catch(n){if(n.code==="ENOENT")return[];throw n}}r(H,"agentDirNames");async function mt(t,e){const n=t.node_id,a=await W(n),o=t.run_id?[]:await B(n,e),s=o.map(f=>f.message.messageId),i=o.map(U);let d=null;if(i.length>0){const f=r(u=>{const h=u.data?.cards;return Array.isArray(h)?h.filter(b=>typeof b=="string"):[]},"cardsFor"),m=[];for(const u of i)(f(u).length>0||m.length===0)&&m.push([]),m.at(-1).push(u);d=(await g(m,async u=>[...f(u[0]),(await O(u)).map(h=>h.text).join(`
4
5
 
5
6
  `)].join(`
6
7
 
7
8
  `))).join(`
8
9
 
9
- `)}const d=await C(e),w=d?.guidance===void 0||d.guidance===""?null:d.guidance;return{yieldMsg:o,unreadDigest:u,unreadMessageIds:i,driftGuidance:w}}r(mt,"drainBearings");async function W(t,n){const e=(await j((await A(t)).filter(a=>a.active),async a=>await R(a.node_id))).filter(a=>a!==null&&(a.status==="active"||a.status==="idle")),o=[];if(e.length>0){const a=e.length,i=a===1?"it has":"they have",f=a===1?"Its":"Their";o.push(`Awaiting ${a} node${a===1?"":"s"} \u2014 ${i} not finished. ${f} reports will wake you.`);for(const u of e)o.push(` - ${u.name} (${u.node_id}) \u2014 ${u.status}`);o.push("",n??"(no unread reports)")}else o.push("Awaiting 0 nodes."),o.push("",n??"(no unread reports)");return`<feed>
10
- ${o.join(`
11
- `)}
12
- </feed>`}r(W,"feedBlock");function z(t,n){const e=(t??G(n)).trim()||"(no command)";return e.length>120?`${e.slice(0,117)}\u2026`:e}r(z,"jobLabel");async function H(t){const n=I(await h(t));if(n.length===0)return null;const e=Date.now(),o=n.length===1,a=[`${n.length} background bash job${o?"":"s"} you started ${o?"is":"are"} STILL RUNNING, detached from any turn and unaffected by your refresh. Each one sends you a message when it exits \u2014 that wake is automatic, so do not poll it and do not relaunch the same command.`];for(const i of n)a.push(` - ${i.jobId} \u2014 ${z(i.purpose,i.command)} \xB7 running ${O(e-i.startedAtMs)} \xB7 log ${i.logPath}`);return a.push("","Read output so far: `tail -n 50 <log>` (or `crtr node bash list --tail 20`). Abandon one: `crtr node bash kill <job-id>`."),`<background-jobs>
10
+ `)}const l=await L(n),p=l?.guidance===void 0||l.guidance===""?null:l.guidance;return{yieldMsg:a,unreadDigest:d,unreadMessageIds:s,driftGuidance:p}}r(mt,"drainBearings");async function P(t,e){const n=(await g((await R(t)).filter(o=>o.active),async o=>await $(o.node_id))).filter(o=>o!==null&&(o.status==="active"||o.status==="idle")),a=[];if(n.length>0){const o=n.length,s=o===1?"it has":"they have",i=o===1?"Its":"Their";a.push(`Awaiting ${o} node${o===1?"":"s"} \u2014 ${s} not finished. ${i} reports will wake you.`);for(const d of n)a.push(` - ${d.name} (${d.node_id}) \u2014 ${d.status}`);a.push("",e??"(no unread reports)")}else a.push("Awaiting 0 nodes."),a.push("",e??"(no unread reports)");return`<feed>
13
11
  ${a.join(`
14
12
  `)}
15
- </background-jobs>`}r(H,"backgroundJobsBlock");async function pt(t,n,e){const o=t.node_id,a=["You have been revived fresh after a context refresh \u2014 your previous in-memory context is gone, by design. Everything below was just read from disk; it is your full bearings. Rebuild from it and continue toward your goal."];e!==void 0&&a.push(Y(e));const i=await _(o);if(!(i!==null&&i.trim()!=="")&&!await S(o)){const s=await v(o);s!==null&&s.trim()!==""&&a.push(`<goal file="${await y(o)}">
16
- ${s.trim()}
17
- </goal>`)}const u=(await K(o)).filter(s=>s!=="yield-message.md");a.push(`<context-dir path="${await h(o)}">
18
- ${u.length>0?u.join(`
19
- `):"(empty)"}
20
- </context-dir>`);const d=await H(o);d!==null&&a.push(d),a.push(await W(o,n.unreadDigest)),a.push(n.yieldMsg!==null?`<yield-message>
21
- ${n.yieldMsg.trim()}
22
- </yield-message>`:"<yield-message/>");const w=(await N(o)).length>0;return a.push(w?"If there is work to do, perform it. Otherwise stop \u2014 pipe the result to `crtr push final` through a single-quoted heredoc if the goal is met, or end your turn without a message to stay dormant awaiting your workers.":"If there is work to do, perform it. Otherwise end your turn without writing a message \u2014 the user already has your last reply, and a status recap would only bury it. You are working directly with the user, so stay available and continue when they write back."),n.driftGuidance!==null&&a.push(`<persona-transition>
23
- Your role was changed while you were away. ${n.driftGuidance}
24
- </persona-transition>`),k("revive",{},`
25
- ${a.join(`
13
+ </feed>`}r(P,"feedBlock");function Y(t,e){const n=(t??A(e)).trim()||"(no command)";return n.length>120?`${n.slice(0,117)}\u2026`:n}r(Y,"jobLabel");async function J(t){const e=await w(t),n=await N(await c(),t);if(n.length===0)return null;const a=Date.now(),o=n.length===1,s=[`${n.length} background bash job${o?"":"s"} you started ${o?"is":"are"} STILL RUNNING, detached from any turn and unaffected by your refresh. Each one sends you a message when it exits \u2014 that wake is automatic, so do not poll it and do not relaunch the same command.`];for(const i of n)s.push(` - ${i.jobId} \u2014 ${Y(i.purpose,i.command)} \xB7 running ${I(a-i.startedAtMs)} \xB7 log ${D(e,i.jobId).jobLog}`);return s.push("","Read output so far: `tail -n 50 <log>` (or `crtr node bash list --tail 20`). Abandon one: `crtr node bash kill <job-id>`."),`<background-jobs>
14
+ ${s.join(`
15
+ `)}
16
+ </background-jobs>`}r(J,"backgroundJobsBlock");async function ht(t,e,n){const a=t.node_id,o=["You have been revived fresh after a context refresh \u2014 your previous in-memory context is gone, by design. Everything below was just read from disk; it is your full bearings. Rebuild from it and continue toward your goal."];n!==void 0&&o.push(M(n));const s=await v(a);if(!(s!==null&&s.trim()!=="")&&!await C(a)){const p=await G(a);p!==null&&p.trim()!==""&&o.push(`<goal file="${await S(a)}">
17
+ ${p.trim()}
18
+ </goal>`)}const d=await J(a);d!==null&&o.push(d),o.push(await P(a,e.unreadDigest)),o.push(e.yieldMsg!==null?`<yield-message>
19
+ ${e.yieldMsg.trim()}
20
+ </yield-message>`:"<yield-message/>");const l=(await j(a)).length>0;return o.push(l?"If there is work to do, perform it. Otherwise stop \u2014 pipe the result to `crtr push final` through a single-quoted heredoc if the goal is met, or end your turn without a message to stay dormant awaiting your workers.":"If there is work to do, perform it. Otherwise end your turn without writing a message \u2014 the user already has your last reply, and a status recap would only bury it. You are working directly with the user, so stay available and continue when they write back."),e.driftGuidance!==null&&o.push(`<persona-transition>
21
+ Your role was changed while you were away. ${e.driftGuidance}
22
+ </persona-transition>`),y("revive",{},`
23
+ ${o.join(`
26
24
 
27
25
  `)}
28
- `)}r(pt,"buildReviveKickoff");export{dt as RUNTIME_RESTART_CONTINUATION,pt as buildReviveKickoff,lt as captureGoalIfAbsent,ht as clearYieldMessage,mt as drainBearings,y as goalPath,S as hasRetainedReports,K as listContextDir,v as readGoal,F as readYieldMessage,P as writeGoal,ft as writeYieldMessage,g as yieldMessagePath};
26
+ `)}r(ht,"buildReviveKickoff");export{dt as RUNTIME_RESTART_CONTINUATION,ht as buildReviveKickoff,ct as captureGoalIfAbsent,pt as clearYieldMessage,mt as drainBearings,S as goalPath,C as hasRetainedReports,ft as listContextDir,G as readGoal,W as readYieldMessage,ut as writeGoal,lt as writeYieldMessage};
@@ -1 +1 @@
1
- import{readMergedLaunchConfig as o}from"../config.js";process.once("message",e=>{try{process.send?.({config:o(e.cwd,e.profileId)})}catch(r){process.send?.({error:r instanceof Error?r.message:String(r)})}});
1
+ import{readMergedLaunchConfig as n}from"../config.js";import{setPersonId as e}from"../canvas/person-state.js";import{installPersonSnapshot as p}from"../scoped-state/person-store.js";process.once("message",r=>{try{r.person!==void 0&&r.snapshot!==void 0&&(e(r.person),p(r.person,r.snapshot)),process.send?.({config:n(r.cwd,r.profileId)})}catch(o){process.send?.({error:o instanceof Error?o.message:String(o)})}});
@@ -1,3 +1,3 @@
1
- var V=Object.defineProperty;var s=(e,r)=>V(e,"name",{value:r,configurable:!0});import{envProfileId as T}from"../../shared/env.js";import{mkdirSync as M}from"node:fs";import{join as U}from"node:path";import{readMergedLaunchConfig as D}from"../config.js";import{fork as F}from"node:child_process";import{fileURLToPath as $}from"node:url";import{freshChildNodeExecPath as G,recheckChildNode as K}from"./branded-host.js";import{LAUNCH_SYSTEM_PROMPT as W}from"./launch-prompt.js";import{nodeEnv as X}from"./nodes.js";import{editorLabel as B}from"../canvas/index.js";import{CANVAS_EXTENSIONS as ye,CANVAS_STOPHOOK_PATH as ve,CANVAS_INBOX_WATCHER_PATH as Le,CANVAS_RECAP_PATH as Re,CANVAS_GOAL_CAPTURE_PATH as be,CANVAS_PASSIVE_CONTEXT_PATH as He,CANVAS_CONTEXT_INTRO_PATH as Ve,CANVAS_TOOL_GUIDE_PATH as Me,CANVAS_DOC_SUBSTRATE_PATH as Ue,CANVAS_STRUCTURED_OUTPUT_PATH as De,CANVAS_BASH_VALVE_PATH as Fe}from"./canvas-extensions.js";import{nodeRunDir as j}from"../canvas/paths.js";import{writeFileBeneath as z}from"../spaces/open-beneath.js";import{projectOutputSchema as Y}from"./structured-output.js";import{CANVAS_EXTENSIONS as Q,mergeCanvasExtensions as P,assertMandatoryCanvasExtensions as J}from"./canvas-extensions.js";import{modelLadders as a,defaultProvider as C,STRENGTH_ALIASES as p,MODEL_PROVIDER_KEYS as x,MODEL_STRENGTHS as A,THINKING_SUFFIXES as Z,stripThinkingSuffix as m}from"./model-selection.js";import{OPENAI_PROVIDER_ENV as Ge,configuredLadderProviders as Ke,inferPortableModelSelection as We}from"./model-selection.js";function k(e,r=a()){return r[e]}s(k,"ladderFor");const S={light:0,medium:1,strong:2,ultra:3};function q(e,r,n){const t=m(e);for(const o of[!0,!1]){const i=o?A:[...A].sort((c,u)=>S[c]-S[u]);for(const c of n)for(const u of i){const f=r[c][u];if(!(o?f!==e:m(f)!==t))return{provider:c,strength:u}}}return null}s(q,"findLadderCell");function N(e){const r=e.lastIndexOf("/"),n=r===-1?void 0:e.slice(0,r),t=r===-1?e:e.slice(r+1),o=p[t];return o!==void 0?o:n!==void 0&&n!=="anthropic"?null:t==="opus"?"strong":t==="sonnet"?"medium":t==="haiku"?"light":null}s(N,"modelTokenStrength");function w(e,r=a()){const n=N(e);return n!==null?n:q(_(e,r),r,x)?.strength??null}s(w,"resolvedModelStrength");function ee(e){return e==="review"||e.startsWith("review/")||e.includes("/reviewers/")}s(ee,"isReviewQualityKind");function ne(e,r,n,t=a()){if(r===void 0)return n;if(!ee(e)||n===void 0)return r;const o=w(r,t),i=w(n,t);return o===null||i===null?r:S[o]<S[i]?n:r}s(ne,"floorReviewModel");function I(e){if(e.includes("/")){const r=e.lastIndexOf("/"),n=e.slice(0,r),t=e.slice(r+1);return n!==""&&(p[t]!==void 0||n==="anthropic"&&(t==="opus"||t==="sonnet"||t==="haiku"))}return p[e]!==void 0||e==="opus"||e==="sonnet"||e==="haiku"}s(I,"isPortableModelToken");function O(e,r=a()){const n=N(e);if(n!==null)return e.includes("/")?{family:e.slice(0,e.lastIndexOf("/")),strength:n}:e==="opus"||e==="sonnet"||e==="haiku"?{family:"anthropic",strength:n}:{family:C(r),strength:n}}s(O,"logicalModelIntent");function Te(e,r=a()){return I(e)?O(e,r):void 0}s(Te,"explicitModelIntent");function _(e,r=a()){if(e.includes("/")){const t=e.indexOf("/"),o=e.slice(0,t),i=e.slice(t+1),c=p[i];if(c!==void 0&&(o==="anthropic"||o==="openai"))return k(o,r)[c];if(o==="anthropic"){if(i==="opus")return r.anthropic.strong;if(i==="sonnet")return r.anthropic.medium;if(i==="haiku")return r.anthropic.light}return e}const n=p[e];return n!==void 0?k(C(r),r)[n]:e==="opus"?r.anthropic.strong:e==="sonnet"?r.anthropic.medium:e==="haiku"?r.anthropic.light:e}s(_,"normalizeModel");function y(e){const r=e.lastIndexOf(":");if(r<=0)return;const n=e.slice(r+1);return Z.has(n)?n:void 0}s(y,"thinkingSuffixOf");function re(e=x){const r=e.length>0?e:x,n=a(),t=[];for(const o of A)for(const i of r)t.push(n[i][o]);return t}s(re,"interleavedLadderCycle");function Pe(e,r=1,n){const t=re(n),o=_(e),i=m(o),c=y(o);let u=t.findIndex(f=>m(f)===i&&y(f)===c);return u===-1&&(u=t.findIndex(f=>m(f)===i)),u===-1?t[0]:t[(u+r+t.length)%t.length]}s(Pe,"nextLadderModel");function v(e,r,n,t){const o=t.kinds[e],i=t.modelLadders,c=r==="orchestrator"?o?.orchestratorModel??o?.model:o?.model,u=n.modelExact===!0?n.model:ne(e,n.model,c,i),f=n.modelExact===!0||n.modelOverride===!0&&n.model!==void 0&&!I(n.model),l=n.modelExact===!0?u:u!==void 0?_(u,i):void 0,h=f?void 0:n.modelIntent??(u!==void 0?O(u,i):void 0);return{launch:{model:l,modelIntent:h,modelExact:f?!0:void 0,tools:o?.tools??[],extensions:P([...Q,...o?.extensions??[]]),systemPrompt:W,env:{...n.extraEnv??{},...h?{CRTR_MODEL_INTENT:`${h.family}/${h.strength}`}:{}}},lifecycle:n.lifecycle}}s(v,"buildLaunchSpecFromMerged");function Ce(e,r,n){return v(e,r,n,D(n.cwd??process.cwd(),n.profileId!==void 0?n.profileId:T()||null))}s(Ce,"buildLaunchSpec");async function ke(e,r,n){const t=n.cwd??process.cwd(),o=n.profileId!==void 0?n.profileId:T()||null,i=await oe(t,o);return v(e,r,n,i)}s(ke,"buildLaunchSpecAsync");const L=15e3;function te(e,r,n){const t=r!==null?`was killed by ${r}`:`exited with code ${e}`,o=n.trim().split(`
1
+ var V=Object.defineProperty;var s=(e,r)=>V(e,"name",{value:r,configurable:!0});import{envProfileId as T}from"../../shared/env.js";import{readMergedLaunchConfig as M}from"../config.js";import{fork as U}from"node:child_process";import{fileURLToPath as D}from"node:url";import{personId as $,PersonUnresolvedError as F,PersonOutsideRequestError as G}from"../canvas/person-state.js";import{currentSnapshot as K,PersonSettingsNotLoadedError as W}from"../scoped-state/person-store.js";import{freshChildNodeExecPath as X,recheckChildNode as B}from"./branded-host.js";import{LAUNCH_SYSTEM_PROMPT as j}from"./launch-prompt.js";import{nodeEnv as z}from"./nodes.js";import{editorLabel as Y}from"../canvas/index.js";import{CANVAS_EXTENSIONS as Ne,CANVAS_STOPHOOK_PATH as Ie,CANVAS_INBOX_WATCHER_PATH as Oe,CANVAS_RECAP_PATH as ve,CANVAS_GOAL_CAPTURE_PATH as Le,CANVAS_PASSIVE_CONTEXT_PATH as ye,CANVAS_CONTEXT_INTRO_PATH as Re,CANVAS_TOOL_GUIDE_PATH as be,CANVAS_DOC_SUBSTRATE_PATH as He,CANVAS_STRUCTURED_OUTPUT_PATH as Ve,CANVAS_BASH_VALVE_PATH as Me}from"./canvas-extensions.js";import{CANVAS_EXTENSIONS as Q,mergeCanvasExtensions as P,assertMandatoryCanvasExtensions as J}from"./canvas-extensions.js";import{modelLadders as a,defaultProvider as k,STRENGTH_ALIASES as p,MODEL_PROVIDER_KEYS as x,MODEL_STRENGTHS as E,THINKING_SUFFIXES as Z,stripThinkingSuffix as m}from"./model-selection.js";import{OPENAI_PROVIDER_ENV as De,configuredLadderProviders as $e,inferPortableModelSelection as Fe}from"./model-selection.js";function C(e,r=a()){return r[e]}s(C,"ladderFor");const S={light:0,medium:1,strong:2,ultra:3};function q(e,r,n){const t=m(e);for(const o of[!0,!1]){const i=o?E:[...E].sort((c,u)=>S[c]-S[u]);for(const c of n)for(const u of i){const f=r[c][u];if(!(o?f!==e:m(f)!==t))return{provider:c,strength:u}}}return null}s(q,"findLadderCell");function w(e){const r=e.lastIndexOf("/"),n=r===-1?void 0:e.slice(0,r),t=r===-1?e:e.slice(r+1),o=p[t];return o!==void 0?o:n!==void 0&&n!=="anthropic"?null:t==="opus"?"strong":t==="sonnet"?"medium":t==="haiku"?"light":null}s(w,"modelTokenStrength");function N(e,r=a()){const n=w(e);return n!==null?n:q(A(e,r),r,x)?.strength??null}s(N,"resolvedModelStrength");function ee(e){return e==="review"||e.startsWith("review/")||e.includes("/reviewers/")}s(ee,"isReviewQualityKind");function ne(e,r,n,t=a()){if(r===void 0)return n;if(!ee(e)||n===void 0)return r;const o=N(r,t),i=N(n,t);return o===null||i===null?r:S[o]<S[i]?n:r}s(ne,"floorReviewModel");function I(e){if(e.includes("/")){const r=e.lastIndexOf("/"),n=e.slice(0,r),t=e.slice(r+1);return n!==""&&(p[t]!==void 0||n==="anthropic"&&(t==="opus"||t==="sonnet"||t==="haiku"))}return p[e]!==void 0||e==="opus"||e==="sonnet"||e==="haiku"}s(I,"isPortableModelToken");function O(e,r=a()){const n=w(e);if(n!==null)return e.includes("/")?{family:e.slice(0,e.lastIndexOf("/")),strength:n}:e==="opus"||e==="sonnet"||e==="haiku"?{family:"anthropic",strength:n}:{family:k(r),strength:n}}s(O,"logicalModelIntent");function Ee(e,r=a()){return I(e)?O(e,r):void 0}s(Ee,"explicitModelIntent");function A(e,r=a()){if(e.includes("/")){const t=e.indexOf("/"),o=e.slice(0,t),i=e.slice(t+1),c=p[i];if(c!==void 0&&(o==="anthropic"||o==="openai"))return C(o,r)[c];if(o==="anthropic"){if(i==="opus")return r.anthropic.strong;if(i==="sonnet")return r.anthropic.medium;if(i==="haiku")return r.anthropic.light}return e}const n=p[e];return n!==void 0?C(k(r),r)[n]:e==="opus"?r.anthropic.strong:e==="sonnet"?r.anthropic.medium:e==="haiku"?r.anthropic.light:e}s(A,"normalizeModel");function v(e){const r=e.lastIndexOf(":");if(r<=0)return;const n=e.slice(r+1);return Z.has(n)?n:void 0}s(v,"thinkingSuffixOf");function re(e=x){const r=e.length>0?e:x,n=a(),t=[];for(const o of E)for(const i of r)t.push(n[i][o]);return t}s(re,"interleavedLadderCycle");function Ae(e,r=1,n){const t=re(n),o=A(e),i=m(o),c=v(o);let u=t.findIndex(f=>m(f)===i&&v(f)===c);return u===-1&&(u=t.findIndex(f=>m(f)===i)),u===-1?t[0]:t[(u+r+t.length)%t.length]}s(Ae,"nextLadderModel");function L(e,r,n,t){const o=t.kinds[e],i=t.modelLadders,c=r==="orchestrator"?o?.orchestratorModel??o?.model:o?.model,u=n.modelExact===!0?n.model:ne(e,n.model,c,i),f=n.modelExact===!0||n.modelOverride===!0&&n.model!==void 0&&!I(n.model),l=n.modelExact===!0?u:u!==void 0?A(u,i):void 0,h=f?void 0:n.modelIntent??(u!==void 0?O(u,i):void 0);return{launch:{model:l,modelIntent:h,modelExact:f?!0:void 0,tools:o?.tools??[],extensions:P([...Q,...o?.extensions??[]]),systemPrompt:j,env:{...n.extraEnv??{},...h?{CRTR_MODEL_INTENT:`${h.family}/${h.strength}`}:{}}},lifecycle:n.lifecycle}}s(L,"buildLaunchSpecFromMerged");function _e(e,r,n){return L(e,r,n,M(n.cwd??process.cwd(),n.profileId!==void 0?n.profileId:T()||null))}s(_e,"buildLaunchSpec");async function Te(e,r,n){const t=n.cwd??process.cwd(),o=n.profileId!==void 0?n.profileId:T()||null,i=await oe(t,o);return L(e,r,n,i)}s(Te,"buildLaunchSpecAsync");const y=15e3;function te(e,r,n){const t=r!==null?`was killed by ${r}`:`exited with code ${e}`,o=n.trim().split(`
2
2
  `).slice(-8).join(`
3
- `).slice(-1500);return`launch config subprocess ${t}${o!==""?`: ${o}`:" (no stderr output)"}`}s(te,"describeLaunchConfigExit");class R extends Error{static{s(this,"LaunchConfigWorkerCrash")}}async function oe(e,r,n={}){const t=n.execPath??await G(),o=n.workerPath??$(new URL("./launch-config-worker.js",import.meta.url));try{return await b(e,r,t,o)}catch(i){if(!(i instanceof R))throw i;const c=await K(t);if(c===t)throw i;return b(e,r,c,o)}}s(oe,"readMergedLaunchConfigAsync");function b(e,r,n,t){return new Promise((o,i)=>{const c=F(t,[],{execPath:n,stdio:["ignore","ignore","pipe","ipc"],serialization:"advanced"});let u="";c.stderr?.setEncoding("utf8").on("data",d=>{u=(u+d).slice(-8192)}),c.send({cwd:e,profileId:r});let f=!1;const l=s(d=>{f||(f=!0,clearTimeout(h),c.connected&&c.disconnect(),c.killed||c.kill("SIGKILL"),d())},"finish"),h=setTimeout(()=>l(()=>i(new Error(`timed out after ${L}ms reading launch config for ${e}`))),L);c.once("message",d=>{d.error!==void 0?l(()=>i(new Error(d.error))):d.config!==void 0?l(()=>o(d.config)):l(()=>i(new Error("launch config subprocess returned no result")))});let g=null;c.on("error",d=>{g??=d}),c.once("close",(d,H)=>{if(f)return;const E=te(d,H,u);l(()=>i(new R(g===null?E:`${E} (${g.message})`)))})})}s(b,"runLaunchConfigWorker");function ie(e,r){try{const n=j(e);M(n,{recursive:!0});const t=U(n,"system-prompt.md");return z(n,t,r,{atomic:!0}),t}catch{return null}}s(ie,"writeSystemPromptFile");function Ne(e,r={}){const n=e.launch,t=P(n?.extensions);J(t);const o=[];for(const i of t)o.push("-e",i);if(o.push("-n",B(e)),r.forkFrom!==void 0&&r.forkFrom!=="")o.push("--fork",r.forkFrom);else{const i=r.resumeSessionPath??r.resumeSessionId;i!==void 0&&o.push("--session",i),r.newCycle===!0&&o.push("--crtr-new-cycle")}if(n?.model!==void 0&&o.push("--model",n.model),n?.modelExact===!0&&o.push("--crtr-model-exact"),n?.tools!==void 0&&n.tools.length>0&&o.push("--tools",n.tools.join(",")),n?.systemPrompt!==void 0&&n.systemPrompt!==""){const i=ie(e.node_id,n.systemPrompt)??n.systemPrompt;o.push("--append-system-prompt",i)}return r.prompt!==void 0&&r.prompt!==""&&o.push(r.prompt),Y(e.node_id),{argv:o,env:X(e)}}s(Ne,"buildPiArgv");function we(e){for(const[t,o]of Object.entries(e.env))process.env[t]=o;const r={cwd:e.env.CRTR_NODE_CWD??process.cwd(),extensionPaths:[]},n=e.argv;for(let t=0;t<n.length;t++){const o=n[t];switch(o){case"-e":r.extensionPaths.push(n[++t]);break;case"-n":r.editorName=n[++t];break;case"--fork":r.forkFrom=n[++t];break;case"--session":{const i=n[++t];i.includes("/")||i.endsWith(".jsonl")?r.resumeSessionPath=i:r.resumeSessionId=i;break}case"--model":r.model=n[++t];break;case"--crtr-model-exact":r.modelExact=!0;break;case"--tools":r.tools=n[++t].split(",").filter(i=>i!=="");break;case"--append-system-prompt":r.appendSystemPromptPath=n[++t];break;case"--crtr-new-cycle":r.newCycle=!0;break;default:r.firstPrompt=o;break}}return r}s(we,"piInvocationToSdkConfig");export{Fe as CANVAS_BASH_VALVE_PATH,Ve as CANVAS_CONTEXT_INTRO_PATH,Ue as CANVAS_DOC_SUBSTRATE_PATH,ye as CANVAS_EXTENSIONS,be as CANVAS_GOAL_CAPTURE_PATH,Le as CANVAS_INBOX_WATCHER_PATH,He as CANVAS_PASSIVE_CONTEXT_PATH,Re as CANVAS_RECAP_PATH,ve as CANVAS_STOPHOOK_PATH,De as CANVAS_STRUCTURED_OUTPUT_PATH,Me as CANVAS_TOOL_GUIDE_PATH,Ge as OPENAI_PROVIDER_ENV,Ce as buildLaunchSpec,ke as buildLaunchSpecAsync,Ne as buildPiArgv,Ke as configuredLadderProviders,te as describeLaunchConfigExit,Te as explicitModelIntent,We as inferPortableModelSelection,re as interleavedLadderCycle,I as isPortableModelToken,O as logicalModelIntent,N as modelTokenStrength,Pe as nextLadderModel,_ as normalizeModel,we as piInvocationToSdkConfig,oe as readMergedLaunchConfigAsync};
3
+ `).slice(-1500);return`launch config subprocess ${t}${o!==""?`: ${o}`:" (no stderr output)"}`}s(te,"describeLaunchConfigExit");class R extends Error{static{s(this,"LaunchConfigWorkerCrash")}}async function oe(e,r,n={}){const t=n.execPath??await X(),o=n.workerPath??D(new URL("./launch-config-worker.js",import.meta.url));try{return await b(e,r,t,o)}catch(i){if(!(i instanceof R))throw i;const c=await B(t);if(c===t)throw i;return b(e,r,c,o)}}s(oe,"readMergedLaunchConfigAsync");function ie(){try{return{person:$(),snapshot:K()}}catch(e){if(e instanceof F||e instanceof G||e instanceof W)return{};throw e}}s(ie,"heldPersonSettings");function b(e,r,n,t){return new Promise((o,i)=>{const c=U(t,[],{execPath:n,stdio:["ignore","ignore","pipe","ipc"],serialization:"advanced"});let u="";c.stderr?.setEncoding("utf8").on("data",d=>{u=(u+d).slice(-8192)}),c.send({cwd:e,profileId:r,...ie()});let f=!1;const l=s(d=>{f||(f=!0,clearTimeout(h),c.connected&&c.disconnect(),c.killed||c.kill("SIGKILL"),d())},"finish"),h=setTimeout(()=>l(()=>i(new Error(`timed out after ${y}ms reading launch config for ${e}`))),y);c.once("message",d=>{d.error!==void 0?l(()=>i(new Error(d.error))):d.config!==void 0?l(()=>o(d.config)):l(()=>i(new Error("launch config subprocess returned no result")))});let g=null;c.on("error",d=>{g??=d}),c.once("close",(d,H)=>{if(f)return;const _=te(d,H,u);l(()=>i(new R(g===null?_:`${_} (${g.message})`)))})})}s(b,"runLaunchConfigWorker");function Pe(e,r={}){const n=e.launch,t=P(n?.extensions);J(t);const o=[];for(const i of t)o.push("-e",i);if(o.push("-n",Y(e)),r.forkFrom!==void 0&&r.forkFrom!=="")o.push("--fork",r.forkFrom);else{const i=r.resumeSessionPath??r.resumeSessionId;i!==void 0&&o.push("--session",i),r.newCycle===!0&&o.push("--crtr-new-cycle")}return n?.model!==void 0&&o.push("--model",n.model),n?.modelExact===!0&&o.push("--crtr-model-exact"),n?.tools!==void 0&&n.tools.length>0&&o.push("--tools",n.tools.join(",")),n?.systemPrompt!==void 0&&n.systemPrompt!==""&&o.push("--append-system-prompt",n.systemPrompt),r.prompt!==void 0&&r.prompt!==""&&o.push(r.prompt),{argv:o,env:z(e),...n?.worktree===void 0?{}:{worktree:n.worktree}}}s(Pe,"buildPiArgv");function ke(e){for(const[t,o]of Object.entries(e.env))process.env[t]=o;const r={cwd:e.env.CRTR_NODE_CWD??process.cwd(),extensionPaths:[]},n=e.argv;for(let t=0;t<n.length;t++){const o=n[t];switch(o){case"-e":r.extensionPaths.push(n[++t]);break;case"-n":r.editorName=n[++t];break;case"--fork":r.forkFrom=n[++t];break;case"--session":{const i=n[++t];i.includes("/")||i.endsWith(".jsonl")?r.resumeSessionPath=i:r.resumeSessionId=i;break}case"--model":r.model=n[++t];break;case"--crtr-model-exact":r.modelExact=!0;break;case"--tools":r.tools=n[++t].split(",").filter(i=>i!=="");break;case"--append-system-prompt":r.appendSystemPromptPath=n[++t];break;case"--crtr-new-cycle":r.newCycle=!0;break;default:r.firstPrompt=o;break}}return r}s(ke,"piInvocationToSdkConfig");export{Me as CANVAS_BASH_VALVE_PATH,Re as CANVAS_CONTEXT_INTRO_PATH,He as CANVAS_DOC_SUBSTRATE_PATH,Ne as CANVAS_EXTENSIONS,Le as CANVAS_GOAL_CAPTURE_PATH,Oe as CANVAS_INBOX_WATCHER_PATH,ye as CANVAS_PASSIVE_CONTEXT_PATH,ve as CANVAS_RECAP_PATH,Ie as CANVAS_STOPHOOK_PATH,Ve as CANVAS_STRUCTURED_OUTPUT_PATH,be as CANVAS_TOOL_GUIDE_PATH,De as OPENAI_PROVIDER_ENV,_e as buildLaunchSpec,Te as buildLaunchSpecAsync,Pe as buildPiArgv,$e as configuredLadderProviders,te as describeLaunchConfigExit,Ee as explicitModelIntent,Fe as inferPortableModelSelection,re as interleavedLadderCycle,I as isPortableModelToken,O as logicalModelIntent,w as modelTokenStrength,Ae as nextLadderModel,A as normalizeModel,ke as piInvocationToSdkConfig,oe as readMergedLaunchConfigAsync};
@@ -1 +1 @@
1
- var i=Object.defineProperty;var r=(o,e)=>i(o,"name",{value:e,configurable:!0});import{join as t}from"node:path";import{ModelRegistry as n,ModelRuntime as m}from"@earendil-works/pi-coding-agent";import{PoolCredentialStore as s}from"../pool-credential-store.js";import{piAgentDir as a}from"./package-health.js";import{secretsDir as l}from"../layout.js";async function j(){const o=a(),e=await m.create({credentials:new s(t(l(),"auth.json")),modelsPath:t(o,"models.json")});return new n(e)}r(j,"openModelRegistry");export{j as openModelRegistry};
1
+ var r=Object.defineProperty;var t=(e,o)=>r(e,"name",{value:o,configurable:!0});import{join as n}from"node:path";import{ModelRegistry as i,ModelRuntime as m}from"@earendil-works/pi-coding-agent";import{PoolCredentialStore as s}from"../pool-credential-store.js";import{piAgentDir as a}from"./package-health.js";async function g(){const e=a(),o=await m.create({credentials:new s,modelsPath:n(e,"models.json")});return new i(o)}t(g,"openModelRegistry");export{g as openModelRegistry};
@@ -10,14 +10,12 @@ export interface NodeSessionRead {
10
10
  sessionFile: string;
11
11
  /** Verbatim contents of the session `.jsonl`. */
12
12
  sessionJsonl: string;
13
- /** The assembled system prompt as last captured, or `null` if never written. */
13
+ /** The system prompt text the latest launch recipe hands pi, or `null` when the node never launched. */
14
14
  systemPrompt: string | null;
15
15
  }
16
- /** Read a node's raw conversation record off disk — no broker, no attach, no
17
- * mapping. The system prompt is NOT part of the session file (pi assembles it
18
- * per boot), so it is read from the sidecar the broker captures on every
19
- * rebind (`<jobDir>/system-prompt.md`), falling back to the one `launch.ts`
20
- * writes at spawn (`<nodeDir>/system-prompt.md`). */
16
+ /** Read a node's raw conversation record — no broker, no attach, no mapping. The system
17
+ * prompt is NOT part of the session file (pi assembles it per boot), so it is the text
18
+ * the node's latest launch recipe passes to pi as `--append-system-prompt`. */
21
19
  export declare function readNodeSession(nodeId: string): Promise<NodeSessionRead>;
22
20
  export interface NodeSnapshotRead {
23
21
  nodeId: string;
@@ -1,3 +1,3 @@
1
- var C=Object.defineProperty;var a=(e,t)=>C(e,"name",{value:t,configurable:!0});import{existsSync as N,readFileSync as j}from"node:fs";import{isBeneathRefusal as F,readFileBeneath as $,readTextBeneathIfExists as x}from"../spaces/open-beneath.js";import{join as p}from"node:path";import{InputError as c}from"../io.js";import{conversationIdFromPath as y,conversationStore as w,ConversationNotFoundError as A}from"../conversation-store/index.js";import{fullName as T,getNode as g}from"../canvas/index.js";import{nodeRunDir as h,nodeRunJobDir as S,sessionPtrPath as k}from"../canvas/paths.js";import{hydratePersistedAdvertisedCommandMessages as v}from"./advertised-command-invocation.js";import{SessionManager as L}from"./broker-sdk.js";import{openModelRegistry as P}from"./model-registry.js";import{BUILTIN_SLASH_COMMANDS as B}from"./pi-vendored.js";import{cycleAwareMessages as J}from"./session-cycles.js";import{projectTranscript as O}from"./session-visibility.js";import{normalizeToolGroupSummaryRecord as E}from"../../shared/tool-groups.js";import{normalizeTurnReplyRecord as U}from"../../shared/turn-replies.js";async function V(e){if(e!==null)try{return(await P()).find(e.provider,e.modelId)}catch{return}}a(V,"resolveRecordedModel");async function b(e,t){const o=a(async i=>{const n=i?y(i):null;if(n===null)return null;try{return(await w().header(n)).path}catch(l){if(l instanceof A)return null;throw l}},"resolvePath"),s=await o(t);if(s!==null)return s;const r=k(e);return N(r)?await o(j(r,"utf8").trim()):null}a(b,"resolveSessionFile");async function W(e){const t=await g(e);if(t===null)throw new c({error:"not_found",message:`no node: ${e}`,field:"id",next:"List nodes with `crtr node inspect list`."});return await b(e,t.pi_session_file)}a(W,"readableSessionFile");function z(e,t){return{sessionFile:t,sessionId:e,userMessages:0,assistantMessages:0,toolCalls:0,toolResults:0,totalMessages:0,tokens:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0},cost:0}}a(z,"emptyStats");function D(e,t,o){const s=z(t,o);s.totalMessages=e.length;for(const r of e)if(r.role==="user")s.userMessages++;else if(r.role==="assistant"){s.assistantMessages++;const i=Array.isArray(r.content)?r.content:[];s.toolCalls+=i.filter(l=>l!==null&&typeof l=="object"&&l.type==="toolCall").length;const n=r.usage;n!==void 0&&(s.tokens.input+=n.input??0,s.tokens.output+=n.output??0,s.tokens.cacheRead+=n.cacheRead??0,s.tokens.cacheWrite+=n.cacheWrite??0,s.cost+=n.cost?.total??0)}else r.role==="toolResult"&&s.toolResults++;return s.tokens.total=s.tokens.input+s.tokens.output+s.tokens.cacheRead+s.tokens.cacheWrite,s}a(D,"statsFromMessages");async function ge(e){const t=await g(e);if(t===null)throw new c({error:"not_found",message:`no node: ${e}`,field:"id",next:"List nodes with `crtr node inspect list`."});const o=await b(e,t.pi_session_file);if(o===null)throw new c({error:"no_session",message:`node has no readable session file: ${e}`,field:"id",next:"Choose a node with captured conversation history."});return{nodeId:e,sessionFile:o,sessionJsonl:await(async()=>{const{header:s,entries:r}=await w().read(y(o));return[s,...r].map(i=>`${JSON.stringify(i)}
2
- `).join("")})(),systemPrompt:M(e,p(S(e),"system-prompt.md"))??M(e,p(h(e),"system-prompt.md"))}}a(ge,"readNodeSession");function M(e,t){try{return $(h(e),t).toString("utf8")}catch(o){if(F(o))throw o;return null}}a(M,"readRunFileIfPresent");function G(e){try{const t=x(h(e),p(S(e),"tool-summaries.json"));return E(t===null?null:JSON.parse(t))}catch{return{}}}a(G,"readToolGroupSummaries");function q(e){try{const t=x(h(e),p(S(e),"turn-replies.json"));return U(t===null?null:JSON.parse(t))}catch{return{}}}a(q,"readTurnReplies");async function R(e){const t=await g(e);if(t===null)throw new c({error:"not_found",message:`no node: ${e}`,field:"id",next:"List nodes with `crtr node inspect list`."});const o=await b(e,t.pi_session_file);if(o===null)throw new c({error:"no_session",message:`node has no readable session file: ${e}`,field:"id",next:"Choose a node with captured conversation history."});const{header:s,entries:r}=await w().read(y(o)),i=L.inMemory(s.cwd,void 0,[s,...r]),n=i.buildSessionContext();v(n.messages);const l=J(i);l!==void 0&&v(l.map(({message:f})=>f));const u=l===void 0?void 0:O(l,{boundaryReviewId:t.review_binding?.review_id,sessionEntries:i.getEntries()}),m=u?.map(({message:f})=>f)??n.messages;return{sessionFile:o,messages:m,identified:u,model:n.model,thinkingLevel:n.thinkingLevel,sessionId:i.getSessionId(),sessionName:i.getSessionName()}}a(R,"reconstructTranscript");function d(){throw new c({error:"invalid_cursor",message:"cursor must be a base64url-encoded messages cursor.",field:"cursor",next:"Omit cursor to start from the newest messages."})}a(d,"invalidCursor");function H(e,t){/^[A-Za-z0-9_-]+$/u.test(e)||d();let o;try{const r=Buffer.from(e,"base64url").toString("utf8");Buffer.from(r,"utf8").toString("base64url")!==e&&d(),o=JSON.parse(r)}catch{d()}(typeof o!="object"||o===null||o.v!==1||!Number.isSafeInteger(o.before))&&d();const s=o.before;return(s<0||s>t)&&d(),s}a(H,"decodeMessagesCursor");function Y(e){return Buffer.from(JSON.stringify({v:1,before:e}),"utf8").toString("base64url")}a(Y,"encodeMessagesCursor");async function Z(e){const t=await R(e),o={messages:t.messages,...t.identified===void 0?{}:{messageIds:t.identified.map(({id:s})=>s)},messageVisibility:t.identified?.map(({visibility:s})=>s)??t.messages.map(()=>"visible"),turnVisibility:"visible",stats:D(t.messages,t.sessionId,t.sessionFile),state:{model:await V(t.model),thinkingLevel:t.thinkingLevel,isStreaming:!1,isCompacting:!1,steeringMode:"one-at-a-time",followUpMode:"one-at-a-time",sessionFile:t.sessionFile,sessionId:t.sessionId,sessionName:t.sessionName,autoCompactionEnabled:!0,messageCount:t.messages.length,pendingMessageCount:0},display:{statuses:{},widgets:{},title:void 0},queued:{steering:[],followUp:[]},toolGroupSummaries:G(e),turnReplies:q(e)};return{nodeId:e,snapshot:o,commands:B.map(s=>({...s,source:"builtin"}))}}a(Z,"readNodeSnapshot");async function he(e,{cursor:t,limit:o=200}){if(!Number.isSafeInteger(o)||o<1||o>500)throw new c({error:"invalid_limit",message:"limit must be an integer from 1 through 500.",field:"limit",next:"Use a limit from 1 through 500."});if(await W(e)===null)return{messages:[],messageIds:[],messageVisibility:[],nextCursor:null};const{messages:s,identified:r}=await R(e),i=t===void 0?s.length:H(t,s.length);let n=Math.max(0,i-o);for(;n>0&&typeof s[n]=="object"&&s[n]!==null&&s[n].role==="toolResult";)n--;const l=r?.slice(n,i);return{messages:l?.map(({message:u})=>u)??s.slice(n,i),...l===void 0?{}:{messageIds:l.map(({id:u})=>u)},messageVisibility:l?.map(({visibility:u})=>u)??s.slice(n,i).map(()=>"visible"),nextCursor:n===0?null:Y(n)}}a(he,"readNodeMessagesPage");function K(e){return typeof e=="string"?e:Array.isArray(e)?e.filter(t=>typeof t=="object"&&t!==null).filter(t=>t.type==="text"&&typeof t.text=="string").map(t=>t.text).join(""):""}a(K,"textFromContent");function Q(e){switch(e.role){case"user":return"You";case"assistant":return"Agent";case"toolResult":return"Tool result";default:return typeof e.role=="string"?e.role:"Message"}}a(Q,"roleLabel");function X(e){return Array.isArray(e.content)?e.content.filter(t=>typeof t=="object"&&t!==null&&t.type==="toolCall").map(t=>`Tool: ${typeof t.name=="string"?t.name:"call"}`):[]}a(X,"toolSummaries");async function ye(e){const t=await g(e);if(t===null)throw new c({error:"not_found",message:`no node: ${e}`,field:"node-id",next:"List nodes with `crtr node inspect list`."});const{snapshot:o}=await Z(e),r=[`# ${T(t)}`,"",`Saved transcript \xB7 ${t.status} \xB7 ${t.lifecycle}`,""];for(const i of o.messages){if(typeof i!="object"||i===null)continue;const n=i;if(n.role==="custom"&&n.display===!1)continue;const l=K(n.content),u=typeof n.text=="string"?n.text:"",m=l.trim()?l:u.trim()?u:"",f=X(n);if(!(!m&&f.length===0)){r.push(`## ${Q(n)}`,""),m&&r.push(m,"");for(const _ of f)r.push(`- ${_}`);f.length&&r.push("")}}return r.length===5&&r.push("_No saved messages._",""),r.join(`
3
- `)}a(ye,"transcriptMarkdown");export{he as readNodeMessagesPage,ge as readNodeSession,Z as readNodeSnapshot,ye as transcriptMarkdown};
1
+ var x=Object.defineProperty;var i=(e,t)=>x(e,"name",{value:t,configurable:!0});import{openDb as _}from"../canvas/db.js";import{latestExecutionForNode as M}from"../canvas/executions.js";import{InputError as c}from"../io.js";import{conversationIdFromPath as g,conversationStore as h,ConversationNotFoundError as C}from"../conversation-store/index.js";import{fullName as N,getNode as p}from"../canvas/index.js";import{hydratePersistedAdvertisedCommandMessages as y}from"./advertised-command-invocation.js";import{SessionManager as R}from"./broker-sdk.js";import{openModelRegistry as A}from"./model-registry.js";import{BUILTIN_SLASH_COMMANDS as $}from"./pi-vendored.js";import{cycleAwareMessages as j}from"./session-cycles.js";import{projectTranscript as F}from"./session-visibility.js";import{normalizeToolGroupSummaryRecord as L}from"../../shared/tool-groups.js";import{normalizeTurnReplyRecord as T}from"../../shared/turn-replies.js";async function k(e){if(e!==null)try{return(await A()).find(e.provider,e.modelId)}catch{return}}i(k,"resolveRecordedModel");async function w(e,t){return await i(async s=>{const r=s?g(s):null;if(r===null)return null;try{return(await h().header(r)).path}catch(a){if(a instanceof C)return null;throw a}},"resolvePath")(t)}i(w,"resolveSessionFile");async function E(e){const t=await p(e);if(t===null)throw new c({error:"not_found",message:`no node: ${e}`,field:"id",next:"List nodes with `crtr node inspect list`."});return await w(e,t.pi_session_file)}i(E,"readableSessionFile");function O(e,t){return{sessionFile:t,sessionId:e,userMessages:0,assistantMessages:0,toolCalls:0,toolResults:0,totalMessages:0,tokens:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0},cost:0}}i(O,"emptyStats");function J(e,t,n){const s=O(t,n);s.totalMessages=e.length;for(const r of e)if(r.role==="user")s.userMessages++;else if(r.role==="assistant"){s.assistantMessages++;const a=Array.isArray(r.content)?r.content:[];s.toolCalls+=a.filter(l=>l!==null&&typeof l=="object"&&l.type==="toolCall").length;const o=r.usage;o!==void 0&&(s.tokens.input+=o.input??0,s.tokens.output+=o.output??0,s.tokens.cacheRead+=o.cacheRead??0,s.tokens.cacheWrite+=o.cacheWrite??0,s.cost+=o.cost?.total??0)}else r.role==="toolResult"&&s.toolResults++;return s.tokens.total=s.tokens.input+s.tokens.output+s.tokens.cacheRead+s.tokens.cacheWrite,s}i(J,"statsFromMessages");async function ae(e){const t=await p(e);if(t===null)throw new c({error:"not_found",message:`no node: ${e}`,field:"id",next:"List nodes with `crtr node inspect list`."});const n=await w(e,t.pi_session_file);if(n===null)throw new c({error:"no_session",message:`node has no readable session file: ${e}`,field:"id",next:"Choose a node with captured conversation history."});return{nodeId:e,sessionFile:n,sessionJsonl:await(async()=>{const{header:s,entries:r}=await h().read(g(n));return[s,...r].map(a=>`${JSON.stringify(a)}
2
+ `).join("")})(),systemPrompt:await P(e)}}i(ae,"readNodeSession");async function P(e){const t=(await M(e))?.launchJson??null;if(t===null)return null;const n=JSON.parse(t).argv;if(!Array.isArray(n))return null;const s=n.indexOf("--append-system-prompt");return s===-1||typeof n[s+1]!="string"?null:n[s+1]}i(P,"launchSystemPrompt");async function S(e,t){const n=await(await _()).prepare(`SELECT ${t} AS raw FROM nodes WHERE node_id = ?`).get(e);try{return n?.raw==null?null:JSON.parse(n.raw)}catch{return null}}i(S,"readSummaryColumn");async function W(e){return L(await S(e,"tool_summaries_json"))}i(W,"readToolGroupSummaries");async function B(e){return T(await S(e,"turn_replies_json"))}i(B,"readTurnReplies");async function b(e){const t=await p(e);if(t===null)throw new c({error:"not_found",message:`no node: ${e}`,field:"id",next:"List nodes with `crtr node inspect list`."});const n=await w(e,t.pi_session_file);if(n===null)throw new c({error:"no_session",message:`node has no readable session file: ${e}`,field:"id",next:"Choose a node with captured conversation history."});const{header:s,entries:r}=await h().read(g(n)),a=R.inMemory(s.cwd,void 0,[s,...r]),o=a.buildSessionContext();y(o.messages);const l=j(a);l!==void 0&&y(l.map(({message:f})=>f));const u=l===void 0?void 0:F(l,{boundaryReviewId:t.review_binding?.review_id,sessionEntries:a.getEntries()}),m=u?.map(({message:f})=>f)??o.messages;return{sessionFile:n,messages:m,identified:u,model:o.model,thinkingLevel:o.thinkingLevel,sessionId:a.getSessionId(),sessionName:a.getSessionName()}}i(b,"reconstructTranscript");function d(){throw new c({error:"invalid_cursor",message:"cursor must be a base64url-encoded messages cursor.",field:"cursor",next:"Omit cursor to start from the newest messages."})}i(d,"invalidCursor");function U(e,t){/^[A-Za-z0-9_-]+$/u.test(e)||d();let n;try{const r=Buffer.from(e,"base64url").toString("utf8");Buffer.from(r,"utf8").toString("base64url")!==e&&d(),n=JSON.parse(r)}catch{d()}(typeof n!="object"||n===null||n.v!==1||!Number.isSafeInteger(n.before))&&d();const s=n.before;return(s<0||s>t)&&d(),s}i(U,"decodeMessagesCursor");function V(e){return Buffer.from(JSON.stringify({v:1,before:e}),"utf8").toString("base64url")}i(V,"encodeMessagesCursor");async function z(e){const t=await b(e),n={messages:t.messages,...t.identified===void 0?{}:{messageIds:t.identified.map(({id:s})=>s)},messageVisibility:t.identified?.map(({visibility:s})=>s)??t.messages.map(()=>"visible"),turnVisibility:"visible",stats:J(t.messages,t.sessionId,t.sessionFile),state:{model:await k(t.model),thinkingLevel:t.thinkingLevel,isStreaming:!1,isCompacting:!1,steeringMode:"one-at-a-time",followUpMode:"one-at-a-time",sessionFile:t.sessionFile,sessionId:t.sessionId,sessionName:t.sessionName,autoCompactionEnabled:!0,messageCount:t.messages.length,pendingMessageCount:0},display:{statuses:{},widgets:{},title:void 0},queued:{steering:[],followUp:[]},toolGroupSummaries:await W(e),turnReplies:await B(e)};return{nodeId:e,snapshot:n,commands:$.map(s=>({...s,source:"builtin"}))}}i(z,"readNodeSnapshot");async function le(e,{cursor:t,limit:n=200}){if(!Number.isSafeInteger(n)||n<1||n>500)throw new c({error:"invalid_limit",message:"limit must be an integer from 1 through 500.",field:"limit",next:"Use a limit from 1 through 500."});if(await E(e)===null)return{messages:[],messageIds:[],messageVisibility:[],nextCursor:null};const{messages:s,identified:r}=await b(e),a=t===void 0?s.length:U(t,s.length);let o=Math.max(0,a-n);for(;o>0&&typeof s[o]=="object"&&s[o]!==null&&s[o].role==="toolResult";)o--;const l=r?.slice(o,a);return{messages:l?.map(({message:u})=>u)??s.slice(o,a),...l===void 0?{}:{messageIds:l.map(({id:u})=>u)},messageVisibility:l?.map(({visibility:u})=>u)??s.slice(o,a).map(()=>"visible"),nextCursor:o===0?null:V(o)}}i(le,"readNodeMessagesPage");function G(e){return typeof e=="string"?e:Array.isArray(e)?e.filter(t=>typeof t=="object"&&t!==null).filter(t=>t.type==="text"&&typeof t.text=="string").map(t=>t.text).join(""):""}i(G,"textFromContent");function D(e){switch(e.role){case"user":return"You";case"assistant":return"Agent";case"toolResult":return"Tool result";default:return typeof e.role=="string"?e.role:"Message"}}i(D,"roleLabel");function H(e){return Array.isArray(e.content)?e.content.filter(t=>typeof t=="object"&&t!==null&&t.type==="toolCall").map(t=>`Tool: ${typeof t.name=="string"?t.name:"call"}`):[]}i(H,"toolSummaries");async function ue(e){const t=await p(e);if(t===null)throw new c({error:"not_found",message:`no node: ${e}`,field:"node-id",next:"List nodes with `crtr node inspect list`."});const{snapshot:n}=await z(e),r=[`# ${N(t)}`,"",`Saved transcript \xB7 ${t.status} \xB7 ${t.lifecycle}`,""];for(const a of n.messages){if(typeof a!="object"||a===null)continue;const o=a;if(o.role==="custom"&&o.display===!1)continue;const l=G(o.content),u=typeof o.text=="string"?o.text:"",m=l.trim()?l:u.trim()?u:"",f=H(o);if(!(!m&&f.length===0)){r.push(`## ${D(o)}`,""),m&&r.push(m,"");for(const v of f)r.push(`- ${v}`);f.length&&r.push("")}}return r.length===5&&r.push("_No saved messages._",""),r.join(`
3
+ `)}i(ue,"transcriptMarkdown");export{le as readNodeMessagesPage,ae as readNodeSession,z as readNodeSnapshot,ue as transcriptMarkdown};
@@ -1 +1 @@
1
- var J=Object.defineProperty;var l=(e,r)=>J(e,"name",{value:r,configurable:!0});import{envHomeOverride as K,envRuntimeHomeOverride as X,INBOX_BETWEEN_TURNS_ENV as z,SCOPES_FILE_ENV as V,scopeAllowed as I}from"../../shared/env.js";import{isOwnMemoryScope as Y,validateScopes as Q}from"../scopes.js";import{activeGrant as F,terminalGrant as k}from"../grants/mirror.js";import{grantSnapshotMissing as Z}from"../../daemon/readiness.js";import{appendRunEvent as ee}from"../runs/events.js";import{personId as ne}from"../canvas/person.js";import{InputError as S}from"../io.js";import{ApiError as g}from"../../api/errors.js";import{assertGranteeRunsHere as re}from"./unsandboxed.js";import{randomBytes as te}from"node:crypto";import{existsSync as B}from"node:fs";import{resolve as ie,relative as oe,isAbsolute as P,join as ae,sep as le}from"node:path";import{appSpace as se}from"../layout.js";import{scopesFilePath as de}from"../canvas/paths.js";import{createNode as ce,assertRunNotDeleting as ue,conversationOwner as fe,getNode as u,getRow as pe}from"../canvas/index.js";import{ensureAppSpace as me}from"../spaces/space.js";import{LAUNCHER_SOCKET as U}from"../../launcher/spec.js";import{resolveInstallId as _e}from"../canvas/install-id.js";import{isAppRun as we}from"../canvas/app-run.js";import{contextDir as ge}from"../canvas/paths.js";import{conversationIdFromPath as he}from"../conversation-store/index.js";import{usage as H}from"../errors.js";import{assertProfileAvailableForBirth as ve}from"../profiles/deletion-reservation.js";import{loadExactProfileManifest as Re}from"../profiles/manifest.js";import{admitNodeCreate as ye}from"../command-hooks/lifecycle-create.js";import{getById as Ee,nodeObject as C,ownerForGrantee as Ie}from"../graph/objects.js";import{recordActedOn as Ce}from"../graph/edges.js";import{recordWatch as Ne,copyWatchesForFork as ke}from"../graph/watches.js";import{publish as Se}from"../graph/events.js";import{canvasDatabaseUrl as Te}from"../canvas/db.js";import{someAsync as Oe}from"../async-array.js";import{admitIntoManagedCheckout as xe}from"../worktree-mutation-async.js";let T;const L=new Map;function hn(e){T=e}l(hn,"setInstallId");async function De(){if(T!==void 0)return T;const e=await Te(),r=L.get(e);if(r!==void 0)return r;const o=await _e();return L.set(e,o),o}l(De,"installId");function be(){return`${Date.now().toString(36)}-${te(4).toString("hex")}`}l(be,"newJobId");async function Ae(){return`${await De()}-${be()}`}l(Ae,"newNodeId");const O=128,Me=/^[a-z0-9-]+$/;class j extends Error{static{l(this,"NodeIdConflictError")}nodeId;constructor(r){super(`node already exists: ${r}`),this.nodeId=r,this.name="NodeIdConflictError"}}function x(e){if(e.length===0||e.length>O)throw H(`invalid --node-id '${e}': must be 1-${O} characters`,{next:`Pass an id-safe string (lowercase letters, digits, hyphens) of at most ${O} characters.`});if(!Me.test(e))throw H(`invalid --node-id '${e}': must contain only lowercase letters, digits, and hyphens (e.g. 'remote42', 'my-node-1')`,{next:"Use only lowercase letters, digits, and hyphens."})}l(x,"validateNodeIdFormat");async function vn(e){if(x(e),await u(e)!==null)throw new j(e)}l(vn,"preflightNodeId");async function $e(e){if(x(e),await u(e)!==null)throw new j(e);return e}l($e,"validatedExplicitNodeId");async function Rn(e){let r=e;const o=new Set;for(;;){if(o.has(r))return r;o.add(r);const s=await pe(r);if(s===null||s.parent==null)return r;r=s.parent}}l(Rn,"rootOfSpine");function yn(){const e=process.env;return{nodeId:e.CRTR_NODE_ID??null,kind:e.CRTR_KIND??null,mode:e.CRTR_MODE??null}}l(yn,"currentNodeContext");function Fe(e){return we(e)}l(Fe,"inboxBetweenTurns");function En(e){const r={CRTR_NODE_ID:e.node_id,CRTR_KIND:e.kind,CRTR_MODE:e.mode,CRTR_LIFECYCLE:e.lifecycle,CRTR_NODE_CWD:e.cwd,CRTR_CONTEXT_DIR:ge(e.node_id,e.grantee),CRTR_CYCLES:(e.cycles??0).toString(),CRTR_PROFILE_ID:e.profile_id??"",PI_CLAUDE_OAUTH_REINJECT_SCOPE:"never"};e.parent&&(r.CRTR_PARENT_NODE_ID=e.parent),e.run_id&&(r.CRTR_RUN_ID=e.run_id),Fe(e)&&(r[z]="1"),e.scopes!==null&&e.scopes!==void 0&&(r[V]=de(e.node_id)),r.CRTR_GRANTEE=e.grantee??"app:terminal";const o=K();o!==void 0&&o!==""&&(r.CRTR_HOME=o);const s=X();s!==void 0&&s!==""&&(r.CRTR_RUNTIME_HOME=s);const f=process.env.CRTR_SUBTREE;return f!==void 0&&f!==""&&(r.CRTR_SUBTREE=f),{...r,...e.launch?.env??{}}}l(En,"nodeEnv");async function Be(e){const r=he(e),o=r===null?null:await fe(r);return o===null?null:await u(o)}l(Be,"forkSourceNode");async function In(e){const r=e.nodeId!==void 0?(x(e.nodeId),e.nodeId):await Ae(),o=e.parent??null,s=o===null,f=e.spawnedBy??o,m=e.creator??null,D=e.mode??"base",N=e.lifecycle??(s?"resident":"terminal"),h=e.run===void 0?await k():null,n={node_id:r,name:e.name??e.kind,description:e.description,cycles:0,created:new Date().toISOString(),cwd:e.cwd,host_kind:"broker",profile_id:e.profile_id??null,kind:e.kind,mode:D,lifecycle:N,persona_ack:{kind:e.kind,mode:D,lifecycle:N},status:"active",parent:o,spawned_by:f,creator:m,fork_from:e.forkFrom,fork_source_file:e.forkSourceFile,review_binding:e.reviewBinding,model_override:e.modelOverride??null,scopes:e.scopes??null,isolated:e.isolated===!0,grantee:e.run?.grantee??"app:terminal",sub:e.run?.sub??h?.sub??null,grant_id:e.run?.grant_id??h?.id??null,client_id:e.run?.client_id??null,metadata_json:s?e.run?.metadata_json??null:null,run_id:s?r:e.run?.run_id??null,event_cursor:s?e.run?.event_cursor??1:null,usage_json:s?e.run?.usage_json??JSON.stringify({input_tokens:0,output_tokens:0,cache_read_tokens:0,cache_write_tokens:0,cost_usd:0}):null,passive_default:e.passiveDefault??!1,caused_by:e.causedBy??null,...e.managedWorktree!==void 0?{managed_worktree:e.managedWorktree}:{},intent:null,deadline_at:e.deadlineAt??null,pi_session_id:null,pi_session_file:null,launch:e.launch},y=e.scopes===void 0?void 0:Q(e.scopes),v=o===null?null:await u(o);if(o!==null&&v===null)throw new Error(`cannot spawn under unknown parent node: ${o}`);if(v?.run_id&&(await u(v.run_id))?.deleting_at)throw new Error("run is deleting");const c=m===null?null:await u(m);if(m!==null&&c===null)throw new Error(`cannot spawn from unknown creator node: ${m}`);if(c?.run_id&&(await u(c.run_id))?.deleting_at)throw new Error("run is deleting");const b=e.forkSourceFile==null?null:await Be(e.forkSourceFile),A=e.replaces==null?null:await u(e.replaces),_=v??b??A??c??(f===null?null:await u(f)),q=[v,c,b,A,f===null?null:await u(f)],M=await Oe(q,async t=>t?.isolated===!0||t?.run_id!=null&&(await u(t.run_id))?.isolated===!0);if(M&&e.isolated===!1)throw new g(403,"isolated_run","isolation cannot be turned off under an isolated run",{param:"isolated"});if(n.isolated=M||e.isolated===!0,_!==null){const t=c??_;if(c&&_.grantee&&c.grantee&&c.grantee!==_.grantee)throw new g(403,"other_app_run","cannot create under another app's node");const i=c&&c!==_?[_,c]:[_],d=[],w=new Set;for(const a of i){a.scopes!==null&&a.scopes!==void 0&&d.push(a.scopes);const p=a.grantee==="app:terminal"?await k():a.grant_id?await F(a.grant_id):null;if(p){const R=[...p.resolved];w.add(R),d.push(R)}else{const R=[];w.add(R),d.push(R)}}const E=l(a=>Y(a,t.grantee??"app:terminal"),"ownMemory"),$=l((a,p)=>E(p)&&w.has(a)||I(a,p),"allowed");if(y!==void 0&&!y.every(a=>d.every(p=>$(p,a))))throw new S({error:"unknown_scope",message:"child scopes must be covered by the creating node, its source and their current grants",received:y,field:"scopes",next:"Request only scopes the creating node currently holds."});if(n.scopes=y??(i.every(a=>a.scopes==null)&&i.every(a=>a.grant_id===t.grant_id&&a.sub===t.sub)?null:i.length===1?_.scopes??null:[...new Set(d.flat().filter(a=>d.every(p=>$(p,a))))]),n.scopes?.includes("crtr:act")&&!I(n.scopes,"crtr:llm"))throw new S({error:"invalid_scope",message:"crtr:act requires crtr:llm",received:n.scopes,field:"scopes",next:"Include crtr:llm or omit crtr:act."});n.grantee=t.grantee,n.sub=t.sub??(n.grantee==="app:terminal"?h?.sub:null)??null,n.grant_id=t.grant_id??(n.grantee==="app:terminal"?h?.id:null)??null,n.client_id=t.client_id,n.run_id=s?r:t.run_id??null}if(re(n.grantee),e.run===void 0&&n.grantee==="app:terminal"&&h===null)throw await Z()?new g(503,"runtime_starting","the first grant snapshot from the directory has not committed"):new g(403,"scope_missing","terminal grant is not active");if(n.isolated){if(process.platform!=="linux"||!B(U))throw new g(400,"isolated_unavailable","isolated nodes require the Linux root launcher");if(e.managedWorktree!==void 0)throw new g(400,"invalid_request","isolated nodes cannot use a worktree",{param:"worktree"});const t=ae(se(n.grantee??"app:terminal").nodes,r),i=oe(t,ie(n.cwd));if(!P(n.cwd)||i===".."||i.startsWith(`..${le}`)||P(i))throw new g(400,"invalid_request","isolated node cwd must be inside its own folder",{param:"cwd"})}if(n.profile_id){const t=Re(n.profile_id).manifest.grantee??"app:terminal";if(t!==n.grantee){const i=`crtr:memory:rw:${t}:profile:${n.profile_id}`,d=n.grantee==="app:terminal"?await k():n.grant_id?await F(n.grant_id):null;if(!d||d.grantee!==n.grantee||!I(d.resolved,i)||!I(n.scopes,i))throw new S({error:"scope_missing",message:`missing scope ${i}`,received:n.profile_id,field:"profile",next:"Select a profile covered by this run and its current grant."})}}if(ve(n.profile_id??null),!n.grantee)throw new Error("node creation requires an app");const W=await ye({kind:n.kind,mode:n.mode,cwd:n.cwd,profile:n.profile_id??null,root:s,parentId:o,requestingNodeId:m,lifecycle:N,replaces:e.replaces??null},n.grantee),G=l(async(t,i)=>{const d=await C(t,i.node_id),w=m??o??e.actor??f??null,E=w!==null&&(await Ee(t,w))?.type==="node"?await C(t,w):await Ie(t,e.run===void 0?ne():i.grantee);await Ce(t,E,d),o!==null&&e.subscribe!==!1&&await Ne(t,await C(t,o),d,"spawn"),e.forkSourceNode&&await ke(t,await C(t,e.forkSourceNode),d),await Se(t,{event:"created",object:d,actor:E,attrs:{name:i.name,kind:i.kind,creator:m??null}})},"recordBirth");try{e.nodeId!==void 0&&await $e(e.nodeId),await e.beforeCreate?.(),(process.platform!=="linux"||B(U))&&await me(n.grantee??"app:terminal"),await xe(n.cwd,r,()=>ce(n,{outcomeDelivery:e.outcomeDelivery,withinCreate:l(async(t,i)=>{i.run_id&&i.run_id!==i.node_id&&await ue(t,i.run_id),s&&e.run===void 0&&await ee(t,r,r,"run.started",{scopes:i.scopes??null,payer:"user",usage:JSON.parse(i.usage_json)}),await e.withinCreate?.(t,i),await G(t,i)},"withinCreate")}))}finally{W()}return n}l(In,"spawnNode");export{j as NodeIdConflictError,yn as currentNodeContext,Be as forkSourceNode,Fe as inboxBetweenTurns,be as newJobId,Ae as newNodeId,En as nodeEnv,vn as preflightNodeId,Rn as rootOfSpine,hn as setInstallId,In as spawnNode};
1
+ var J=Object.defineProperty;var l=(e,r)=>J(e,"name",{value:r,configurable:!0});import{envHomeOverride as K,envRuntimeHomeOverride as X,INBOX_BETWEEN_TURNS_ENV as z,SCOPES_FILE_ENV as V,scopeAllowed as I}from"../../shared/env.js";import{isOwnMemoryScope as Y,validateScopes as Q}from"../scopes.js";import{activeGrant as F,terminalGrant as k}from"../grants/mirror.js";import{grantSnapshotMissing as Z}from"../../daemon/readiness.js";import{appendRunEvent as ee}from"../runs/events.js";import{personId as ne}from"../canvas/person.js";import{InputError as S}from"../io.js";import{ApiError as g}from"../../api/errors.js";import{assertGranteeRunsHere as re}from"./unsandboxed.js";import{randomBytes as te}from"node:crypto";import{existsSync as B}from"node:fs";import{resolve as ie,relative as oe,isAbsolute as L,join as ae,sep as le}from"node:path";import{appSpace as se}from"../layout.js";import{scopesFilePath as de}from"../canvas/paths.js";import{createNode as ce,assertRunNotDeleting as ue,conversationOwner as fe,getNode as u,getRow as pe}from"../canvas/index.js";import{ensureAppSpace as _e}from"../spaces/space.js";import{LAUNCHER_SOCKET as P}from"../../launcher/spec.js";import{resolveInstallId as me}from"../canvas/install-id.js";import{isAppRun as we}from"../canvas/app-run.js";import{contextDir as ge}from"../canvas/paths.js";import{conversationIdFromPath as he}from"../conversation-store/index.js";import{usage as U}from"../errors.js";import{assertProfileAvailableForBirth as Re}from"../profiles/deletion-reservation.js";import{loadExactProfileManifest as ve}from"../profiles/manifest.js";import{admitNodeCreate as ye}from"../command-hooks/lifecycle-create.js";import{getById as Ee,nodeObject as N,ownerForGrantee as Ie}from"../graph/objects.js";import{recordActedOn as Ne}from"../graph/edges.js";import{recordWatch as Ce,copyWatchesForFork as ke}from"../graph/watches.js";import{publish as Se}from"../graph/events.js";import{canvasDatabaseUrl as Te}from"../canvas/db.js";import{someAsync as De}from"../async-array.js";import{admitIntoManagedCheckout as Oe}from"../worktree-mutation-async.js";let T;const H=new Map;function hn(e){T=e}l(hn,"setInstallId");async function xe(){if(T!==void 0)return T;const e=await Te(),r=H.get(e);if(r!==void 0)return r;const o=await me();return H.set(e,o),o}l(xe,"installId");function be(){return`${Date.now().toString(36)}-${te(4).toString("hex")}`}l(be,"newJobId");async function Ae(){return`${await xe()}-${be()}`}l(Ae,"newNodeId");const D=128,Me=/^[a-z0-9-]+$/;class j extends Error{static{l(this,"NodeIdConflictError")}nodeId;constructor(r){super(`node already exists: ${r}`),this.nodeId=r,this.name="NodeIdConflictError"}}function O(e){if(e.length===0||e.length>D)throw U(`invalid --node-id '${e}': must be 1-${D} characters`,{next:`Pass an id-safe string (lowercase letters, digits, hyphens) of at most ${D} characters.`});if(!Me.test(e))throw U(`invalid --node-id '${e}': must contain only lowercase letters, digits, and hyphens (e.g. 'remote42', 'my-node-1')`,{next:"Use only lowercase letters, digits, and hyphens."})}l(O,"validateNodeIdFormat");async function Rn(e){if(O(e),await u(e)!==null)throw new j(e)}l(Rn,"preflightNodeId");async function $e(e){if(O(e),await u(e)!==null)throw new j(e);return e}l($e,"validatedExplicitNodeId");async function vn(e){let r=e;const o=new Set;for(;;){if(o.has(r))return r;o.add(r);const s=await pe(r);if(s===null||s.parent==null)return r;r=s.parent}}l(vn,"rootOfSpine");function yn(){const e=process.env;return{nodeId:e.CRTR_NODE_ID??null,kind:e.CRTR_KIND??null,mode:e.CRTR_MODE??null}}l(yn,"currentNodeContext");function Fe(e){return we(e)}l(Fe,"inboxBetweenTurns");function En(e){const r={CRTR_NODE_ID:e.node_id,CRTR_KIND:e.kind,CRTR_MODE:e.mode,CRTR_LIFECYCLE:e.lifecycle,CRTR_NODE_CWD:e.cwd,CRTR_CONTEXT_DIR:ge(e.node_id,e.grantee),...e.deadline_at?{CRTR_NODE_DEADLINE_AT:e.deadline_at}:{},CRTR_CYCLES:(e.cycles??0).toString(),CRTR_PROFILE_ID:e.profile_id??"",PI_CLAUDE_OAUTH_REINJECT_SCOPE:"never"};e.parent&&(r.CRTR_PARENT_NODE_ID=e.parent),e.run_id&&(r.CRTR_RUN_ID=e.run_id),Fe(e)&&(r[z]="1"),e.scopes!==null&&e.scopes!==void 0&&(r[V]=de(e.node_id)),r.CRTR_GRANTEE=e.grantee??"app:terminal";const o=K();o!==void 0&&o!==""&&(r.CRTR_HOME=o);const s=X();s!==void 0&&s!==""&&(r.CRTR_RUNTIME_HOME=s);const f=process.env.CRTR_SUBTREE;return f!==void 0&&f!==""&&(r.CRTR_SUBTREE=f),{...r,...e.launch?.env??{}}}l(En,"nodeEnv");async function Be(e){const r=he(e),o=r===null?null:await fe(r);return o===null?null:await u(o)}l(Be,"forkSourceNode");async function In(e){const r=e.nodeId!==void 0?(O(e.nodeId),e.nodeId):await Ae(),o=e.parent??null,s=o===null,f=e.spawnedBy??o,_=e.creator??null,x=e.mode??"base",C=e.lifecycle??(s?"resident":"terminal"),h=e.run===void 0?await k():null,n={node_id:r,name:e.name??e.kind,description:e.description,cycles:0,created:new Date().toISOString(),cwd:e.cwd,host_kind:"broker",profile_id:e.profile_id??null,kind:e.kind,mode:x,lifecycle:C,persona_ack:{kind:e.kind,mode:x,lifecycle:C},status:"active",parent:o,spawned_by:f,creator:_,fork_from:e.forkFrom,fork_source_file:e.forkSourceFile,review_binding:e.reviewBinding,model_override:e.modelOverride??null,scopes:e.scopes??null,isolated:e.isolated===!0,grantee:e.run?.grantee??"app:terminal",sub:e.run?.sub??h?.sub??null,grant_id:e.run?.grant_id??h?.id??null,client_id:e.run?.client_id??null,metadata_json:s?e.run?.metadata_json??null:null,run_id:s?r:e.run?.run_id??null,event_cursor:s?e.run?.event_cursor??1:null,usage_json:s?e.run?.usage_json??JSON.stringify({input_tokens:0,output_tokens:0,cache_read_tokens:0,cache_write_tokens:0,cost_usd:0}):null,passive_default:e.passiveDefault??!1,caused_by:e.causedBy??null,...e.managedWorktree!==void 0?{managed_worktree:e.managedWorktree}:{},intent:null,deadline_at:e.deadlineAt??null,pi_session_id:null,pi_session_file:null,launch:e.launch},y=e.scopes===void 0?void 0:Q(e.scopes),R=o===null?null:await u(o);if(o!==null&&R===null)throw new Error(`cannot spawn under unknown parent node: ${o}`);if(R?.run_id&&(await u(R.run_id))?.deleting_at)throw new Error("run is deleting");const c=_===null?null:await u(_);if(_!==null&&c===null)throw new Error(`cannot spawn from unknown creator node: ${_}`);if(c?.run_id&&(await u(c.run_id))?.deleting_at)throw new Error("run is deleting");const b=e.forkSourceFile==null?null:await Be(e.forkSourceFile),A=e.replaces==null?null:await u(e.replaces),m=R??b??A??c??(f===null?null:await u(f)),q=[R,c,b,A,f===null?null:await u(f)],M=await De(q,async t=>t?.isolated===!0||t?.run_id!=null&&(await u(t.run_id))?.isolated===!0);if(M&&e.isolated===!1)throw new g(403,"isolated_run","isolation cannot be turned off under an isolated run",{param:"isolated"});if(n.isolated=M||e.isolated===!0,m!==null){const t=c??m;if(c&&m.grantee&&c.grantee&&c.grantee!==m.grantee)throw new g(403,"other_app_run","cannot create under another app's node");const i=c&&c!==m?[m,c]:[m],d=[],w=new Set;for(const a of i){a.scopes!==null&&a.scopes!==void 0&&d.push(a.scopes);const p=a.grantee==="app:terminal"?await k():a.grant_id?await F(a.grant_id):null;if(p){const v=[...p.resolved];w.add(v),d.push(v)}else{const v=[];w.add(v),d.push(v)}}const E=l(a=>Y(a,t.grantee??"app:terminal"),"ownMemory"),$=l((a,p)=>E(p)&&w.has(a)||I(a,p),"allowed");if(y!==void 0&&!y.every(a=>d.every(p=>$(p,a))))throw new S({error:"unknown_scope",message:"child scopes must be covered by the creating node, its source and their current grants",received:y,field:"scopes",next:"Request only scopes the creating node currently holds."});if(n.scopes=y??(i.every(a=>a.scopes==null)&&i.every(a=>a.grant_id===t.grant_id&&a.sub===t.sub)?null:i.length===1?m.scopes??null:[...new Set(d.flat().filter(a=>d.every(p=>$(p,a))))]),n.scopes?.includes("crtr:act")&&!I(n.scopes,"crtr:llm"))throw new S({error:"invalid_scope",message:"crtr:act requires crtr:llm",received:n.scopes,field:"scopes",next:"Include crtr:llm or omit crtr:act."});n.grantee=t.grantee,n.sub=t.sub??(n.grantee==="app:terminal"?h?.sub:null)??null,n.grant_id=t.grant_id??(n.grantee==="app:terminal"?h?.id:null)??null,n.client_id=t.client_id,n.run_id=s?r:t.run_id??null}if(re(n.grantee),e.run===void 0&&n.grantee==="app:terminal"&&h===null)throw await Z()?new g(503,"runtime_starting","the first grant snapshot from the directory has not committed"):new g(403,"scope_missing","terminal grant is not active");if(n.isolated){if(process.platform!=="linux"||!B(P))throw new g(400,"isolated_unavailable","isolated nodes require the Linux root launcher");if(e.managedWorktree!==void 0)throw new g(400,"invalid_request","isolated nodes cannot use a worktree",{param:"worktree"});const t=ae(se(n.grantee??"app:terminal").nodes,r),i=oe(t,ie(n.cwd));if(!L(n.cwd)||i===".."||i.startsWith(`..${le}`)||L(i))throw new g(400,"invalid_request","isolated node cwd must be inside its own folder",{param:"cwd"})}if(n.profile_id){const t=ve(n.profile_id).manifest.grantee??"app:terminal";if(t!==n.grantee){const i=`crtr:memory:rw:${t}:profile:${n.profile_id}`,d=n.grantee==="app:terminal"?await k():n.grant_id?await F(n.grant_id):null;if(!d||d.grantee!==n.grantee||!I(d.resolved,i)||!I(n.scopes,i))throw new S({error:"scope_missing",message:`missing scope ${i}`,received:n.profile_id,field:"profile",next:"Select a profile covered by this run and its current grant."})}}if(Re(n.profile_id??null),!n.grantee)throw new Error("node creation requires an app");const W=await ye({kind:n.kind,mode:n.mode,cwd:n.cwd,profile:n.profile_id??null,root:s,parentId:o,requestingNodeId:_,lifecycle:C,replaces:e.replaces??null},n.grantee),G=l(async(t,i)=>{const d=await N(t,i.node_id),w=_??o??e.actor??f??null,E=w!==null&&(await Ee(t,w))?.type==="node"?await N(t,w):await Ie(t,e.run===void 0?ne():i.grantee);await Ne(t,E,d),o!==null&&e.subscribe!==!1&&await Ce(t,await N(t,o),d,"spawn"),e.forkSourceNode&&await ke(t,await N(t,e.forkSourceNode),d),await Se(t,{event:"created",object:d,actor:E,attrs:{name:i.name,kind:i.kind,creator:_??null}})},"recordBirth");try{e.nodeId!==void 0&&await $e(e.nodeId),await e.beforeCreate?.(),(process.platform!=="linux"||B(P))&&await _e(n.grantee??"app:terminal"),await Oe(n.cwd,r,()=>ce(n,{outcomeDelivery:e.outcomeDelivery,withinCreate:l(async(t,i)=>{i.run_id&&i.run_id!==i.node_id&&await ue(t,i.run_id),s&&e.run===void 0&&await ee(t,r,r,"run.started",{scopes:i.scopes??null,payer:"user",usage:JSON.parse(i.usage_json)}),await e.withinCreate?.(t,i),await G(t,i)},"withinCreate")}))}finally{W()}return n}l(In,"spawnNode");export{j as NodeIdConflictError,yn as currentNodeContext,Be as forkSourceNode,Fe as inboxBetweenTurns,be as newJobId,Ae as newNodeId,En as nodeEnv,Rn as preflightNodeId,vn as rootOfSpine,hn as setInstallId,In as spawnNode};
@@ -27,7 +27,6 @@ export interface NodeOutcomeDocumentV1 {
27
27
  };
28
28
  structuredResult?: unknown;
29
29
  structuredResultOmitted?: true;
30
- structuredResultPath?: string;
31
30
  };
32
31
  failure?: {
33
32
  message: string | null;
@@ -1 +1 @@
1
- var c=Object.defineProperty;var s=(t,e)=>c(t,"name",{value:e,configurable:!0});import{contextDir as f}from"../canvas/node-agent-paths.js";import{readOutputResult as m}from"./structured-output.js";const p=256*1024;function y(t,e){try{return m(t,e)}catch{return}}s(y,"structuredResult");function _(t){if(t===null)return null;try{return JSON.parse(t)}catch{return null}}s(_,"parseDetail");function a(t){if(Buffer.byteLength(t,"utf8")<=1024)return t;const n="\u2026";let r=Buffer.byteLength(n,"utf8"),l="";for(const i of t){const d=Buffer.byteLength(i,"utf8");if(r+d>1024)break;r+=d,l+=i}return`${l}${n}`}s(a,"truncateDescription");async function k(t){const{node:e,outcome:n}=t,r=_(n.detailJson),l=t.finalReport??e.final_report??"",i=a(e.name),d=e.description===void 0?void 0:a(e.description),o=n.kind==="result"?t.structuredResult===void 0?y(e.node_id,e.grantee):t.structuredResult:void 0,u={schema:"crtr.node-outcome/v1",outcomeId:`${e.node_id}:${n.revision}`,nodeId:e.node_id,revision:n.revision,kind:n.kind,reason:n.reason,settledAt:n.at,node:{name:i,...d===void 0?{}:{description:d},kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,terminalReason:e.terminal_reason??null,cwd:e.cwd,createdAt:e.created,parent:e.parent??null,spawnedBy:e.spawned_by??null},...n.kind==="result"?{result:{finalReport:{name:`${e.node_id}/${l}`},...o===void 0?{}:{structuredResult:o}}}:{failure:{message:r?.message??null,faultKind:r?.fault_kind??null,errorClass:r?.error_class??null,respawnFailures:r?.respawn_failures??null,deadline:r?.deadline===void 0?null:{deadlineAt:r.deadline.deadline_at,elapsedMs:r.deadline.elapsed_ms},declined:r?.declined??null}}};return Buffer.byteLength(JSON.stringify(u),"utf8")>p&&u.result?.structuredResult!==void 0&&(delete u.result.structuredResult,u.result.structuredResultOmitted=!0,u.result.structuredResultPath=`${await f(e.node_id,e.grantee)}/result.json`),u}s(k,"composeNodeOutcomeDocument");export{k as composeNodeOutcomeDocument};
1
+ var c=Object.defineProperty;var s=(t,e)=>c(t,"name",{value:e,configurable:!0});import{readOutputResult as f}from"./output-result.js";const m=256*1024;async function p(t){return await f(t)}s(p,"structuredResult");function y(t){if(t===null)return null;try{return JSON.parse(t)}catch{return null}}s(y,"parseDetail");function a(t){if(Buffer.byteLength(t,"utf8")<=1024)return t;const n="\u2026";let r=Buffer.byteLength(n,"utf8"),l="";for(const i of t){const u=Buffer.byteLength(i,"utf8");if(r+u>1024)break;r+=u,l+=i}return`${l}${n}`}s(a,"truncateDescription");async function B(t){const{node:e,outcome:n}=t,r=y(n.detailJson),l=t.finalReport??e.final_report??"",i=a(e.name),u=e.description===void 0?void 0:a(e.description),o=n.kind==="result"?t.structuredResult===void 0?await p(e.node_id):t.structuredResult:void 0,d={schema:"crtr.node-outcome/v1",outcomeId:`${e.node_id}:${n.revision}`,nodeId:e.node_id,revision:n.revision,kind:n.kind,reason:n.reason,settledAt:n.at,node:{name:i,...u===void 0?{}:{description:u},kind:e.kind,mode:e.mode,lifecycle:e.lifecycle,status:e.status,terminalReason:e.terminal_reason??null,cwd:e.cwd,createdAt:e.created,parent:e.parent??null,spawnedBy:e.spawned_by??null},...n.kind==="result"?{result:{finalReport:{name:`${e.node_id}/${l}`},...o===void 0?{}:{structuredResult:o}}}:{failure:{message:r?.message??null,faultKind:r?.fault_kind??null,errorClass:r?.error_class??null,respawnFailures:r?.respawn_failures??null,deadline:r?.deadline===void 0?null:{deadlineAt:r.deadline.deadline_at,elapsedMs:r.deadline.elapsed_ms},declined:r?.declined??null}}};return Buffer.byteLength(JSON.stringify(d),"utf8")>m&&d.result?.structuredResult!==void 0&&(delete d.result.structuredResult,d.result.structuredResultOmitted=!0),d}s(B,"composeNodeOutcomeDocument");export{B as composeNodeOutcomeDocument};
@@ -0,0 +1,15 @@
1
+ /** The node's machine result: the latest completed terminal structured request's result row; undefined when none completed. */
2
+ export declare function readOutputResult(nodeId: string): Promise<unknown>;
3
+ import type { StructuredOutputRequest } from './structured-output.js';
4
+ /** The node's pending structured request, read from its `structured_requests` row; null when none is pending. */
5
+ export declare function readOutputRequest(nodeId: string): Promise<StructuredOutputRequest | null>;
6
+ export interface SchemaReprompts {
7
+ count: number;
8
+ at: number;
9
+ }
10
+ /** The pending request's consecutive schema reprompts (stop guard); none recorded reads as 0. */
11
+ export declare function readSchemaReprompts(nodeId: string): Promise<SchemaReprompts>;
12
+ /** Record one reprompt only if the stored count is still `from`; false when another process counted first. */
13
+ export declare function takeSchemaReprompt(nodeId: string, from: number, count: number, at: number): Promise<boolean>;
14
+ /** A submission resets the count. */
15
+ export declare function clearSchemaReprompts(nodeId: string): Promise<void>;
@@ -0,0 +1,5 @@
1
+ var u=Object.defineProperty;var r=(t,e)=>u(t,"name",{value:e,configurable:!0});import{openDb as s}from"../canvas/db.js";async function d(t){const e=await(await s()).prepareUncached(`SELECT result_json FROM structured_requests
2
+ WHERE node_id = ? AND submission = 'terminal' AND state = 'completed' AND result_json IS NOT NULL
3
+ ORDER BY settled_at DESC, seq DESC LIMIT 1`).get(t);return e===void 0?void 0:JSON.parse(e.result_json)}r(d,"readOutputResult");async function c(t){const e=await(await s()).prepareUncached(`SELECT request_id, submission, schema_json, request_message_id FROM structured_requests
4
+ WHERE node_id = ? AND state = 'pending'`).get(t);return e===void 0?null:{request_id:e.request_id,mode:e.submission,schema:JSON.parse(e.schema_json),...e.request_message_id===null?{}:{requestMessageId:e.request_message_id}}}r(c,"readOutputRequest");async function i(t){const e=await(await s()).prepareUncached("SELECT reprompt_count, reprompted_at FROM structured_requests WHERE node_id = ? AND state = 'pending'").get(t);return{count:Number(e?.reprompt_count??0),at:Number(e?.reprompted_at??0)}}r(i,"readSchemaReprompts");async function _(t,e,n,a){return Number((await(await s()).prepareUncached(`UPDATE structured_requests SET reprompt_count = ?, reprompted_at = ?
5
+ WHERE node_id = ? AND state = 'pending' AND reprompt_count = ?`).run(n,a,t,e)).changes)===1}r(_,"takeSchemaReprompt");async function m(t){await(await s()).prepareUncached("UPDATE structured_requests SET reprompt_count = 0, reprompted_at = NULL WHERE node_id = ? AND state = 'pending'").run(t)}r(m,"clearSchemaReprompts");export{m as clearSchemaReprompts,c as readOutputRequest,d as readOutputResult,i as readSchemaReprompts,_ as takeSchemaReprompt};
@@ -1,11 +1,27 @@
1
1
  import { type FocusRow } from '../canvas/index.js';
2
2
  export type { FocusRow };
3
- export { splitWindow, breakPane, selectLayout, selectPane, focusWindow, selectWindow, switchClient, openNodeWindow, ensureSession, paneLocation, paneExists, paneRunning, paneCurrentPath, currentTmux, inTmux, paneOfNode, setPaneOption, getPaneOption, piCommand, shellQuote, respawnPaneSync, closePane, displayPopup, windowOfPane, renameWindow, paneOfWindow, windowAlive, listLivePanes, listLivePanesAsync, } from './tmux-driver.js';
3
+ export { splitWindow, breakPane, selectLayout, selectPane, focusWindow, selectWindow, switchClient, openNodeWindow, ensureSession, paneLocation, paneExists, paneRunning, paneCurrentPath, currentTmux, inTmux, paneOfNode, setPaneOption, getPaneOption, piCommand, shellQuote, respawnPaneSync, closePane, displayPopup, windowOfPane, renameWindow, paneOfWindow, windowAlive, listLivePanes, listLivePanesAsync, paneStateAsync, } from './tmux-driver.js';
4
4
  export type { RespawnPaneOpts } from './tmux-driver.js';
5
5
  export { installTmuxBindings } from './tmux-bindings.js';
6
6
  export type { TmuxInstalledPair, TmuxInstallDiagnostic, TmuxInstallResult } from './tmux-bindings.js';
7
7
  /** The viewer a node has on screen, or null. UNIQUE(node_id) ⇒ at most one. */
8
8
  export declare function focusOf(nodeId: string): Promise<FocusRow | null>;
9
+ /** A node's viewer, probed ahead of a canvas write: `live` is the row whose pane tmux answered for (or did not answer for in time),
10
+ * `stale` the row whose pane tmux reported gone; both null means the node had no row. The probe is a snapshot taken outside the
11
+ * write, so the write passes it through {@link confirmViewer} before deciding from it. */
12
+ export interface ViewerProbe {
13
+ nodeId: string;
14
+ live: FocusRow | null;
15
+ stale: FocusRow | null;
16
+ }
17
+ /** Read a node's viewer row and probe its pane with a bounded, non-blocking tmux call. Call it BEFORE `withCanvasWrite`: the
18
+ * probe holds no connection, and a hung tmux costs one timeout instead of an open transaction. A timed-out probe counts as live. */
19
+ export declare function probeViewer(nodeId: string): Promise<ViewerProbe>;
20
+ /** Inside the write: re-read the node's viewer row under its lock and compare it with the probe. A row that matches the probe
21
+ * (same focus and pane) keeps the probe's verdict, and a stale one is deleted here, only while it is still on the probed pane.
22
+ * A row that differs from the probe — re-pointed to another pane, or created after an empty probe — was never probed, so it
23
+ * counts as a live viewer and nothing is deleted; the next settle probes it. No tmux runs here. */
24
+ export declare function confirmViewer(probe: ViewerProbe): Promise<ViewerProbe>;
9
25
  /** Does this node have a live viewer on screen? */
10
26
  export declare function isFocused(nodeId: string): Promise<boolean>;
11
27
  /** The viewer realized by a given pane (`%id`), or null. */
@@ -1 +1 @@
1
- var V=Object.defineProperty;var s=(e,n)=>V(e,"name",{value:n,configurable:!0});import{envNodeId as $}from"../../shared/env.js";import{getNode as m,fullName as H,deleteNode as R,listNodes as M,openFocusRow as z,closeFocusRow as u,getFocusByNode as T,getFocusByPane as _,getFocusById as D,listFocuses as J}from"../canvas/index.js";import{nodeHasAssistantMessage as Q}from"../canvas/render-source.js";import{headlessBrokerHost as k}from"./host.js";import{publishNotice as U}from"./close.js";import{paneExists as p,listLivePanesAsync as X,paneLocation as x,closePane as P,currentTmux as j,switchClient as q,selectWindow as G,selectLayout as K,selectPane as A,getPaneOption as Y,setPaneOption as Z,respawnPaneSync as I,windowOfPane as ee,renameWindow as ne}from"./tmux-driver.js";import{openViewerPane as ae,viewerSplitEnv as S,waitForBrokerViewSocket as ie}from"./placement-tmux.js";import{newJobId as te}from"./nodes.js";import{isPidAlive as h}from"../canvas/pid.js";import{splitWindow as Re,breakPane as Te,selectLayout as ke,selectPane as Ae,focusWindow as Se,selectWindow as We,switchClient as be,openNodeWindow as Be,ensureSession as Ee,paneLocation as Le,paneExists as Ce,paneRunning as Ve,paneCurrentPath as $e,currentTmux as He,inTmux as Me,paneOfNode as ze,setPaneOption as De,getPaneOption as Je,piCommand as Qe,shellQuote as Ue,respawnPaneSync as Xe,closePane as je,displayPopup as qe,windowOfPane as Ge,renameWindow as Ke,paneOfWindow as Ye,windowAlive as Ze,listLivePanes as Ie,listLivePanesAsync as en}from"./tmux-driver.js";import{installTmuxBindings as an}from"./tmux-bindings.js";async function g(e,n=null){return e===null?null:e.pane!==null&&!(n!==null?n.has(e.pane):p(e.pane))?(await u(e.focus_id),null):e}s(g,"liveOrPrune");async function w(e){return await g(await T(e))}s(w,"focusOf");async function _e(e){return await w(e)!==null}s(_e,"isFocused");async function se(e){return await g(await _(e))}s(se,"focusByPane");async function xe(){return new Set((await oe()).map(e=>e.node_id))}s(xe,"focusedNodes");async function oe(){const e=[],n=await J(),i=n.some(a=>a.pane!==null)?await X():null;for(const a of n)await g(a,i)!==null&&e.push(a);return e}s(oe,"listFocuses");function re(){return`f-${te()}`}s(re,"newFocusId");async function W(e,n,i,a){const l=await _(n);if(l!==null)return l;const o=await T(e);if(o!==null)return o;const r=re();return await z(r,n,i,e),await D(r)}s(W,"registerViewerFocus");async function b(e,n,i={}){const a=ae(e,n,i);return a===null?null:await W(e,a.pane,a.session,a.window)}s(b,"openViewerWindow");function B(e){const n=x(e)?.window??null;n!==null&&K(n,"even-horizontal"),A(e)}s(B,"surfaceNewPane");async function he(e,n){const i=await m(e);if(i===null)return{focused:!1,session:null,inPlace:!1,revived:!1};const a=n.pane??process.env.TMUX_PANE??j()?.pane;if(a===void 0||a==="")return{focused:!1,session:null,inPlace:!1,revived:!1};const l=h(i.pi_pid??null),o=n.revive(e),r=!l;if(!await ie(e,o?.launch?.exited))return{focused:!1,session:null,inPlace:!1,revived:r};const y=x(a)?.session??null,N=y??"";if(n.inPlace===!0){const t=await w(e);t!==null&&(t.pane!==null&&t.pane!==a&&p(t.pane)&&P(t.pane),await u(t.focus_id));const c=await _(a);c!==null&&c.node_id!==e&&await u(c.focus_id);try{Z(a,"@crtr_node","")}catch{}const v=ee(a),F=c?.node_id,C=F===void 0?S():{...S(),CRTR_ATTACH_ROSTER:F},O=I({pane:a,cwd:i.cwd,env:C,command:`crtr surface attach to ${e}`});return O&&(v!==null&&ne(v,H(i)),await W(e,a,y,v)),{focused:O,session:y,inPlace:!0,revived:r}}if(n.newPane===!0){const t=await w(e);t!==null&&(t.pane!==null&&p(t.pane)&&P(t.pane),await u(t.focus_id));const c=await b(e,N,{cwd:i.cwd,besidePane:a});return c===null?{focused:!1,session:null,inPlace:!1,revived:r}:(c.pane!==null&&B(c.pane),{focused:!0,session:c.session,inPlace:!1,revived:r})}const f=await w(e);if(f!==null&&f.pane!==null)if(Y(f.pane,"@crtr_node")===e){const t=x(f.pane);if(t!==null)return q(t.session),G(t.session,t.window),A(f.pane),{focused:!0,session:t.session,inPlace:!0,revived:r};await u(f.focus_id)}else await u(f.focus_id);const d=await b(e,N,{cwd:i.cwd,besidePane:a});return d===null?{focused:!1,session:null,inPlace:!1,revived:r}:(d.pane!==null&&B(d.pane),{focused:!0,session:d.session,inPlace:!1,revived:r})}s(he,"focus");async function E(e,n){const i=await w(e);i!==null&&(i.pane!==null&&i.pane!==n&&p(i.pane)&&P(i.pane),await u(i.focus_id))}s(E,"tearDownNode");async function ge(e,n){const i=n??(await w(e))?.pane??null;if(i===null||!p(i))return!1;const a=await se(i);a!==null&&await u(a.focus_id);const l=P(i);return await le(e),l}s(ge,"detachToBackground");async function L(e){const n=await m(e);return n===null||n.streaming===!0&&h(n.pi_pid)?!1:!await Q(n.pi_session_file)}s(L,"isEmptyNode");async function le(e,n,i=!0){return(await m(e))?.managed_worktree?.state==="open"||!await L(e)?!1:(i&&k.teardown(e),await E(e,n),(await R(e)).deleted)}s(le,"reapIfEmpty");async function Ne(e={}){const n=e.dryRun??!1,i=$()??"",a=[];for(const l of await M()){const o=l.node_id,r=await m(o);o===i||l.status==="dead"||h(l.pi_pid)||r?.managed_worktree?.state==="open"||!await L(o)||!n&&(await U(o,"notice.close",`Child closed \u2014 ${r?.name??o} (${o}) was closed from the canvas and is no longer running.`,{reason:"child-closed",child:o}),k.teardown(o),await E(o),!(await R(o)).deleted)||a.push(o)}return a}s(Ne,"reapEmptyNodes");export{Te as breakPane,je as closePane,He as currentTmux,ge as detachToBackground,qe as displayPopup,Ee as ensureSession,he as focus,se as focusByPane,w as focusOf,Se as focusWindow,xe as focusedNodes,Je as getPaneOption,Me as inTmux,an as installTmuxBindings,_e as isFocused,oe as listFocuses,Ie as listLivePanes,en as listLivePanesAsync,Be as openNodeWindow,b as openViewerWindow,$e as paneCurrentPath,Ce as paneExists,Le as paneLocation,ze as paneOfNode,Ye as paneOfWindow,Ve as paneRunning,Qe as piCommand,Ne as reapEmptyNodes,le as reapIfEmpty,W as registerViewerFocus,Ke as renameWindow,Xe as respawnPaneSync,ke as selectLayout,Ae as selectPane,We as selectWindow,De as setPaneOption,Ue as shellQuote,Re as splitWindow,be as switchClient,E as tearDownNode,Ze as windowAlive,Ge as windowOfPane};
1
+ var b=Object.defineProperty;var i=(e,n)=>b(e,"name",{value:n,configurable:!0});import{envNodeId as H}from"../../shared/env.js";import{getNode as p,fullName as M,deleteNode as R,listNodes as U,openFocusRow as z,closeFocusRow as c,closeFocusRowOnPane as D,getFocusByNodeForUpdate as J,getFocusByNode as _,getFocusByPane as x,getFocusById as Q,listFocuses as X}from"../canvas/index.js";import{nodeHasAssistantMessage as j}from"../canvas/render-source.js";import{headlessBrokerHost as S}from"./host.js";import{publishNotice as q}from"./close.js";import{paneExists as m,paneStateAsync as T,listLivePanesAsync as G,paneLocation as g,closePane as P,currentTmux as K,switchClient as Y,selectWindow as Z,selectLayout as I,selectPane as k,getPaneOption as ee,setPaneOption as ne,respawnPaneSync as ae,windowOfPane as te,renameWindow as ie}from"./tmux-driver.js";import{openViewerPane as se,viewerSplitEnv as B,waitForBrokerViewSocket as oe}from"./placement-tmux.js";import{newJobId as le}from"./nodes.js";import{isPidAlive as h}from"../canvas/pid.js";import{splitWindow as Be,breakPane as We,selectLayout as Ee,selectPane as Le,focusWindow as Ce,selectWindow as Ve,switchClient as $e,openNodeWindow as be,ensureSession as He,paneLocation as Me,paneExists as Ue,paneRunning as ze,paneCurrentPath as De,currentTmux as Je,inTmux as Qe,paneOfNode as Xe,setPaneOption as je,getPaneOption as qe,piCommand as Ge,shellQuote as Ke,respawnPaneSync as Ye,closePane as Ze,displayPopup as Ie,windowOfPane as en,renameWindow as nn,paneOfWindow as an,windowAlive as tn,listLivePanes as sn,listLivePanesAsync as on,paneStateAsync as ln}from"./tmux-driver.js";import{installTmuxBindings as un}from"./tmux-bindings.js";async function N(e,n=null){return e===null?null:e.pane!==null&&!(n!==null?n.has(e.pane):await T(e.pane)!=="gone")?(await c(e.focus_id),null):e}i(N,"liveOrPrune");async function w(e){return await N(await _(e))}i(w,"focusOf");async function he(e){const n=await _(e);return n===null?{nodeId:e,live:null,stale:null}:n.pane===null||await T(n.pane)!=="gone"?{nodeId:e,live:n,stale:null}:{nodeId:e,live:null,stale:n}}i(he,"probeViewer");async function Ne(e){const n=await J(e.nodeId),a=e.live??e.stale;return n===null?{nodeId:e.nodeId,live:null,stale:null}:a===null||a.focus_id!==n.focus_id||a.pane!==n.pane?{nodeId:e.nodeId,live:n,stale:null}:e.stale!==null?(await D(n.focus_id,n.pane),{nodeId:e.nodeId,live:null,stale:null}):{nodeId:e.nodeId,live:n,stale:null}}i(Ne,"confirmViewer");async function Fe(e){return await w(e)!==null}i(Fe,"isFocused");async function re(e){return await N(await x(e))}i(re,"focusByPane");async function Oe(){return new Set((await ue()).map(e=>e.node_id))}i(Oe,"focusedNodes");async function ue(){const e=[],n=await X(),a=n.some(t=>t.pane!==null)?await G():null;for(const t of n)await N(t,a)!==null&&e.push(t);return e}i(ue,"listFocuses");function ce(){return`f-${le()}`}i(ce,"newFocusId");async function W(e,n,a,t){const r=await x(n);if(r!==null)return r;const o=await _(e);if(o!==null)return o;const l=ce();return await z(l,n,a,e),await Q(l)}i(W,"registerViewerFocus");async function E(e,n,a={}){const t=se(e,n,a);return t===null?null:await W(e,t.pane,t.session,t.window)}i(E,"openViewerWindow");function L(e){const n=g(e)?.window??null;n!==null&&I(n,"even-horizontal"),k(e)}i(L,"surfaceNewPane");async function Ae(e,n){const a=await p(e);if(a===null)return{focused:!1,session:null,inPlace:!1,revived:!1};const t=n.pane??process.env.TMUX_PANE??K()?.pane;if(t===void 0||t==="")return{focused:!1,session:null,inPlace:!1,revived:!1};const r=h(a.pi_pid??null),o=n.revive(e),l=!r;if(!await oe(e,o?.launch?.exited))return{focused:!1,session:null,inPlace:!1,revived:l};const y=g(t)?.session??null,F=y??"";if(n.inPlace===!0){const s=await w(e);s!==null&&(s.pane!==null&&s.pane!==t&&m(s.pane)&&P(s.pane),await c(s.focus_id));const u=await x(t);u!==null&&u.node_id!==e&&await c(u.focus_id);try{ne(t,"@crtr_node","")}catch{}const v=te(t),O=u?.node_id,$=O===void 0?B():{...B(),CRTR_ATTACH_ROSTER:O},A=ae({pane:t,cwd:a.cwd,env:$,command:`crtr surface attach to ${e}`});return A&&(v!==null&&ie(v,M(a)),await W(e,t,y,v)),{focused:A,session:y,inPlace:!0,revived:l}}if(n.newPane===!0){const s=await w(e);s!==null&&(s.pane!==null&&m(s.pane)&&P(s.pane),await c(s.focus_id));const u=await E(e,F,{cwd:a.cwd,besidePane:t});return u===null?{focused:!1,session:null,inPlace:!1,revived:l}:(u.pane!==null&&L(u.pane),{focused:!0,session:u.session,inPlace:!1,revived:l})}const f=await w(e);if(f!==null&&f.pane!==null)if(ee(f.pane,"@crtr_node")===e){const s=g(f.pane);if(s!==null)return Y(s.session),Z(s.session,s.window),k(f.pane),{focused:!0,session:s.session,inPlace:!0,revived:l};await c(f.focus_id)}else await c(f.focus_id);const d=await E(e,F,{cwd:a.cwd,besidePane:t});return d===null?{focused:!1,session:null,inPlace:!1,revived:l}:(d.pane!==null&&L(d.pane),{focused:!0,session:d.session,inPlace:!1,revived:l})}i(Ae,"focus");async function C(e,n){const a=await w(e);a!==null&&(a.pane!==null&&a.pane!==n&&m(a.pane)&&P(a.pane),await c(a.focus_id))}i(C,"tearDownNode");async function Re(e,n){const a=n??(await w(e))?.pane??null;if(a===null||!m(a))return!1;const t=await re(a);t!==null&&await c(t.focus_id);const r=P(a);return await fe(e),r}i(Re,"detachToBackground");async function V(e){const n=await p(e);return n===null||n.streaming===!0&&h(n.pi_pid)?!1:!await j(n.pi_session_file)}i(V,"isEmptyNode");async function fe(e,n,a=!0){return(await p(e))?.managed_worktree?.state==="open"||!await V(e)?!1:(a&&S.teardown(e),await C(e,n),(await R(e)).deleted)}i(fe,"reapIfEmpty");async function Se(e={}){const n=e.dryRun??!1,a=H()??"",t=[];for(const r of await U()){const o=r.node_id,l=await p(o);o===a||r.status==="dead"||h(r.pi_pid)||l?.managed_worktree?.state==="open"||!await V(o)||!n&&(await q(o,"notice.close",`Child closed \u2014 ${l?.name??o} (${o}) was closed from the canvas and is no longer running.`,{reason:"child-closed",child:o}),S.teardown(o),await C(o),!(await R(o)).deleted)||t.push(o)}return t}i(Se,"reapEmptyNodes");export{We as breakPane,Ze as closePane,Ne as confirmViewer,Je as currentTmux,Re as detachToBackground,Ie as displayPopup,He as ensureSession,Ae as focus,re as focusByPane,w as focusOf,Ce as focusWindow,Oe as focusedNodes,qe as getPaneOption,Qe as inTmux,un as installTmuxBindings,Fe as isFocused,ue as listFocuses,sn as listLivePanes,on as listLivePanesAsync,be as openNodeWindow,E as openViewerWindow,De as paneCurrentPath,Ue as paneExists,Me as paneLocation,Xe as paneOfNode,an as paneOfWindow,ze as paneRunning,ln as paneStateAsync,Ge as piCommand,he as probeViewer,Se as reapEmptyNodes,fe as reapIfEmpty,W as registerViewerFocus,nn as renameWindow,Ye as respawnPaneSync,Ee as selectLayout,Le as selectPane,Ve as selectWindow,je as setPaneOption,Ke as shellQuote,Be as splitWindow,$e as switchClient,C as tearDownNode,tn as windowAlive,en as windowOfPane};
@@ -1,4 +1,8 @@
1
+ import type { CredentialStore } from '@earendil-works/pi-ai';
2
+ /** The daemon, which owns the rows, registers its row-backed store; every other process asks the daemon over /v1/model-auth. */
3
+ export declare function registerGateCredentialStore(store: CredentialStore): void;
1
4
  export declare const NO_PROVIDER_CREDENTIAL_MESSAGE = "crtr: no provider credential; run `crtr sys setup` to log in.";
2
- /** Check the setup catalog before a path creates a broker-backed node. */
3
- export declare function hasConfiguredProviderCredential(profileId?: string | null): Promise<boolean>;
5
+ /** Check the setup catalog before a path creates a broker-backed node. `profileEnvNames` are the names stored on the
6
+ * launching profile (values are never needed: a stored value is never empty). */
7
+ export declare function hasConfiguredProviderCredential(profileEnvNames: readonly string[]): Promise<boolean>;
4
8
  export declare function exitForMissingProviderCredential(): never;
@@ -1,2 +1,2 @@
1
- var m=Object.defineProperty;var o=(r,e)=>m(r,"name",{value:e,configurable:!0});import{ModelRegistry as p,ModelRuntime as a}from"@earendil-works/pi-coding-agent";import{join as n}from"node:path";import{PoolCredentialStore as c}from"../pool-credential-store.js";import{readProfileEnvVars as d}from"../profiles/env-store.js";import{hasProviderCredential as l}from"../provider-credential.js";import{piAgentDir as f}from"./package-health.js";import{secretsDir as u}from"../layout.js";import{PROVIDER_ENV_KEYS as E}from"./spawn-env.js";const v="crtr: no provider credential; run `crtr sys setup` to log in.";async function w(r=null){const e=d(r);if(Object.values(E).some(i=>(e[i]??process.env[i])?.trim()))return!0;const s=f(),t=await a.create({credentials:new c(n(u(),"auth.json")),modelsPath:n(s,"models.json")});return l(t,new p(t))}o(w,"hasConfiguredProviderCredential");function M(){process.stderr.write(`${v}
2
- `),process.exit(1)}o(M,"exitForMissingProviderCredential");export{v as NO_PROVIDER_CREDENTIAL_MESSAGE,M as exitForMissingProviderCredential,w as hasConfiguredProviderCredential};
1
+ var m=Object.defineProperty;var t=(r,o)=>m(r,"name",{value:o,configurable:!0});import{ModelRegistry as a,ModelRuntime as d}from"@earendil-works/pi-coding-agent";import{join as p}from"node:path";import{ApiCredentialStore as c}from"../model-auth/api-credential-store.js";import{cliClient as l}from"../../commands/api-client.js";import{hasProviderCredential as f}from"../provider-credential.js";import{piAgentDir as u}from"./package-health.js";import{PROVIDER_ENV_KEYS as E}from"./spawn-env.js";let n;function S(r){n=r}t(S,"registerGateCredentialStore");const C="crtr: no provider credential; run `crtr sys setup` to log in.";async function _(r){const o=Object.fromEntries(r.map(e=>[e,"stored"]));if(Object.values(E).some(e=>(o[e]??process.env[e])?.trim()))return!0;const s=u(),i=await d.create({credentials:n??new c(()=>l()),modelsPath:p(s,"models.json")});return await f(i,new a(i))}t(_,"hasConfiguredProviderCredential");function j(){process.stderr.write(`${C}
2
+ `),process.exit(1)}t(j,"exitForMissingProviderCredential");export{C as NO_PROVIDER_CREDENTIAL_MESSAGE,j as exitForMissingProviderCredential,_ as hasConfiguredProviderCredential,S as registerGateCredentialStore};
@@ -1,2 +1,21 @@
1
- export declare function holdRecovery(nodeId: string): () => void;
2
- export declare function isRecoveryHeld(nodeId: string): boolean;
1
+ /** A stop in progress on a node, held on the node's row (`recovery_held_until`, `recovery_held_by`).
2
+ * Dead-row recovery leaves a held node alone, so the broker's exit cannot be read as a crash and
3
+ * resumed before the caller that is stopping it on purpose (a grant-sync revocation stop) decides the
4
+ * row's next state. The same hold is the single-flight of a node's stop across processes: one
5
+ * holder at a time, and a holder that died frees the node when the hold expires. */
6
+ export declare const RECOVERY_HOLD_MS: number;
7
+ /** A stop's claim on a node. It renews itself every third of the hold's length while the stop runs, so a stop longer than
8
+ * the hold never lets recovery restart the node; `renew` is also the fence a stop checks before each step it must not
9
+ * repeat after losing the hold. */
10
+ export interface RecoveryHold {
11
+ /** Extends the hold; false when it lapsed and another stop took it (or its expiry passed). */
12
+ renew(): Promise<boolean>;
13
+ release(): Promise<void>;
14
+ }
15
+ /** Claims the hold for a fresh owner token, or null when another stop holds the node. A holder that overran its expiry
16
+ * cannot renew or release a successor's hold: both match the owner token. */
17
+ export declare function holdRecovery(nodeId: string): Promise<RecoveryHold | null>;
18
+ export declare function isRecoveryHeld(nodeId: string): Promise<boolean>;
19
+ /** Waits until no stop holds the node. `lapsed` means the last holder never released (it died or stalled past expiry), so
20
+ * the stop it was running did not finish; `released` means it finished and cleared the hold itself. */
21
+ export declare function waitForRecoveryHold(nodeId: string): Promise<'released' | 'lapsed'>;
@@ -1 +1,2 @@
1
- var o=Object.defineProperty;var t=(e,n)=>o(e,"name",{value:n,configurable:!0});const r=new Set;function d(e){return r.add(e),()=>{r.delete(e)}}t(d,"holdRecovery");function l(e){return r.has(e)}t(l,"isRecoveryHeld");export{d as holdRecovery,l as isRecoveryHeld};
1
+ var l=Object.defineProperty;var t=(e,r)=>l(e,"name",{value:r,configurable:!0});import{randomUUID as _}from"node:crypto";import{openDb as n}from"../canvas/db.js";const a=5*6e4;async function v(e){const r=_(),o=new Date;if((await(await n()).prepare(`UPDATE nodes SET recovery_held_until = ?, recovery_held_by = ?
2
+ WHERE node_id = ? AND (recovery_held_until IS NULL OR recovery_held_until <= ?)`).run(new Date(o.getTime()+a).toISOString(),r,e,o.toISOString())).changes!==1)return null;const i=t(async()=>{const d=new Date;return(await(await n()).prepare("UPDATE nodes SET recovery_held_until = ? WHERE node_id = ? AND recovery_held_by = ? AND recovery_held_until > ?").run(new Date(d.getTime()+a).toISOString(),e,r,d.toISOString())).changes===1},"renew"),c=setInterval(()=>{i().catch(()=>{})},a/3);return c.unref(),{renew:i,release:t(async()=>{clearInterval(c),await(await n()).prepare("UPDATE nodes SET recovery_held_until = NULL, recovery_held_by = NULL WHERE node_id = ? AND recovery_held_by = ?").run(e,r)},"release")}}t(v,"holdRecovery");async function s(e){return await(await n()).prepare("SELECT 1 AS held FROM nodes WHERE node_id = ? AND recovery_held_until > ?").get(e,new Date().toISOString())!==void 0}t(s,"isRecoveryHeld");async function p(e){for(;await s(e);)await new Promise(o=>setTimeout(o,250));return(await(await n()).prepare("SELECT recovery_held_by FROM nodes WHERE node_id = ?").get(e))?.recovery_held_by==null?"released":"lapsed"}t(p,"waitForRecoveryHold");export{a as RECOVERY_HOLD_MS,v as holdRecovery,s as isRecoveryHeld,p as waitForRecoveryHold};
@@ -1 +1 @@
1
- var p=Object.defineProperty;var n=(e,t)=>p(e,"name",{value:t,configurable:!0});import{abortExecution as y,beginExecution as _,getNode as s,setPresence as h,setFocusOccupant as v,fullName as R,recordExecutionPid as b,recordLaunch as k}from"../canvas/index.js";import{pushFinal as E}from"../feed/feed.js";import{newestReportBody as g}from"../feed/reports.js";import{spawnNode as S,rootOfSpine as x}from"./nodes.js";import{buildLaunchSpecAsync as T,buildPiArgv as B}from"./launch.js";import{focusOf as N,respawnPaneSync as O,setPaneOption as P}from"./placement.js";import{waitForBrokerViewSocket as C,viewerSplitEnv as D}from"./placement-tmux.js";import{headlessBrokerHost as u}from"./host.js";import{boundFleet as F}from"./fleet.js";import{transition as z}from"./lifecycle.js";import{ensureDaemon as A}from"../../daemon/manage.js";import{invokeBirthLifecycleHooks as L}from"./spawn.js";import{checkStart as U}from"./start-check.js";async function ne(e,t){const a=await s(e);if(a===null)return{recycled:!1,finalized:!1,newRoot:null,delivered:[]};const o=t??process.env.TMUX_PANE;if(o===void 0||o==="")return{recycled:!1,finalized:!1,newRoot:null,delivered:[]};await U(a);const w=await N(e);try{A()}catch{}const{launch:f}=await T("general","base",{lifecycle:"resident",hasManager:!1,cwd:a.cwd,profileId:a.profile_id}),m=await g(e)||`Closed via recycle \u2014 no final summary was authored by ${a.name}.`;let c=[],d=!1;const r=await S({kind:"general",mode:"base",lifecycle:"resident",cwd:a.cwd,name:"general",parent:null,replaces:e,profile_id:a.profile_id,launch:f,beforeCreate:n(async()=>{try{c=(await E(e,m)).deliveredTo,d=!0}catch{}},"beforeCreate")}),i=await s(r.node_id);await L(i);const l=B(i);if(l.env={...l.env,CRTR_SUBTREE:await x(r.node_id)},!await H(i,l))return{recycled:!1,finalized:d,newRoot:r.node_id,delivered:c};try{u.teardown(e)}catch{}try{await h(e,{pane:null,window:null,tmux_session:null})}catch{}if(w!==null)try{await v(w.focus_id,r.node_id)}catch{}return{recycled:V(i,o),finalized:d,newRoot:r.node_id,delivered:c}}n(ne,"recycleNode");async function H(e,t){const a=await _(e.node_id,{daemonEpoch:F().epoch()});t.env={...t.env,CRTR_EXECUTION_ID:a};let o;try{if(o=await u.launch(e.node_id,t,{cwd:e.cwd,name:R(e),resuming:!1}),o.pid===null)throw new Error("broker host returned no pid");if(await k(e.node_id,new Date().toISOString()),await b(a,e.node_id,o.pid)==="shutdown")throw new Error("broker execution was superseded");if(await C(e.node_id,o.exited))return!0}catch{await y(a,{reason:"launch_failed"})}try{await M(e.node_id)}catch{}try{u.teardown(e.node_id)}catch{}return!1}n(H,"launchRecycledBroker");async function M(e){const t=await s(e);(t?.status==="active"||t?.status==="idle")&&await z(e,"crash")}n(M,"transitionReplacementToDead");function V(e,t){try{P(t,"@crtr_node","")}catch{}return O({pane:t,cwd:e.cwd,env:D(),command:`crtr surface attach to ${e.node_id}`})}n(V,"respawnRecycledViewer");export{ne as recycleNode};
1
+ var p=Object.defineProperty;var r=(e,t)=>p(e,"name",{value:t,configurable:!0});import{abortExecution as y,beginExecution as _,getNode as s,setPresence as h,setFocusOccupant as v,fullName as R,recordExecutionPid as b,recordLaunch as k}from"../canvas/index.js";import{pushFinal as E}from"../feed/feed.js";import{newestReportBody as g}from"../feed/reports.js";import{spawnNode as S,rootOfSpine as x}from"./nodes.js";import{buildLaunchSpecAsync as T,buildPiArgv as B}from"./launch.js";import{focusOf as C,respawnPaneSync as N,setPaneOption as O}from"./placement.js";import{waitForBrokerViewSocket as P,viewerSplitEnv as D}from"./placement-tmux.js";import{headlessBrokerHost as u}from"./host.js";import{boundFleet as F,brokerThresholdsForDaemon as z}from"./fleet.js";import{transition as A}from"./lifecycle.js";import{ensureDaemon as L}from"../../daemon/manage.js";import{invokeBirthLifecycleHooks as U}from"./spawn.js";import{checkStart as H}from"./start-check.js";async function ne(e,t){const a=await s(e);if(a===null)return{recycled:!1,finalized:!1,newRoot:null,delivered:[]};const o=t??process.env.TMUX_PANE;if(o===void 0||o==="")return{recycled:!1,finalized:!1,newRoot:null,delivered:[]};await H(a);const w=await C(e);try{L()}catch{}const{launch:f}=await T("general","base",{lifecycle:"resident",hasManager:!1,cwd:a.cwd,profileId:a.profile_id}),m=await g(e)||`Closed via recycle \u2014 no final summary was authored by ${a.name}.`;let c=[],d=!1;const n=await S({kind:"general",mode:"base",lifecycle:"resident",cwd:a.cwd,name:"general",parent:null,replaces:e,profile_id:a.profile_id,launch:f,beforeCreate:r(async()=>{try{c=(await E(e,m)).deliveredTo,d=!0}catch{}},"beforeCreate")}),i=await s(n.node_id);await U(i);const l=B(i);if(l.env={...l.env,CRTR_SUBTREE:await x(n.node_id)},!await M(i,l))return{recycled:!1,finalized:d,newRoot:n.node_id,delivered:c};try{u.teardown(e)}catch{}try{await h(e,{pane:null,window:null,tmux_session:null})}catch{}if(w!==null)try{await v(w.focus_id,n.node_id)}catch{}return{recycled:X(i,o),finalized:d,newRoot:n.node_id,delivered:c}}r(ne,"recycleNode");async function M(e,t){const a=await _(e.node_id,{daemonEpoch:F().epoch(),cap:z().automaticReviveCap});t.env={...t.env,CRTR_EXECUTION_ID:a};let o;try{if(o=await u.launch(e.node_id,t,{cwd:e.cwd,name:R(e),resuming:!1}),o.pid===null)throw new Error("broker host returned no pid");if(await k(e.node_id,new Date().toISOString()),await b(a,e.node_id,o.pid)==="shutdown")throw new Error("broker execution was superseded");if(await P(e.node_id,o.exited))return!0}catch{await y(a,{reason:"launch_failed"})}try{await V(e.node_id)}catch{}try{u.teardown(e.node_id)}catch{}return!1}r(M,"launchRecycledBroker");async function V(e){const t=await s(e);(t?.status==="active"||t?.status==="idle")&&await A(e,"crash")}r(V,"transitionReplacementToDead");function X(e,t){try{O(t,"@crtr_node","")}catch{}return N({pane:t,cwd:e.cwd,env:D(),command:`crtr surface attach to ${e.node_id}`})}r(X,"respawnRecycledViewer");export{ne as recycleNode};
@@ -1 +1 @@
1
- var S=Object.defineProperty;var s=(e,a)=>S(e,"name",{value:a,configurable:!0});import{getNode as f,beginExecution as B,recordExecutionPid as N,abortExecution as v,bindSession as b,recordLaunch as g,fullName as x,liveExecutionForNode as F,closeFocusRow as R,view as O}from"../canvas/index.js";import{transition as r}from"./lifecycle.js";import{headlessBrokerHost as y,requestBrokerTeardown as V}from"./host.js";import{boundFleet as C}from"./fleet.js";import{tearDownNode as D,focusOf as P,registerViewerFocus as T,respawnPaneSync as I,windowOfPane as L,renameWindow as q}from"./placement.js";import{viewerSplitEnv as A,waitForBrokerViewSocket as H}from"./placement-tmux.js";import{buildLaunchSpecAsync as M,buildPiArgv as U}from"./launch.js";import{newNodeId as j,spawnNode as W,rootOfSpine as X}from"./nodes.js";import{appSpace as $}from"../layout.js";import{join as z}from"node:path";import{invokeBirthLifecycleHooks as G}from"./spawn.js";import{checkStart as J}from"./start-check.js";async function K(e){const a=[];for(const i of await O(e))try{await r(i,"cancel",{reason:"closed"}),V(i),await D(i),a.push(i)}catch{}return a}s(K,"reapDescendants");async function ue(e,a={}){const i=a.launchBroker??y.launch,l=a.waitForViewSocket??H,p=a.respawnViewer??I,c=a.teardownBroker??y.teardown,n=await f(e);if(n===null||n.parent!=null||n.status==="done")return null;await J(n);const d=await P(e),h=n.isolated?await j():void 0,_=h?z($(n.grantee??"app:terminal").nodes,h):n.cwd,{launch:E}=await M(n.kind,"base",{lifecycle:"resident",hasManager:!1,model:n.model_override??void 0,modelIntent:n.launch?.modelIntent,modelExact:n.launch?.modelExact,cwd:_,profileId:n.profile_id}),t=await W({nodeId:h,kind:n.kind,mode:"base",lifecycle:"resident",cwd:_,name:n.kind,parent:null,replaces:e,profile_id:n.profile_id,launch:E,modelOverride:n.model_override??void 0});await G(t);const u=U(t,{});u.env={...u.env,CRTR_SUBTREE:await X(t.node_id)};const w=await B(t.node_id,{daemonEpoch:C().epoch()});u.env={...u.env,CRTR_EXECUTION_ID:w};let m;try{m=await i(t.node_id,u,{cwd:_,name:x(t),resuming:!1})}catch(o){throw await v(w,{reason:"launch_failed"}),await r(t.node_id,"crash"),o}if(m.pid==null)return await v(w,{reason:"launch_failed"}),await r(t.node_id,"crash"),null;if(await g(t.node_id,new Date().toISOString()),await N(w,t.node_id,m.pid)==="shutdown"){await v(w,{reason:"superseded"});try{c(t.node_id)}catch{}return await r(t.node_id,"crash"),null}let k=!1;try{k=await l(t.node_id,m.exited)}catch{}if(!k){const o=await f(t.node_id);(o?.status==="active"||o?.status==="idle")&&await r(t.node_id,"crash");try{c(t.node_id)}catch{}return null}if(await K(e),await r(e,"finish"),d?.pane!=null){await R(d.focus_id),p({pane:d.pane,cwd:n.cwd,env:A(),command:`crtr surface attach to ${t.node_id}`});const o=L(d.pane);o!==null&&q(o,x(t)),await T(t.node_id,d.pane,d.session,o)}return c(e),{newNodeId:t.node_id}}s(ue,"relaunchRoot");async function Q(e,a,i){const l=await f(e),p={reaped:[],detached:[],reset:!1};if(l===null||l.parent==null)return p;if(a!==void 0){const c=await F(e);c!==null&&await b(e,{executionId:c.executionId,sessionId:a,transcriptPath:i??null})}return p}s(Q,"resetRoot");async function we(e,a,i){return await f(e)===null?{path:"noop"}:(await Q(e,a,i),{path:"reset-child"})}s(we,"handleNewSession");async function fe(e,a){if(a!=="quit")return!1;const i=await f(e);return i===null||i.status!=="active"&&i.status!=="idle"||i.intent!=null?!1:(await r(e,"finish"),!0)}s(fe,"markCleanExitDone");export{we as handleNewSession,fe as markCleanExitDone,K as reapDescendants,ue as relaunchRoot,Q as resetRoot};
1
+ var S=Object.defineProperty;var s=(e,a)=>S(e,"name",{value:a,configurable:!0});import{getNode as f,beginExecution as b,recordExecutionPid as B,abortExecution as v,bindSession as F,recordLaunch as N,fullName as x,liveExecutionForNode as R,closeFocusRow as g,view as C}from"../canvas/index.js";import{transition as r}from"./lifecycle.js";import{headlessBrokerHost as y,requestBrokerTeardown as D}from"./host.js";import{boundFleet as O,brokerThresholdsForDaemon as T}from"./fleet.js";import{tearDownNode as V,focusOf as P,registerViewerFocus as I,respawnPaneSync as L,windowOfPane as q,renameWindow as A}from"./placement.js";import{viewerSplitEnv as H,waitForBrokerViewSocket as M}from"./placement-tmux.js";import{buildLaunchSpecAsync as U,buildPiArgv as j}from"./launch.js";import{newNodeId as W,spawnNode as X,rootOfSpine as $}from"./nodes.js";import{appSpace as z}from"../layout.js";import{join as G}from"node:path";import{invokeBirthLifecycleHooks as J}from"./spawn.js";import{checkStart as K}from"./start-check.js";async function Q(e){const a=[];for(const i of await C(e))try{await r(i,"cancel",{reason:"closed"}),D(i),await V(i),a.push(i)}catch{}return a}s(Q,"reapDescendants");async function we(e,a={}){const i=a.launchBroker??y.launch,l=a.waitForViewSocket??M,p=a.respawnViewer??L,c=a.teardownBroker??y.teardown,n=await f(e);if(n===null||n.parent!=null||n.status==="done")return null;await K(n);const d=await P(e),h=n.isolated?await W():void 0,_=h?G(z(n.grantee??"app:terminal").nodes,h):n.cwd,{launch:E}=await U(n.kind,"base",{lifecycle:"resident",hasManager:!1,model:n.model_override??void 0,modelIntent:n.launch?.modelIntent,modelExact:n.launch?.modelExact,cwd:_,profileId:n.profile_id}),t=await X({nodeId:h,kind:n.kind,mode:"base",lifecycle:"resident",cwd:_,name:n.kind,parent:null,replaces:e,profile_id:n.profile_id,launch:E,modelOverride:n.model_override??void 0});await J(t);const u=j(t,{});u.env={...u.env,CRTR_SUBTREE:await $(t.node_id)};const w=await b(t.node_id,{daemonEpoch:O().epoch(),cap:T().automaticReviveCap});u.env={...u.env,CRTR_EXECUTION_ID:w};let m;try{m=await i(t.node_id,u,{cwd:_,name:x(t),resuming:!1})}catch(o){throw await v(w,{reason:"launch_failed"}),await r(t.node_id,"crash"),o}if(m.pid==null)return await v(w,{reason:"launch_failed"}),await r(t.node_id,"crash"),null;if(await N(t.node_id,new Date().toISOString()),await B(w,t.node_id,m.pid)==="shutdown"){await v(w,{reason:"superseded"});try{c(t.node_id)}catch{}return await r(t.node_id,"crash"),null}let k=!1;try{k=await l(t.node_id,m.exited)}catch{}if(!k){const o=await f(t.node_id);(o?.status==="active"||o?.status==="idle")&&await r(t.node_id,"crash");try{c(t.node_id)}catch{}return null}if(await Q(e),await r(e,"finish"),d?.pane!=null){await g(d.focus_id),p({pane:d.pane,cwd:n.cwd,env:H(),command:`crtr surface attach to ${t.node_id}`});const o=q(d.pane);o!==null&&A(o,x(t)),await I(t.node_id,d.pane,d.session,o)}return c(e),{newNodeId:t.node_id}}s(we,"relaunchRoot");async function Y(e,a,i){const l=await f(e),p={reaped:[],detached:[],reset:!1};if(l===null||l.parent==null)return p;if(a!==void 0){const c=await R(e);c!==null&&await F(e,{executionId:c.executionId,sessionId:a,transcriptPath:i??null})}return p}s(Y,"resetRoot");async function fe(e,a,i){return await f(e)===null?{path:"noop"}:(await Y(e,a,i),{path:"reset-child"})}s(fe,"handleNewSession");async function pe(e,a){if(a!=="quit")return!1;const i=await f(e);return i===null||i.status!=="active"&&i.status!=="idle"||i.intent!=null?!1:(await r(e,"finish"),!0)}s(pe,"markCleanExitDone");export{fe as handleNewSession,pe as markCleanExitDone,Q as reapDescendants,we as relaunchRoot,Y as resetRoot};
@@ -4,7 +4,7 @@ import type { WakeOrigin } from './bearings.js';
4
4
  * abort is the one exception: continue the persisted transcript with a factual
5
5
  * warning rather than creating a fresh cycle. */
6
6
  export type ReviveWakeReason = WakeOrigin | 'runtime-restart-abort';
7
- import { headlessBrokerHost } from './host.js';
7
+ import { processRunner } from './runner/process.js';
8
8
  /** Pick the `--session` source for a revive. Both resume=true (a true resume)
9
9
  * and resume=false (a refresh-yield) resume by the absolute session-file path
10
10
  * (immune to cwd; pi opens it directly) — but ONLY when that file actually
@@ -45,7 +45,7 @@ export interface ReviveResult {
45
45
  resumed: boolean;
46
46
  /** Launch handle for the detached broker, so callers can fail fast on its real
47
47
  * exit before the socket appears. */
48
- launch?: Awaited<ReturnType<typeof headlessBrokerHost.launch>>;
48
+ launch?: Awaited<ReturnType<typeof processRunner.start>>;
49
49
  /** Reads a fatal launch fault recorded by THIS revive attempt, scoped via
50
50
  * `beginBootFaultAttempt` at the exact clear-then-launch boundary below.
51
51
  * Present only when a fresh launch actually happened (absent on the