@north-light/crouter 0.3.318 → 0.3.320

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 (1304) hide show
  1. package/README.md +0 -3
  2. package/dist/api/client.js +2 -912
  3. package/dist/api/dto/attach.js +0 -13
  4. package/dist/api/dto/bash-jobs.js +1 -9
  5. package/dist/api/dto/broker-ops.js +0 -6
  6. package/dist/api/dto/broker.js +0 -20
  7. package/dist/api/dto/canvas.js +0 -2
  8. package/dist/api/dto/chat-inventory.js +0 -11
  9. package/dist/api/dto/common.js +1 -15
  10. package/dist/api/dto/config.js +0 -3
  11. package/dist/api/dto/crons.js +1 -10
  12. package/dist/api/dto/files.js +0 -7
  13. package/dist/api/dto/focus.js +0 -10
  14. package/dist/api/dto/health.js +0 -2
  15. package/dist/api/dto/human-requests.js +0 -4
  16. package/dist/api/dto/human.js +0 -4
  17. package/dist/api/dto/inbox.js +0 -4
  18. package/dist/api/dto/lifecycle.js +0 -3
  19. package/dist/api/dto/mail.js +0 -1
  20. package/dist/api/dto/memory.js +0 -6
  21. package/dist/api/dto/messages.js +0 -2
  22. package/dist/api/dto/model-config.js +0 -1
  23. package/dist/api/dto/modelauth.js +0 -4
  24. package/dist/api/dto/node-outcomes.js +0 -2
  25. package/dist/api/dto/nodes.js +0 -3
  26. package/dist/api/dto/profiles.js +1 -4
  27. package/dist/api/dto/recovery.js +0 -1
  28. package/dist/api/dto/reports.js +0 -2
  29. package/dist/api/dto/review-comments.js +0 -5
  30. package/dist/api/dto/reviews.js +0 -5
  31. package/dist/api/dto/subscriptions.js +0 -2
  32. package/dist/api/dto/worktree.js +0 -6
  33. package/dist/api/errors.js +1 -40
  34. package/dist/api/index.js +1 -33
  35. package/dist/api/plugin-manifest-schema.js +0 -23
  36. package/dist/api/routes.js +1 -147
  37. package/dist/build-root.js +1 -198
  38. package/dist/cli.js +3 -99
  39. package/dist/clients/attach/ansi-cells.js +1 -137
  40. package/dist/clients/attach/chrome/bash-jobs.js +1 -31
  41. package/dist/clients/attach/chrome/canvas-panels.js +1 -194
  42. package/dist/clients/attach/chrome/completion-bell.js +1 -89
  43. package/dist/clients/attach/chrome/cron-wait.js +1 -34
  44. package/dist/clients/attach/chrome/git-info.js +2 -44
  45. package/dist/clients/attach/chrome/header.js +1 -30
  46. package/dist/clients/attach/chrome/inbox-strip.js +1 -199
  47. package/dist/clients/attach/chrome/recap.js +1 -19
  48. package/dist/clients/attach/chrome/review-wait.js +1 -22
  49. package/dist/clients/attach/chrome/roster.js +4 -275
  50. package/dist/clients/attach/chrome/status-line.js +1 -117
  51. package/dist/clients/attach/chrome/ticket-panel.js +1 -280
  52. package/dist/clients/attach/chrome/widgets.js +1 -51
  53. package/dist/clients/attach/command.js +1 -107
  54. package/dist/clients/attach/config.js +1 -274
  55. package/dist/clients/attach/input/capabilities.js +1 -104
  56. package/dist/clients/attach/input/clipboard-image.js +3 -220
  57. package/dist/clients/attach/input/completion-frecency.js +1 -141
  58. package/dist/clients/attach/input/controller.js +7 -377
  59. package/dist/clients/attach/input/overlay-owner.js +1 -199
  60. package/dist/clients/attach/input/ref-autocomplete.js +2 -176
  61. package/dist/clients/attach/input/titled-editor.js +4 -859
  62. package/dist/clients/attach/overlays/auth.js +2 -271
  63. package/dist/clients/attach/overlays/dialogs.js +2 -102
  64. package/dist/clients/attach/overlays/file-review.js +2 -128
  65. package/dist/clients/attach/overlays/graph.js +1 -661
  66. package/dist/clients/attach/overlays/help.js +1 -211
  67. package/dist/clients/attach/overlays/mcp.js +1 -302
  68. package/dist/clients/attach/overlays/pickers.js +1 -163
  69. package/dist/clients/attach/render/activity-slot.js +1 -13
  70. package/dist/clients/attach/render/assistant-message.js +1 -56
  71. package/dist/clients/attach/render/card-presentation.js +5 -218
  72. package/dist/clients/attach/render/chat-view.js +5 -1708
  73. package/dist/clients/attach/render/condensed-history.js +1 -60
  74. package/dist/clients/attach/render/context-message.js +1 -63
  75. package/dist/clients/attach/render/crtr-output.js +17 -905
  76. package/dist/clients/attach/render/diagram.js +7 -111
  77. package/dist/clients/attach/render/edit-diff.js +5 -304
  78. package/dist/clients/attach/render/glyph-codepoints.js +1 -42
  79. package/dist/clients/attach/render/group-activity.js +2 -263
  80. package/dist/clients/attach/render/group-recap.js +1 -152
  81. package/dist/clients/attach/render/markdown-source.js +5 -266
  82. package/dist/clients/attach/render/measured-container.js +1 -322
  83. package/dist/clients/attach/render/page-block.js +1 -183
  84. package/dist/clients/attach/render/scroll-animation.js +1 -80
  85. package/dist/clients/attach/render/tool-calls.js +3 -361
  86. package/dist/clients/attach/render/transcript-copy.js +2 -81
  87. package/dist/clients/attach/render/transcript-search.js +1 -152
  88. package/dist/clients/attach/render/viewport.js +1 -184
  89. package/dist/clients/attach/session/banner.js +1 -29
  90. package/dist/clients/attach/session/bindings.js +1 -71
  91. package/dist/clients/attach/session/chrome-refresh.js +1 -94
  92. package/dist/clients/attach/session/connection.js +1 -186
  93. package/dist/clients/attach/session/context.js +0 -16
  94. package/dist/clients/attach/session/editor-frame.js +1 -142
  95. package/dist/clients/attach/session/editor-inventory.js +6 -160
  96. package/dist/clients/attach/session/file-links.js +1 -68
  97. package/dist/clients/attach/session/focus-events.js +1 -12
  98. package/dist/clients/attach/session/frame.js +1 -214
  99. package/dist/clients/attach/session/frames.js +1 -188
  100. package/dist/clients/attach/session/identity.js +1 -26
  101. package/dist/clients/attach/session/input-wiring.js +1 -140
  102. package/dist/clients/attach/session/invariant.js +1 -15
  103. package/dist/clients/attach/session/keys.js +1 -77
  104. package/dist/clients/attach/session/layout.js +1 -59
  105. package/dist/clients/attach/session/mouse.js +1 -78
  106. package/dist/clients/attach/session/pane-focus.js +1 -42
  107. package/dist/clients/attach/session/pane-tag.js +1 -112
  108. package/dist/clients/attach/session/pi-assets.js +1 -24
  109. package/dist/clients/attach/session/pi-oauth-flows.js +1 -21
  110. package/dist/clients/attach/session/profile-files.js +1 -228
  111. package/dist/clients/attach/session/reconnect.js +1 -175
  112. package/dist/clients/attach/session/selection.js +3 -108
  113. package/dist/clients/attach/session/state-sync.js +1 -67
  114. package/dist/clients/attach/session/surface-frame.js +1 -73
  115. package/dist/clients/attach/session/surface-host.js +1 -255
  116. package/dist/clients/attach/session/teardown.js +5 -94
  117. package/dist/clients/attach/session/transcript-search.js +3 -151
  118. package/dist/clients/attach/session/whip-achievements.js +2 -145
  119. package/dist/clients/attach/session/whip.js +1 -362
  120. package/dist/clients/attach/slash/dispatch.js +1 -706
  121. package/dist/clients/attach/slash/prompt-preview.js +1 -121
  122. package/dist/clients/attach/viewer.js +441 -441
  123. package/dist/clients/conversation/projection.js +1 -324
  124. package/dist/clients/conversation/submit.js +1 -51
  125. package/dist/clients/inbox/controller.js +1 -701
  126. package/dist/clients/inbox/dto-adapt.js +1 -93
  127. package/dist/clients/inbox/layout.js +1 -9
  128. package/dist/clients/inbox/page-adapter.js +1 -55
  129. package/dist/clients/inbox/resolve.js +1 -35
  130. package/dist/clients/inbox/review/anchors.js +1 -89
  131. package/dist/clients/inbox/review/comments-client.js +1 -98
  132. package/dist/clients/inbox/review/companion-pane.js +1 -82
  133. package/dist/clients/inbox/review/document-surface.js +2 -1188
  134. package/dist/clients/inbox/review/frame.js +1 -216
  135. package/dist/clients/inbox/review/keys.js +1 -123
  136. package/dist/clients/inbox/review/launch.js +1 -151
  137. package/dist/clients/inbox/review/live-source.js +1 -160
  138. package/dist/clients/inbox/review/nvim.js +1 -44
  139. package/dist/clients/inbox/review/remap.js +1 -157
  140. package/dist/clients/inbox/review/review-client.js +1 -123
  141. package/dist/clients/inbox/review/roundtrip.js +3 -36
  142. package/dist/clients/inbox/review/state.js +4 -315
  143. package/dist/clients/inbox/review-adapter.js +1 -43
  144. package/dist/clients/inbox/surface.js +1 -152
  145. package/dist/clients/inbox/tui/ansi.js +3 -321
  146. package/dist/clients/inbox/tui/input.js +5 -392
  147. package/dist/clients/inbox/tui/keys.js +1 -104
  148. package/dist/clients/inbox/tui/page-body.js +1 -66
  149. package/dist/clients/inbox/tui/panel.js +1 -84
  150. package/dist/clients/inbox/tui/render.js +2 -368
  151. package/dist/clients/inbox/tui/slots.js +3 -134
  152. package/dist/clients/inbox/tui/types.js +0 -1
  153. package/dist/clients/inbox/tui.js +1 -86
  154. package/dist/clients/surfaces/host.js +0 -1
  155. package/dist/commands/api-client.js +4 -290
  156. package/dist/commands/attention.js +1 -215
  157. package/dist/commands/canvas-browse.js +1 -70
  158. package/dist/commands/canvas-config.js +2 -192
  159. package/dist/commands/canvas-history/grep.js +7 -85
  160. package/dist/commands/canvas-history/read.js +3 -50
  161. package/dist/commands/canvas-history/search.js +10 -99
  162. package/dist/commands/canvas-history/shared.js +1 -139
  163. package/dist/commands/canvas-history/stats.js +6 -68
  164. package/dist/commands/canvas-history.js +1 -32
  165. package/dist/commands/canvas-issue.js +14 -149
  166. package/dist/commands/canvas-prune.js +1 -108
  167. package/dist/commands/canvas-roster.js +1 -69
  168. package/dist/commands/canvas-snapshot.js +1 -34
  169. package/dist/commands/canvas-use.js +1 -61
  170. package/dist/commands/canvas.js +1 -49
  171. package/dist/commands/chord.js +1 -241
  172. package/dist/commands/cron.js +11 -534
  173. package/dist/commands/dashboard.js +1 -85
  174. package/dist/commands/human/components.js +3 -77
  175. package/dist/commands/human/feedback.js +1 -112
  176. package/dist/commands/human/prompts.js +1 -331
  177. package/dist/commands/human/queue.js +1 -191
  178. package/dist/commands/human/request.js +1 -266
  179. package/dist/commands/human/review.js +1 -288
  180. package/dist/commands/human/shared.js +1 -67
  181. package/dist/commands/human.js +4 -60
  182. package/dist/commands/memory/delete.js +1 -100
  183. package/dist/commands/memory/edit.js +21 -219
  184. package/dist/commands/memory/find.js +2 -244
  185. package/dist/commands/memory/history.js +5 -199
  186. package/dist/commands/memory/lint.js +1 -107
  187. package/dist/commands/memory/list.js +1 -142
  188. package/dist/commands/memory/move.js +1 -223
  189. package/dist/commands/memory/origin.js +1 -130
  190. package/dist/commands/memory/read.js +6 -232
  191. package/dist/commands/memory/shared.js +12 -802
  192. package/dist/commands/memory/write.js +13 -235
  193. package/dist/commands/memory.js +1 -30
  194. package/dist/commands/node/bash.js +5 -245
  195. package/dist/commands/node/create.js +3 -332
  196. package/dist/commands/node/inspect.js +12 -300
  197. package/dist/commands/node/lifecycle.js +2 -453
  198. package/dist/commands/node/message.js +1 -161
  199. package/dist/commands/node/outcome.js +4 -134
  200. package/dist/commands/node/pyramid.js +2 -79
  201. package/dist/commands/node/subscription.js +1 -78
  202. package/dist/commands/node/wait.js +7 -163
  203. package/dist/commands/node-context.js +2 -159
  204. package/dist/commands/node-inspect-artifacts.js +8 -109
  205. package/dist/commands/node-lifecycle-revive.js +1 -217
  206. package/dist/commands/node-snapshot.js +1 -37
  207. package/dist/commands/node-transcript.js +1 -62
  208. package/dist/commands/node-worktree.js +1 -138
  209. package/dist/commands/node.js +1 -29
  210. package/dist/commands/pkg/browse/actions.js +1 -198
  211. package/dist/commands/pkg/browse/catalog.js +1 -466
  212. package/dist/commands/pkg/browse/command-view.js +1 -191
  213. package/dist/commands/pkg/browse/detail-panel.js +1 -402
  214. package/dist/commands/pkg/browse/doc-view.js +1 -89
  215. package/dist/commands/pkg/browse/list-panel.js +2 -168
  216. package/dist/commands/pkg/browse/model.js +1 -36
  217. package/dist/commands/pkg/browse/shell.js +1 -640
  218. package/dist/commands/pkg/browse.js +1 -27
  219. package/dist/commands/pkg/market-inspect.js +1 -141
  220. package/dist/commands/pkg/market-manage.js +1 -327
  221. package/dist/commands/pkg/market.js +1 -14
  222. package/dist/commands/pkg/plugin-inspect.js +1 -168
  223. package/dist/commands/pkg/plugin-manage.js +17 -1109
  224. package/dist/commands/pkg/plugin.js +1 -14
  225. package/dist/commands/pkg/shared.js +1 -62
  226. package/dist/commands/pkg.js +1 -21
  227. package/dist/commands/profile/default.js +1 -139
  228. package/dist/commands/profile/delete.js +1 -66
  229. package/dist/commands/profile/env.js +3 -188
  230. package/dist/commands/profile/kind.js +2 -35
  231. package/dist/commands/profile/list.js +1 -43
  232. package/dist/commands/profile/meta.js +1 -67
  233. package/dist/commands/profile/new.js +1 -115
  234. package/dist/commands/profile/pause.js +1 -59
  235. package/dist/commands/profile/project.js +1 -113
  236. package/dist/commands/profile/rename.js +1 -38
  237. package/dist/commands/profile/show.js +1 -52
  238. package/dist/commands/profile.js +1 -35
  239. package/dist/commands/push.js +9 -265
  240. package/dist/commands/revive.js +10 -181
  241. package/dist/commands/surface/node/cycle.js +1 -83
  242. package/dist/commands/surface/node/focus.js +1 -81
  243. package/dist/commands/surface/node/id.js +1 -38
  244. package/dist/commands/surface/node/pin.js +1 -42
  245. package/dist/commands/surface/node/placement.js +1 -134
  246. package/dist/commands/surface-edit.js +1 -157
  247. package/dist/commands/surface-inbox.js +1 -98
  248. package/dist/commands/surface-inspect.js +1 -39
  249. package/dist/commands/surface-node.js +1 -19
  250. package/dist/commands/surface-reload.js +2 -134
  251. package/dist/commands/surface-tmux-spread.js +1 -214
  252. package/dist/commands/surface.js +1 -28
  253. package/dist/commands/sys/branch.js +1 -19
  254. package/dist/commands/sys/config.js +1 -353
  255. package/dist/commands/sys/context/admin/actions.js +2 -246
  256. package/dist/commands/sys/context/admin/detail-panel.js +1 -247
  257. package/dist/commands/sys/context/admin/docs-panel.js +1 -191
  258. package/dist/commands/sys/context/admin/list-view.js +1 -183
  259. package/dist/commands/sys/context/admin/model.js +1 -229
  260. package/dist/commands/sys/context/admin/rail-panel.js +1 -227
  261. package/dist/commands/sys/context/admin/read-view.js +2 -194
  262. package/dist/commands/sys/context/admin/shell.js +1 -910
  263. package/dist/commands/sys/context/admin.js +2 -126
  264. package/dist/commands/sys/context/doc.js +3 -197
  265. package/dist/commands/sys/context/prompt-review.js +11 -291
  266. package/dist/commands/sys/context/resolve.js +10 -489
  267. package/dist/commands/sys/context/sysprompt.js +5 -96
  268. package/dist/commands/sys/context.js +1 -20
  269. package/dist/commands/sys/daemon.js +1 -313
  270. package/dist/commands/sys/doctor.js +1 -617
  271. package/dist/commands/sys/feedback.js +7 -228
  272. package/dist/commands/sys/logs.js +3 -129
  273. package/dist/commands/sys/migrate.js +1 -94
  274. package/dist/commands/sys/panels/broker-limits-panel.js +2 -110
  275. package/dist/commands/sys/panels/dependencies-panel.js +1 -80
  276. package/dist/commands/sys/panels/keybindings-panel.js +1 -703
  277. package/dist/commands/sys/panels/models-panel.js +1 -1133
  278. package/dist/commands/sys/panels/plugins-panel.js +1 -80
  279. package/dist/commands/sys/panels/prefs-panel.js +1 -85
  280. package/dist/commands/sys/panels/profiles-panel.js +1 -601
  281. package/dist/commands/sys/panels/provider-panel.js +1 -538
  282. package/dist/commands/sys/settings-shell.js +1 -400
  283. package/dist/commands/sys/settings.js +1 -46
  284. package/dist/commands/sys/setup-core.js +6 -579
  285. package/dist/commands/sys/setup-settings-runner.js +1 -16
  286. package/dist/commands/sys/setup-wizard.js +1 -279
  287. package/dist/commands/sys/setup.js +1 -34
  288. package/dist/commands/sys/shared.js +1 -81
  289. package/dist/commands/sys/support/prepare.js +3 -239
  290. package/dist/commands/sys/support/submit.js +6 -524
  291. package/dist/commands/sys/support.js +1 -18
  292. package/dist/commands/sys/sync-deps.js +15 -498
  293. package/dist/commands/sys/sync-project-guidance.js +4 -481
  294. package/dist/commands/sys/sync-shared.js +1 -49
  295. package/dist/commands/sys/sync-skills.js +2 -311
  296. package/dist/commands/sys/sync.js +1 -18
  297. package/dist/commands/sys/update.js +1 -147
  298. package/dist/commands/sys/worktrees.js +5 -53
  299. package/dist/commands/sys.js +1 -18
  300. package/dist/core/activity-signal.js +2 -38
  301. package/dist/core/asset-root.js +1 -18
  302. package/dist/core/auth-file.js +2 -179
  303. package/dist/core/auth-interaction.js +3 -94
  304. package/dist/core/auto-update.js +4 -94
  305. package/dist/core/bash-guard.js +11 -393
  306. package/dist/core/bash-jobs.js +7 -411
  307. package/dist/core/bootstrap.js +2 -53
  308. package/dist/core/broker-client/client.js +1 -184
  309. package/dist/core/broker-client/index.js +1 -13
  310. package/dist/core/broker-client/transport-relay.js +1 -157
  311. package/dist/core/broker-client/transport-socket.js +1 -179
  312. package/dist/core/broker-client/transport.js +1 -26
  313. package/dist/core/canvas/attention.js +1 -47
  314. package/dist/core/canvas/boot-id.js +1 -26
  315. package/dist/core/canvas/boot.js +1 -186
  316. package/dist/core/canvas/browse/app.js +3 -919
  317. package/dist/core/canvas/browse/model.js +1 -477
  318. package/dist/core/canvas/browse/pins.js +1 -29
  319. package/dist/core/canvas/browse/render.js +3 -1055
  320. package/dist/core/canvas/canvas.js +15 -922
  321. package/dist/core/canvas/crons.js +11 -481
  322. package/dist/core/canvas/daemon-owner.js +2 -146
  323. package/dist/core/canvas/db.js +2 -100
  324. package/dist/core/canvas/deliveries.js +22 -283
  325. package/dist/core/canvas/delivery-contract.js +1 -8
  326. package/dist/core/canvas/executions.js +1 -68
  327. package/dist/core/canvas/extensions.js +1 -83
  328. package/dist/core/canvas/focuses.js +1 -77
  329. package/dist/core/canvas/history.js +24 -860
  330. package/dist/core/canvas/index.js +1 -15
  331. package/dist/core/canvas/install-id.js +1 -84
  332. package/dist/core/canvas/labels.js +1 -43
  333. package/dist/core/canvas/meta-file.js +1 -89
  334. package/dist/core/canvas/migrations.js +41 -1150
  335. package/dist/core/canvas/nav-model.js +1 -231
  336. package/dist/core/canvas/nav-render.js +1 -260
  337. package/dist/core/canvas/node-order.js +1 -37
  338. package/dist/core/canvas/node-recap.js +2 -67
  339. package/dist/core/canvas/node-sql-migration.js +2 -209
  340. package/dist/core/canvas/paths.js +1 -153
  341. package/dist/core/canvas/pid.js +4 -683
  342. package/dist/core/canvas/recovery.js +3 -565
  343. package/dist/core/canvas/remote-canvas-source.js +1 -288
  344. package/dist/core/canvas/remote-transport.js +1 -57
  345. package/dist/core/canvas/render-source.js +10 -635
  346. package/dist/core/canvas/sessions.js +1 -78
  347. package/dist/core/canvas/source.js +1 -47
  348. package/dist/core/canvas/status-glyph.js +1 -132
  349. package/dist/core/canvas/telemetry.js +1 -35
  350. package/dist/core/canvas/types.js +1 -6
  351. package/dist/core/canvas/waits.js +4 -68
  352. package/dist/core/canvas/worktrees.js +1 -93
  353. package/dist/core/clipboard-text.js +1 -57
  354. package/dist/core/command-hooks/artifact.js +1 -145
  355. package/dist/core/command-hooks/catalog.js +1 -38
  356. package/dist/core/command-hooks/compose.js +1 -99
  357. package/dist/core/command-hooks/discovery.js +1 -228
  358. package/dist/core/command-hooks/help.js +1 -18
  359. package/dist/core/command-hooks/index.js +1 -7
  360. package/dist/core/command-hooks/lifecycle-catalog.js +1 -9
  361. package/dist/core/command-hooks/lifecycle-create.js +1 -51
  362. package/dist/core/command-hooks/report.js +1 -28
  363. package/dist/core/command-hooks/schema.js +1 -157
  364. package/dist/core/command-hooks/transport/exec-invoke.js +1 -276
  365. package/dist/core/command-hooks/transport/exec-lifecycle.js +1 -211
  366. package/dist/core/command-manifests/manifest.js +1 -324
  367. package/dist/core/command-manifests/registry.js +1 -118
  368. package/dist/core/command-manifests/schema.js +1 -736
  369. package/dist/core/command-plugins/bundle.js +1 -261
  370. package/dist/core/command-plugins/compose.js +1 -65
  371. package/dist/core/command-plugins/discovery.js +1 -245
  372. package/dist/core/command-plugins/endpoint.js +1 -48
  373. package/dist/core/command-plugins/extensions.js +1 -166
  374. package/dist/core/command-plugins/help-addenda.js +1 -44
  375. package/dist/core/command-plugins/presence.js +1 -17
  376. package/dist/core/command-plugins/revalidate.js +2 -152
  377. package/dist/core/command-plugins/transport/exec-invoke.js +1 -215
  378. package/dist/core/command-plugins/transport/http-fetch.js +1 -68
  379. package/dist/core/command-plugins/transport/http-invoke.js +3 -546
  380. package/dist/core/command.js +10 -739
  381. package/dist/core/config.js +1 -1059
  382. package/dist/core/document-lines.js +3 -6
  383. package/dist/core/env-name.js +1 -9
  384. package/dist/core/errors.js +1 -52
  385. package/dist/core/events/emit.js +1 -17
  386. package/dist/core/events/envelope.js +1 -84
  387. package/dist/core/events/errors.js +1 -69
  388. package/dist/core/events/index.js +1 -4
  389. package/dist/core/events/operation-id.js +1 -24
  390. package/dist/core/events/read.js +1 -623
  391. package/dist/core/events/serialize.js +1 -199
  392. package/dist/core/events/source.js +1 -31
  393. package/dist/core/events/types.js +1 -11
  394. package/dist/core/exclusive-lock.js +1 -197
  395. package/dist/core/fault-classifier.js +1 -96
  396. package/dist/core/feed/feed.js +7 -202
  397. package/dist/core/feed/inbox-migrate.js +3 -135
  398. package/dist/core/feed/inbox.js +10 -122
  399. package/dist/core/feed/messages.js +6 -212
  400. package/dist/core/frontmatter.js +1 -35
  401. package/dist/core/fs-utils.js +3 -202
  402. package/dist/core/git.js +2 -103
  403. package/dist/core/help.js +9 -310
  404. package/dist/core/host-exports/builtins.js +9 -68
  405. package/dist/core/host-exports/export.js +3 -124
  406. package/dist/core/human/action-binding.js +1 -40
  407. package/dist/core/human/answer-text.js +5 -100
  408. package/dist/core/human/answer.js +1 -119
  409. package/dist/core/human/claim.js +3 -67
  410. package/dist/core/human/completion.js +1 -27
  411. package/dist/core/human/component-docs.js +78 -272
  412. package/dist/core/human/convention.js +2 -82
  413. package/dist/core/human/feedback-companion.js +1 -106
  414. package/dist/core/human/feedback.js +1 -88
  415. package/dist/core/human/page-authoring.js +1 -19
  416. package/dist/core/human/page-catalog.js +1 -172
  417. package/dist/core/human/page-errors.js +1 -7
  418. package/dist/core/human/page-eval.js +1 -125
  419. package/dist/core/human/page-html-markdown.js +8 -260
  420. package/dist/core/human/page-markdown.js +17 -295
  421. package/dist/core/human/page-schema.js +1 -373
  422. package/dist/core/human/page-synth.js +8 -27
  423. package/dist/core/human/page.js +1 -198
  424. package/dist/core/human/requests.js +15 -466
  425. package/dist/core/human/review-schema.js +1 -34
  426. package/dist/core/human/root.js +1 -11
  427. package/dist/core/human/scan.js +1 -69
  428. package/dist/core/human/summary.js +1 -5
  429. package/dist/core/human/tickets.js +1 -171
  430. package/dist/core/human/types.js +0 -1
  431. package/dist/core/human/visible-paths.js +1 -77
  432. package/dist/core/human-actions.js +1 -101
  433. package/dist/core/inspector/chrome.js +1 -14
  434. package/dist/core/inspector/contract.js +0 -1
  435. package/dist/core/inspector/core.js +2 -295
  436. package/dist/core/inspector/host.js +4 -538
  437. package/dist/core/inspector/model.js +2 -226
  438. package/dist/core/inspector/text.js +6 -45
  439. package/dist/core/inspector/transport.js +1 -36
  440. package/dist/core/inspector/tui.js +2 -295
  441. package/dist/core/installed-plugins.js +1 -78
  442. package/dist/core/io.js +7 -356
  443. package/dist/core/keybindings/attach-control.js +1 -42
  444. package/dist/core/keybindings/background-bash.js +1 -33
  445. package/dist/core/keybindings/catalog.js +1 -256
  446. package/dist/core/keybindings/inbox.js +1 -25
  447. package/dist/core/keybindings/index.js +1 -7
  448. package/dist/core/keybindings/match.js +1 -127
  449. package/dist/core/keybindings/persistence.js +1 -49
  450. package/dist/core/keybindings/resolve.js +1 -348
  451. package/dist/core/keybindings/types.js +0 -1
  452. package/dist/core/locked-file.js +1 -118
  453. package/dist/core/log.js +3 -27
  454. package/dist/core/manifest-recovery.js +1 -72
  455. package/dist/core/manifest-stale.js +1 -39
  456. package/dist/core/manifest.js +1 -20
  457. package/dist/core/memory/doc-link-grammar.js +2 -109
  458. package/dist/core/memory/extensions.js +1 -221
  459. package/dist/core/memory/history.js +6 -268
  460. package/dist/core/memory/identity.js +1 -181
  461. package/dist/core/memory/inline-ref-grammar.js +1 -98
  462. package/dist/core/memory/inline-ref-guidance.js +2 -35
  463. package/dist/core/memory/inline-ref-inventory.js +1 -59
  464. package/dist/core/memory/lint.js +2 -671
  465. package/dist/core/memory/project-namespace.js +2 -85
  466. package/dist/core/memory/repository-association.js +1 -129
  467. package/dist/core/memory/tree.js +1 -93
  468. package/dist/core/memory-resolver.js +2 -611
  469. package/dist/core/model-config.js +1 -107
  470. package/dist/core/model-routes.js +1 -201
  471. package/dist/core/nested-stores.js +2 -166
  472. package/dist/core/output.js +7 -99
  473. package/dist/core/pagination.js +1 -88
  474. package/dist/core/plugin-swap-lock.js +1 -31
  475. package/dist/core/pool-credential-store.js +1 -116
  476. package/dist/core/predicate.js +1 -191
  477. package/dist/core/preview-registry.js +2 -411
  478. package/dist/core/preview-result-path.js +1 -26
  479. package/dist/core/profiles/default-binding.js +1 -24
  480. package/dist/core/profiles/deletion-reservation.js +1 -42
  481. package/dist/core/profiles/env-store.js +2 -162
  482. package/dist/core/profiles/fuzzy-match.js +1 -92
  483. package/dist/core/profiles/manifest.js +1 -574
  484. package/dist/core/profiles/select.js +35 -741
  485. package/dist/core/profiles/state-block.js +3 -17
  486. package/dist/core/provider-error-recognition.js +1 -74
  487. package/dist/core/provider-failure.js +1 -86
  488. package/dist/core/provider-management.js +1 -22
  489. package/dist/core/remote-canvas-target.js +1 -30
  490. package/dist/core/render.js +18 -138
  491. package/dist/core/resolver.js +1 -111
  492. package/dist/core/review/birth.js +1 -52
  493. package/dist/core/review/comments.js +5 -279
  494. package/dist/core/review/companion.js +1 -215
  495. package/dist/core/review/document.js +2 -138
  496. package/dist/core/review/project.js +1 -36
  497. package/dist/core/review/realize.js +1 -71
  498. package/dist/core/review/remap.js +4 -141
  499. package/dist/core/review/signal.js +1 -12
  500. package/dist/core/review/stage.js +1 -184
  501. package/dist/core/review/store.js +1 -168
  502. package/dist/core/review/types.js +1 -23
  503. package/dist/core/runtime/advertised-command-invocation.js +1 -233
  504. package/dist/core/runtime/auth-reload.js +1 -67
  505. package/dist/core/runtime/banner.js +1 -51
  506. package/dist/core/runtime/bearings-render.js +18 -250
  507. package/dist/core/runtime/bearings.js +7 -194
  508. package/dist/core/runtime/bin-contributions.js +2 -186
  509. package/dist/core/runtime/boot-root.js +1 -107
  510. package/dist/core/runtime/branded-host.js +2 -264
  511. package/dist/core/runtime/broker/auth-reload.js +1 -157
  512. package/dist/core/runtime/broker/client-registry.js +1 -179
  513. package/dist/core/runtime/broker/daemon-ops.js +1 -88
  514. package/dist/core/runtime/broker/engine-drive.js +1 -354
  515. package/dist/core/runtime/broker/engine-routing.js +1 -211
  516. package/dist/core/runtime/broker/event-projection.js +1 -193
  517. package/dist/core/runtime/broker/extension-abort.js +1 -36
  518. package/dist/core/runtime/broker/fault-retry.js +1 -588
  519. package/dist/core/runtime/broker/frame-client.js +1 -132
  520. package/dist/core/runtime/broker/frame-dispatch.js +1 -183
  521. package/dist/core/runtime/broker/frame-engine-control.js +1 -231
  522. package/dist/core/runtime/broker/frame-memory-refs.js +1 -41
  523. package/dist/core/runtime/broker/frame-model-query.js +1 -69
  524. package/dist/core/runtime/broker/frame-read.js +1 -116
  525. package/dist/core/runtime/broker/frame-replies.js +1 -64
  526. package/dist/core/runtime/broker/frame-session.js +4 -203
  527. package/dist/core/runtime/broker/held-deferred-inbox.js +1 -13
  528. package/dist/core/runtime/broker/inbox.js +13 -163
  529. package/dist/core/runtime/broker/node-named.js +1 -27
  530. package/dist/core/runtime/broker/read-ops.js +1 -171
  531. package/dist/core/runtime/broker/rebind.js +1 -318
  532. package/dist/core/runtime/broker/tool-groups.js +1 -246
  533. package/dist/core/runtime/broker/turn-admission.js +1 -31
  534. package/dist/core/runtime/broker/turn-ignition.js +1 -84
  535. package/dist/core/runtime/broker-cli.js +3 -81
  536. package/dist/core/runtime/broker-extension-render.js +5 -135
  537. package/dist/core/runtime/broker-inventory.js +1 -116
  538. package/dist/core/runtime/broker-persona-guidance.js +4 -154
  539. package/dist/core/runtime/broker-protocol.js +3 -152
  540. package/dist/core/runtime/broker-request.js +1 -85
  541. package/dist/core/runtime/broker-sdk.js +1 -129
  542. package/dist/core/runtime/broker.js +1 -1214
  543. package/dist/core/runtime/canvas-extensions.js +1 -96
  544. package/dist/core/runtime/chat-inventory-rows.js +1 -105
  545. package/dist/core/runtime/close.js +1 -265
  546. package/dist/core/runtime/command-expansion.js +9 -104
  547. package/dist/core/runtime/command-surface.js +1 -117
  548. package/dist/core/runtime/connectivity.js +1 -73
  549. package/dist/core/runtime/deliver-live.js +1 -88
  550. package/dist/core/runtime/fault-recovery.js +1 -83
  551. package/dist/core/runtime/fault.js +1 -17
  552. package/dist/core/runtime/fleet.js +1 -58
  553. package/dist/core/runtime/front-door-env.js +1 -16
  554. package/dist/core/runtime/front-door.js +7 -183
  555. package/dist/core/runtime/headless-pi.js +1 -161
  556. package/dist/core/runtime/host.js +1 -457
  557. package/dist/core/runtime/interactive-deliver.js +1 -51
  558. package/dist/core/runtime/invocation.js +0 -10
  559. package/dist/core/runtime/kickoff.js +30 -327
  560. package/dist/core/runtime/launch-config-worker.js +1 -12
  561. package/dist/core/runtime/launch-prompt.js +4 -13
  562. package/dist/core/runtime/launch-target.js +1 -55
  563. package/dist/core/runtime/launch.js +1 -483
  564. package/dist/core/runtime/lifecycle.js +2 -213
  565. package/dist/core/runtime/managed-provider-cooling.js +1 -62
  566. package/dist/core/runtime/memory.js +1 -17
  567. package/dist/core/runtime/model-registry.js +1 -13
  568. package/dist/core/runtime/model-selection.js +1 -135
  569. package/dist/core/runtime/model-swap.js +1 -86
  570. package/dist/core/runtime/naming.js +14 -298
  571. package/dist/core/runtime/nerd-font.js +2 -127
  572. package/dist/core/runtime/node-read.js +2 -386
  573. package/dist/core/runtime/nodes.js +1 -331
  574. package/dist/core/runtime/outcome-document.js +1 -97
  575. package/dist/core/runtime/package-health.js +4 -99
  576. package/dist/core/runtime/persona.js +2 -55
  577. package/dist/core/runtime/pi-cli.js +1 -65
  578. package/dist/core/runtime/pi-vendored.js +1 -66
  579. package/dist/core/runtime/placement-tmux.js +1 -81
  580. package/dist/core/runtime/placement.js +1 -386
  581. package/dist/core/runtime/promote.js +1 -174
  582. package/dist/core/runtime/prospective-inventory-cli.js +3 -61
  583. package/dist/core/runtime/prospective-inventory.js +2 -88
  584. package/dist/core/runtime/recap.js +27 -103
  585. package/dist/core/runtime/recycle.js +1 -190
  586. package/dist/core/runtime/reopen.js +1 -138
  587. package/dist/core/runtime/reset.js +1 -245
  588. package/dist/core/runtime/resume-root.js +10 -290
  589. package/dist/core/runtime/revive-all.js +1 -107
  590. package/dist/core/runtime/revive.js +4 -544
  591. package/dist/core/runtime/roadmap.js +4 -38
  592. package/dist/core/runtime/session-branch.js +1 -46
  593. package/dist/core/runtime/session-cycles.js +1 -110
  594. package/dist/core/runtime/session-list-cache.js +1 -406
  595. package/dist/core/runtime/session-visibility.js +1 -99
  596. package/dist/core/runtime/shell-expansion.js +9 -100
  597. package/dist/core/runtime/situational-context.js +2 -67
  598. package/dist/core/runtime/situational-live.js +1 -41
  599. package/dist/core/runtime/spawn-env.js +1 -255
  600. package/dist/core/runtime/spawn.js +3 -577
  601. package/dist/core/runtime/stamp/channel.js +1 -76
  602. package/dist/core/runtime/stamp/protocol.js +1 -113
  603. package/dist/core/runtime/stop-guard.js +7 -116
  604. package/dist/core/runtime/stop-signals.js +1 -46
  605. package/dist/core/runtime/stream-watchdog.js +1 -134
  606. package/dist/core/runtime/structured-output.js +4 -156
  607. package/dist/core/runtime/surface-bg.js +1 -85
  608. package/dist/core/runtime/tmux-bindings.js +4 -730
  609. package/dist/core/runtime/tmux-chrome.js +1 -5
  610. package/dist/core/runtime/tmux-driver.js +7 -637
  611. package/dist/core/runtime/tool-group-summary.js +6 -85
  612. package/dist/core/runtime/turn-visibility.js +1 -31
  613. package/dist/core/runtime/view-socket.js +1 -83
  614. package/dist/core/runtime/warm-pool.js +1 -395
  615. package/dist/core/scope.js +1 -254
  616. package/dist/core/scoped-state/db.js +1 -135
  617. package/dist/core/scoped-state/migrate.js +3 -181
  618. package/dist/core/scoped-state/paths.js +1 -27
  619. package/dist/core/scoped-state/profiles.js +1 -62
  620. package/dist/core/scoped-state/providers.js +1 -8
  621. package/dist/core/scoped-state/schema.js +3 -16
  622. package/dist/core/scoped-state/settings.js +1 -82
  623. package/dist/core/secrets.js +2 -55
  624. package/dist/core/self-update.js +1 -71
  625. package/dist/core/session-model/session-state.js +1 -180
  626. package/dist/core/shell-segments.js +4 -169
  627. package/dist/core/spawn.js +1 -26
  628. package/dist/core/stdout-errors.js +1 -14
  629. package/dist/core/subscription-state.js +3 -193
  630. package/dist/core/substrate/frontmatter-validation.js +1 -105
  631. package/dist/core/substrate/gate-explain.js +1 -424
  632. package/dist/core/substrate/gate.js +1 -26
  633. package/dist/core/substrate/index.js +1 -30
  634. package/dist/core/substrate/injected-store.js +1 -249
  635. package/dist/core/substrate/listings.js +1 -115
  636. package/dist/core/substrate/on-read-node.js +1 -36
  637. package/dist/core/substrate/on-read.js +9 -315
  638. package/dist/core/substrate/plan.js +1 -266
  639. package/dist/core/substrate/render-node.js +1 -30
  640. package/dist/core/substrate/render.js +65 -689
  641. package/dist/core/substrate/schema.js +1 -186
  642. package/dist/core/substrate/session-cache.js +1 -83
  643. package/dist/core/substrate/subject-fields.js +1 -35
  644. package/dist/core/substrate/subject.js +1 -47
  645. package/dist/core/substrate/surface-match.js +1 -242
  646. package/dist/core/termrender/code-doc.js +5 -92
  647. package/dist/core/termrender/display.js +2 -56
  648. package/dist/core/termrender/termrender.js +14 -719
  649. package/dist/core/termrender/version.js +1 -1
  650. package/dist/core/timing.js +2 -94
  651. package/dist/core/tui/draw.js +2 -378
  652. package/dist/core/tui/fuzzy.js +1 -38
  653. package/dist/core/tui/markdown.js +3 -407
  654. package/dist/core/tui/page-host.js +1 -74
  655. package/dist/core/tui/panel.js +1 -137
  656. package/dist/core/tui/terminal.js +2 -100
  657. package/dist/core/user-settings.js +1 -454
  658. package/dist/core/wake.js +1 -296
  659. package/dist/core/worktree-close.js +6 -228
  660. package/dist/core/worktree-containment.js +3 -48
  661. package/dist/core/worktree-landing.js +4 -56
  662. package/dist/core/worktree-mutation-async.js +10 -280
  663. package/dist/core/worktree-quarantine.js +1 -54
  664. package/dist/core/worktree-sweep.js +6 -453
  665. package/dist/core/worktree.js +18 -899
  666. package/dist/daemon/api/bridge.js +8 -418
  667. package/dist/daemon/api/handlers/attach.js +1 -65
  668. package/dist/daemon/api/handlers/bash-jobs.js +2 -91
  669. package/dist/daemon/api/handlers/broker-ops.js +1 -447
  670. package/dist/daemon/api/handlers/broker-recovery.js +1 -251
  671. package/dist/daemon/api/handlers/canvas.js +6 -490
  672. package/dist/daemon/api/handlers/chat-inventory.js +1 -25
  673. package/dist/daemon/api/handlers/crons.js +1 -373
  674. package/dist/daemon/api/handlers/daemon.js +1 -76
  675. package/dist/daemon/api/handlers/feedback-comments.js +3 -199
  676. package/dist/daemon/api/handlers/files.js +1 -63
  677. package/dist/daemon/api/handlers/focus.js +1 -92
  678. package/dist/daemon/api/handlers/health.js +1 -76
  679. package/dist/daemon/api/handlers/human-requests.js +1 -379
  680. package/dist/daemon/api/handlers/human.js +1 -3
  681. package/dist/daemon/api/handlers/inbox-page.js +1 -89
  682. package/dist/daemon/api/handlers/inbox.js +1 -301
  683. package/dist/daemon/api/handlers/memory.js +1 -50
  684. package/dist/daemon/api/handlers/messages.js +2 -506
  685. package/dist/daemon/api/handlers/model-config.js +1 -44
  686. package/dist/daemon/api/handlers/modelauth.js +1 -165
  687. package/dist/daemon/api/handlers/node-outcomes.js +1 -181
  688. package/dist/daemon/api/handlers/nodes.js +1 -939
  689. package/dist/daemon/api/handlers/profiles.js +1 -140
  690. package/dist/daemon/api/handlers/prospective-chat-inventory.js +1 -59
  691. package/dist/daemon/api/handlers/reports.js +16 -332
  692. package/dist/daemon/api/handlers/review-comments.js +1 -465
  693. package/dist/daemon/api/handlers/reviews.js +1 -200
  694. package/dist/daemon/api/handlers/subscriptions.js +1 -53
  695. package/dist/daemon/api/handlers/validate.js +1 -58
  696. package/dist/daemon/api/handlers/worktree.js +1 -39
  697. package/dist/daemon/api/map.js +2 -735
  698. package/dist/daemon/api/router.js +1 -190
  699. package/dist/daemon/api/server.js +11 -408
  700. package/dist/daemon/boot-migrations.js +1 -31
  701. package/dist/daemon/companion-retire.js +1 -34
  702. package/dist/daemon/control.js +1 -22
  703. package/dist/daemon/cron/armed-context.js +1 -100
  704. package/dist/daemon/cron/capture.js +2 -45
  705. package/dist/daemon/cron/disposition.js +1 -55
  706. package/dist/daemon/cron/escalation.js +3 -124
  707. package/dist/daemon/cron/held.js +1 -20
  708. package/dist/daemon/cron/lease-recovery.js +1 -119
  709. package/dist/daemon/cron/live-runs.js +1 -23
  710. package/dist/daemon/cron/passes.js +1 -58
  711. package/dist/daemon/cron/settle.js +1 -61
  712. package/dist/daemon/cron/sinks.js +2 -59
  713. package/dist/daemon/cron-run.js +1 -405
  714. package/dist/daemon/crtrd-cli.js +1 -23
  715. package/dist/daemon/crtrd.js +8 -854
  716. package/dist/daemon/delivery/run-delivery.js +1 -164
  717. package/dist/daemon/fleet.js +17 -475
  718. package/dist/daemon/human/finish.js +10 -179
  719. package/dist/daemon/human/settle.js +1 -89
  720. package/dist/daemon/human/sweep.js +1 -66
  721. package/dist/daemon/manage.js +2 -595
  722. package/dist/daemon/messaging/node-message.js +1 -99
  723. package/dist/daemon/park-activity.js +1 -30
  724. package/dist/daemon/park-pending.js +1 -52
  725. package/dist/daemon/pidfile.js +1 -37
  726. package/dist/daemon/profile-delete.js +1 -306
  727. package/dist/daemon/reconcilers/bash-deadline.js +1 -80
  728. package/dist/daemon/reconcilers/broker-supervision.js +4 -761
  729. package/dist/daemon/reconcilers/controller-death.js +1 -14
  730. package/dist/daemon/reconcilers/cron-lane.js +1 -29
  731. package/dist/daemon/reconcilers/delivery-lane.js +1 -130
  732. package/dist/daemon/reconcilers/live-obligation.js +1 -87
  733. package/dist/daemon/reconcilers/managed-worktree-sweep.js +1 -202
  734. package/dist/daemon/reconcilers/node-deadline.js +1 -82
  735. package/dist/daemon/reconcilers/node-lifecycle/freeze-lane.js +1 -172
  736. package/dist/daemon/reconcilers/node-lifecycle/respawn-policy.js +1 -59
  737. package/dist/daemon/reconcilers/node-lifecycle/terminating.js +1 -12
  738. package/dist/daemon/reconcilers/node-lifecycle/tick.js +1 -146
  739. package/dist/daemon/reconcilers/node-lifecycle/wants-execution.js +1 -11
  740. package/dist/daemon/reconcilers/pending-review-submit.js +1 -36
  741. package/dist/daemon/reconcilers/storage-maintenance.js +1 -207
  742. package/dist/daemon/review/comment-notify.js +2 -109
  743. package/dist/daemon/review/companion.js +1 -29
  744. package/dist/daemon/review/deliver.js +3 -8
  745. package/dist/daemon/review/finish.js +1 -122
  746. package/dist/daemon/review/sweep.js +1 -18
  747. package/dist/daemon/startup-policy.js +1 -1
  748. package/dist/daemon/supervise-cadence.js +1 -6
  749. package/dist/hook-authoring.js +5 -447
  750. package/dist/hook-process.js +1 -34
  751. package/dist/index.js +1 -52
  752. package/dist/migrations/001-surfaces-frontmatter.js +1 -161
  753. package/dist/migrations/002-profile-project-memory.js +1 -72
  754. package/dist/migrations/003-repository-root-memory-identity/front-door.js +11 -231
  755. package/dist/migrations/003-repository-root-memory-identity/index.js +5 -513
  756. package/dist/migrations/003-repository-root-memory-identity/references.js +5 -469
  757. package/dist/migrations/003-repository-root-memory-identity/repository-facts.js +3 -349
  758. package/dist/migrations/activation.js +2 -89
  759. package/dist/migrations/convergent.js +2 -82
  760. package/dist/migrations/corpus.js +3 -483
  761. package/dist/migrations/frontmatter-splice.js +8 -176
  762. package/dist/migrations/profile-manifests.js +2 -70
  763. package/dist/migrations/registry.js +1 -42
  764. package/dist/migrations/runner.js +1 -85
  765. package/dist/migrations/types.js +0 -24
  766. package/dist/pi-extensions/broker-local.js +2 -106
  767. package/dist/pi-extensions/canvas-bash-valve.js +7 -461
  768. package/dist/pi-extensions/canvas-context-intro.js +2 -113
  769. package/dist/pi-extensions/canvas-doc-substrate.js +9 -178
  770. package/dist/pi-extensions/canvas-goal-capture.js +1 -83
  771. package/dist/pi-extensions/canvas-inbox-watcher.js +1 -1010
  772. package/dist/pi-extensions/canvas-passive-context.js +14 -203
  773. package/dist/pi-extensions/canvas-preview-result.js +2 -72
  774. package/dist/pi-extensions/canvas-prompt-scrub.js +2 -54
  775. package/dist/pi-extensions/canvas-recap.js +11 -405
  776. package/dist/pi-extensions/canvas-review-boundary.js +3 -63
  777. package/dist/pi-extensions/canvas-stamp.js +2 -77
  778. package/dist/pi-extensions/canvas-stophook.js +1 -643
  779. package/dist/pi-extensions/canvas-structured-output.js +13 -35
  780. package/dist/pi-extensions/canvas-tool-guide.js +9 -78
  781. package/dist/pi-extensions/envelope-merge.js +8 -29
  782. package/dist/prompts/review.js +20 -42
  783. package/dist/shared/birth-announcement.js +1 -25
  784. package/dist/shared/crtr-version.js +1 -18
  785. package/dist/shared/env.js +1 -214
  786. package/dist/shared/generated-context.js +11 -226
  787. package/dist/shared/predicates.js +1 -4
  788. package/dist/shared/shell-quote.js +1 -5
  789. package/dist/shared/tool-groups.js +1 -64
  790. package/dist/shared/working-activity.js +1 -27
  791. package/dist/suppress-experimental-warnings.js +1 -15
  792. package/dist/types.js +1 -185
  793. package/docs/public-api.md +10 -9
  794. package/package.json +6 -4
  795. package/runtime.lock.json +5 -5
  796. package/scripts/pack-minify.mjs +108 -0
  797. package/dist/api/__tests__/integration/client.test.d.ts +0 -1
  798. package/dist/api/__tests__/integration/client.test.js +0 -163
  799. package/dist/builtin-pi-packages/pi-crtr-extensions/__tests__/insights-active-init.test.ts +0 -98
  800. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/crtr-commands.test.ts +0 -93
  801. package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/__tests__/integration/provider-rotation.test.ts +0 -2530
  802. package/dist/clients/__tests__/helpers/human-daemon.d.ts +0 -11
  803. package/dist/clients/__tests__/helpers/human-daemon.js +0 -60
  804. package/dist/clients/attach/__tests__/attach-remote-readonly.test.d.ts +0 -1
  805. package/dist/clients/attach/__tests__/attach-remote-readonly.test.js +0 -97
  806. package/dist/clients/attach/__tests__/bash-call-width.test.d.ts +0 -1
  807. package/dist/clients/attach/__tests__/bash-call-width.test.js +0 -38
  808. package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.d.ts +0 -1
  809. package/dist/clients/attach/__tests__/chat-view-snapshot-ordering.test.js +0 -175
  810. package/dist/clients/attach/__tests__/completion-frecency.test.d.ts +0 -1
  811. package/dist/clients/attach/__tests__/completion-frecency.test.js +0 -35
  812. package/dist/clients/attach/__tests__/context-message.test.d.ts +0 -1
  813. package/dist/clients/attach/__tests__/context-message.test.js +0 -130
  814. package/dist/clients/attach/__tests__/crtr-output.test.d.ts +0 -1
  815. package/dist/clients/attach/__tests__/crtr-output.test.js +0 -68
  816. package/dist/clients/attach/__tests__/diagram.test.d.ts +0 -1
  817. package/dist/clients/attach/__tests__/diagram.test.js +0 -42
  818. package/dist/clients/attach/__tests__/edit-diff.test.d.ts +0 -1
  819. package/dist/clients/attach/__tests__/edit-diff.test.js +0 -31
  820. package/dist/clients/attach/__tests__/frame-selection.test.d.ts +0 -1
  821. package/dist/clients/attach/__tests__/frame-selection.test.js +0 -84
  822. package/dist/clients/attach/__tests__/group-activity.test.d.ts +0 -1
  823. package/dist/clients/attach/__tests__/group-activity.test.js +0 -165
  824. package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.d.ts +0 -1
  825. package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.js +0 -83
  826. package/dist/clients/attach/__tests__/pane-tag-successor.test.d.ts +0 -1
  827. package/dist/clients/attach/__tests__/pane-tag-successor.test.js +0 -56
  828. package/dist/clients/attach/__tests__/profile-files.test.d.ts +0 -1
  829. package/dist/clients/attach/__tests__/profile-files.test.js +0 -21
  830. package/dist/clients/attach/__tests__/prompt-preview.test.d.ts +0 -1
  831. package/dist/clients/attach/__tests__/prompt-preview.test.js +0 -21
  832. package/dist/clients/attach/__tests__/ref-autocomplete.test.d.ts +0 -1
  833. package/dist/clients/attach/__tests__/ref-autocomplete.test.js +0 -64
  834. package/dist/clients/attach/__tests__/titled-editor-paste.test.d.ts +0 -1
  835. package/dist/clients/attach/__tests__/titled-editor-paste.test.js +0 -114
  836. package/dist/clients/attach/__tests__/titled-editor-preview.test.d.ts +0 -1
  837. package/dist/clients/attach/__tests__/titled-editor-preview.test.js +0 -83
  838. package/dist/clients/inbox/__tests__/integration/inbox-controller.test.d.ts +0 -1
  839. package/dist/clients/inbox/__tests__/integration/inbox-controller.test.js +0 -81
  840. package/dist/clients/inbox/__tests__/integration/mount-panel.test.d.ts +0 -1
  841. package/dist/clients/inbox/__tests__/integration/mount-panel.test.js +0 -135
  842. package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.d.ts +0 -1
  843. package/dist/clients/inbox/__tests__/integration/stale-row-activation.test.js +0 -66
  844. package/dist/clients/inbox/review/__tests__/editor-roundtrip.test.d.ts +0 -1
  845. package/dist/clients/inbox/review/__tests__/editor-roundtrip.test.js +0 -35
  846. package/dist/clients/inbox/review/__tests__/review-core.test.d.ts +0 -1
  847. package/dist/clients/inbox/review/__tests__/review-core.test.js +0 -52
  848. package/dist/clients/inbox/review/__tests__/teardown-notice.test.d.ts +0 -1
  849. package/dist/clients/inbox/review/__tests__/teardown-notice.test.js +0 -100
  850. package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.d.ts +0 -1
  851. package/dist/commands/__tests__/api-client-cold-start-diagnostic.test.js +0 -69
  852. package/dist/commands/__tests__/human.test.d.ts +0 -1
  853. package/dist/commands/__tests__/human.test.js +0 -172
  854. package/dist/commands/__tests__/integration/dashboard-snapshot.test.d.ts +0 -1
  855. package/dist/commands/__tests__/integration/dashboard-snapshot.test.js +0 -237
  856. package/dist/commands/__tests__/integration/migrate.test.d.ts +0 -1
  857. package/dist/commands/__tests__/integration/migrate.test.js +0 -1330
  858. package/dist/commands/__tests__/node-message.test.d.ts +0 -1
  859. package/dist/commands/__tests__/node-message.test.js +0 -112
  860. package/dist/commands/__tests__/node-new.test.d.ts +0 -1
  861. package/dist/commands/__tests__/node-new.test.js +0 -58
  862. package/dist/commands/__tests__/revive-now-gate.test.d.ts +0 -1
  863. package/dist/commands/__tests__/revive-now-gate.test.js +0 -62
  864. package/dist/commands/__tests__/seam/daemon-status.test.d.ts +0 -1
  865. package/dist/commands/__tests__/seam/daemon-status.test.js +0 -29
  866. package/dist/commands/__tests__/surface-reload-target.test.d.ts +0 -1
  867. package/dist/commands/__tests__/surface-reload-target.test.js +0 -21
  868. package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.d.ts +0 -1
  869. package/dist/commands/memory/__tests__/command-selector-and-mutation-guards.test.js +0 -379
  870. package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.d.ts +0 -1
  871. package/dist/commands/memory/__tests__/memory-list-and-lint-ignore.test.js +0 -124
  872. package/dist/commands/memory/__tests__/repository-root-lint.test.d.ts +0 -1
  873. package/dist/commands/memory/__tests__/repository-root-lint.test.js +0 -148
  874. package/dist/commands/sys/__tests__/config-model-ladders.test.d.ts +0 -1
  875. package/dist/commands/sys/__tests__/config-model-ladders.test.js +0 -114
  876. package/dist/commands/sys/__tests__/setup-core.test.d.ts +0 -1
  877. package/dist/commands/sys/__tests__/setup-core.test.js +0 -45
  878. package/dist/commands/sys/__tests__/sync-project-guidance.test.d.ts +0 -1
  879. package/dist/commands/sys/__tests__/sync-project-guidance.test.js +0 -244
  880. package/dist/core/__tests__/bash-guard.test.d.ts +0 -1
  881. package/dist/core/__tests__/bash-guard.test.js +0 -190
  882. package/dist/core/__tests__/boot-fault-attempt.test.d.ts +0 -1
  883. package/dist/core/__tests__/boot-fault-attempt.test.js +0 -105
  884. package/dist/core/__tests__/boot.test.d.ts +0 -1
  885. package/dist/core/__tests__/boot.test.js +0 -274
  886. package/dist/core/__tests__/branded-host-concurrency.test.d.ts +0 -1
  887. package/dist/core/__tests__/branded-host-concurrency.test.js +0 -72
  888. package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.d.ts +0 -1
  889. package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.js +0 -75
  890. package/dist/core/__tests__/broker-launch-candidates.test.d.ts +0 -1
  891. package/dist/core/__tests__/broker-launch-candidates.test.js +0 -311
  892. package/dist/core/__tests__/broker-preflight.test.d.ts +0 -1
  893. package/dist/core/__tests__/broker-preflight.test.js +0 -95
  894. package/dist/core/__tests__/broker-stream-watchdog-floor.test.d.ts +0 -1
  895. package/dist/core/__tests__/broker-stream-watchdog-floor.test.js +0 -82
  896. package/dist/core/__tests__/broker-turn-admission.test.d.ts +0 -1
  897. package/dist/core/__tests__/broker-turn-admission.test.js +0 -44
  898. package/dist/core/__tests__/canvas-db-boundary.test.d.ts +0 -1
  899. package/dist/core/__tests__/canvas-db-boundary.test.js +0 -46
  900. package/dist/core/__tests__/canvas-inbox-watcher-hold.test.d.ts +0 -1
  901. package/dist/core/__tests__/canvas-inbox-watcher-hold.test.js +0 -710
  902. package/dist/core/__tests__/canvas-inbox-watcher-naming.test.d.ts +0 -1
  903. package/dist/core/__tests__/canvas-inbox-watcher-naming.test.js +0 -310
  904. package/dist/core/__tests__/canvas-inbox-watcher.test.d.ts +0 -1
  905. package/dist/core/__tests__/canvas-inbox-watcher.test.js +0 -397
  906. package/dist/core/__tests__/canvas.test.d.ts +0 -1
  907. package/dist/core/__tests__/canvas.test.js +0 -138
  908. package/dist/core/__tests__/child-death-wake.test.d.ts +0 -1
  909. package/dist/core/__tests__/child-death-wake.test.js +0 -153
  910. package/dist/core/__tests__/cli-help-contract.test.d.ts +0 -1
  911. package/dist/core/__tests__/cli-help-contract.test.js +0 -152
  912. package/dist/core/__tests__/close.test.d.ts +0 -1
  913. package/dist/core/__tests__/close.test.js +0 -284
  914. package/dist/core/__tests__/collectible.test.d.ts +0 -1
  915. package/dist/core/__tests__/collectible.test.js +0 -89
  916. package/dist/core/__tests__/config-change-delta.test.d.ts +0 -1
  917. package/dist/core/__tests__/config-change-delta.test.js +0 -108
  918. package/dist/core/__tests__/context-intro.test.d.ts +0 -1
  919. package/dist/core/__tests__/context-intro.test.js +0 -123
  920. package/dist/core/__tests__/cron-armed-context-failure.test.d.ts +0 -1
  921. package/dist/core/__tests__/cron-armed-context-failure.test.js +0 -150
  922. package/dist/core/__tests__/cron-held-settlement.test.d.ts +0 -1
  923. package/dist/core/__tests__/cron-held-settlement.test.js +0 -240
  924. package/dist/core/__tests__/cron-node-sink-parked-root.test.d.ts +0 -1
  925. package/dist/core/__tests__/cron-node-sink-parked-root.test.js +0 -166
  926. package/dist/core/__tests__/cron-self-cancel-delivery.test.d.ts +0 -1
  927. package/dist/core/__tests__/cron-self-cancel-delivery.test.js +0 -84
  928. package/dist/core/__tests__/cron-timeout-descendants.test.d.ts +0 -1
  929. package/dist/core/__tests__/cron-timeout-descendants.test.js +0 -114
  930. package/dist/core/__tests__/daemon-boot.test.d.ts +0 -1
  931. package/dist/core/__tests__/daemon-boot.test.js +0 -422
  932. package/dist/core/__tests__/daemon-wedge.test.d.ts +0 -1
  933. package/dist/core/__tests__/daemon-wedge.test.js +0 -106
  934. package/dist/core/__tests__/dead-node-policy-table.test.d.ts +0 -1
  935. package/dist/core/__tests__/dead-node-policy-table.test.js +0 -77
  936. package/dist/core/__tests__/events-contract.test.d.ts +0 -1
  937. package/dist/core/__tests__/events-contract.test.js +0 -76
  938. package/dist/core/__tests__/extension-abort.test.d.ts +0 -1
  939. package/dist/core/__tests__/extension-abort.test.js +0 -21
  940. package/dist/core/__tests__/fault-classifier.test.d.ts +0 -1
  941. package/dist/core/__tests__/fault-classifier.test.js +0 -138
  942. package/dist/core/__tests__/fixtures/api-server-host.d.ts +0 -1
  943. package/dist/core/__tests__/fixtures/api-server-host.js +0 -47
  944. package/dist/core/__tests__/fixtures/c3-custom-provider-ext.d.ts +0 -2
  945. package/dist/core/__tests__/fixtures/c3-custom-provider-ext.js +0 -34
  946. package/dist/core/__tests__/fixtures/c5-command-boundary-ext.d.ts +0 -2
  947. package/dist/core/__tests__/fixtures/c5-command-boundary-ext.js +0 -32
  948. package/dist/core/__tests__/fixtures/fake-engine.d.ts +0 -347
  949. package/dist/core/__tests__/fixtures/fake-engine.js +0 -1509
  950. package/dist/core/__tests__/fixtures/fake-pi-host.d.ts +0 -2
  951. package/dist/core/__tests__/fixtures/fake-pi-host.js +0 -311
  952. package/dist/core/__tests__/fixtures/memory-slash-live-probe.d.ts +0 -1
  953. package/dist/core/__tests__/fixtures/memory-slash-live-probe.js +0 -75
  954. package/dist/core/__tests__/fixtures/metadata-migration-race.d.ts +0 -1
  955. package/dist/core/__tests__/fixtures/metadata-migration-race.js +0 -49
  956. package/dist/core/__tests__/focuses.test.d.ts +0 -1
  957. package/dist/core/__tests__/focuses.test.js +0 -113
  958. package/dist/core/__tests__/fs-utils.test.d.ts +0 -1
  959. package/dist/core/__tests__/fs-utils.test.js +0 -50
  960. package/dist/core/__tests__/helpers/broker-clients.d.ts +0 -43
  961. package/dist/core/__tests__/helpers/broker-clients.js +0 -174
  962. package/dist/core/__tests__/helpers/fleet.d.ts +0 -12
  963. package/dist/core/__tests__/helpers/fleet.js +0 -50
  964. package/dist/core/__tests__/helpers/harness.d.ts +0 -124
  965. package/dist/core/__tests__/helpers/harness.js +0 -806
  966. package/dist/core/__tests__/helpers/viewer-panes.d.ts +0 -12
  967. package/dist/core/__tests__/helpers/viewer-panes.js +0 -133
  968. package/dist/core/__tests__/history-inbox.test.d.ts +0 -1
  969. package/dist/core/__tests__/history-inbox.test.js +0 -121
  970. package/dist/core/__tests__/human-action-delivery.test.d.ts +0 -1
  971. package/dist/core/__tests__/human-action-delivery.test.js +0 -162
  972. package/dist/core/__tests__/human-actions.test.d.ts +0 -1
  973. package/dist/core/__tests__/human-actions.test.js +0 -120
  974. package/dist/core/__tests__/inline-memory-refs.test.d.ts +0 -1
  975. package/dist/core/__tests__/inline-memory-refs.test.js +0 -225
  976. package/dist/core/__tests__/integration/broker-fork-seam.test.d.ts +0 -1
  977. package/dist/core/__tests__/integration/broker-fork-seam.test.js +0 -193
  978. package/dist/core/__tests__/integration/broker-sdk-wiring.test.d.ts +0 -1
  979. package/dist/core/__tests__/integration/broker-sdk-wiring.test.js +0 -750
  980. package/dist/core/__tests__/integration/broker-snapshot-history.test.d.ts +0 -1
  981. package/dist/core/__tests__/integration/broker-snapshot-history.test.js +0 -288
  982. package/dist/core/__tests__/integration/broker-wedge-supervision.test.d.ts +0 -1
  983. package/dist/core/__tests__/integration/broker-wedge-supervision.test.js +0 -103
  984. package/dist/core/__tests__/integration/command-plugins.test.d.ts +0 -1
  985. package/dist/core/__tests__/integration/command-plugins.test.js +0 -1200
  986. package/dist/core/__tests__/integration/deferred-no-wake.test.d.ts +0 -1
  987. package/dist/core/__tests__/integration/deferred-no-wake.test.js +0 -610
  988. package/dist/core/__tests__/integration/flagship-lifecycle.test.d.ts +0 -1
  989. package/dist/core/__tests__/integration/flagship-lifecycle.test.js +0 -264
  990. package/dist/core/__tests__/integration/fresh-home-commands.test.d.ts +0 -1
  991. package/dist/core/__tests__/integration/fresh-home-commands.test.js +0 -49
  992. package/dist/core/__tests__/integration/git-optional-locks.test.d.ts +0 -1
  993. package/dist/core/__tests__/integration/git-optional-locks.test.js +0 -81
  994. package/dist/core/__tests__/integration/host-teardown-process-group.test.d.ts +0 -1
  995. package/dist/core/__tests__/integration/host-teardown-process-group.test.js +0 -480
  996. package/dist/core/__tests__/integration/lifecycle-hooks.test.d.ts +0 -1
  997. package/dist/core/__tests__/integration/lifecycle-hooks.test.js +0 -498
  998. package/dist/core/__tests__/integration/live-mutation-verbs.test.d.ts +0 -1
  999. package/dist/core/__tests__/integration/live-mutation-verbs.test.js +0 -180
  1000. package/dist/core/__tests__/integration/live-mutation.test.d.ts +0 -1
  1001. package/dist/core/__tests__/integration/live-mutation.test.js +0 -173
  1002. package/dist/core/__tests__/integration/plugin-revalidate.test.d.ts +0 -1
  1003. package/dist/core/__tests__/integration/plugin-revalidate.test.js +0 -359
  1004. package/dist/core/__tests__/integration/profile-pause.test.d.ts +0 -1
  1005. package/dist/core/__tests__/integration/profile-pause.test.js +0 -115
  1006. package/dist/core/__tests__/integration/refresh-stall-recycle.test.d.ts +0 -1
  1007. package/dist/core/__tests__/integration/refresh-stall-recycle.test.js +0 -151
  1008. package/dist/core/__tests__/integration/revive.test.d.ts +0 -1
  1009. package/dist/core/__tests__/integration/revive.test.js +0 -615
  1010. package/dist/core/__tests__/integration/spawn-root.test.d.ts +0 -1
  1011. package/dist/core/__tests__/integration/spawn-root.test.js +0 -536
  1012. package/dist/core/__tests__/integration/subscription-delivery.test.d.ts +0 -1
  1013. package/dist/core/__tests__/integration/subscription-delivery.test.js +0 -132
  1014. package/dist/core/__tests__/integration/tmux-surface.test.d.ts +0 -1
  1015. package/dist/core/__tests__/integration/tmux-surface.test.js +0 -330
  1016. package/dist/core/__tests__/integration/worktree-land.test.d.ts +0 -1
  1017. package/dist/core/__tests__/integration/worktree-land.test.js +0 -607
  1018. package/dist/core/__tests__/integration/worktree-reap.test.d.ts +0 -1
  1019. package/dist/core/__tests__/integration/worktree-reap.test.js +0 -842
  1020. package/dist/core/__tests__/kickoff.test.d.ts +0 -1
  1021. package/dist/core/__tests__/kickoff.test.js +0 -196
  1022. package/dist/core/__tests__/lifecycle-terminal-reasons.test.d.ts +0 -1
  1023. package/dist/core/__tests__/lifecycle-terminal-reasons.test.js +0 -62
  1024. package/dist/core/__tests__/lifecycle.test.d.ts +0 -1
  1025. package/dist/core/__tests__/lifecycle.test.js +0 -176
  1026. package/dist/core/__tests__/live-lifecycle-prompt.test.d.ts +0 -1
  1027. package/dist/core/__tests__/live-lifecycle-prompt.test.js +0 -63
  1028. package/dist/core/__tests__/memory-resolver-precedence.test.d.ts +0 -1
  1029. package/dist/core/__tests__/memory-resolver-precedence.test.js +0 -228
  1030. package/dist/core/__tests__/migration.test.d.ts +0 -1
  1031. package/dist/core/__tests__/migration.test.js +0 -946
  1032. package/dist/core/__tests__/model-pin-durability.test.d.ts +0 -1
  1033. package/dist/core/__tests__/model-pin-durability.test.js +0 -195
  1034. package/dist/core/__tests__/model-routes-config.test.d.ts +0 -1
  1035. package/dist/core/__tests__/model-routes-config.test.js +0 -150
  1036. package/dist/core/__tests__/nested-store-discovery.test.d.ts +0 -1
  1037. package/dist/core/__tests__/nested-store-discovery.test.js +0 -89
  1038. package/dist/core/__tests__/node-outcome.test.d.ts +0 -1
  1039. package/dist/core/__tests__/node-outcome.test.js +0 -246
  1040. package/dist/core/__tests__/on-read-crouter-home-fence.test.d.ts +0 -1
  1041. package/dist/core/__tests__/on-read-crouter-home-fence.test.js +0 -66
  1042. package/dist/core/__tests__/on-read-dedup-resume.test.d.ts +0 -1
  1043. package/dist/core/__tests__/on-read-dedup-resume.test.js +0 -132
  1044. package/dist/core/__tests__/on-read-nested-store.test.d.ts +0 -1
  1045. package/dist/core/__tests__/on-read-nested-store.test.js +0 -135
  1046. package/dist/core/__tests__/parse-argv-stdin-secret.test.d.ts +0 -1
  1047. package/dist/core/__tests__/parse-argv-stdin-secret.test.js +0 -68
  1048. package/dist/core/__tests__/passive-subscription.test.d.ts +0 -1
  1049. package/dist/core/__tests__/passive-subscription.test.js +0 -120
  1050. package/dist/core/__tests__/pid-identity-match.test.d.ts +0 -1
  1051. package/dist/core/__tests__/pid-identity-match.test.js +0 -145
  1052. package/dist/core/__tests__/pid-zombie.test.d.ts +0 -1
  1053. package/dist/core/__tests__/pid-zombie.test.js +0 -42
  1054. package/dist/core/__tests__/plugin-kinds.test.d.ts +0 -1
  1055. package/dist/core/__tests__/plugin-kinds.test.js +0 -182
  1056. package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.d.ts +0 -1
  1057. package/dist/core/__tests__/plugin-link-symlinked-scope-root.test.js +0 -43
  1058. package/dist/core/__tests__/plugin-page-components.test.d.ts +0 -1
  1059. package/dist/core/__tests__/plugin-page-components.test.js +0 -159
  1060. package/dist/core/__tests__/preview-mirror-cap.test.d.ts +0 -1
  1061. package/dist/core/__tests__/preview-mirror-cap.test.js +0 -53
  1062. package/dist/core/__tests__/preview-registry-sync.test.d.ts +0 -1
  1063. package/dist/core/__tests__/preview-registry-sync.test.js +0 -107
  1064. package/dist/core/__tests__/profile-project-memory-delivery.test.d.ts +0 -1
  1065. package/dist/core/__tests__/profile-project-memory-delivery.test.js +0 -644
  1066. package/dist/core/__tests__/prospective-inventory-capability-parity.test.d.ts +0 -1
  1067. package/dist/core/__tests__/prospective-inventory-capability-parity.test.js +0 -91
  1068. package/dist/core/__tests__/prune.test.d.ts +0 -1
  1069. package/dist/core/__tests__/prune.test.js +0 -243
  1070. package/dist/core/__tests__/push-final-guard.test.d.ts +0 -1
  1071. package/dist/core/__tests__/push-final-guard.test.js +0 -191
  1072. package/dist/core/__tests__/relaunch-root.test.d.ts +0 -1
  1073. package/dist/core/__tests__/relaunch-root.test.js +0 -249
  1074. package/dist/core/__tests__/remote-canvas-target.test.d.ts +0 -1
  1075. package/dist/core/__tests__/remote-canvas-target.test.js +0 -93
  1076. package/dist/core/__tests__/repository-association.test.d.ts +0 -1
  1077. package/dist/core/__tests__/repository-association.test.js +0 -153
  1078. package/dist/core/__tests__/repository-root-identity.test.d.ts +0 -1
  1079. package/dist/core/__tests__/repository-root-identity.test.js +0 -223
  1080. package/dist/core/__tests__/respawn-throttle.test.d.ts +0 -1
  1081. package/dist/core/__tests__/respawn-throttle.test.js +0 -20
  1082. package/dist/core/__tests__/review-model-floor.test.d.ts +0 -1
  1083. package/dist/core/__tests__/review-model-floor.test.js +0 -83
  1084. package/dist/core/__tests__/revive-all.test.d.ts +0 -1
  1085. package/dist/core/__tests__/revive-all.test.js +0 -157
  1086. package/dist/core/__tests__/revive-capacity.test.d.ts +0 -1
  1087. package/dist/core/__tests__/revive-capacity.test.js +0 -184
  1088. package/dist/core/__tests__/revive-parked-fresh.test.d.ts +0 -1
  1089. package/dist/core/__tests__/revive-parked-fresh.test.js +0 -176
  1090. package/dist/core/__tests__/scope-crouter-home-fence.test.d.ts +0 -1
  1091. package/dist/core/__tests__/scope-crouter-home-fence.test.js +0 -55
  1092. package/dist/core/__tests__/seam/broker-attach-multiclient.test.d.ts +0 -1
  1093. package/dist/core/__tests__/seam/broker-attach-multiclient.test.js +0 -262
  1094. package/dist/core/__tests__/seam/broker-attach-stream.test.d.ts +0 -1
  1095. package/dist/core/__tests__/seam/broker-attach-stream.test.js +0 -176
  1096. package/dist/core/__tests__/seam/broker-cap-freeze.test.d.ts +0 -1
  1097. package/dist/core/__tests__/seam/broker-cap-freeze.test.js +0 -155
  1098. package/dist/core/__tests__/seam/broker-crash-teardown.test.d.ts +0 -1
  1099. package/dist/core/__tests__/seam/broker-crash-teardown.test.js +0 -131
  1100. package/dist/core/__tests__/seam/broker-pane-resolution.test.d.ts +0 -1
  1101. package/dist/core/__tests__/seam/broker-pane-resolution.test.js +0 -204
  1102. package/dist/core/__tests__/seam/broker-provider-retry.test.d.ts +0 -1
  1103. package/dist/core/__tests__/seam/broker-provider-retry.test.js +0 -686
  1104. package/dist/core/__tests__/seam/broker-startup-diagnostics.test.d.ts +0 -1
  1105. package/dist/core/__tests__/seam/broker-startup-diagnostics.test.js +0 -82
  1106. package/dist/core/__tests__/seam/broker-whip-interrupt.test.d.ts +0 -1
  1107. package/dist/core/__tests__/seam/broker-whip-interrupt.test.js +0 -50
  1108. package/dist/core/__tests__/seam/deadline-wake-delivery.test.d.ts +0 -1
  1109. package/dist/core/__tests__/seam/deadline-wake-delivery.test.js +0 -138
  1110. package/dist/core/__tests__/seam/dormancy-release.test.d.ts +0 -1
  1111. package/dist/core/__tests__/seam/dormancy-release.test.js +0 -516
  1112. package/dist/core/__tests__/seam/held-deferred-human-prompt.test.d.ts +0 -1
  1113. package/dist/core/__tests__/seam/held-deferred-human-prompt.test.js +0 -65
  1114. package/dist/core/__tests__/seam/inbox-reference-guidance.test.d.ts +0 -1
  1115. package/dist/core/__tests__/seam/inbox-reference-guidance.test.js +0 -84
  1116. package/dist/core/__tests__/seam/memory-slash-node-relative-inventory.test.d.ts +0 -1
  1117. package/dist/core/__tests__/seam/memory-slash-node-relative-inventory.test.js +0 -160
  1118. package/dist/core/__tests__/seam/node-outcome-delivery.test.d.ts +0 -1
  1119. package/dist/core/__tests__/seam/node-outcome-delivery.test.js +0 -177
  1120. package/dist/core/__tests__/seam/prospective-inventory-stdout.test.d.ts +0 -1
  1121. package/dist/core/__tests__/seam/prospective-inventory-stdout.test.js +0 -31
  1122. package/dist/core/__tests__/seam/reopen-invalidated-worktree.test.d.ts +0 -1
  1123. package/dist/core/__tests__/seam/reopen-invalidated-worktree.test.js +0 -60
  1124. package/dist/core/__tests__/seam/self-close-teardown.test.d.ts +0 -1
  1125. package/dist/core/__tests__/seam/self-close-teardown.test.js +0 -49
  1126. package/dist/core/__tests__/seam/yield-refresh-transaction.test.d.ts +0 -1
  1127. package/dist/core/__tests__/seam/yield-refresh-transaction.test.js +0 -100
  1128. package/dist/core/__tests__/secrets.test.d.ts +0 -1
  1129. package/dist/core/__tests__/secrets.test.js +0 -49
  1130. package/dist/core/__tests__/self-update.test.d.ts +0 -1
  1131. package/dist/core/__tests__/self-update.test.js +0 -46
  1132. package/dist/core/__tests__/session-branch.test.d.ts +0 -1
  1133. package/dist/core/__tests__/session-branch.test.js +0 -61
  1134. package/dist/core/__tests__/session-cycles.test.d.ts +0 -1
  1135. package/dist/core/__tests__/session-cycles.test.js +0 -133
  1136. package/dist/core/__tests__/session-model.test.d.ts +0 -1
  1137. package/dist/core/__tests__/session-model.test.js +0 -111
  1138. package/dist/core/__tests__/spawn-worktree-id-conflict.test.d.ts +0 -1
  1139. package/dist/core/__tests__/spawn-worktree-id-conflict.test.js +0 -71
  1140. package/dist/core/__tests__/stdin-body-no-discard.test.d.ts +0 -1
  1141. package/dist/core/__tests__/stdin-body-no-discard.test.js +0 -33
  1142. package/dist/core/__tests__/stdout-errors.test.d.ts +0 -1
  1143. package/dist/core/__tests__/stdout-errors.test.js +0 -16
  1144. package/dist/core/__tests__/stop-guard.test.d.ts +0 -1
  1145. package/dist/core/__tests__/stop-guard.test.js +0 -237
  1146. package/dist/core/__tests__/stream-watchdog.test.d.ts +0 -1
  1147. package/dist/core/__tests__/stream-watchdog.test.js +0 -154
  1148. package/dist/core/__tests__/subscription-pool-credential-guard.test.d.ts +0 -1
  1149. package/dist/core/__tests__/subscription-pool-credential-guard.test.js +0 -95
  1150. package/dist/core/__tests__/tmux-driver-boundary.test.d.ts +0 -1
  1151. package/dist/core/__tests__/tmux-driver-boundary.test.js +0 -50
  1152. package/dist/core/__tests__/warm-claim-preference-snapshot.test.d.ts +0 -1
  1153. package/dist/core/__tests__/warm-claim-preference-snapshot.test.js +0 -54
  1154. package/dist/core/__tests__/worktree-landing.test.d.ts +0 -1
  1155. package/dist/core/__tests__/worktree-landing.test.js +0 -11
  1156. package/dist/core/__tests__/yield-ensures-daemon.test.d.ts +0 -1
  1157. package/dist/core/__tests__/yield-ensures-daemon.test.js +0 -55
  1158. package/dist/core/broker-client/__tests__/transport-relay.test.d.ts +0 -1
  1159. package/dist/core/broker-client/__tests__/transport-relay.test.js +0 -214
  1160. package/dist/core/broker-client/__tests__/transport-socket.test.d.ts +0 -1
  1161. package/dist/core/broker-client/__tests__/transport-socket.test.js +0 -73
  1162. package/dist/core/canvas/__tests__/attention.test.d.ts +0 -1
  1163. package/dist/core/canvas/__tests__/attention.test.js +0 -83
  1164. package/dist/core/canvas/__tests__/history-transcript.test.d.ts +0 -1
  1165. package/dist/core/canvas/__tests__/history-transcript.test.js +0 -102
  1166. package/dist/core/canvas/__tests__/remote-canvas-source.test.d.ts +0 -1
  1167. package/dist/core/canvas/__tests__/remote-canvas-source.test.js +0 -328
  1168. package/dist/core/canvas/__tests__/remote-transport.test.d.ts +0 -1
  1169. package/dist/core/canvas/__tests__/remote-transport.test.js +0 -97
  1170. package/dist/core/canvas/__tests__/render-remote.test.d.ts +0 -1
  1171. package/dist/core/canvas/__tests__/render-remote.test.js +0 -243
  1172. package/dist/core/canvas/__tests__/session-window.test.d.ts +0 -1
  1173. package/dist/core/canvas/__tests__/session-window.test.js +0 -70
  1174. package/dist/core/feed/__tests__/inbox-migrate.test.d.ts +0 -1
  1175. package/dist/core/feed/__tests__/inbox-migrate.test.js +0 -49
  1176. package/dist/core/human/__tests__/page-catalog.test.d.ts +0 -1
  1177. package/dist/core/human/__tests__/page-catalog.test.js +0 -20
  1178. package/dist/core/human/__tests__/page-html-markdown.test.d.ts +0 -1
  1179. package/dist/core/human/__tests__/page-html-markdown.test.js +0 -48
  1180. package/dist/core/human/__tests__/page.test.d.ts +0 -1
  1181. package/dist/core/human/__tests__/page.test.js +0 -92
  1182. package/dist/core/keybindings/__tests__/resolve.test.d.ts +0 -1
  1183. package/dist/core/keybindings/__tests__/resolve.test.js +0 -171
  1184. package/dist/core/profiles/__tests__/env-store.test.d.ts +0 -1
  1185. package/dist/core/profiles/__tests__/env-store.test.js +0 -99
  1186. package/dist/core/profiles/__tests__/fuzzy-match.test.d.ts +0 -1
  1187. package/dist/core/profiles/__tests__/fuzzy-match.test.js +0 -51
  1188. package/dist/core/profiles/__tests__/root-profile.test.d.ts +0 -1
  1189. package/dist/core/profiles/__tests__/root-profile.test.js +0 -59
  1190. package/dist/core/review/__tests__/capture-origin.test.d.ts +0 -1
  1191. package/dist/core/review/__tests__/capture-origin.test.js +0 -150
  1192. package/dist/core/review/__tests__/comments.test.d.ts +0 -1
  1193. package/dist/core/review/__tests__/comments.test.js +0 -116
  1194. package/dist/core/review/__tests__/remap.test.d.ts +0 -1
  1195. package/dist/core/review/__tests__/remap.test.js +0 -177
  1196. package/dist/core/review/__tests__/stage-identity.test.d.ts +0 -1
  1197. package/dist/core/review/__tests__/stage-identity.test.js +0 -150
  1198. package/dist/core/runtime/__tests__/engine-route.test.d.ts +0 -1
  1199. package/dist/core/runtime/__tests__/engine-route.test.js +0 -36
  1200. package/dist/core/runtime/__tests__/install-id-cache-scoping.test.d.ts +0 -1
  1201. package/dist/core/runtime/__tests__/install-id-cache-scoping.test.js +0 -45
  1202. package/dist/core/runtime/__tests__/node-env.test.d.ts +0 -1
  1203. package/dist/core/runtime/__tests__/node-env.test.js +0 -73
  1204. package/dist/core/runtime/__tests__/spawn-env.test.d.ts +0 -1
  1205. package/dist/core/runtime/__tests__/spawn-env.test.js +0 -259
  1206. package/dist/core/substrate/__tests__/surface-match-command.test.d.ts +0 -1
  1207. package/dist/core/substrate/__tests__/surface-match-command.test.js +0 -89
  1208. package/dist/core/substrate/__tests__/surface-match-memory-read.test.d.ts +0 -1
  1209. package/dist/core/substrate/__tests__/surface-match-memory-read.test.js +0 -28
  1210. package/dist/core/substrate/__tests__/surface-match-pre-command.test.d.ts +0 -1
  1211. package/dist/core/substrate/__tests__/surface-match-pre-command.test.js +0 -92
  1212. package/dist/daemon/__tests__/autostart-storm.test.d.ts +0 -1
  1213. package/dist/daemon/__tests__/autostart-storm.test.js +0 -128
  1214. package/dist/daemon/__tests__/broker-ownership.test.d.ts +0 -1
  1215. package/dist/daemon/__tests__/broker-ownership.test.js +0 -25
  1216. package/dist/daemon/__tests__/daemon-ownership.test.d.ts +0 -1
  1217. package/dist/daemon/__tests__/daemon-ownership.test.js +0 -27
  1218. package/dist/daemon/__tests__/helpers/source-daemon.d.ts +0 -30
  1219. package/dist/daemon/__tests__/helpers/source-daemon.js +0 -176
  1220. package/dist/daemon/__tests__/integration/api-startup-readiness.test.d.ts +0 -1
  1221. package/dist/daemon/__tests__/integration/api-startup-readiness.test.js +0 -83
  1222. package/dist/daemon/__tests__/integration/migration-startup.test.d.ts +0 -1
  1223. package/dist/daemon/__tests__/integration/migration-startup.test.js +0 -127
  1224. package/dist/daemon/__tests__/node-deadline-lane.test.d.ts +0 -1
  1225. package/dist/daemon/__tests__/node-deadline-lane.test.js +0 -77
  1226. package/dist/daemon/__tests__/node-outcome-birth-invariants.test.d.ts +0 -1
  1227. package/dist/daemon/__tests__/node-outcome-birth-invariants.test.js +0 -146
  1228. package/dist/daemon/__tests__/node-outcome-delivery.test.d.ts +0 -1
  1229. package/dist/daemon/__tests__/node-outcome-delivery.test.js +0 -116
  1230. package/dist/daemon/__tests__/reconciler-signature.test.d.ts +0 -1
  1231. package/dist/daemon/__tests__/reconciler-signature.test.js +0 -37
  1232. package/dist/daemon/__tests__/subtree-filter-freshness.test.d.ts +0 -1
  1233. package/dist/daemon/__tests__/subtree-filter-freshness.test.js +0 -63
  1234. package/dist/daemon/__tests__/thaw-order.test.d.ts +0 -1
  1235. package/dist/daemon/__tests__/thaw-order.test.js +0 -55
  1236. package/dist/daemon/api/__tests__/bridge-heartbeat.test.d.ts +0 -1
  1237. package/dist/daemon/api/__tests__/bridge-heartbeat.test.js +0 -58
  1238. package/dist/daemon/api/__tests__/broker-settle-park.test.d.ts +0 -1
  1239. package/dist/daemon/api/__tests__/broker-settle-park.test.js +0 -175
  1240. package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.d.ts +0 -1
  1241. package/dist/daemon/api/__tests__/canvas-snapshot-fields.test.js +0 -216
  1242. package/dist/daemon/api/__tests__/error-seam.test.d.ts +0 -1
  1243. package/dist/daemon/api/__tests__/error-seam.test.js +0 -83
  1244. package/dist/daemon/api/__tests__/model-config.test.d.ts +0 -1
  1245. package/dist/daemon/api/__tests__/model-config.test.js +0 -73
  1246. package/dist/daemon/api/__tests__/node-create-description.test.d.ts +0 -1
  1247. package/dist/daemon/api/__tests__/node-create-description.test.js +0 -127
  1248. package/dist/daemon/api/__tests__/node-model-validation.test.d.ts +0 -1
  1249. package/dist/daemon/api/__tests__/node-model-validation.test.js +0 -183
  1250. package/dist/daemon/api/__tests__/nodes-activity-query.test.d.ts +0 -1
  1251. package/dist/daemon/api/__tests__/nodes-activity-query.test.js +0 -99
  1252. package/dist/daemon/api/__tests__/profile-launch-gates.test.d.ts +0 -1
  1253. package/dist/daemon/api/__tests__/profile-launch-gates.test.js +0 -172
  1254. package/dist/daemon/api/__tests__/profile-metadata-route.test.d.ts +0 -1
  1255. package/dist/daemon/api/__tests__/profile-metadata-route.test.js +0 -95
  1256. package/dist/daemon/api/__tests__/reopen-delivery.test.d.ts +0 -1
  1257. package/dist/daemon/api/__tests__/reopen-delivery.test.js +0 -260
  1258. package/dist/daemon/api/__tests__/seam/api-server.test.d.ts +0 -1
  1259. package/dist/daemon/api/__tests__/seam/api-server.test.js +0 -442
  1260. package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.d.ts +0 -1
  1261. package/dist/daemon/api/__tests__/seam/b10-attach-modelauth.test.js +0 -310
  1262. package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.d.ts +0 -1
  1263. package/dist/daemon/api/__tests__/seam/leaf-api-parity.test.js +0 -351
  1264. package/dist/daemon/api/__tests__/seam/node-outcome-api.test.d.ts +0 -1
  1265. package/dist/daemon/api/__tests__/seam/node-outcome-api.test.js +0 -159
  1266. package/dist/daemon/api/__tests__/seam/profile-delete.test.d.ts +0 -1
  1267. package/dist/daemon/api/__tests__/seam/profile-delete.test.js +0 -372
  1268. package/dist/daemon/api/__tests__/submit-result.test.d.ts +0 -1
  1269. package/dist/daemon/api/__tests__/submit-result.test.js +0 -215
  1270. package/dist/migrations/__tests__/activation-concurrency.test.d.ts +0 -1
  1271. package/dist/migrations/__tests__/activation-concurrency.test.js +0 -146
  1272. package/dist/migrations/__tests__/activation.test.d.ts +0 -1
  1273. package/dist/migrations/__tests__/activation.test.js +0 -152
  1274. package/dist/migrations/__tests__/deletion-and-root-declaration.test.d.ts +0 -1
  1275. package/dist/migrations/__tests__/deletion-and-root-declaration.test.js +0 -149
  1276. package/dist/pi-extensions/__tests__/canvas-bash-valve.test.d.ts +0 -1
  1277. package/dist/pi-extensions/__tests__/canvas-bash-valve.test.js +0 -86
  1278. package/dist/pi-extensions/__tests__/canvas-context-intro.test.d.ts +0 -1
  1279. package/dist/pi-extensions/__tests__/canvas-context-intro.test.js +0 -364
  1280. package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.d.ts +0 -1
  1281. package/dist/pi-extensions/__tests__/canvas-goal-capture-envelope.test.js +0 -106
  1282. package/dist/pi-extensions/__tests__/canvas-recap.test.d.ts +0 -1
  1283. package/dist/pi-extensions/__tests__/canvas-recap.test.js +0 -62
  1284. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.d.ts +0 -1
  1285. package/dist/pi-extensions/__tests__/canvas-stophook-agentend.test.js +0 -432
  1286. package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.d.ts +0 -1
  1287. package/dist/pi-extensions/__tests__/canvas-stophook-context-nudge.test.js +0 -152
  1288. package/dist/pi-extensions/__tests__/canvas-structured-output.test.d.ts +0 -1
  1289. package/dist/pi-extensions/__tests__/canvas-structured-output.test.js +0 -88
  1290. package/dist/pi-extensions/__tests__/canvas-tool-guide.test.d.ts +0 -1
  1291. package/dist/pi-extensions/__tests__/canvas-tool-guide.test.js +0 -96
  1292. package/dist/pi-extensions/__tests__/integration/canvas-bash-valve.test.d.ts +0 -1
  1293. package/dist/pi-extensions/__tests__/integration/canvas-bash-valve.test.js +0 -133
  1294. package/dist/pi-extensions/__tests__/pre-command-gate.test.d.ts +0 -1
  1295. package/dist/pi-extensions/__tests__/pre-command-gate.test.js +0 -232
  1296. package/dist/shared/__tests__/env-boundary.test.d.ts +0 -1
  1297. package/dist/shared/__tests__/env-boundary.test.js +0 -95
  1298. package/dist/shared/__tests__/generated-context-grammar.test.d.ts +0 -1
  1299. package/dist/shared/__tests__/generated-context-grammar.test.js +0 -80
  1300. package/docs/compat/hearth-crtr-v1.md +0 -179
  1301. package/docs/compat/hearth-crtr-v2.md +0 -177
  1302. package/docs/compat/hearth-crtr-v3.md +0 -176
  1303. package/docs/compat/hearth-crtr-v4.md +0 -182
  1304. package/docs/compat/hearth-crtr-v5.md +0 -169
@@ -1,899 +1,18 @@
1
- import { existsSync, mkdirSync, readFileSync, realpathSync, rmSync, writeFileSync } from 'node:fs';
2
- import { createHash } from 'node:crypto';
3
- import { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
4
- import { gitAsync, gitSync } from './git.js';
5
- import { crtrHome } from './canvas/paths.js';
6
- import { closeWorktreeAndRepoint, getNode, recordLandIntent } from './canvas/index.js';
7
- import { CONFIG_FILE, CRTR_DIR_NAME, STATE_FILE } from '../types.js';
8
- import { withExclusiveDirectoryLock } from './exclusive-lock.js';
9
- import { parseStatusPorcelain, planLandIntoCheckout, refDeleteTransactionStdin } from './worktree-landing.js';
10
- import { shellQuote } from '../shared/shell-quote.js';
11
- export class WorktreeError extends Error {
12
- code;
13
- next;
14
- detail;
15
- constructor(code, message, next, detail) {
16
- super(message);
17
- this.name = 'WorktreeError';
18
- this.code = code;
19
- this.next = next;
20
- this.detail = detail;
21
- }
22
- }
23
- function runGit(cwd, args, code, next) {
24
- const res = gitSync(args, cwd);
25
- if (res.status !== 0) {
26
- const detail = (res.stderr.trim() || res.stdout.trim()).trim();
27
- throw new WorktreeError(code, `git ${args.join(' ')} failed`, next, detail);
28
- }
29
- return res.stdout.trim();
30
- }
31
- export function managedWorktreesRoot() {
32
- return `${crtrHome()}/worktrees`;
33
- }
34
- export function managedWorktreePath(nodeId) {
35
- return `${managedWorktreesRoot()}/${nodeId}`;
36
- }
37
- export function hasOpenManagedWorktree(node) {
38
- return node?.managed_worktree?.state === 'open';
39
- }
40
- export function openManagedWorktreeForNode(nodeId) {
41
- const node = getNode(nodeId);
42
- const wt = node?.managed_worktree;
43
- return wt?.state === 'open' ? wt : null;
44
- }
45
- function repoRootFor(cwd) {
46
- const result = gitSync(['rev-parse', '--show-toplevel'], cwd);
47
- if (result.status !== 0) {
48
- const detail = (result.stderr.trim() || result.stdout.trim()).trim();
49
- throw new WorktreeError('not_git_repo', `cwd ${cwd} is not a git repository`, 'Pass --cwd <real repo> pointing inside a git repository.', detail);
50
- }
51
- return result.stdout.trim();
52
- }
53
- export function isManagedWorktreeBase(repoRoot) {
54
- const path = relative(canonicalPath(managedWorktreesRoot()), canonicalPath(repoRoot));
55
- return path !== '' && path !== '..' && !path.startsWith(`..${sep}`) && !isAbsolute(path);
56
- }
57
- function recordedBranchExists(cwd, branch) {
58
- const ref = `refs/heads/${branch}`;
59
- const exists = gitSync(['show-ref', '--verify', '--quiet', ref], cwd);
60
- if (exists.status === 0)
61
- return true;
62
- if (exists.status === 1 && exists.executionFailed !== true)
63
- return false;
64
- const stderr = exists.stderr.trim() || '<empty>';
65
- const execution = exists.processError === undefined ? '' : `\nprocess error: ${exists.processError}`;
66
- throw new WorktreeError('recorded_branch_inspection_failed', `could not inspect recorded branch '${branch}' (git show-ref exited with status ${exists.status})`, 'Inspect the repository and its Git metadata, then retry.', `status: ${exists.status}\nstderr: ${stderr}${execution}`);
67
- }
68
- function resolveLandableBase(repoRoot, baseRef) {
69
- const ref = `refs/heads/${baseRef}`;
70
- // Verify the exact refs/heads name first: rev-parse alone accepts revision
71
- // syntax, which could turn a SHA or a `^{commit}` suffix into a non-landable
72
- // base even though no local branch by that exact name exists.
73
- const exists = gitSync(['show-ref', '--verify', '--quiet', ref], repoRoot);
74
- // `show-ref --verify --quiet` reserves exit 1 for an absent ref. gitSync
75
- // preserves that numeric status for compatibility, but marks spawn failures,
76
- // timeouts, and signal exits so they cannot masquerade as an absent branch.
77
- if (exists.status === 1 && exists.executionFailed !== true) {
78
- throw new WorktreeError('missing_base_branch', `managed worktree base '${baseRef}' does not name an existing local branch`, 'The base must be a local branch that landing can fast-forward — freshen your local branch from origin first (rebase-not-merge), then base on it.');
79
- }
80
- if (exists.status !== 0) {
81
- const stderr = exists.stderr.trim() || '<empty>';
82
- const execution = exists.processError === undefined ? '' : `\nprocess error: ${exists.processError}`;
83
- throw new WorktreeError('base_branch_inspection_failed', `could not inspect local base branch '${baseRef}' (git show-ref exited with status ${exists.status})`, 'Inspect the repository and its Git metadata, then retry.', `status: ${exists.status}\nstderr: ${stderr}${execution}`);
84
- }
85
- return runGit(repoRoot, ['rev-parse', '--verify', ref], 'base_branch_resolve_failed', 'Inspect the local base branch, then retry.');
86
- }
87
- /** Path of the worktree where a local branch is currently checked out, or null
88
- * if it is not checked out in any worktree. */
89
- function checkoutPathForBranch(repoRoot, branch) {
90
- const out = runGit(repoRoot, ['worktree', 'list', '--porcelain'], 'worktree_list_failed', 'Inspect the repository worktrees manually, then retry.');
91
- return checkoutPathForBranchInList(out, branch);
92
- }
93
- /** Shared parse for a `git worktree list --porcelain` blob already in hand —
94
- * callers that must not throw on a read failure (an absent-path proof that
95
- * needs to fail closed rather than error) call `gitSync` themselves and pass
96
- * the output here instead of going through `checkoutPathForBranch`. */
97
- export function checkoutPathForBranchInList(porcelain, branch) {
98
- let current = null;
99
- for (const line of porcelain.split('\n')) {
100
- if (line.startsWith('worktree '))
101
- current = line.slice('worktree '.length).trim();
102
- else if (line === `branch refs/heads/${branch}`)
103
- return current;
104
- }
105
- return null;
106
- }
107
- /** Are these two spellings the same directory?
108
- *
109
- * Git canonicalizes every path it prints in `worktree list --porcelain`, while
110
- * a recorded managed-worktree path preserves the spelling of `CRTR_HOME`. When
111
- * the canvas home is reached through a symlink (macOS's `/var` → `/private/var`
112
- * is the everyday case) the two forms name one directory but differ as
113
- * strings, so a raw `===` reads a checkout crtr created as unowned. Resolution
114
- * failures fall back to `resolve`, which is the pre-canonical comparison — no
115
- * worse than the string compare it replaces. */
116
- export function samePath(a, b) {
117
- return a === b || canonicalPath(a) === canonicalPath(b);
118
- }
119
- function canonicalPath(path) {
120
- try {
121
- return realpathSync.native(path);
122
- }
123
- catch {
124
- return resolve(path);
125
- }
126
- }
127
- export const WORKTREE_LOCK_WAIT_MS = 30_000;
128
- /** The lock directory naming one repository's common Git dir. Every process
129
- * that mutates a managed worktree — the synchronous commands here and the
130
- * daemon's asynchronous sweep — derives its lock path through this function,
131
- * so the two locking styles contend for the SAME name. */
132
- export function worktreeLockPathForCommonDir(commonDir) {
133
- const lockRoot = `${crtrHome()}/worktree-locks`;
134
- mkdirSync(lockRoot, { recursive: true });
135
- return `${lockRoot}/${createHash('sha256').update(commonDir).digest('hex')}`;
136
- }
137
- function commonGitDir(repoRoot) {
138
- const commonDir = runGit(repoRoot, ['rev-parse', '--git-common-dir'], 'git_common_dir_failed', 'Inspect the repository git metadata, then retry.');
139
- return realpathSync(resolve(repoRoot, commonDir));
140
- }
141
- /** Serialize worktree mutation for one repository across crtr processes. Git's
142
- * own worktree metadata lock is intentionally short-lived and rejects a second
143
- * add instead of waiting, so callers take this transaction lock first. */
144
- function withRepositoryWorktreeLock(repoRoot, action) {
145
- const commonDir = commonGitDir(repoRoot);
146
- return withExclusiveDirectoryLock(worktreeLockPathForCommonDir(commonDir), action, {
147
- timeoutMs: WORKTREE_LOCK_WAIT_MS,
148
- timeoutError: () => new WorktreeError('worktree_lock_timeout', `timed out waiting to create a managed worktree in ${commonDir}`, 'Wait for the other managed-worktree operation to finish, then retry.'),
149
- });
150
- }
151
- function registeredWorktree(repoRoot, path, branch) {
152
- const list = gitSync(['worktree', 'list', '--porcelain'], repoRoot);
153
- if (list.status !== 0)
154
- return null;
155
- let current = null;
156
- for (const line of list.stdout.split('\n')) {
157
- if (line.startsWith('worktree '))
158
- current = line.slice('worktree '.length).trim();
159
- else if (current !== null && samePath(current, path) && line === `branch refs/heads/${branch}`)
160
- return true;
161
- }
162
- return false;
163
- }
164
- function proveBranchContained(cwd, baseRef, branchSha) {
165
- const candidates = [];
166
- const localBaseRef = `refs/heads/${baseRef}`;
167
- const localBase = gitSync(['rev-parse', '--verify', '--quiet', localBaseRef], cwd);
168
- if (localBase.status === 0)
169
- candidates.push({ ref: localBaseRef, sha: localBase.stdout.trim() });
170
- const upstream = gitSync(['rev-parse', '--symbolic-full-name', '--verify', `${baseRef}@{upstream}`], cwd);
171
- const upstreamRef = upstream.status === 0 && upstream.stdout.trim().startsWith('refs/') ? upstream.stdout.trim() : `refs/remotes/origin/${baseRef}`;
172
- const upstreamSha = gitSync(['rev-parse', '--verify', '--quiet', upstreamRef], cwd);
173
- if (upstreamSha.status === 0)
174
- candidates.push({ ref: upstreamRef, sha: upstreamSha.stdout.trim() });
175
- if (candidates.length === 0)
176
- return null;
177
- for (const c of candidates) {
178
- if (gitSync(['merge-base', '--is-ancestor', branchSha, c.sha], cwd).status === 0)
179
- return { containingRef: c.ref, containingSha: c.sha };
180
- }
181
- for (const c of candidates) {
182
- const cherry = gitSync(['cherry', c.sha, branchSha], cwd);
183
- if (cherry.status !== 0)
184
- continue;
185
- const lines = cherry.stdout.split('\n').map((l) => l.trim()).filter((l) => l !== '');
186
- if (lines.every((l) => l.startsWith('-')))
187
- return { containingRef: c.ref, containingSha: c.sha };
188
- }
189
- for (const c of candidates) {
190
- const candidateTree = gitSync(['rev-parse', '--verify', `${c.sha}^{tree}`], cwd);
191
- if (candidateTree.status !== 0)
192
- continue;
193
- const merged = gitSync(['merge-tree', '--write-tree', c.sha, branchSha], cwd);
194
- if (merged.status !== 0)
195
- continue;
196
- if (merged.stdout.split('\n')[0]?.trim() === candidateTree.stdout.trim())
197
- return { containingRef: c.ref, containingSha: c.sha };
198
- }
199
- return null;
200
- }
201
- /** Undo a creation attempt, but only resources whose recorded path, branch,
202
- * and original base still prove they belong to that attempt. */
203
- function rollbackManagedWorktreeLocked(wt, pathWasAbsent) {
204
- const branch = gitSync(['rev-parse', '--verify', `refs/heads/${wt.branch}`], wt.repo_root);
205
- // A branch at the original base is the ownership proof for every destructive
206
- // rollback step. If it was advanced or repurposed, preserve all resources.
207
- if (branch.status !== 0 || branch.stdout.trim() !== wt.base_sha)
208
- return;
209
- const registration = registeredWorktree(wt.repo_root, wt.path, wt.branch);
210
- // A failed registry read proves nothing. Preserve every resource rather than
211
- // guessing that an uninspected checkout belongs to this failed attempt.
212
- if (registration === null)
213
- return;
214
- if (registration) {
215
- if (gitSync(['worktree', 'remove', '--force', wt.path], wt.repo_root).status !== 0)
216
- return;
217
- if (registeredWorktree(wt.repo_root, wt.path, wt.branch) !== false)
218
- return;
219
- }
220
- else if (pathWasAbsent && existsSync(wt.path)) {
221
- // The caller observed this path absent while holding the repository lock;
222
- // only its failed `worktree add` can have created it.
223
- try {
224
- rmSync(wt.path, { recursive: true, force: true });
225
- }
226
- catch {
227
- return;
228
- }
229
- }
230
- // Compare-and-delete retains the ownership guard through the final mutation.
231
- try {
232
- gitSync(['update-ref', '-d', `refs/heads/${wt.branch}`, wt.base_sha], wt.repo_root);
233
- }
234
- catch { /* best-effort */ }
235
- }
236
- export function rollbackManagedWorktree(wt) {
237
- withRepositoryWorktreeLock(wt.repo_root, () => rollbackManagedWorktreeLocked(wt, false));
238
- }
239
- // Every crtr process auto-initializes a project scope's
240
- // `.crouter/config.json` (`ensureProjectScope` → `ensureScopeInitialized`)
241
- // the first time it runs against a project root that has no ancestor
242
- // `.crouter/` yet — which every fresh managed worktree checkout is, unless
243
- // the repo itself already tracks `.crouter/memory/` (crouter's own repo does).
244
- // That write is untracked crtr bookkeeping, not node work, so `git status`
245
- // inside the worktree always shows `?? .crouter/config.json` and `close`'s
246
- // dirty check refuses to land. `state.json` is the same category (written at
247
- // project scope by explicit `pkg`/`canvas config` commands) — excluded
248
- // defensively even though no automatic path writes it today.
249
- //
250
- // These two filenames, NOT the whole `.crouter/` directory, are the only
251
- // patterns seeded below. `.git/info/exclude` only ever suppresses UNTRACKED
252
- // paths from `git status` — it can never hide a modification to an
253
- // already-tracked file — but crouter's own repo tracks `.crouter/memory/`,
254
- // and a node can legitimately add a brand-new (untracked until committed)
255
- // memory doc there. A blanket `.crouter/` exclude would silently hide that
256
- // new doc from `git status` too, letting close/push-final land or auto-drop
257
- // while it is quietly lost. Naming exactly `config.json`/`state.json` avoids
258
- // that: nothing crtr writes automatically ever lands under `.crouter/memory/`.
259
- const MANAGED_WORKTREE_EXCLUDE_MARKER = '# crtr: exclude crtr\'s own untracked project-scope bookkeeping (auto-added at managed-worktree creation)';
260
- const MANAGED_WORKTREE_EXCLUDE_PATTERNS = [
261
- `/${CRTR_DIR_NAME}/${CONFIG_FILE}`,
262
- `/${CRTR_DIR_NAME}/${STATE_FILE}`,
263
- ];
264
- /** Seed the repository's SHARED `.git/info/exclude` (one file per common git
265
- * dir, not per worktree — `git rev-parse --git-path info/exclude` resolves
266
- * there from every linked worktree, including the primary checkout) with
267
- * crtr's own runtime bookkeeping patterns, idempotently. Leading `/` anchors
268
- * each pattern to the toplevel of WHICHEVER worktree `git status` runs in,
269
- * which is exactly where `ensureScopeInitialized` writes `.crouter/config.json`
270
- * — the managed worktree's own root. Called once per managed-worktree
271
- * creation, already inside `withRepositoryWorktreeLock`, so concurrent
272
- * creators cannot race the append. */
273
- function seedManagedWorktreeExclude(repoRoot) {
274
- try {
275
- const excludePath = join(commonGitDir(repoRoot), 'info', 'exclude');
276
- mkdirSync(dirname(excludePath), { recursive: true });
277
- let existing = '';
278
- try {
279
- existing = readFileSync(excludePath, 'utf8');
280
- }
281
- catch { /* first worktree this repo has ever had */ }
282
- const present = new Set(existing.split('\n').map((l) => l.trim()));
283
- const missing = MANAGED_WORKTREE_EXCLUDE_PATTERNS.filter((p) => !present.has(p));
284
- if (missing.length === 0)
285
- return;
286
- const needsLeadingNewline = existing.length > 0 && !existing.endsWith('\n');
287
- const block = (needsLeadingNewline ? '\n' : '') + MANAGED_WORKTREE_EXCLUDE_MARKER + '\n' + missing.join('\n') + '\n';
288
- writeFileSync(excludePath, existing + block);
289
- }
290
- catch { /* best-effort; a failure here is cosmetic (one extra untracked bookkeeping line in git status) and must never fail worktree creation */ }
291
- }
292
- export function createManagedWorktree(cwd, nodeId, baseRef = 'main') {
293
- const repoRoot = repoRootFor(cwd);
294
- if (isManagedWorktreeBase(repoRoot)) {
295
- throw new WorktreeError('managed_worktree_base', `cwd ${repoRoot} is a managed worktree and cannot be used as a managed worktree base`, 'Pass --cwd <real repo> pointing at the repository’s primary checkout.');
296
- }
297
- return withRepositoryWorktreeLock(repoRoot, () => {
298
- const baseSha = resolveLandableBase(repoRoot, baseRef);
299
- const path = managedWorktreePath(nodeId);
300
- const branch = `crtr/${nodeId}`;
301
- if (existsSync(path)) {
302
- throw new WorktreeError('worktree_path_exists', `managed worktree path already exists: ${path}`, 'Remove the stale path or choose a fresh node id.');
303
- }
304
- if (gitSync(['show-ref', '--verify', '--quiet', `refs/heads/${branch}`], repoRoot).status === 0) {
305
- throw new WorktreeError('worktree_branch_exists', `managed worktree branch already exists: ${branch}`, 'Remove the stale branch or choose a fresh node id.');
306
- }
307
- const wt = {
308
- state: 'open', path, branch, repo_root: repoRoot, base_ref: baseRef, base_sha: baseSha, created: new Date().toISOString(),
309
- };
310
- runGit(repoRoot, ['branch', branch, baseSha], 'worktree_branch_create_failed', 'Inspect the git error, fix the repository/worktree state, then retry spawning with --worktree.');
311
- try {
312
- runGit(repoRoot, ['worktree', 'add', path, branch], 'worktree_add_failed', 'Inspect the git error, fix the repository/worktree state, then retry spawning with --worktree.');
313
- seedManagedWorktreeExclude(repoRoot);
314
- return wt;
315
- }
316
- catch (err) {
317
- rollbackManagedWorktreeLocked(wt, true);
318
- throw err;
319
- }
320
- });
321
- }
322
- function statusPorcelain(cwd) {
323
- return runGit(cwd, ['status', '--porcelain'], 'status_failed', 'Inspect the worktree manually, then retry.');
324
- }
325
- function currentBranch(cwd) {
326
- return runGit(cwd, ['rev-parse', '--abbrev-ref', 'HEAD'], 'branch_check_failed', 'Inspect the worktree manually, then retry.');
327
- }
328
- function gitPath(cwd, logicalPath) {
329
- return runGit(cwd, ['rev-parse', '--git-path', logicalPath], 'git_path_failed', 'Inspect the worktree manually, then retry.');
330
- }
331
- export function isRebaseInProgress(cwd) {
332
- return existsSync(gitPath(cwd, 'rebase-merge')) || existsSync(gitPath(cwd, 'rebase-apply'));
333
- }
334
- /** The ONE authoritative closed-worktree state transition, shared by every
335
- * closing path (explicit `closeManagedWorktreeLocked` land, the clean
336
- * `autoDropCleanManagedWorktreeLocked` push-final drop, and the daemon sweep's
337
- * `reconcileManagedWorktree`): persist
338
- * `managed_worktree.state: 'closed'`, name its cleanup state, and repoint the
339
- * node's launch `cwd` to the durable base checkout. The caller broker stays
340
- * alive and is Pi's sole transcript writer, so its session header cannot be
341
- * safely rewritten here; clear the session coordinates and let the later
342
- * revive launch fresh instead. Both closing paths MUST go through this helper
343
- * instead of hand-rolling the `updateNode` call, so neither can drift out of
344
- * sync. */
345
- export function persistClosedWorktreeState(nodeId, wt, cleanup = 'pending') {
346
- const node = getNode(nodeId);
347
- closeWorktreeAndRepoint(nodeId, {
348
- cwd: wt.repo_root,
349
- cleanup,
350
- closedAt: new Date().toISOString(),
351
- unbindSession: node?.pi_session_id != null || node?.pi_session_file != null,
352
- });
353
- }
354
- /** Record that this node ASKED to land and was blocked, so the daemon sweep may
355
- * later retry exactly that land once the base checkout stops blocking it. The
356
- * sweep never lands commits for a node that did not get this far: a node that
357
- * crashed mid-work and never called close has its worktree preserved for a
358
- * human instead. Recording a fresh intent also clears any prior refusal state,
359
- * so the sweep re-examines promptly rather than honoring an old backoff. */
360
- function recordBlockedLandIntent(nodeId, blocked) {
361
- const current = getNode(nodeId)?.managed_worktree;
362
- if (current == null || current.state !== 'open')
363
- return;
364
- recordLandIntent(nodeId, { at: new Date().toISOString(), blocked });
365
- }
366
- /** Fast-forward a base branch that is CHECKED OUT somewhere, landing underneath
367
- * whatever local changes that checkout holds.
368
- *
369
- * The base checkout is shared by every other node using this repository, and
370
- * its local changes usually have nothing to do with the child that is closing.
371
- * Disjoint changes ride along untouched; overlapping ones are stashed, the
372
- * fast-forward runs underneath them, and they are re-applied. The re-apply is
373
- * `stash apply`, never `stash pop`, so a conflict cannot consume the stash and
374
- * lose the work: on conflict the checkout is reset to the landed commit and the
375
- * stash is deliberately KEPT for a person to apply. Either way this never
376
- * leaves conflict markers behind in a checkout other nodes are using. */
377
- function landIntoBaseCheckout(baseCheckout, branch, baseSha, landedSha) {
378
- const status = gitSync(['status', '--porcelain'], baseCheckout);
379
- if (status.status !== 0)
380
- return { ok: false, detail: (status.stderr.trim() || status.stdout.trim()).trim() };
381
- const diff = gitSync(['diff', '--name-only', baseSha, landedSha], baseCheckout);
382
- if (diff.status !== 0)
383
- return { ok: false, detail: (diff.stderr.trim() || diff.stdout.trim()).trim() };
384
- const incoming = diff.stdout.split('\n').map((l) => l.trim()).filter((l) => l !== '');
385
- const plan = planLandIntoCheckout(parseStatusPorcelain(status.stdout), incoming);
386
- if (plan.kind === 'refuse') {
387
- return { ok: false, detail: `untracked files in ${baseCheckout} would be overwritten by the incoming commits: ${plan.collisions.join(', ')}` };
388
- }
389
- const merge = () => {
390
- const res = gitSync(['merge', '--ff-only', landedSha], baseCheckout);
391
- return res.status === 0 ? { ok: true } : { ok: false, detail: (res.stderr.trim() || res.stdout.trim()).trim() };
392
- };
393
- if (plan.kind === 'direct')
394
- return merge();
395
- // Identify the stash by the exact commit this push created. `refs/stash` can
396
- // already name an UNRELATED stash the user made earlier, and a push that
397
- // saved nothing leaves it untouched — applying or dropping that one would
398
- // destroy work this code never owned.
399
- const before = gitSync(['rev-parse', '--verify', '--quiet', 'refs/stash'], baseCheckout);
400
- const beforeSha = before.status === 0 ? before.stdout.trim() : null;
401
- const push = gitSync(['stash', 'push', '--message', `crtr landing ${branch}`], baseCheckout);
402
- if (push.status !== 0)
403
- return { ok: false, detail: (push.stderr.trim() || push.stdout.trim()).trim() };
404
- const after = gitSync(['rev-parse', '--verify', '--quiet', 'refs/stash'], baseCheckout);
405
- const stashSha = after.status === 0 ? after.stdout.trim() : null;
406
- if (stashSha === null || stashSha === beforeSha)
407
- return merge(); // nothing was saved
408
- const recovery = `local changes from ${baseCheckout} are retained in stash ${stashSha}; recover them with \`git -C ${shellQuote(baseCheckout)} stash apply ${stashSha}\` and resolve any conflict.`;
409
- const landed = merge();
410
- if (!landed.ok) {
411
- // The failed merge left the tree exactly as the stash found it, so this
412
- // re-apply is clean; restore before surfacing the refusal.
413
- if (gitSync(['stash', 'apply', stashSha], baseCheckout).status === 0) {
414
- dropStashIfStillTip(baseCheckout, stashSha);
415
- return landed;
416
- }
417
- return { ok: false, detail: `${landed.detail}\n${recovery}` };
418
- }
419
- if (gitSync(['stash', 'apply', stashSha], baseCheckout).status === 0) {
420
- dropStashIfStillTip(baseCheckout, stashSha);
421
- return { ok: true };
422
- }
423
- gitSync(['reset', '--hard', landedSha], baseCheckout);
424
- return {
425
- ok: true,
426
- stash: `the shared base checkout was reset to landed commit ${landedSha} because local changes conflicted with it. ${recovery}`,
427
- };
428
- }
429
- /** Drop a stash entry only while it is still the tip `stash@{0}` names, so a
430
- * stash someone else pushed in between is never dropped instead. */
431
- function dropStashIfStillTip(cwd, stashSha) {
432
- const tip = gitSync(['rev-parse', '--verify', '--quiet', 'refs/stash'], cwd);
433
- if (tip.status === 0 && tip.stdout.trim() === stashSha)
434
- gitSync(['stash', 'drop'], cwd);
435
- }
436
- function deferredCleanupResult(wt) {
437
- const remove = `git -C ${shellQuote(wt.repo_root)} worktree remove ${shellQuote(wt.path)}`;
438
- return {
439
- worktree_removed: false,
440
- worktree_remove_error: `cleanup pending: the caller checkout at ${wt.path} remains intact. After its node exits, run \`${remove}\` after confirming it is safe to delete.`,
441
- branch_deleted: false,
442
- branch_delete_error: `cleanup pending: local branch ${wt.branch} remains checked out at ${wt.path}; delete it only after that checkout is removed and its landed commit is still contained in ${wt.base_ref}.`,
443
- };
444
- }
445
- /** The disposal path for `close` when the recorded `crtr/*` branch is gone:
446
- * ordinary PR work moved this checkout onto a real branch. This never lands
447
- * or rebases that branch — it belongs to a workflow crouter does not own —
448
- * and never deletes it. It only AUTHORIZES the daemon sweep to remove the
449
- * checkout later, once this node's own broker has exited, and only after
450
- * proving the branch's content is already delivered. Runs after the caller
451
- * already proved the checkout clean and not mid-rebase. */
452
- function closeBranchMovedWorktree(nodeId, wt, actualBranch) {
453
- if (registeredWorktree(wt.repo_root, wt.path, actualBranch) !== true) {
454
- throw new WorktreeError('wrong_branch', `managed worktree's recorded branch ${wt.branch} no longer exists, and its checkout at ${wt.path} is not registered to ${actualBranch} either`, `Inspect ${wt.path} and its git worktree registration, then ask the user with \`crtr human send\` if you are unsure how to proceed.`);
455
- }
456
- const actualSha = runGit(wt.path, ['rev-parse', 'HEAD'], 'branch_check_failed', 'Inspect the worktree manually, then retry.');
457
- const proof = proveBranchContained(wt.path, wt.base_ref, actualSha);
458
- if (proof === null) {
459
- throw new WorktreeError('branch_moved_unlanded', `managed worktree's recorded branch ${wt.branch} no longer exists; its checkout is now on ${actualBranch} at ${actualSha}, which carries content local base branch '${wt.base_ref}' does not yet contain`, `Land or push ${actualBranch} through its own workflow (merge its PR, or fast-forward '${wt.base_ref}' to include it) before closing, or ask the user with \`crtr human send\` if you are unsure how ${actualBranch} should be delivered.`);
460
- }
461
- const commonDir = commonGitDir(wt.repo_root);
462
- // Recheck identity immediately before writing the authorization: nothing
463
- // about the checkout may have moved between the proof above and this write.
464
- const stillRegistered = registeredWorktree(wt.repo_root, wt.path, actualBranch) === true;
465
- const stillOnBranch = currentBranch(wt.path) === actualBranch;
466
- const stillAtSha = runGit(wt.path, ['rev-parse', 'HEAD'], 'branch_check_failed', 'Inspect the worktree manually, then retry.') === actualSha;
467
- if (!stillRegistered || !stillOnBranch || !stillAtSha) {
468
- throw new WorktreeError('wrong_branch', `managed worktree at ${wt.path} changed while closing`, `Inspect ${wt.path}, then rerun \`crtr node worktree close\`.`);
469
- }
470
- const disposal = { observed_branch: actualBranch, observed_sha: actualSha, common_dir: commonDir, authorized: new Date().toISOString() };
471
- persistClosedWorktreeState(nodeId, { ...wt, disposal }, 'pending');
472
- const remove = `git -C ${shellQuote(wt.repo_root)} worktree remove ${shellQuote(wt.path)}`;
473
- return {
474
- node_id: nodeId,
475
- branch: actualBranch,
476
- worktree_path: wt.path,
477
- // Nothing was rebased or fast-forwarded here: `${actualBranch}`'s content
478
- // was already proven contained in `${proof.containingRef}` at `${proof.containingSha}`.
479
- landed_sha: actualSha,
480
- worktree_removed: false,
481
- worktree_remove_error: `cleanup pending: the caller checkout at ${wt.path} remains intact. After its node exits, run \`${remove}\` after confirming it is safe to delete.`,
482
- branch_deleted: false,
483
- branch_delete_error: `${actualBranch} is not a crtr-managed branch and will never be deleted automatically; it is preserved once the checkout above is removed.`,
484
- };
485
- }
486
- /** Word the `no_managed_worktree` refusal from the record's ACTUAL state
487
- * rather than a blanket "no worktree". A `closed`/`cleanup: pending` record
488
- * still has its checkout on disk, scheduled for the daemon sweep to finish —
489
- * that is not lost ownership, and three separate reports (#849, #862, #872)
490
- * were misdiagnosed because the old wording read as if it were. */
491
- function noManagedWorktreeMessage(nodeId, verb) {
492
- const wt = getNode(nodeId)?.managed_worktree;
493
- if (wt == null)
494
- return { message: `node ${nodeId} has no managed worktree`, next: `Nothing to ${verb} for this node.` };
495
- if (wt.state === 'abandoned') {
496
- const branch = wt.abandoned?.branch ?? wt.branch;
497
- return { message: `node ${nodeId}'s managed worktree was already abandoned`, next: `Nothing to ${verb} for this node; its work was retained on branch ${branch}.` };
498
- }
499
- if (wt.state === 'closed') {
500
- return wt.cleanup === 'complete'
501
- ? { message: `node ${nodeId}'s managed worktree is already closed and its cleanup is complete`, next: `Nothing to ${verb} for this node.` }
502
- : { message: `node ${nodeId}'s managed worktree is already closed; this is not lost ownership — its checkout at ${wt.path} is scheduled for automatic cleanup once that is safe`, next: `Nothing to ${verb} for this node. The daemon sweep finishes removing ${wt.path} on its own; inspect it directly only if it still needs manual attention.` };
503
- }
504
- return { message: `node ${nodeId} has no open managed worktree`, next: `Nothing to ${verb} for this node.` };
505
- }
506
- function closeManagedWorktreeLocked(nodeId) {
507
- const node = getNode(nodeId);
508
- if (node === null) {
509
- throw new WorktreeError('unknown_node', `unknown node: ${nodeId}`, 'Run this from a live node, or pass a real node id once that command supports it.');
510
- }
511
- const wt = openManagedWorktreeForNode(nodeId);
512
- if (wt === null) {
513
- const { message, next } = noManagedWorktreeMessage(nodeId, 'close');
514
- throw new WorktreeError('no_managed_worktree', message, next);
515
- }
516
- if (!existsSync(wt.path)) {
517
- const proof = proveAbsentPathManagedWorktree(wt);
518
- if (proof === null) {
519
- throw new WorktreeError('worktree_missing', `managed worktree path is missing: ${wt.path}`, missingWorktreeRecoveryHint(wt));
520
- }
521
- const dropped = autoDropAbsentPathManagedWorktreeLocked(nodeId, wt, proof);
522
- if (dropped === null) {
523
- throw new WorktreeError('worktree_missing', `managed worktree path is missing: ${wt.path}`, missingWorktreeRecoveryHint(wt));
524
- }
525
- return {
526
- node_id: nodeId,
527
- branch: wt.branch,
528
- worktree_path: wt.path,
529
- // No local fast-forward happened in this recovery path. When the branch
530
- // still exists, this is its remotely/local-base-delivered tip; when it
531
- // was already deleted, the recorded creation base is the only durable
532
- // SHA left to report through the established close result contract.
533
- landed_sha: proof.branchSha ?? wt.base_sha,
534
- worktree_removed: true,
535
- branch_deleted: true,
536
- };
537
- }
538
- if (isRebaseInProgress(wt.path)) {
539
- throw new WorktreeError('rebase_in_progress', 'this managed worktree is mid-rebase', `Resolve conflicts in ${wt.path}, run \`git rebase --continue\` there, then rerun \`crtr node worktree close\`.`);
540
- }
541
- const dirty = statusPorcelain(wt.path);
542
- if (dirty !== '') {
543
- throw new WorktreeError('dirty_worktree', 'managed worktree has uncommitted changes', `Commit the work in ${wt.path} (or ask the user with \`crtr human send\` if you do not know whether to keep it), then rerun \`crtr node worktree close\`.`);
544
- }
545
- const branch = currentBranch(wt.path);
546
- if (branch !== wt.branch) {
547
- const found = branch === 'HEAD' ? 'detached HEAD' : branch;
548
- const recordedRefExists = recordedBranchExists(wt.path, wt.branch);
549
- if (recordedRefExists || branch === 'HEAD') {
550
- throw new WorktreeError('wrong_branch', `managed worktree is not on its recorded branch (expected ${wt.branch}, found ${found})`, recordedRefExists
551
- ? `Check out ${wt.branch} in ${wt.path} before closing, or ask the user with \`crtr human send\` if you are unsure why it changed, then rerun \`crtr node worktree close\`.`
552
- : `The recorded branch ${wt.branch} no longer exists, and ${wt.path} is in detached HEAD, so there is no branch to preserve. Check out or create a branch there before closing, or ask the user with \`crtr human send\` if you are unsure how to proceed.`);
553
- }
554
- // The recorded crtr/* branch is gone: ordinary PR work moved this checkout
555
- // onto a real branch. The checkout is already proven clean and not
556
- // mid-rebase (both checked above), so disposal may proceed.
557
- return closeBranchMovedWorktree(nodeId, wt, branch);
558
- }
559
- let baseSha;
560
- try {
561
- // `repo_root` is the checkout that created this child, and it can vanish
562
- // when that parent finishes first. The live managed checkout still names
563
- // the shared repository and is the authority for every close operation.
564
- baseSha = resolveLandableBase(wt.path, wt.base_ref);
565
- }
566
- catch (error) {
567
- // A deleted parent base cannot receive a fast-forward. A clean child at
568
- // its recorded creation SHA has nothing to land, however, so conclude its
569
- // deferred cleanup without guessing where work should go.
570
- const head = runGit(wt.path, ['rev-parse', 'HEAD'], 'landed_sha_failed', 'Inspect the worktree checkout manually, then rerun `crtr node worktree close`.');
571
- if (!(error instanceof WorktreeError) || error.code !== 'missing_base_branch' || head !== wt.base_sha)
572
- throw error;
573
- persistClosedWorktreeState(nodeId, wt, 'pending');
574
- return {
575
- node_id: nodeId,
576
- branch: wt.branch,
577
- worktree_path: wt.path,
578
- landed_sha: wt.base_sha,
579
- ...deferredCleanupResult(wt),
580
- };
581
- }
582
- const rebase = gitSync(['rebase', baseSha], wt.path);
583
- if (rebase.status !== 0) {
584
- const detail = (rebase.stderr.trim() || rebase.stdout.trim()).trim();
585
- throw new WorktreeError('rebase_failed', `rebase onto local base branch '${wt.base_ref}' did not complete`, `Resolve conflicts in ${wt.path}, run \`git rebase --continue\` there, then rerun \`crtr node worktree close\`. If the blocker is not mechanical, ask the user with \`crtr human send\`.`, detail);
586
- }
587
- const landedSha = runGit(wt.path, ['rev-parse', 'HEAD'], 'landed_sha_failed', 'Inspect the worktree checkout manually, then rerun `crtr node worktree close`.');
588
- // Fast-forward the local base branch to the worktree tip rebased onto the
589
- // captured baseSha — landing is purely local, nothing is ever pushed to
590
- // origin. Both landing paths require the base to still be exactly at that
591
- // captured tip, so neither can overwrite a concurrent base change.
592
- // Every refusal below leaves a rebased, landable branch that this node ASKED
593
- // to land. Recording that blocked intent is what later authorizes the daemon
594
- // sweep to finish exactly this land once the blocker clears.
595
- const blocked = (message, next, detail) => {
596
- recordBlockedLandIntent(nodeId, message);
597
- return new WorktreeError('land_base_failed', message, next, detail);
598
- };
599
- const fastForward = gitSync(['merge-base', '--is-ancestor', baseSha, landedSha], wt.path);
600
- if (fastForward.status !== 0) {
601
- throw blocked(`rebased worktree is not a fast-forward of local base branch '${wt.base_ref}'`, 'Ask the user with `crtr human send` how to land this managed worktree.', (fastForward.stderr.trim() || fastForward.stdout.trim()).trim());
602
- }
603
- const baseCheckout = checkoutPathForBranch(wt.path, wt.base_ref);
604
- if (baseCheckout !== null) {
605
- const checkoutHead = gitSync(['rev-parse', 'HEAD'], baseCheckout);
606
- const actualHead = checkoutHead.stdout.trim();
607
- if (checkoutHead.status !== 0 || actualHead !== baseSha) {
608
- const detail = checkoutHead.status !== 0
609
- ? (checkoutHead.stderr.trim() || actualHead).trim()
610
- : `expected ${baseSha}, found ${actualHead}`;
611
- throw blocked(`local base branch '${wt.base_ref}' changed while this worktree was closing`, `Reconcile the base checkout at ${baseCheckout}, then rerun \`crtr node worktree close\`. If you are unsure, ask the user with \`crtr human send\`.`, detail);
612
- }
613
- }
614
- let stashNote;
615
- if (baseCheckout !== null) {
616
- const landed = landIntoBaseCheckout(baseCheckout, wt.branch, baseSha, landedSha);
617
- if (!landed.ok) {
618
- throw blocked(`could not fast-forward local base branch '${wt.base_ref}' to this worktree`, `Local base branch '${wt.base_ref}' is checked out at ${baseCheckout} in a state that blocks a fast-forward. Reconcile it there, then rerun \`crtr node worktree close\`. If you are unsure, ask the user with \`crtr human send\`.`, landed.detail);
619
- }
620
- stashNote = landed.stash;
621
- }
622
- else {
623
- const land = gitSync(['update-ref', `refs/heads/${wt.base_ref}`, landedSha, baseSha], wt.path);
624
- if (land.status !== 0) {
625
- throw blocked(`could not fast-forward local base branch '${wt.base_ref}' to this worktree`, 'Ask the user with `crtr human send` how to land this managed worktree.', (land.stderr.trim() || land.stdout.trim()).trim());
626
- }
627
- }
628
- // The caller broker still runs from wt.path after this API response. Do not
629
- // invoke `git worktree remove`: it recursively deletes the caller's cwd and
630
- // a timeout can kill Git between individual unlink operations. Keep the
631
- // checkout and its checked-out branch intact in the named pending-cleanup
632
- // state; the successful land is still the point of no return for this node.
633
- persistClosedWorktreeState(nodeId, wt, 'pending');
634
- return {
635
- node_id: nodeId,
636
- branch: wt.branch,
637
- worktree_path: wt.path,
638
- landed_sha: landedSha,
639
- ...deferredCleanupResult(wt),
640
- ...(stashNote === undefined ? {} : { base_checkout_stash: stashNote }),
641
- };
642
- }
643
- export function closeManagedWorktree(nodeId) {
644
- const wt = openManagedWorktreeForNode(nodeId);
645
- // Preserve the existing precise unknown/no-open-worktree errors without a
646
- // repository to lock; every state-mutating close path runs under the lock.
647
- if (wt === null)
648
- return closeManagedWorktreeLocked(nodeId);
649
- // An absent checkout has no live Git directory; its separate recovery proof
650
- // still relies on the recorded repository path. Every live close locks from
651
- // the child checkout instead of the parent that created it.
652
- return withRepositoryWorktreeLock(existsSync(wt.path) ? wt.path : wt.repo_root, () => closeManagedWorktreeLocked(nodeId));
653
- }
654
- // Push-final auto-drop of a clean, zero-commit managed worktree
655
- /** Delete a source branch only while the ref that proved it already delivered
656
- * is still at the exact inspected SHA. `containingRef` can be the recorded
657
- * local base or that base's remote-tracking upstream. */
658
- function bestEffortDeleteBranchWithContainmentProof(wt, branchSha, containingRef, containingSha) {
659
- const stdin = refDeleteTransactionStdin(wt.branch, branchSha, containingRef, containingSha);
660
- const transaction = gitSync(['update-ref', '--stdin'], wt.repo_root, stdin);
661
- const branchDeleted = transaction.status === 0;
662
- if (branchDeleted)
663
- return { branchDeleted };
664
- const detail = (transaction.stderr.trim() || transaction.stdout.trim()).trim();
665
- return {
666
- branchDeleted,
667
- branchDeleteError: `local branch ${wt.branch} could not be deleted automatically (${detail}); run \`git -C ${shellQuote(wt.repo_root)} branch -D ${shellQuote(wt.branch)}\` after confirming it is merged.`,
668
- };
669
- }
670
- /** A missing checkout can still be concluded, but only from refs: either the
671
- * recorded local branch is already gone, or its tip is contained in the
672
- * recorded base or that base's upstream. Filesystem absence alone proves
673
- * nothing about commits. */
674
- function proveAbsentPathManagedWorktree(wt) {
675
- if (wt.state !== 'open' || existsSync(wt.path))
676
- return null;
677
- const branchRef = `refs/heads/${wt.branch}`;
678
- const branchExists = gitSync(['show-ref', '--verify', '--quiet', branchRef], wt.repo_root);
679
- if (branchExists.status === 1)
680
- return { branchSha: null };
681
- if (branchExists.status !== 0)
682
- return null;
683
- const branch = gitSync(['rev-parse', '--verify', branchRef], wt.repo_root);
684
- if (branch.status !== 0)
685
- return null;
686
- const branchSha = branch.stdout.trim();
687
- // The recorded path being absent does NOT mean the branch has no live
688
- // checkout: `git worktree move` (or a remove-then-re-add elsewhere) can
689
- // relocate it to a different path while leaving `wt.path` gone. Deleting a
690
- // branch that is still checked out somewhere else would bypass Git's own
691
- // checked-out-branch protection and can abandon uncommitted work at that
692
- // other path. Fail closed on any ambiguity from the inspection itself.
693
- const worktreeList = gitSync(['worktree', 'list', '--porcelain'], wt.repo_root);
694
- if (worktreeList.status !== 0)
695
- return null;
696
- if (checkoutPathForBranchInList(worktreeList.stdout, wt.branch) !== null)
697
- return null;
698
- const candidates = [];
699
- const localBaseRef = `refs/heads/${wt.base_ref}`;
700
- const localBaseExists = gitSync(['show-ref', '--verify', '--quiet', localBaseRef], wt.repo_root);
701
- if (localBaseExists.status === 0) {
702
- const localBase = gitSync(['rev-parse', '--verify', localBaseRef], wt.repo_root);
703
- if (localBase.status !== 0)
704
- return null;
705
- candidates.push({ ref: localBaseRef, sha: localBase.stdout.trim() });
706
- }
707
- else if (localBaseExists.status !== 1) {
708
- return null;
709
- }
710
- const upstream = gitSync(['rev-parse', '--symbolic-full-name', '--verify', `${wt.base_ref}@{upstream}`], wt.repo_root);
711
- if (upstream.status === 0) {
712
- const ref = upstream.stdout.trim();
713
- const sha = gitSync(['rev-parse', '--verify', ref], wt.repo_root);
714
- if (ref.startsWith('refs/') && sha.status === 0)
715
- candidates.push({ ref, sha: sha.stdout.trim() });
716
- }
717
- else {
718
- // Managed bases normally track origin. Retained records from before that
719
- // configuration existed can still prove delivery through origin/<base>.
720
- const ref = `refs/remotes/origin/${wt.base_ref}`;
721
- const exists = gitSync(['show-ref', '--verify', '--quiet', ref], wt.repo_root);
722
- if (exists.status === 0) {
723
- const sha = gitSync(['rev-parse', '--verify', ref], wt.repo_root);
724
- if (sha.status === 0)
725
- candidates.push({ ref, sha: sha.stdout.trim() });
726
- }
727
- else if (exists.status !== 1) {
728
- return null;
729
- }
730
- }
731
- for (const candidate of candidates) {
732
- if (gitSync(['merge-base', '--is-ancestor', branchSha, candidate.sha], wt.repo_root).status === 0) {
733
- return { branchSha, containingRef: candidate.ref, containingSha: candidate.sha };
734
- }
735
- }
736
- return null;
737
- }
738
- /** Recovery guidance for a vanished checkout whose refs do not prove that its
739
- * work is delivered. This deliberately never recommends `worktree close`:
740
- * that command cannot operate on the absent checkout. */
741
- export function missingWorktreeRecoveryHint(wt) {
742
- return `The recorded checkout path is gone, but crtr cannot prove ${wt.branch} is already delivered. Push or land ${wt.branch}, then rerun \`crtr push final\`; if you cannot establish what happened to the branch, ask the user with \`crtr human send\`.`;
743
- }
744
- /** Fix B's shared "nothing to land" test — the SAME clean-worktree definition
745
- * `close`'s own dirty check now naturally satisfies once `.git/info/exclude`
746
- * hides crtr's own `.crouter/config.json`/`state.json` bookkeeping (Fix A),
747
- * plus one more requirement close doesn't need: the branch tip must already
748
- * be a git-ancestor of (or equal to) the CURRENT tip of its recorded base
749
- * branch — i.e. landing it would be a pure no-op. Any ambiguity (missing
750
- * path, mid-rebase, wrong branch, an unresolvable base, or a real ancestry
751
- * divergence) returns null. A missing base is the one exception: equality
752
- * between the live HEAD and recorded creation SHA proves no work was added.
753
- * This function only ever proves a no-op land from live Git state, never on
754
- * a heuristic guess, so real unlanded work always falls through to the explicit-close guard. The locked
755
- * path re-checks this predicate before recording deferred cleanup; production
756
- * code must always go through `autoDropCleanManagedWorktree`. */
757
- export function proveCleanEmptyManagedWorktree(wt) {
758
- if (wt.state !== 'open')
759
- return null;
760
- if (!existsSync(wt.path))
761
- return null;
762
- if (isRebaseInProgress(wt.path))
763
- return null;
764
- const branch = gitSync(['rev-parse', '--abbrev-ref', 'HEAD'], wt.path);
765
- if (branch.status !== 0 || branch.stdout.trim() !== wt.branch)
766
- return null;
767
- const status = gitSync(['status', '--porcelain'], wt.path);
768
- if (status.status !== 0 || status.stdout.trim() !== '')
769
- return null;
770
- const head = gitSync(['rev-parse', 'HEAD'], wt.path);
771
- if (head.status !== 0)
772
- return null;
773
- const branchSha = head.stdout.trim();
774
- let baseSha;
775
- try {
776
- baseSha = resolveLandableBase(wt.path, wt.base_ref);
777
- }
778
- catch (error) {
779
- // A parent-first close can remove the recorded base branch. Equality with
780
- // the durable creation SHA proves this clean child never added work.
781
- if (error instanceof WorktreeError && error.code === 'missing_base_branch' && branchSha === wt.base_sha) {
782
- return { branchSha, baseSha: wt.base_sha };
783
- }
784
- throw error;
785
- }
786
- const ancestor = gitSync(['merge-base', '--is-ancestor', branchSha, baseSha], wt.path);
787
- if (ancestor.status !== 0)
788
- return null;
789
- return { branchSha, baseSha };
790
- }
791
- /** Conclude an absent-path record only after `proveAbsentPathManagedWorktree`
792
- * has established the same no-unlanded-work property required by auto-drop.
793
- * There is no checkout left to remove; persistClosedWorktreeState records the
794
- * completed cleanup and repoints cwd to the durable base checkout. */
795
- function autoDropAbsentPathManagedWorktreeLocked(nodeId, wt, proof) {
796
- if (existsSync(wt.path))
797
- return null;
798
- if (proof.branchSha === null) {
799
- persistClosedWorktreeState(nodeId, wt, 'complete');
800
- return { node_id: nodeId, branch: wt.branch, worktree_path: wt.path, worktree_removed: true, branch_deleted: true };
801
- }
802
- if (proof.containingRef === undefined || proof.containingSha === undefined)
803
- return null;
804
- const { branchDeleted } = bestEffortDeleteBranchWithContainmentProof(wt, proof.branchSha, proof.containingRef, proof.containingSha);
805
- if (!branchDeleted)
806
- return null;
807
- persistClosedWorktreeState(nodeId, wt, 'complete');
808
- return { node_id: nodeId, branch: wt.branch, worktree_path: wt.path, worktree_removed: true, branch_deleted: true };
809
- }
810
- /** Re-check a clean auto-drop before closing its record. `push final` runs
811
- * inside the owner broker, so it has the same destructive-cwd boundary as
812
- * explicit close: removal and branch deletion are deferred until that owner
813
- * has exited. */
814
- export function autoDropCleanManagedWorktreeLocked(nodeId, wt, proof) {
815
- const current = proveCleanEmptyManagedWorktree(wt);
816
- if (current === null || current.branchSha !== proof.branchSha)
817
- return null;
818
- // The owner is still running in this checkout while it publishes final.
819
- // Preserve its files and checked-out branch; physical cleanup is explicitly
820
- // recorded as pending rather than racing Git's recursive removal.
821
- persistClosedWorktreeState(nodeId, wt, 'pending');
822
- return {
823
- node_id: nodeId,
824
- branch: wt.branch,
825
- worktree_path: wt.path,
826
- ...deferredCleanupResult(wt),
827
- };
828
- }
829
- /** `push final`'s escape hatch: a managed worktree that has
830
- * nothing to land is auto-dropped instead of blocking on an explicit
831
- * `node worktree close` — one the caller may have been told NOT to run
832
- * because a manager already landed the same change another way, or
833
- * that never had anything to close in the first place (a read-only
834
- * review node). Returns null and changes nothing when the worktree is not
835
- * PROVABLY empty-and-clean by `proveCleanEmptyManagedWorktree`, OR when a
836
- * concurrent mutation invalidates that proof before the record is closed
837
- * (see `autoDropCleanManagedWorktreeLocked`); the caller's existing
838
- * `open_managed_worktree` guard then still applies unchanged — real
839
- * commits, real uncommitted changes, and a lost race all require the
840
- * explicit path. */
841
- function cleanCurrentCheckoutTip(wt) {
842
- if (wt.state !== 'open' || !existsSync(wt.path) || isRebaseInProgress(wt.path))
843
- return null;
844
- const status = gitSync(['status', '--porcelain'], wt.path);
845
- if (status.status !== 0 || status.stdout.trim() !== '')
846
- return null;
847
- const head = gitSync(['rev-parse', 'HEAD'], wt.path);
848
- return head.status === 0 ? head.stdout.trim() : null;
849
- }
850
- export async function branchIsPushedAtCurrentTip(wt) {
851
- const initialTip = cleanCurrentCheckoutTip(wt);
852
- if (initialTip === null)
853
- return false;
854
- // A cached origin branch can be stale in either direction. Query origin's
855
- // heads directly and require exact-tip equality: a remote that has an older
856
- // commit would still leave newer local work stranded at finalization. The
857
- // branch name is deliberately irrelevant because PR workflows publish this
858
- // managed checkout's tip under a human-readable branch name.
859
- // This runs asynchronously with a bounded, non-interactive Git invocation so
860
- // an unreachable remote never stalls crtrd's event loop.
861
- const ssh = process.env['GIT_SSH_COMMAND'] ?? process.env['GIT_SSH'] ?? 'ssh';
862
- const remote = await gitAsync(['ls-remote', '--exit-code', '--heads', 'origin'], wt.path, undefined, { timeoutMs: 10_000, env: { ...process.env, GIT_TERMINAL_PROMPT: '0', GIT_SSH_COMMAND: `${ssh} -o BatchMode=yes` } });
863
- if (remote.status !== 0)
864
- return false;
865
- const remotelyPushed = remote.stdout.split('\n').some((line) => {
866
- const [sha, ref] = line.split('\t', 2);
867
- return sha === initialTip && ref?.startsWith('refs/heads/') === true;
868
- });
869
- if (!remotelyPushed)
870
- return false;
871
- // The remote proof is useful only if the local checkout is still the exact
872
- // clean tip it inspected when finalization begins.
873
- return cleanCurrentCheckoutTip(wt) === initialTip;
874
- }
875
- export function autoDropCleanManagedWorktree(nodeId) {
876
- const wt = openManagedWorktreeForNode(nodeId);
877
- if (wt === null)
878
- return null;
879
- // A negative read-only preflight must fail before waiting on the repository
880
- // mutation lock: real unlanded work should reach push-final's guard promptly.
881
- const pathAbsent = !existsSync(wt.path);
882
- if (pathAbsent ? proveAbsentPathManagedWorktree(wt) === null : proveCleanEmptyManagedWorktree(wt) === null)
883
- return null;
884
- return withRepositoryWorktreeLock(pathAbsent ? wt.repo_root : wt.path, () => {
885
- // Re-fetch inside the lock: state may have changed since the caller's
886
- // hasOpenManagedWorktree check ran outside it.
887
- const locked = openManagedWorktreeForNode(nodeId);
888
- if (locked === null)
889
- return null;
890
- // Re-prove the matching predicate under the lock before changing state.
891
- // A path that reappeared follows the ordinary checkout path.
892
- if (!existsSync(locked.path)) {
893
- const proof = proveAbsentPathManagedWorktree(locked);
894
- return proof === null ? null : autoDropAbsentPathManagedWorktreeLocked(nodeId, locked, proof);
895
- }
896
- const proof = proveCleanEmptyManagedWorktree(locked);
897
- return proof === null ? null : autoDropCleanManagedWorktreeLocked(nodeId, locked, proof);
898
- });
899
- }
1
+ var J=Object.defineProperty;var a=(e,r)=>J(e,"name",{value:r,configurable:!0});import{existsSync as _,mkdirSync as H,readFileSync as V,realpathSync as N,rmSync as Y,writeFileSync as Z}from"node:fs";import{createHash as ee}from"node:crypto";import{dirname as te,isAbsolute as re,join as ne,relative as oe,resolve as C,sep as se}from"node:path";import{gitAsync as ae,gitSync as i}from"./git.js";import{crtrHome as O}from"./canvas/paths.js";import{closeWorktreeAndRepoint as ie,getNode as v,recordLandIntent as ce}from"./canvas/index.js";import{CONFIG_FILE as he,CRTR_DIR_NAME as F,STATE_FILE as ue}from"../types.js";import{withExclusiveDirectoryLock as le}from"./exclusive-lock.js";import{parseStatusPorcelain as de,planLandIntoCheckout as fe,refDeleteTransactionStdin as pe}from"./worktree-landing.js";import{shellQuote as w}from"../shared/shell-quote.js";class f extends Error{static{a(this,"WorktreeError")}code;next;detail;constructor(r,t,n,o){super(t),this.name="WorktreeError",this.code=r,this.next=n,this.detail=o}}function k(e,r,t,n){const o=i(r,e);if(o.status!==0){const s=(o.stderr.trim()||o.stdout.trim()).trim();throw new f(t,`git ${r.join(" ")} failed`,n,s)}return o.stdout.trim()}a(k,"runGit");function I(){return`${O()}/worktrees`}a(I,"managedWorktreesRoot");function me(e){return`${I()}/${e}`}a(me,"managedWorktreePath");function Ke(e){return e?.managed_worktree?.state==="open"}a(Ke,"hasOpenManagedWorktree");function x(e){const t=v(e)?.managed_worktree;return t?.state==="open"?t:null}a(x,"openManagedWorktreeForNode");function be(e){const r=i(["rev-parse","--show-toplevel"],e);if(r.status!==0){const t=(r.stderr.trim()||r.stdout.trim()).trim();throw new f("not_git_repo",`cwd ${e} is not a git repository`,"Pass --cwd <real repo> pointing inside a git repository.",t)}return r.stdout.trim()}a(be,"repoRootFor");function _e(e){const r=oe(S(I()),S(e));return r!==""&&r!==".."&&!r.startsWith(`..${se}`)&&!re(r)}a(_e,"isManagedWorktreeBase");function ke(e,r){const t=`refs/heads/${r}`,n=i(["show-ref","--verify","--quiet",t],e);if(n.status===0)return!0;if(n.status===1&&n.executionFailed!==!0)return!1;const o=n.stderr.trim()||"<empty>",s=n.processError===void 0?"":`
2
+ process error: ${n.processError}`;throw new f("recorded_branch_inspection_failed",`could not inspect recorded branch '${r}' (git show-ref exited with status ${n.status})`,"Inspect the repository and its Git metadata, then retry.",`status: ${n.status}
3
+ stderr: ${o}${s}`)}a(ke,"recordedBranchExists");function A(e,r){const t=`refs/heads/${r}`,n=i(["show-ref","--verify","--quiet",t],e);if(n.status===1&&n.executionFailed!==!0)throw new f("missing_base_branch",`managed worktree base '${r}' does not name an existing local branch`,"The base must be a local branch that landing can fast-forward \u2014 freshen your local branch from origin first (rebase-not-merge), then base on it.");if(n.status!==0){const o=n.stderr.trim()||"<empty>",s=n.processError===void 0?"":`
4
+ process error: ${n.processError}`;throw new f("base_branch_inspection_failed",`could not inspect local base branch '${r}' (git show-ref exited with status ${n.status})`,"Inspect the repository and its Git metadata, then retry.",`status: ${n.status}
5
+ stderr: ${o}${s}`)}return k(e,["rev-parse","--verify",t],"base_branch_resolve_failed","Inspect the local base branch, then retry.")}a(A,"resolveLandableBase");function ge(e,r){const t=k(e,["worktree","list","--porcelain"],"worktree_list_failed","Inspect the repository worktrees manually, then retry.");return q(t,r)}a(ge,"checkoutPathForBranch");function q(e,r){let t=null;for(const n of e.split(`
6
+ `))if(n.startsWith("worktree "))t=n.slice(9).trim();else if(n===`branch refs/heads/${r}`)return t;return null}a(q,"checkoutPathForBranchInList");function we(e,r){return e===r||S(e)===S(r)}a(we,"samePath");function S(e){try{return N.native(e)}catch{return C(e)}}a(S,"canonicalPath");const $e=3e4;function ye(e){const r=`${O()}/worktree-locks`;return H(r,{recursive:!0}),`${r}/${ee("sha256").update(e).digest("hex")}`}a(ye,"worktreeLockPathForCommonDir");function R(e){const r=k(e,["rev-parse","--git-common-dir"],"git_common_dir_failed","Inspect the repository git metadata, then retry.");return N(C(e,r))}a(R,"commonGitDir");function E(e,r){const t=R(e);return le(ye(t),r,{timeoutMs:$e,timeoutError:a(()=>new f("worktree_lock_timeout",`timed out waiting to create a managed worktree in ${t}`,"Wait for the other managed-worktree operation to finish, then retry."),"timeoutError")})}a(E,"withRepositoryWorktreeLock");function D(e,r,t){const n=i(["worktree","list","--porcelain"],e);if(n.status!==0)return null;let o=null;for(const s of n.stdout.split(`
7
+ `))if(s.startsWith("worktree "))o=s.slice(9).trim();else if(o!==null&&we(o,r)&&s===`branch refs/heads/${t}`)return!0;return!1}a(D,"registeredWorktree");function ve(e,r,t){const n=[],o=`refs/heads/${r}`,s=i(["rev-parse","--verify","--quiet",o],e);s.status===0&&n.push({ref:o,sha:s.stdout.trim()});const u=i(["rev-parse","--symbolic-full-name","--verify",`${r}@{upstream}`],e),h=u.status===0&&u.stdout.trim().startsWith("refs/")?u.stdout.trim():`refs/remotes/origin/${r}`,m=i(["rev-parse","--verify","--quiet",h],e);if(m.status===0&&n.push({ref:h,sha:m.stdout.trim()}),n.length===0)return null;for(const d of n)if(i(["merge-base","--is-ancestor",t,d.sha],e).status===0)return{containingRef:d.ref,containingSha:d.sha};for(const d of n){const l=i(["cherry",d.sha,t],e);if(l.status!==0)continue;if(l.stdout.split(`
8
+ `).map(c=>c.trim()).filter(c=>c!=="").every(c=>c.startsWith("-")))return{containingRef:d.ref,containingSha:d.sha}}for(const d of n){const l=i(["rev-parse","--verify",`${d.sha}^{tree}`],e);if(l.status!==0)continue;const b=i(["merge-tree","--write-tree",d.sha,t],e);if(b.status===0&&b.stdout.split(`
9
+ `)[0]?.trim()===l.stdout.trim())return{containingRef:d.ref,containingSha:d.sha}}return null}a(ve,"proveBranchContained");function G(e,r){const t=i(["rev-parse","--verify",`refs/heads/${e.branch}`],e.repo_root);if(t.status!==0||t.stdout.trim()!==e.base_sha)return;const n=D(e.repo_root,e.path,e.branch);if(n!==null){if(n){if(i(["worktree","remove","--force",e.path],e.repo_root).status!==0||D(e.repo_root,e.path,e.branch)!==!1)return}else if(r&&_(e.path))try{Y(e.path,{recursive:!0,force:!0})}catch{return}try{i(["update-ref","-d",`refs/heads/${e.branch}`,e.base_sha],e.repo_root)}catch{}}}a(G,"rollbackManagedWorktreeLocked");function Ue(e){E(e.repo_root,()=>G(e,!1))}a(Ue,"rollbackManagedWorktree");const xe="# crtr: exclude crtr's own untracked project-scope bookkeeping (auto-added at managed-worktree creation)",Se=[`/${F}/${he}`,`/${F}/${ue}`];function Ee(e){try{const r=ne(R(e),"info","exclude");H(te(r),{recursive:!0});let t="";try{t=V(r,"utf8")}catch{}const n=new Set(t.split(`
10
+ `).map(h=>h.trim())),o=Se.filter(h=>!n.has(h));if(o.length===0)return;const u=(t.length>0&&!t.endsWith(`
11
+ `)?`
12
+ `:"")+xe+`
13
+ `+o.join(`
14
+ `)+`
15
+ `;Z(r,t+u)}catch{}}a(Ee,"seedManagedWorktreeExclude");function Xe(e,r,t="main"){const n=be(e);if(_e(n))throw new f("managed_worktree_base",`cwd ${n} is a managed worktree and cannot be used as a managed worktree base`,"Pass --cwd <real repo> pointing at the repository\u2019s primary checkout.");return E(n,()=>{const o=A(n,t),s=me(r),u=`crtr/${r}`;if(_(s))throw new f("worktree_path_exists",`managed worktree path already exists: ${s}`,"Remove the stale path or choose a fresh node id.");if(i(["show-ref","--verify","--quiet",`refs/heads/${u}`],n).status===0)throw new f("worktree_branch_exists",`managed worktree branch already exists: ${u}`,"Remove the stale branch or choose a fresh node id.");const h={state:"open",path:s,branch:u,repo_root:n,base_ref:t,base_sha:o,created:new Date().toISOString()};k(n,["branch",u,o],"worktree_branch_create_failed","Inspect the git error, fix the repository/worktree state, then retry spawning with --worktree.");try{return k(n,["worktree","add",s,u],"worktree_add_failed","Inspect the git error, fix the repository/worktree state, then retry spawning with --worktree."),Ee(n),h}catch(m){throw G(h,!0),m}})}a(Xe,"createManagedWorktree");function De(e){return k(e,["status","--porcelain"],"status_failed","Inspect the worktree manually, then retry.")}a(De,"statusPorcelain");function B(e){return k(e,["rev-parse","--abbrev-ref","HEAD"],"branch_check_failed","Inspect the worktree manually, then retry.")}a(B,"currentBranch");function j(e,r){return k(e,["rev-parse","--git-path",r],"git_path_failed","Inspect the worktree manually, then retry.")}a(j,"gitPath");function M(e){return _(j(e,"rebase-merge"))||_(j(e,"rebase-apply"))}a(M,"isRebaseInProgress");function y(e,r,t="pending"){const n=v(e);ie(e,{cwd:r.repo_root,cleanup:t,closedAt:new Date().toISOString(),unbindSession:n?.pi_session_id!=null||n?.pi_session_file!=null})}a(y,"persistClosedWorktreeState");function We(e,r){const t=v(e)?.managed_worktree;t==null||t.state!=="open"||ce(e,{at:new Date().toISOString(),blocked:r})}a(We,"recordBlockedLandIntent");function Ae(e,r,t,n){const o=i(["status","--porcelain"],e);if(o.status!==0)return{ok:!1,detail:(o.stderr.trim()||o.stdout.trim()).trim()};const s=i(["diff","--name-only",t,n],e);if(s.status!==0)return{ok:!1,detail:(s.stderr.trim()||s.stdout.trim()).trim()};const u=s.stdout.split(`
16
+ `).map(g=>g.trim()).filter(g=>g!==""),h=fe(de(o.stdout),u);if(h.kind==="refuse")return{ok:!1,detail:`untracked files in ${e} would be overwritten by the incoming commits: ${h.collisions.join(", ")}`};const m=a(()=>{const g=i(["merge","--ff-only",n],e);return g.status===0?{ok:!0}:{ok:!1,detail:(g.stderr.trim()||g.stdout.trim()).trim()}},"merge");if(h.kind==="direct")return m();const d=i(["rev-parse","--verify","--quiet","refs/stash"],e),l=d.status===0?d.stdout.trim():null,b=i(["stash","push","--message",`crtr landing ${r}`],e);if(b.status!==0)return{ok:!1,detail:(b.stderr.trim()||b.stdout.trim()).trim()};const c=i(["rev-parse","--verify","--quiet","refs/stash"],e),p=c.status===0?c.stdout.trim():null;if(p===null||p===l)return m();const $=`local changes from ${e} are retained in stash ${p}; recover them with \`git -C ${w(e)} stash apply ${p}\` and resolve any conflict.`,W=m();return W.ok?i(["stash","apply",p],e).status===0?(K(e,p),{ok:!0}):(i(["reset","--hard",n],e),{ok:!0,stash:`the shared base checkout was reset to landed commit ${n} because local changes conflicted with it. ${$}`}):i(["stash","apply",p],e).status===0?(K(e,p),W):{ok:!1,detail:`${W.detail}
17
+ ${$}`}}a(Ae,"landIntoBaseCheckout");function K(e,r){const t=i(["rev-parse","--verify","--quiet","refs/stash"],e);t.status===0&&t.stdout.trim()===r&&i(["stash","drop"],e)}a(K,"dropStashIfStillTip");function T(e){const r=`git -C ${w(e.repo_root)} worktree remove ${w(e.path)}`;return{worktree_removed:!1,worktree_remove_error:`cleanup pending: the caller checkout at ${e.path} remains intact. After its node exits, run \`${r}\` after confirming it is safe to delete.`,branch_deleted:!1,branch_delete_error:`cleanup pending: local branch ${e.branch} remains checked out at ${e.path}; delete it only after that checkout is removed and its landed commit is still contained in ${e.base_ref}.`}}a(T,"deferredCleanupResult");function Re(e,r,t){if(D(r.repo_root,r.path,t)!==!0)throw new f("wrong_branch",`managed worktree's recorded branch ${r.branch} no longer exists, and its checkout at ${r.path} is not registered to ${t} either`,`Inspect ${r.path} and its git worktree registration, then ask the user with \`crtr human send\` if you are unsure how to proceed.`);const n=k(r.path,["rev-parse","HEAD"],"branch_check_failed","Inspect the worktree manually, then retry.");if(ve(r.path,r.base_ref,n)===null)throw new f("branch_moved_unlanded",`managed worktree's recorded branch ${r.branch} no longer exists; its checkout is now on ${t} at ${n}, which carries content local base branch '${r.base_ref}' does not yet contain`,`Land or push ${t} through its own workflow (merge its PR, or fast-forward '${r.base_ref}' to include it) before closing, or ask the user with \`crtr human send\` if you are unsure how ${t} should be delivered.`);const s=R(r.repo_root),u=D(r.repo_root,r.path,t)===!0,h=B(r.path)===t,m=k(r.path,["rev-parse","HEAD"],"branch_check_failed","Inspect the worktree manually, then retry.")===n;if(!u||!h||!m)throw new f("wrong_branch",`managed worktree at ${r.path} changed while closing`,`Inspect ${r.path}, then rerun \`crtr node worktree close\`.`);const d={observed_branch:t,observed_sha:n,common_dir:s,authorized:new Date().toISOString()};y(e,{...r,disposal:d},"pending");const l=`git -C ${w(r.repo_root)} worktree remove ${w(r.path)}`;return{node_id:e,branch:t,worktree_path:r.path,landed_sha:n,worktree_removed:!1,worktree_remove_error:`cleanup pending: the caller checkout at ${r.path} remains intact. After its node exits, run \`${l}\` after confirming it is safe to delete.`,branch_deleted:!1,branch_delete_error:`${t} is not a crtr-managed branch and will never be deleted automatically; it is preserved once the checkout above is removed.`}}a(Re,"closeBranchMovedWorktree");function Me(e,r){const t=v(e)?.managed_worktree;if(t==null)return{message:`node ${e} has no managed worktree`,next:`Nothing to ${r} for this node.`};if(t.state==="abandoned"){const n=t.abandoned?.branch??t.branch;return{message:`node ${e}'s managed worktree was already abandoned`,next:`Nothing to ${r} for this node; its work was retained on branch ${n}.`}}return t.state==="closed"?t.cleanup==="complete"?{message:`node ${e}'s managed worktree is already closed and its cleanup is complete`,next:`Nothing to ${r} for this node.`}:{message:`node ${e}'s managed worktree is already closed; this is not lost ownership \u2014 its checkout at ${t.path} is scheduled for automatic cleanup once that is safe`,next:`Nothing to ${r} for this node. The daemon sweep finishes removing ${t.path} on its own; inspect it directly only if it still needs manual attention.`}:{message:`node ${e} has no open managed worktree`,next:`Nothing to ${r} for this node.`}}a(Me,"noManagedWorktreeMessage");function U(e){if(v(e)===null)throw new f("unknown_node",`unknown node: ${e}`,"Run this from a live node, or pass a real node id once that command supports it.");const t=x(e);if(t===null){const{message:c,next:p}=Me(e,"close");throw new f("no_managed_worktree",c,p)}if(!_(t.path)){const c=P(t);if(c===null)throw new f("worktree_missing",`managed worktree path is missing: ${t.path}`,X(t));if(z(e,t,c)===null)throw new f("worktree_missing",`managed worktree path is missing: ${t.path}`,X(t));return{node_id:e,branch:t.branch,worktree_path:t.path,landed_sha:c.branchSha??t.base_sha,worktree_removed:!0,branch_deleted:!0}}if(M(t.path))throw new f("rebase_in_progress","this managed worktree is mid-rebase",`Resolve conflicts in ${t.path}, run \`git rebase --continue\` there, then rerun \`crtr node worktree close\`.`);if(De(t.path)!=="")throw new f("dirty_worktree","managed worktree has uncommitted changes",`Commit the work in ${t.path} (or ask the user with \`crtr human send\` if you do not know whether to keep it), then rerun \`crtr node worktree close\`.`);const o=B(t.path);if(o!==t.branch){const c=o==="HEAD"?"detached HEAD":o,p=ke(t.path,t.branch);if(p||o==="HEAD")throw new f("wrong_branch",`managed worktree is not on its recorded branch (expected ${t.branch}, found ${c})`,p?`Check out ${t.branch} in ${t.path} before closing, or ask the user with \`crtr human send\` if you are unsure why it changed, then rerun \`crtr node worktree close\`.`:`The recorded branch ${t.branch} no longer exists, and ${t.path} is in detached HEAD, so there is no branch to preserve. Check out or create a branch there before closing, or ask the user with \`crtr human send\` if you are unsure how to proceed.`);return Re(e,t,o)}let s;try{s=A(t.path,t.base_ref)}catch(c){const p=k(t.path,["rev-parse","HEAD"],"landed_sha_failed","Inspect the worktree checkout manually, then rerun `crtr node worktree close`.");if(!(c instanceof f)||c.code!=="missing_base_branch"||p!==t.base_sha)throw c;return y(e,t,"pending"),{node_id:e,branch:t.branch,worktree_path:t.path,landed_sha:t.base_sha,...T(t)}}const u=i(["rebase",s],t.path);if(u.status!==0){const c=(u.stderr.trim()||u.stdout.trim()).trim();throw new f("rebase_failed",`rebase onto local base branch '${t.base_ref}' did not complete`,`Resolve conflicts in ${t.path}, run \`git rebase --continue\` there, then rerun \`crtr node worktree close\`. If the blocker is not mechanical, ask the user with \`crtr human send\`.`,c)}const h=k(t.path,["rev-parse","HEAD"],"landed_sha_failed","Inspect the worktree checkout manually, then rerun `crtr node worktree close`."),m=a((c,p,$)=>(We(e,c),new f("land_base_failed",c,p,$)),"blocked"),d=i(["merge-base","--is-ancestor",s,h],t.path);if(d.status!==0)throw m(`rebased worktree is not a fast-forward of local base branch '${t.base_ref}'`,"Ask the user with `crtr human send` how to land this managed worktree.",(d.stderr.trim()||d.stdout.trim()).trim());const l=ge(t.path,t.base_ref);if(l!==null){const c=i(["rev-parse","HEAD"],l),p=c.stdout.trim();if(c.status!==0||p!==s){const $=c.status!==0?(c.stderr.trim()||p).trim():`expected ${s}, found ${p}`;throw m(`local base branch '${t.base_ref}' changed while this worktree was closing`,`Reconcile the base checkout at ${l}, then rerun \`crtr node worktree close\`. If you are unsure, ask the user with \`crtr human send\`.`,$)}}let b;if(l!==null){const c=Ae(l,t.branch,s,h);if(!c.ok)throw m(`could not fast-forward local base branch '${t.base_ref}' to this worktree`,`Local base branch '${t.base_ref}' is checked out at ${l} in a state that blocks a fast-forward. Reconcile it there, then rerun \`crtr node worktree close\`. If you are unsure, ask the user with \`crtr human send\`.`,c.detail);b=c.stash}else{const c=i(["update-ref",`refs/heads/${t.base_ref}`,h,s],t.path);if(c.status!==0)throw m(`could not fast-forward local base branch '${t.base_ref}' to this worktree`,"Ask the user with `crtr human send` how to land this managed worktree.",(c.stderr.trim()||c.stdout.trim()).trim())}return y(e,t,"pending"),{node_id:e,branch:t.branch,worktree_path:t.path,landed_sha:h,...T(t),...b===void 0?{}:{base_checkout_stash:b}}}a(U,"closeManagedWorktreeLocked");function ze(e){const r=x(e);return r===null?U(e):E(_(r.path)?r.path:r.repo_root,()=>U(e))}a(ze,"closeManagedWorktree");function Te(e,r,t,n){const o=pe(e.branch,r,t,n),s=i(["update-ref","--stdin"],e.repo_root,o),u=s.status===0;if(u)return{branchDeleted:u};const h=(s.stderr.trim()||s.stdout.trim()).trim();return{branchDeleted:u,branchDeleteError:`local branch ${e.branch} could not be deleted automatically (${h}); run \`git -C ${w(e.repo_root)} branch -D ${w(e.branch)}\` after confirming it is merged.`}}a(Te,"bestEffortDeleteBranchWithContainmentProof");function P(e){if(e.state!=="open"||_(e.path))return null;const r=`refs/heads/${e.branch}`,t=i(["show-ref","--verify","--quiet",r],e.repo_root);if(t.status===1)return{branchSha:null};if(t.status!==0)return null;const n=i(["rev-parse","--verify",r],e.repo_root);if(n.status!==0)return null;const o=n.stdout.trim(),s=i(["worktree","list","--porcelain"],e.repo_root);if(s.status!==0||q(s.stdout,e.branch)!==null)return null;const u=[],h=`refs/heads/${e.base_ref}`,m=i(["show-ref","--verify","--quiet",h],e.repo_root);if(m.status===0){const l=i(["rev-parse","--verify",h],e.repo_root);if(l.status!==0)return null;u.push({ref:h,sha:l.stdout.trim()})}else if(m.status!==1)return null;const d=i(["rev-parse","--symbolic-full-name","--verify",`${e.base_ref}@{upstream}`],e.repo_root);if(d.status===0){const l=d.stdout.trim(),b=i(["rev-parse","--verify",l],e.repo_root);l.startsWith("refs/")&&b.status===0&&u.push({ref:l,sha:b.stdout.trim()})}else{const l=`refs/remotes/origin/${e.base_ref}`,b=i(["show-ref","--verify","--quiet",l],e.repo_root);if(b.status===0){const c=i(["rev-parse","--verify",l],e.repo_root);c.status===0&&u.push({ref:l,sha:c.stdout.trim()})}else if(b.status!==1)return null}for(const l of u)if(i(["merge-base","--is-ancestor",o,l.sha],e.repo_root).status===0)return{branchSha:o,containingRef:l.ref,containingSha:l.sha};return null}a(P,"proveAbsentPathManagedWorktree");function X(e){return`The recorded checkout path is gone, but crtr cannot prove ${e.branch} is already delivered. Push or land ${e.branch}, then rerun \`crtr push final\`; if you cannot establish what happened to the branch, ask the user with \`crtr human send\`.`}a(X,"missingWorktreeRecoveryHint");function L(e){if(e.state!=="open"||!_(e.path)||M(e.path))return null;const r=i(["rev-parse","--abbrev-ref","HEAD"],e.path);if(r.status!==0||r.stdout.trim()!==e.branch)return null;const t=i(["status","--porcelain"],e.path);if(t.status!==0||t.stdout.trim()!=="")return null;const n=i(["rev-parse","HEAD"],e.path);if(n.status!==0)return null;const o=n.stdout.trim();let s;try{s=A(e.path,e.base_ref)}catch(h){if(h instanceof f&&h.code==="missing_base_branch"&&o===e.base_sha)return{branchSha:o,baseSha:e.base_sha};throw h}return i(["merge-base","--is-ancestor",o,s],e.path).status!==0?null:{branchSha:o,baseSha:s}}a(L,"proveCleanEmptyManagedWorktree");function z(e,r,t){if(_(r.path))return null;if(t.branchSha===null)return y(e,r,"complete"),{node_id:e,branch:r.branch,worktree_path:r.path,worktree_removed:!0,branch_deleted:!0};if(t.containingRef===void 0||t.containingSha===void 0)return null;const{branchDeleted:n}=Te(r,t.branchSha,t.containingRef,t.containingSha);return n?(y(e,r,"complete"),{node_id:e,branch:r.branch,worktree_path:r.path,worktree_removed:!0,branch_deleted:!0}):null}a(z,"autoDropAbsentPathManagedWorktreeLocked");function Pe(e,r,t){const n=L(r);return n===null||n.branchSha!==t.branchSha?null:(y(e,r,"pending"),{node_id:e,branch:r.branch,worktree_path:r.path,...T(r)})}a(Pe,"autoDropCleanManagedWorktreeLocked");function Q(e){if(e.state!=="open"||!_(e.path)||M(e.path))return null;const r=i(["status","--porcelain"],e.path);if(r.status!==0||r.stdout.trim()!=="")return null;const t=i(["rev-parse","HEAD"],e.path);return t.status===0?t.stdout.trim():null}a(Q,"cleanCurrentCheckoutTip");async function Qe(e){const r=Q(e);if(r===null)return!1;const t=process.env.GIT_SSH_COMMAND??process.env.GIT_SSH??"ssh",n=await ae(["ls-remote","--exit-code","--heads","origin"],e.path,void 0,{timeoutMs:1e4,env:{...process.env,GIT_TERMINAL_PROMPT:"0",GIT_SSH_COMMAND:`${t} -o BatchMode=yes`}});return n.status!==0||!n.stdout.split(`
18
+ `).some(s=>{const[u,h]=s.split(" ",2);return u===r&&h?.startsWith("refs/heads/")===!0})?!1:Q(e)===r}a(Qe,"branchIsPushedAtCurrentTip");function Je(e){const r=x(e);if(r===null)return null;const t=!_(r.path);return(t?P(r)===null:L(r)===null)?null:E(t?r.repo_root:r.path,()=>{const n=x(e);if(n===null)return null;if(!_(n.path)){const s=P(n);return s===null?null:z(e,n,s)}const o=L(n);return o===null?null:Pe(e,n,o)})}a(Je,"autoDropCleanManagedWorktree");export{$e as WORKTREE_LOCK_WAIT_MS,f as WorktreeError,Je as autoDropCleanManagedWorktree,Pe as autoDropCleanManagedWorktreeLocked,Qe as branchIsPushedAtCurrentTip,q as checkoutPathForBranchInList,ze as closeManagedWorktree,Xe as createManagedWorktree,Ke as hasOpenManagedWorktree,_e as isManagedWorktreeBase,M as isRebaseInProgress,me as managedWorktreePath,I as managedWorktreesRoot,X as missingWorktreeRecoveryHint,x as openManagedWorktreeForNode,y as persistClosedWorktreeState,L as proveCleanEmptyManagedWorktree,Ue as rollbackManagedWorktree,we as samePath,ye as worktreeLockPathForCommonDir};