glimmervoid 0.44.1 → 0.45.0

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 (163) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/glimmervoid.js +8 -8
  3. package/dist/chunks/{adapters-B2IgKmuZ.js → adapters-BGuI5U_-.js} +1 -1
  4. package/dist/chunks/{adapters-BsoXEvlZ.js → adapters-D99c4zCx.js} +2 -2
  5. package/dist/chunks/{agent-api-cli-DIl92JjQ.js → agent-api-cli-DIGH1v3_.js} +1 -1
  6. package/dist/chunks/{agent-api-cli-B-QxkZAQ.js → agent-api-cli-DdrR2vnB.js} +1 -1
  7. package/dist/chunks/{agent-api-core-BCFplxXu.js → agent-api-core-D49OzKho.js} +2 -2
  8. package/dist/chunks/{config-Dh4e-Mkv.js → config-BLeRKmn9.js} +21 -2
  9. package/dist/chunks/{config-store-CEsetno2.js → config-store-CXLnauAa.js} +2 -2
  10. package/dist/chunks/config-store-DlaaBY9p.js +1 -0
  11. package/dist/chunks/{contracts-dj-GFptp.js → contracts-CucdticH.js} +19 -10
  12. package/dist/chunks/{main-CA3ONCUS.js → main-CX9CkTDx.js} +408 -44
  13. package/dist/chunks/{pair-cli-CWHMbInF.js → pair-cli-BPyh48--.js} +2 -2
  14. package/dist/chunks/{remote-config-CtcoO10O.js → remote-config-B0zBDBak.js} +1 -1
  15. package/dist/chunks/{settings-cli-DGOkkmW-.js → settings-cli-DzIasX94.js} +4 -4
  16. package/dist/chunks/{settings-readout-core-BVb6tTLq.js → settings-readout-core-BOv6tqdK.js} +1 -1
  17. package/dist/chunks/{ssh-sign-cli-BdvvBKkj.js → ssh-sign-cli-C_QYhDvI.js} +1 -1
  18. package/dist/client/assets/action-status-DrMQzohk.js +1 -0
  19. package/dist/client/assets/action-status-DrMQzohk.js.br +0 -0
  20. package/dist/client/assets/benchmark-panel-D09qvrAY.js +1 -0
  21. package/dist/client/assets/benchmark-panel-D09qvrAY.js.br +0 -0
  22. package/dist/client/assets/dom-helpers-CZ8NZKxw.js +4 -0
  23. package/dist/client/assets/dom-helpers-CZ8NZKxw.js.br +0 -0
  24. package/dist/client/assets/hooks-panel-R-L7DuIz.js +1 -0
  25. package/dist/client/assets/hooks-panel-R-L7DuIz.js.br +0 -0
  26. package/dist/client/assets/index-B7TvZo7W.js +173 -0
  27. package/dist/client/assets/index-B7TvZo7W.js.br +0 -0
  28. package/dist/client/assets/index-C3nOrTwM.css +2 -0
  29. package/dist/client/assets/index-C3nOrTwM.css.br +0 -0
  30. package/dist/client/assets/issues-panel-CyB4oq9Z.js +1 -0
  31. package/dist/client/assets/issues-panel-CyB4oq9Z.js.br +0 -0
  32. package/dist/client/assets/modal-M_mJ8--V.js +1 -0
  33. package/dist/client/assets/modal-M_mJ8--V.js.br +0 -0
  34. package/dist/client/assets/poll-ago-ItO-gOWA.js +1 -0
  35. package/dist/client/assets/poll-ago-ItO-gOWA.js.br +0 -0
  36. package/dist/client/assets/pr-queue-columns-Cu3-PADL.js +1 -0
  37. package/dist/client/assets/pr-queue-columns-Cu3-PADL.js.br +0 -0
  38. package/dist/client/assets/radar-panel-Cl3yPWed.js +1 -0
  39. package/dist/client/assets/radar-panel-Cl3yPWed.js.br +0 -0
  40. package/dist/client/assets/review-queue-panel-CVujzadC.js +2 -0
  41. package/dist/client/assets/review-queue-panel-CVujzadC.js.br +0 -0
  42. package/dist/client/assets/settings-panel-DW5An8lQ.js +3 -0
  43. package/dist/client/assets/settings-panel-DW5An8lQ.js.br +0 -0
  44. package/dist/client/assets/sprite-bee-DwCVghaj.png +0 -0
  45. package/dist/client/assets/sprite-cat-DRx9MYM3.png +0 -0
  46. package/dist/client/assets/sprite-cow-BX3Phf6B.png +0 -0
  47. package/dist/client/assets/sprite-deer-DwQYMzDV.png +0 -0
  48. package/dist/client/assets/sprite-dragon-CTIHOQJ3.png +0 -0
  49. package/dist/client/assets/sprite-fox-BI43RV3z.png +0 -0
  50. package/dist/client/assets/sprite-frog-CwGTpt-c.png +0 -0
  51. package/dist/client/assets/sprite-giraffe-DwM3MmKG.png +0 -0
  52. package/dist/client/assets/sprite-hamster-WN4q03Wr.png +0 -0
  53. package/dist/client/assets/sprite-hedgehog-CM9XZtPS.png +0 -0
  54. package/dist/client/assets/sprite-horse-B5CMO0Ue.png +0 -0
  55. package/dist/client/assets/sprite-owl-BybpXmvP.png +0 -0
  56. package/dist/client/assets/sprite-panda-DxAHDNb3.png +0 -0
  57. package/dist/client/assets/sprite-penguin-Du588fg8.png +0 -0
  58. package/dist/client/assets/sprite-pig-BTuwvuhq.png +0 -0
  59. package/dist/client/assets/sprite-red-panda-5y9J8xSy.png +0 -0
  60. package/dist/client/assets/sprite-sheep-vHUTjc5U.png +0 -0
  61. package/dist/client/assets/sprite-unicorn-CJ3g8Zet.png +0 -0
  62. package/dist/client/assets/sprite-whale-C3Galw4z.png +0 -0
  63. package/dist/client/assets/trace-panel-B6TiM5pb.js +1 -0
  64. package/dist/client/assets/trace-panel-B6TiM5pb.js.br +0 -0
  65. package/dist/client/assets/trail-acacia-5Fr79eBl.png +0 -0
  66. package/dist/client/assets/trail-acacia-frame2-D83GtoaY.png +0 -0
  67. package/dist/client/assets/trail-acacia-frame3-BBXTo5I-.png +0 -0
  68. package/dist/client/assets/trail-acacia-frame4-Xv9ZEsyD.png +0 -0
  69. package/dist/client/assets/trail-acorns-BOCEZemb.png +0 -0
  70. package/dist/client/assets/trail-acorns-frame2-BhHnaBud.png +0 -0
  71. package/dist/client/assets/trail-acorns-frame3-DKXXievy.png +0 -0
  72. package/dist/client/assets/trail-acorns-frame4-Ch2VXeMA.png +0 -0
  73. package/dist/client/assets/trail-bamboo-GqKJxCTV.png +0 -0
  74. package/dist/client/assets/trail-bamboo-frame2-bHacG8f_.png +0 -0
  75. package/dist/client/assets/trail-bamboo-frame3-CaoctCwJ.png +0 -0
  76. package/dist/client/assets/trail-bamboo-frame4-CqBfq3ff.png +0 -0
  77. package/dist/client/assets/trail-bubbles-frame2-eNpysXFZ.png +0 -0
  78. package/dist/client/assets/trail-bubbles-frame3-CWwqOJLM.png +0 -0
  79. package/dist/client/assets/trail-bubbles-frame4-Dj9TUXsV.png +0 -0
  80. package/dist/client/assets/trail-bubbles-pZ5FzCq7.png +0 -0
  81. package/dist/client/assets/trail-clouds-D18nQlSc.png +0 -0
  82. package/dist/client/assets/trail-clouds-frame2-W-_5l_i2.png +0 -0
  83. package/dist/client/assets/trail-clouds-frame3-CGQnOEBI.png +0 -0
  84. package/dist/client/assets/trail-clouds-frame4-CvlkFN6d.png +0 -0
  85. package/dist/client/assets/trail-clover-Ci7hUdO0.png +0 -0
  86. package/dist/client/assets/trail-clover-frame2-Z6NRhQ3U.png +0 -0
  87. package/dist/client/assets/trail-clover-frame3-0srIKU22.png +0 -0
  88. package/dist/client/assets/trail-clover-frame4-BO9UjM_-.png +0 -0
  89. package/dist/client/assets/trail-daisies-DVEPmnHq.png +0 -0
  90. package/dist/client/assets/trail-daisies-frame2-C_3-bnO5.png +0 -0
  91. package/dist/client/assets/trail-daisies-frame3-CR7GzXzm.png +0 -0
  92. package/dist/client/assets/trail-daisies-frame4-CKQDb8cR.png +0 -0
  93. package/dist/client/assets/trail-dust-Cf48D_ja.png +0 -0
  94. package/dist/client/assets/trail-dust-frame2-DAisulyH.png +0 -0
  95. package/dist/client/assets/trail-dust-frame3-BLi-DUzo.png +0 -0
  96. package/dist/client/assets/trail-dust-frame4-DGXo_Q2f.png +0 -0
  97. package/dist/client/assets/trail-embers-c-vlGDDo.png +0 -0
  98. package/dist/client/assets/trail-embers-frame2-wCK1DXpW.png +0 -0
  99. package/dist/client/assets/trail-embers-frame3-C5QS1ZRt.png +0 -0
  100. package/dist/client/assets/trail-embers-frame4-DA-O9bwZ.png +0 -0
  101. package/dist/client/assets/trail-hearts-DQwkXjr0.png +0 -0
  102. package/dist/client/assets/trail-hearts-frame2-DbyTUdl2.png +0 -0
  103. package/dist/client/assets/trail-hearts-frame3-XHaluU_W.png +0 -0
  104. package/dist/client/assets/trail-hearts-frame4-BA0W9inL.png +0 -0
  105. package/dist/client/assets/trail-honey-BC7CvXOJ.png +0 -0
  106. package/dist/client/assets/trail-honey-frame2-C4tRQx2J.png +0 -0
  107. package/dist/client/assets/trail-honey-frame3-V4pdDsZr.png +0 -0
  108. package/dist/client/assets/trail-honey-frame4-BqfUOIZk.png +0 -0
  109. package/dist/client/assets/trail-leaves-Di39skyY.png +0 -0
  110. package/dist/client/assets/trail-leaves-frame2-Dibep-05.png +0 -0
  111. package/dist/client/assets/trail-leaves-frame3-ByxojOFR.png +0 -0
  112. package/dist/client/assets/trail-leaves-frame4-CQGuAWJE.png +0 -0
  113. package/dist/client/assets/trail-logomarks-eIe8WIQx.png +0 -0
  114. package/dist/client/assets/trail-logomarks-frame2-Dw7X4i4F.png +0 -0
  115. package/dist/client/assets/trail-logomarks-frame3-CwoFgR8k.png +0 -0
  116. package/dist/client/assets/trail-logomarks-frame4-B7tFxRZO.png +0 -0
  117. package/dist/client/assets/trail-paws-C4cgGpTt.png +0 -0
  118. package/dist/client/assets/trail-paws-frame2-D8gNCPFb.png +0 -0
  119. package/dist/client/assets/trail-paws-frame3-BiEhbm80.png +0 -0
  120. package/dist/client/assets/trail-paws-frame4-BLLXXSyZ.png +0 -0
  121. package/dist/client/assets/trail-rainbow-BavE03WZ.png +0 -0
  122. package/dist/client/assets/trail-rainbow-frame2-BGZ7ZuQD.png +0 -0
  123. package/dist/client/assets/trail-rainbow-frame3-CY3FOgWe.png +0 -0
  124. package/dist/client/assets/trail-rainbow-frame4-DPWH6W3T.png +0 -0
  125. package/dist/client/assets/trail-seeds-BVCYzFRY.png +0 -0
  126. package/dist/client/assets/trail-seeds-frame2-CgopUUJh.png +0 -0
  127. package/dist/client/assets/trail-seeds-frame3-D2rIJzox.png +0 -0
  128. package/dist/client/assets/trail-seeds-frame4-WbnqCHlJ.png +0 -0
  129. package/dist/client/assets/trail-snow-BmXmGNtx.png +0 -0
  130. package/dist/client/assets/trail-snow-frame2-BQC5GITf.png +0 -0
  131. package/dist/client/assets/trail-snow-frame3-1GIpb4hr.png +0 -0
  132. package/dist/client/assets/trail-snow-frame4-BB4B66p3.png +0 -0
  133. package/dist/client/assets/trail-sparkles-D3Ivb6ob.png +0 -0
  134. package/dist/client/assets/trail-sparkles-frame2-DR03q4T0.png +0 -0
  135. package/dist/client/assets/trail-sparkles-frame3-DtdWWuVM.png +0 -0
  136. package/dist/client/assets/trail-sparkles-frame4-ea8pBjiu.png +0 -0
  137. package/dist/client/assets/trail-stars-EgySiFbH.png +0 -0
  138. package/dist/client/assets/trail-stars-frame2-BOXk5jcm.png +0 -0
  139. package/dist/client/assets/trail-stars-frame3-DJ2AW0RA.png +0 -0
  140. package/dist/client/assets/trail-stars-frame4-BcSJ1AVu.png +0 -0
  141. package/dist/client/assets/ui-prefs-CQHZFVx6.js +1 -0
  142. package/dist/client/assets/ui-prefs-CQHZFVx6.js.br +0 -0
  143. package/dist/client/assets/usage-panel-D2RX3LtG.js +1 -0
  144. package/dist/client/assets/usage-panel-D2RX3LtG.js.br +0 -0
  145. package/dist/client/assets/visions-panel-BV9EKCBw.js +1 -0
  146. package/dist/client/assets/visions-panel-BV9EKCBw.js.br +0 -0
  147. package/dist/client/assets/xterm-BdQ2Kshh.js +79 -0
  148. package/dist/client/assets/xterm-BdQ2Kshh.js.br +0 -0
  149. package/dist/client/assets/zod-BRLv4KqJ.js.br +0 -0
  150. package/dist/client/fonts/CommitMono-OFL.txt.br +0 -0
  151. package/dist/client/fonts/commit-mono-400-regular-core.woff2 +0 -0
  152. package/dist/client/fonts/commit-mono-700-regular-core.woff2 +0 -0
  153. package/dist/client/index.html +7 -3
  154. package/dist/client/index.html.br +0 -0
  155. package/dist/client/octicons-LICENSE.txt.br +3 -0
  156. package/dist/server/index.js +1 -1
  157. package/package.json +1 -1
  158. package/dist/chunks/config-store-DVwdcnub.js +0 -1
  159. package/dist/client/assets/index-BR-wN5UF.js +0 -177
  160. package/dist/client/assets/index-QxVyoSUP.css +0 -2
  161. package/dist/client/assets/xterm-kR64YvZ-.js +0 -79
  162. package/dist/client/fonts/commit-mono-400-italic.woff2 +0 -0
  163. package/dist/client/fonts/commit-mono-700-italic.woff2 +0 -0
@@ -4,9 +4,9 @@ import { a as sanitizeWorktreeName, i as safePathSegment, n as equalsIgnoringCas
4
4
  import { c as resolvePackageBin, i as clientDir, n as bundled, o as packageRoot, r as cliPath, s as relayPath, t as assetRoot } from "./runtime-paths-ghcH9CeW.js";
5
5
  import { $ as MyPrMergeWhenReadyRequest, $t as RESTARTABLE_STATES, A as SESSION_NAME_RULE_TEXT, At as TeamReviewStateEntry, Bt as HEX_SHA_RE, C as ConversationQuestion, Ct as ReviewResult, D as SESSION_DOC_BODY_CAP_BYTES, Et as TeamReviewActionRequest, Ft as canApproveAfterComment, G as MyPrCheckContextsResponse, Gt as repoParts, H as MyPr, Ht as GH_SEGMENT, It as decisionAsIfApprovalRequired, J as MyPrLaneEntry, K as MyPrKeepMergeableRequest, L as SshSignRequest, M as SSH_SIGN_BODY_CAP_BYTES, Mt as TeamReviewThreadCommentsResponse, Nt as TeamReviewThreadResult, Ot as TeamReviewCompareFiles, Pt as TeamReviewThreadsRepository, Q as MyPrMergeStateResponse, Qt as MERGEABLE_LIVE_STATES, Rt as hasStandingViewerApproval, St as ReviewFinding, Tt as ReviewVerdict, U as MyPrAutoRebase, Ut as NODE_ID_RE, V as LinkedPr, Vt as shortSha, W as MyPrCheckContext, Wt as REPO_SLUG_RE, X as MyPrMergeRequest, Xt as BADGE_LABELS, Y as MyPrMergeMethod, Zt as KILLABLE_STATES, _ as CONVERSATION_PERMISSION_HOOK_EVENT, _t as PrDetail, at as MyPrsState, bt as ReviewComment, dt as DECIDING_REVIEW_STATES, en as STATES, ft as EarlierReview, g as CONVERSATION_APPROVAL_SUMMARY_MAX_CHARS, gt as PostingPlan, h as COHERENCE_HOOKS_INACTIVE, ht as GithubReviewState, it as MyPrsSnapshot, j as SIGN_URL_ENV, jt as TeamReviewStatus, k as SESSION_NAME_PATTERN, kt as TeamReviewResolveResponse, n as AGENT_URL_ENV, nt as MyPrThreadNode, pt as FindingSeverity, r as ASK_USER_QUESTION_TOOL_NAME, rt as MyPrThreadsResponse, ut as CommitSha, v as CONVERSATION_TOOL_RESULT_HOOK_EVENT, vt as QueuedReview, wt as ReviewThreadId, xt as ReviewDraft, z as TaskTitle } from "./session-CUc6d7aS.js";
6
6
  import { n as execFileAsync, o as spawn, r as execFileSync, t as execFile } from "./child-process-safe-D4hyVIXj.js";
7
- import { A as BenchmarkStatus, At as GithubIssueResponse, B as comparablePrKey, Ct as PLAN_RESULT_HOOK_EVENT, D as BenchmarkId, Dt as parseExitPlanModeHookPayload, E as BenchmarkCase, Et as PlanRevision, F as PrCheckoutCaseInput, Ft as IssuesStatus, H as WorkflowLabelName, I as GithubPrDetailNode, It as issuePullRequestStateFromGithub, L as GithubPrKey, M as CommitComparison, Mt as IssueUpdate, N as MergedPrListing, Nt as IssuesSearchResponse, O as BenchmarkJudgement, Ot as planTitle, P as MinedPrReviewData, Pt as IssuesState, R as GithubPrLightSearchNode, St as PLAN_HOOK_OUTPUT_MAX_CHARS, T as BenchmarkActionRequest, Tt as PlanDecision, U as WorkflowsSettings, V as WorkflowCommentBody, W as WorkflowsState, Y as KEEP_MERGEABLE_TIMEOUT_MINUTES_RANGE, _ as ClientMessage, _t as CoherenceJournalOutput, a as ConfigUpdate, bt as PLAN_BODY_CAP_BYTES, ft as UpdateJournal, g as CONTROL_FRAME_MAX_BYTES, gt as TraceRecord, ht as TraceCheckpoint, j as BenchmarkSuite, jt as IssueKey, k as BenchmarkRun, kt as GithubIssuePullRequestsRepository, l as configIssueMessage, m as USAGE_VENDOR_KEYS, mt as MAX_RAW_LINE_CHARS, p as USAGE_COST_MODES, pt as SessionSetup, r as BrowserConfig, s as RUNTIME_CONFIG_SCALAR_KEYS, st as USAGE_INTEGER_RANGES, vt as ChangeMap, w as pullRequestKeyFromReference, wt as PLAN_TOOL_NAME, xt as PLAN_HOOK_EVENT, yt as changeMapFactId, z as GithubPrsFrame } from "./config-Dh4e-Mkv.js";
7
+ import { A as BenchmarkId, At as parseExitPlanModeHookPayload, B as GithubPrKey, Ct as PLAN_BODY_CAP_BYTES, D as pullRequestKeyFromReference, Dt as PLAN_TOOL_NAME, Et as PLAN_RESULT_HOOK_EVENT, F as CommitComparison, Ft as IssueUpdate, G as WorkflowLabelName, H as GithubPrsFrame, I as MergedPrListing, It as IssuesSearchResponse, K as WorkflowsSettings, L as MinedPrReviewData, Lt as IssuesState, M as BenchmarkRun, Mt as GithubIssuePullRequestsRepository, N as BenchmarkStatus, Nt as GithubIssueResponse, O as BenchmarkActionRequest, Ot as PlanDecision, P as BenchmarkSuite, Pt as IssueKey, Q as KEEP_MERGEABLE_TIMEOUT_MINUTES_RANGE, R as PrCheckoutCaseInput, Rt as IssuesStatus, St as changeMapFactId, Tt as PLAN_HOOK_OUTPUT_MAX_CHARS, U as comparablePrKey, V as GithubPrLightSearchNode, W as WorkflowCommentBody, _t as MAX_RAW_LINE_CHARS, a as ConfigUpdate, b as ClientMessage, bt as CoherenceJournalOutput, g as CHANGES_POLL_INTERVAL_MS, gt as SessionSetup, ht as UpdateJournal, j as BenchmarkJudgement, jt as planTitle, k as BenchmarkCase, kt as PlanRevision, l as configIssueMessage, m as USAGE_VENDOR_KEYS, p as USAGE_COST_MODES, q as WorkflowsState, r as BrowserConfig, s as RUNTIME_CONFIG_SCALAR_KEYS, ut as USAGE_INTEGER_RANGES, v as CLIENT_LOG_TEXT_MAX_CHARS, vt as TraceCheckpoint, wt as PLAN_HOOK_EVENT, xt as ChangeMap, y as CONTROL_FRAME_MAX_BYTES, yt as TraceRecord, z as GithubPrDetailNode, zt as issuePullRequestStateFromGithub } from "./config-BLeRKmn9.js";
8
8
  import { a as permitsHelpCommand, r as describeSessionLimits } from "./session-routes--hrsvv7a.js";
9
- import { A as seedTaskTitleSources, B as listRepoWorktreePaths, C as extractPromptTaskTitle, D as parseRefinedTaskTitle, E as parseRefinedSessionName, F as resumePromptFor, I as shouldAdoptReportedResumeId, L as claudeProjectsDir, M as RESUME_ID_RE, N as pickAutoResume, O as resolveRefocusTaskTitle, P as resolveResumeTarget, R as encodeProjectDir, S as extractOscTaskTitle, T as isSubstantivePrompt, V as isAutoNameOf, _ as buildTaskTitleRefinementPrompt, a as decideSpawnAllowance, b as decideTaskTitleRefinement, c as describeKeptChildAttention, d as describeUnpushedCloseRefusal, g as buildPersistedTaskTitle, h as projectReviews, i as decideAgentRequest, j as AUTO_CONTINUE_PROMPT, k as resolveTaskTitle, l as describePushLanding, m as projectMyPrs, n as REFUSAL_REASON, o as deriveChildSessionName, p as parseAgentVerb, s as describeChildEndNote, u as describeRoleRefusal, v as chooseRefinedSessionName, w as isSelfWakePrompt, x as extractAiTitle, y as cleanTaskPrompt, z as listRepoConversations } from "./agent-api-core-BCFplxXu.js";
9
+ import { A as seedTaskTitleSources, B as listRepoWorktreePaths, C as extractPromptTaskTitle, D as parseRefinedTaskTitle, E as parseRefinedSessionName, F as resumePromptFor, H as nextSuggestedName, I as shouldAdoptReportedResumeId, L as claudeProjectsDir, M as RESUME_ID_RE, N as pickAutoResume, O as resolveRefocusTaskTitle, P as resolveResumeTarget, R as encodeProjectDir, S as extractOscTaskTitle, T as isSubstantivePrompt, V as isAutoNameOf, _ as buildTaskTitleRefinementPrompt, a as decideSpawnAllowance, b as decideTaskTitleRefinement, c as describeKeptChildAttention, d as describeUnpushedCloseRefusal, g as buildPersistedTaskTitle, h as projectReviews, i as decideAgentRequest, j as AUTO_CONTINUE_PROMPT, k as resolveTaskTitle, l as describePushLanding, m as projectMyPrs, n as REFUSAL_REASON, o as deriveChildSessionName, p as parseAgentVerb, s as describeChildEndNote, u as describeRoleRefusal, v as chooseRefinedSessionName, w as isSelfWakePrompt, x as extractAiTitle, y as cleanTaskPrompt, z as listRepoConversations } from "./agent-api-core-D49OzKho.js";
10
10
  import { a as positiveIntOr, c as textOr, i as numberOr, n as isRecord, o as positiveNumberOr, r as nonNegativeIntOr, s as rawTextOr, t as coercedNumberOr } from "./coerce-NSst8oRP.js";
11
11
  import { n as glimmervoidHomeDir, t as decideConfigPath } from "./config-path-core-DFt-TemS.js";
12
12
  import { i as parseCommandLine, n as warnWhenGitIsTooOld } from "./git-version-C3lznLS_.js";
@@ -21,13 +21,13 @@ import { n as DEFAULT_MAX_MS, r as nextBackoffMs, t as DEFAULT_BASE_MS } from ".
21
21
  import { n as unrefTimer, t as DEFAULT_TIMER_FNS } from "./timer-deps-u2DAQLok.js";
22
22
  import { n as shellQuote } from "./hook-command-core-qTNK-xMF.js";
23
23
  import { C as parseCgroupBytes, S as memoryReserveBytes, T as parseMemAvailableBytes, _ as createSpawnGate, a as jsonStateLoadError, b as cgroupLimitBytes, c as loadedJsonValue, d as writeJsonAtomicSync, f as writeTextAtomic, g as createSerialQueue, h as createMemoryAdmission, i as createJsonStateWriter, m as createKeyedSerialQueue, n as appendJsonLines, o as loadJsonStateFile, p as writeTextAtomicSync, r as createJsonStateStore, s as loadJsonStateFileSync, t as appendJsonLine, u as writeJsonAtomic, v as isQueueAdmissionTimeout, w as parseCgroupV2Path, x as headroomFromReadings, y as cgroupAncestorPaths } from "./json-file-DFCTvPjj.js";
24
- import { B as buildExceptionProperties, F as TELEMETRY_BATCH_URL, G as decideIsDevInstall, H as classifySessionExit, I as TELEMETRY_FLAGS_URL, J as exceptionFingerprint, K as decideRemoteTelemetryState, L as adapterBucket, P as FIRST_RUN_NOTICE, R as buildAiGenerationEvents, U as claudeAccountUuidOf, V as buildPersonProperties, W as codexUserIdOf, X as parsePosthogReleaseId, Y as nodeMajorVersion, Z as resolveProjectToken, a as generateProjectId, at as planWorktreeGc, b as validateSettingsBlock, ct as worktreeIntegrationTips, d as assetForPlatform, dt as isSameDirectoryPath, et as stableConfigKey, f as decideRtkInstall, g as verifyDigest, h as isRtkBinaryName, i as ensureProjectIds, it as planBranchGc, lt as canonicalizePath, m as installTargetPath, n as DEFAULT_CONFIG, nt as DEFAULT_BRANCH_GC_PREFIXES, o as glimmervoidHomeDir$1, ot as sessionIdFromBranch, p as findEscapingArchiveMember, q as decideTelemetryConsent, r as createConfigStore, rt as matchedPrefix, st as usablePrefixes, t as ABORT_CONFIG_SAVE, ut as comparableDirectoryPath, v as mergeSettingsBlock, y as settingsBlockSpecFor, z as buildBrowserExceptionProperties } from "./config-store-CEsetno2.js";
25
- import { a as parseDataClientMessage, c as PendingCrashReport, d as TelemetryState, i as parseDataAttachHistory, l as TELEMETRY_EVENT_SCHEMAS, n as HookEnvelope, o as DashboardTelemetryReport, r as DEEP_HISTORY_SCROLLBACK_LINES, t as HTTP_URL_RE } from "./contracts-dj-GFptp.js";
26
- import { A as dedupeCodexFiles, B as shouldPersistWarehouse, C as shortSha$1, D as codexSessionIdFromPath, E as codexRootCandidates, F as passOutcome, H as claudeCode, I as projectDirCandidates, L as resolveProjectsDirs, M as grokHomes, N as grokRootCandidates, O as continuationDelayMs, P as isUsageFile, R as scopedClaudeRoots, S as parseResolvedSha, T as codexHomes, V as splitLines$1, _ as isCheckFresh, a as describeAgentResolvability, b as parseRegistryDeprecation, c as isKnownAgentId, d as resolveAdapter, f as setCustomAgents, g as decideUpdateStatus, h as decideInstallFlavor, i as customAgentFingerprint, j as expandTilde, k as decideFileRead, l as listAgentIds, m as readHostCodexVersion, n as cachedAgentResolvability, o as getAdapter, p as codex, r as commandFor, s as hookProfileOf, t as DEFAULT_AGENT_ID, u as resetCommandCache, v as normalizeSha, w as codexFallbackRoots, x as parseRegistryLatest, y as normalizeUpdateChannel, z as shouldEvaluateDespiteIoFailures } from "./adapters-BsoXEvlZ.js";
24
+ import { B as buildExceptionProperties, F as TELEMETRY_BATCH_URL, G as decideIsDevInstall, H as classifySessionExit, I as TELEMETRY_FLAGS_URL, J as exceptionFingerprint, K as decideRemoteTelemetryState, L as adapterBucket, P as FIRST_RUN_NOTICE, R as buildAiGenerationEvents, U as claudeAccountUuidOf, V as buildPersonProperties, W as codexUserIdOf, X as parsePosthogReleaseId, Y as nodeMajorVersion, Z as resolveProjectToken, a as generateProjectId, at as planWorktreeGc, b as validateSettingsBlock, ct as worktreeIntegrationTips, d as assetForPlatform, dt as isSameDirectoryPath, et as stableConfigKey, f as decideRtkInstall, g as verifyDigest, h as isRtkBinaryName, i as ensureProjectIds, it as planBranchGc, lt as canonicalizePath, m as installTargetPath, n as DEFAULT_CONFIG, nt as DEFAULT_BRANCH_GC_PREFIXES, o as glimmervoidHomeDir$1, ot as sessionIdFromBranch, p as findEscapingArchiveMember, q as decideTelemetryConsent, r as createConfigStore, rt as matchedPrefix, st as usablePrefixes, t as ABORT_CONFIG_SAVE, ut as comparableDirectoryPath, v as mergeSettingsBlock, y as settingsBlockSpecFor, z as buildBrowserExceptionProperties } from "./config-store-CXLnauAa.js";
25
+ import { a as parseDataClientMessage, c as PendingCrashReport, d as TelemetryState, i as parseDataAttach, l as TELEMETRY_EVENT_SCHEMAS, n as HookEnvelope, o as DashboardTelemetryReport, r as DEEP_HISTORY_SCROLLBACK_LINES, t as HTTP_URL_RE } from "./contracts-CucdticH.js";
26
+ import { A as dedupeCodexFiles, B as shouldPersistWarehouse, C as shortSha$1, D as codexSessionIdFromPath, E as codexRootCandidates, F as passOutcome, H as claudeCode, I as projectDirCandidates, L as resolveProjectsDirs, M as grokHomes, N as grokRootCandidates, O as continuationDelayMs, P as isUsageFile, R as scopedClaudeRoots, S as parseResolvedSha, T as codexHomes, V as splitLines$1, _ as isCheckFresh, a as describeAgentResolvability, b as parseRegistryDeprecation, c as isKnownAgentId, d as resolveAdapter, f as setCustomAgents, g as decideUpdateStatus, h as decideInstallFlavor, i as customAgentFingerprint, j as expandTilde, k as decideFileRead, l as listAgentIds, m as readHostCodexVersion, n as cachedAgentResolvability, o as getAdapter, p as codex, r as commandFor, s as hookProfileOf, t as DEFAULT_AGENT_ID, u as resetCommandCache, v as normalizeSha, w as codexFallbackRoots, x as parseRegistryLatest, y as normalizeUpdateChannel, z as shouldEvaluateDespiteIoFailures } from "./adapters-D99c4zCx.js";
27
27
  import { t as HOOK_TOOLS } from "./hook-tools-Dl7-r2Eb.js";
28
28
  import { a as formatSshPublicKey, c as orderAgentSockets, i as commitSigningShimText, l as parseSshPublicKey, n as NO_AGENT_HOLDS_KEY, o as isForwardedAgentDirName, r as agentListsKey, s as isSignableGitObject, t as COMMIT_SIGNING_SHIM_NAME } from "./ssh-signing-core-CRhVVWNW.js";
29
- import { a as configSiblingPath, c as defaultPairingsPath, d as decideDeviceAuth, f as deviceNameFromUserAgent, l as defaultSeenPath, n as normalizeRemoteConfig, o as createPairingsStore, p as hashSecret, r as validateRemoteConfig, s as createSeenStore, t as decideBindHost, u as DEFAULT_DEVICE_MAX_AGE_MS } from "./remote-config-CtcoO10O.js";
30
- import { n as configFileViewOf, u as readSettingsForAgent } from "./settings-readout-core-BVb6tTLq.js";
29
+ import { a as configSiblingPath, c as defaultPairingsPath, d as decideDeviceAuth, f as deviceNameFromUserAgent, l as defaultSeenPath, n as normalizeRemoteConfig, o as createPairingsStore, p as hashSecret, r as validateRemoteConfig, s as createSeenStore, t as decideBindHost, u as DEFAULT_DEVICE_MAX_AGE_MS } from "./remote-config-B0zBDBak.js";
30
+ import { n as configFileViewOf, u as readSettingsForAgent } from "./settings-readout-core-BOv6tqdK.js";
31
31
  import { _ as escapeMarkup, g as createLaneLog, n as createVisionsSetup } from "./visions-setup-VMMyqOpl.js";
32
32
  import { t as getRtkPath } from "./rtk-resolver-BDHi6RMv.js";
33
33
  import { createRequire } from "node:module";
@@ -2153,11 +2153,71 @@ function createBackendHttpApp(dependencies) {
2153
2153
  mountCustomSoundRoutes(app, { soundsDir: customSoundsDir });
2154
2154
  if (staticDir === "auto") {
2155
2155
  if (!fs.existsSync(path.join(clientDir, "index.html"))) throw Object.assign(/* @__PURE__ */ new Error("Dashboard build not found (dist/client). Run `npm run build` first, or use `npm run dev`."), { glimmervoidBoot: true });
2156
- app.use(express.static(clientDir));
2156
+ serveClientDir(app, clientDir);
2157
2157
  }
2158
- if (staticDir !== "auto" && typeof staticDir === "string") app.use(express.static(staticDir));
2158
+ if (staticDir !== "auto" && typeof staticDir === "string") serveClientDir(app, staticDir);
2159
2159
  return app;
2160
2160
  }
2161
+ var HASHED_ASSET_PREFIX = "/assets/";
2162
+ var ONE_YEAR_MS = 31536e6;
2163
+ function isHashedAssetPath(requestPath) {
2164
+ return requestPath.startsWith(HASHED_ASSET_PREFIX);
2165
+ }
2166
+ function acceptsBrotli(acceptEncoding) {
2167
+ return (Array.isArray(acceptEncoding) ? acceptEncoding.join(",") : acceptEncoding ?? "").split(",").some((entry) => {
2168
+ const [coding = "", ...parameters] = entry.trim().toLowerCase().split(";");
2169
+ if (coding.trim() !== "br") return false;
2170
+ const quality = parameters.map((parameter) => parameter.trim()).find((parameter) => parameter.startsWith("q="));
2171
+ return quality === void 0 || Number(quality.slice(2)) > 0;
2172
+ });
2173
+ }
2174
+ function resolveClientFile(rootDir, requestPath) {
2175
+ let decodedPath;
2176
+ try {
2177
+ decodedPath = decodeURIComponent(requestPath);
2178
+ } catch {
2179
+ return null;
2180
+ }
2181
+ if (decodedPath.includes("\0")) return null;
2182
+ const relativePath = decodedPath.endsWith("/") ? `${decodedPath}index.html` : decodedPath;
2183
+ const filePath = path.resolve(rootDir, `.${relativePath}`);
2184
+ if (!filePath.startsWith(path.resolve(rootDir) + path.sep)) return null;
2185
+ return filePath;
2186
+ }
2187
+ function createPrecompressedStatic(rootDir) {
2188
+ return (req, res, next) => {
2189
+ if (req.method !== "GET" && req.method !== "HEAD") return next();
2190
+ const filePath = resolveClientFile(rootDir, req.path);
2191
+ if (!filePath) return next();
2192
+ const compressedPath = `${filePath}.br`;
2193
+ fs$1.stat(compressedPath).then((compressedStat) => {
2194
+ if (!compressedStat.isFile()) return next();
2195
+ res.setHeader("Vary", "Accept-Encoding");
2196
+ if (!acceptsBrotli(req.headers["accept-encoding"])) return next();
2197
+ res.type(path.extname(filePath));
2198
+ res.setHeader("Content-Encoding", "br");
2199
+ const cacheOptions = isHashedAssetPath(req.path) ? {
2200
+ maxAge: ONE_YEAR_MS,
2201
+ immutable: true
2202
+ } : {};
2203
+ res.sendFile(path.relative(rootDir, compressedPath), {
2204
+ root: rootDir,
2205
+ ...cacheOptions
2206
+ }, (error) => {
2207
+ if (!error || res.headersSent) return;
2208
+ res.removeHeader("Content-Encoding");
2209
+ next();
2210
+ });
2211
+ }).catch(() => next());
2212
+ };
2213
+ }
2214
+ function serveClientDir(app, rootDir) {
2215
+ app.use(createPrecompressedStatic(rootDir));
2216
+ app.use(express.static(rootDir, { setHeaders: (res, filePath) => {
2217
+ if (!filePath.startsWith(path.join(path.resolve(rootDir), "assets") + path.sep)) return;
2218
+ res.setHeader("Cache-Control", `public, max-age=${ONE_YEAR_MS / 1e3}, immutable`);
2219
+ } }));
2220
+ }
2161
2221
  //#endregion
2162
2222
  //#region server/host-url-opener.ts
2163
2223
  var OPENER_EXIT_WINDOW_MS = 2e3;
@@ -4677,7 +4737,13 @@ function createAgentApiWiring({ config, agentSessions, listAllSessions, listBoar
4677
4737
  if (roleRefusal) return roleRefusal;
4678
4738
  return dispatch(session, parsed.verb, parsed.request);
4679
4739
  }
4680
- return { handle };
4740
+ function markChildWorktreeDiscard(childId) {
4741
+ childIdsToDiscard.add(childId);
4742
+ }
4743
+ return {
4744
+ handle,
4745
+ markChildWorktreeDiscard
4746
+ };
4681
4747
  }
4682
4748
  //#endregion
4683
4749
  //#region server/remote-setup-wiring.ts
@@ -5019,7 +5085,10 @@ function createWsSender(ws, opts = {}) {
5019
5085
  let sentOffset = initialOffset;
5020
5086
  let desynced = false;
5021
5087
  let refusedOutOfBand = null;
5022
- let isOutputPaused = false;
5088
+ let isOutputPaused = opts.isStartedPaused === true;
5089
+ let isScreenSnapshotOwed = opts.isStartedPaused === true;
5090
+ let heldAttachSnapshot = opts.heldAttachSnapshot ?? null;
5091
+ const onPausedData = opts.onPausedData ?? (() => {});
5023
5092
  const bufferedAmount = () => ws.bufferedAmount || 0;
5024
5093
  const isOpen = () => ws.readyState === OPEN;
5025
5094
  const overHighWater = () => bufferedAmount() > cfg.highWaterMark;
@@ -5084,7 +5153,11 @@ function createWsSender(ws, opts = {}) {
5084
5153
  scheduleImmediate(flushSend);
5085
5154
  }
5086
5155
  function onData(data) {
5087
- if (destroyed || isOutputPaused || !isOpen()) return;
5156
+ if (destroyed || !isOpen()) return;
5157
+ if (isOutputPaused) {
5158
+ onPausedData();
5159
+ return;
5160
+ }
5088
5161
  if (desynced && !overHighWater()) {
5089
5162
  maybeBackfill();
5090
5163
  return;
@@ -5131,6 +5204,12 @@ function createWsSender(ws, opts = {}) {
5131
5204
  ws.send(payload);
5132
5205
  return true;
5133
5206
  }
5207
+ function sendDroppable(payload) {
5208
+ if (destroyed || !isOpen()) return false;
5209
+ if (refusedOutOfBand !== null || desynced || sendBuffer.length > 0 || overHighWater()) return false;
5210
+ ws.send(payload);
5211
+ return true;
5212
+ }
5134
5213
  function pauseOutput() {
5135
5214
  if (destroyed || isOutputPaused) return;
5136
5215
  flushSend();
@@ -5153,6 +5232,20 @@ function createWsSender(ws, opts = {}) {
5153
5232
  if (destroyed || !isOutputPaused) return;
5154
5233
  isOutputPaused = false;
5155
5234
  if (!source || !isOpen()) return;
5235
+ if (isScreenSnapshotOwed) {
5236
+ isScreenSnapshotOwed = false;
5237
+ const attachSnapshot = heldAttachSnapshot;
5238
+ heldAttachSnapshot = null;
5239
+ if (!(attachSnapshot !== null && !hasResizedWhilePaused && outputOffset - attachSnapshot.offset <= cfg.maxSendBuffer)) {
5240
+ resetToScreenSnapshot(readScreenSnapshot());
5241
+ return;
5242
+ }
5243
+ resetToScreenSnapshot(attachSnapshot);
5244
+ if (outputOffset <= sentOffset) return;
5245
+ desynced = true;
5246
+ maybeBackfill();
5247
+ return;
5248
+ }
5156
5249
  const missedByteCount = outputOffset - sentOffset;
5157
5250
  if (missedByteCount <= 0 && !desynced) return;
5158
5251
  if (!hasResizedWhilePaused && missedByteCount <= cfg.maxSendBuffer) {
@@ -5166,6 +5259,7 @@ function createWsSender(ws, opts = {}) {
5166
5259
  destroyed = true;
5167
5260
  clearStall();
5168
5261
  refusedOutOfBand = null;
5262
+ heldAttachSnapshot = null;
5169
5263
  sendBuffer = "";
5170
5264
  sendScheduled = false;
5171
5265
  flushNextData = false;
@@ -5177,6 +5271,7 @@ function createWsSender(ws, opts = {}) {
5177
5271
  markInputFlush,
5178
5272
  sendImmediate,
5179
5273
  sendOutOfBand,
5274
+ sendDroppable,
5180
5275
  destroy
5181
5276
  };
5182
5277
  }
@@ -5207,6 +5302,7 @@ function sendPtySizeFrame(sender, size) {
5207
5302
  };
5208
5303
  sender.sendOutOfBand(Buffer.from(JSON.stringify(frame), "utf8"));
5209
5304
  }
5305
+ var OUTPUT_BEAT_FRAME = Buffer.from(JSON.stringify({ type: "output-beat" }), "utf8");
5210
5306
  function frameType(stamped) {
5211
5307
  return typeof stamped.type === "string" ? stamped.type : "";
5212
5308
  }
@@ -5214,11 +5310,13 @@ function createBackendWebSockets(dependencies) {
5214
5310
  const { remote, remoteAuth, remoteListenerPort, allowedHosts, listenerPortsFor, tokenMatches, getSession, getVisionsLane, recordOutcome = () => {}, logger } = dependencies;
5215
5311
  const controlWss = new WebSocketServer({
5216
5312
  noServer: true,
5217
- maxPayload: CONTROL_FRAME_MAX_BYTES
5313
+ maxPayload: CONTROL_FRAME_MAX_BYTES,
5314
+ perMessageDeflate: true
5218
5315
  });
5219
5316
  const dataWss = new WebSocketServer({
5220
5317
  noServer: true,
5221
- maxPayload: 2097152
5318
+ maxPayload: 2097152,
5319
+ perMessageDeflate: true
5222
5320
  });
5223
5321
  controlWss.on("connection", (socket) => {
5224
5322
  recordOutcome("controlWsOpened");
@@ -5264,8 +5362,12 @@ function createBackendWebSockets(dependencies) {
5264
5362
  return;
5265
5363
  }
5266
5364
  socket.on("error", (error) => reportDataSocketError(session, error));
5267
- if (parseDataAttachHistory(request.url) === "screen") {
5268
- wireDataSocket(socket, session, sessionId, session.getScreenSnapshot());
5365
+ const attach = parseDataAttach(request.url);
5366
+ if (attach.history === "screen") {
5367
+ wireDataSocket(socket, session, sessionId, session.getScreenSnapshot(), {
5368
+ isAttachedPaused: attach.isOutputPaused,
5369
+ isDeepAttach: false
5370
+ });
5269
5371
  return;
5270
5372
  }
5271
5373
  const messagesBeforeWiring = [];
@@ -5280,7 +5382,10 @@ function createBackendWebSockets(dependencies) {
5280
5382
  socket.close(1008, "Session not found");
5281
5383
  return;
5282
5384
  }
5283
- wireDataSocket(socket, session, sessionId, snapshot);
5385
+ wireDataSocket(socket, session, sessionId, snapshot, {
5386
+ isAttachedPaused: attach.isOutputPaused,
5387
+ isDeepAttach: true
5388
+ });
5284
5389
  for (const raw of messagesBeforeWiring) socket.emit("message", raw, false);
5285
5390
  }, (error) => {
5286
5391
  logger.warn(`[data-ws] Deep history failed for ${session.name}: ${String(error)}`);
@@ -5299,7 +5404,7 @@ function createBackendWebSockets(dependencies) {
5299
5404
  timestamp: Date.now()
5300
5405
  });
5301
5406
  }
5302
- function wireDataSocket(socket, session, sessionId, snapshot) {
5407
+ function wireDataSocket(socket, session, sessionId, snapshot, { isAttachedPaused, isDeepAttach }) {
5303
5408
  let viewerSizes = sessionDataClients.get(sessionId);
5304
5409
  if (!viewerSizes) {
5305
5410
  viewerSizes = /* @__PURE__ */ new Map();
@@ -5323,17 +5428,27 @@ function createBackendWebSockets(dependencies) {
5323
5428
  if (sessionDataClients.get(activeSessionId) !== viewerSizeMap) return;
5324
5429
  applyResolvedSize(true);
5325
5430
  };
5431
+ let lastOutputBeatAt = 0;
5432
+ const sendOutputBeat = () => {
5433
+ const now = Date.now();
5434
+ if (now - lastOutputBeatAt < 320) return;
5435
+ lastOutputBeatAt = now;
5436
+ sender.sendDroppable(OUTPUT_BEAT_FRAME);
5437
+ };
5326
5438
  const sender = createWsSender(socket, {
5327
5439
  source: { getBufferSince: (offset) => session.getBufferSince(offset) },
5328
- startOffset: snapshot.offset
5440
+ startOffset: snapshot.offset,
5441
+ isStartedPaused: isAttachedPaused,
5442
+ heldAttachSnapshot: isAttachedPaused && isDeepAttach ? snapshot : null,
5443
+ onPausedData: sendOutputBeat
5329
5444
  });
5330
5445
  sendPtySizeFrame(sender, session.ptySize());
5331
- if (snapshot.data) sender.sendImmediate(snapshot.data, 0);
5446
+ if (snapshot.data && !isAttachedPaused) sender.sendImmediate(snapshot.data, 0);
5332
5447
  const dataListener = (data) => sender.onData(data);
5333
5448
  session.on("data", dataListener);
5334
5449
  const resizeListener = (size) => sendPtySizeFrame(sender, size);
5335
5450
  session.on("resize", resizeListener);
5336
- let resizeSeqAtPause = null;
5451
+ let resizeSeqAtPause = isAttachedPaused ? session.ptySize().seq : null;
5337
5452
  socket.on("message", (raw) => {
5338
5453
  const message = parseDataClientMessage(String(raw));
5339
5454
  if (!message) return;
@@ -5875,6 +5990,15 @@ function decideAcknowledge(isAcknowledgeDeferred, from, event, isIdleCompactionA
5875
5990
  };
5876
5991
  }
5877
5992
  //#endregion
5993
+ //#region session/core/exit-close.ts
5994
+ var UNMERGED_MERGE_STATUSES = /* @__PURE__ */ new Set(["pending-review", "parked"]);
5995
+ function decideExitClose(facts) {
5996
+ if (!facts.exitedOnItsOwn || !facts.isConfiguredSession) return "keep";
5997
+ if (facts.isWorkspace || facts.hasRemoteEnvironment) return "confirm";
5998
+ if (UNMERGED_MERGE_STATUSES.has(facts.mergeStatus)) return "confirm";
5999
+ return "remove";
6000
+ }
6001
+ //#endregion
5878
6002
  //#region session/core/claude-approval-core.ts
5879
6003
  var MAIN_AGENT_KEY$1 = "";
5880
6004
  var SESSION_DESTINATION = "session";
@@ -6955,7 +7079,7 @@ function createSessionEventWiring(dependencies) {
6955
7079
  dependencies.logger.error(`[${session.name}] error: ${errorMessage(error)}`);
6956
7080
  dependencies.telemetry?.captureException(error, { handled: true });
6957
7081
  });
6958
- session.on("exit", ({ exitCode, signal, reason }) => {
7082
+ session.on("exit", ({ exitCode, signal, reason, exitedOnItsOwn }) => {
6959
7083
  if (postTurnDebounce) {
6960
7084
  clearTimeout(postTurnDebounce);
6961
7085
  postTurnDebounce = null;
@@ -6968,7 +7092,28 @@ function createSessionEventWiring(dependencies) {
6968
7092
  signal,
6969
7093
  reason
6970
7094
  }));
7095
+ closeSessionAfterExit(exitedOnItsOwn === true);
6971
7096
  });
7097
+ function closeSessionAfterExit(exitedOnItsOwn) {
7098
+ const project = dependencies.config.projects.find((candidate) => candidate.id === session.id);
7099
+ const exitClose = decideExitClose({
7100
+ exitedOnItsOwn,
7101
+ isConfiguredSession: project !== void 0,
7102
+ mergeStatus: session.mergeStatus,
7103
+ isWorkspace: session.isWorkspace,
7104
+ hasRemoteEnvironment: Boolean(project?.environment)
7105
+ });
7106
+ if (exitClose === "remove") {
7107
+ dependencies.logger.log(`[${session.name}] agent quit on its own, removing the session`);
7108
+ dependencies.removeExitedSession?.(session.id);
7109
+ return;
7110
+ }
7111
+ if (exitClose === "confirm") dependencies.broadcastControl({
7112
+ type: "session-close-confirm",
7113
+ id: session.id,
7114
+ mergeStatus: session.mergeStatus
7115
+ });
7116
+ }
6972
7117
  session.on("teardown", ({ cause }) => {
6973
7118
  clearCompactionConfirm();
6974
7119
  isAcknowledgeDeferredForCompaction = false;
@@ -21097,7 +21242,7 @@ var Session = class extends EventEmitter {
21097
21242
  const remoteExitReason = await pendingRemoteExitReason;
21098
21243
  if (remoteExitReason && this._isExitHeadedForFailure(event)) this.failureReason = remoteExitReason;
21099
21244
  }
21100
- this.transition(event, detail);
21245
+ const isUnsignalledCleanExit = this.transition(event, detail) && event === "process_exit_ok" && !signal;
21101
21246
  if (this._recorder) {
21102
21247
  this._recorder.writeFooter("pty_exit", exitCode);
21103
21248
  this._recorder.finishRecordingFile();
@@ -21105,10 +21250,12 @@ var Session = class extends EventEmitter {
21105
21250
  try {
21106
21251
  await this._settleWorktreeOnExit();
21107
21252
  } catch {}
21253
+ const exitedOnItsOwn = isUnsignalledCleanExit && this.state === STATES.DONE && !this._teardownPending() && !this._destroyed;
21108
21254
  this.emit("exit", {
21109
21255
  exitCode,
21110
21256
  signal,
21111
- reason
21257
+ reason,
21258
+ exitedOnItsOwn
21112
21259
  });
21113
21260
  }
21114
21261
  getScreenSnapshot() {
@@ -49778,6 +49925,55 @@ function deriveIssueSessionName(issue) {
49778
49925
  return sanitizeSessionName(`issue-${issueNumber}-${String(issue.title ?? "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "untitled"}`) || `issue-${issueNumber}`;
49779
49926
  }
49780
49927
  //#endregion
49928
+ //#region server/session/core/quick-session-core.ts
49929
+ var COPIED_RUN_SETTINGS = [
49930
+ "baseBranch",
49931
+ "codexBypassHookTrust",
49932
+ "conversationView"
49933
+ ];
49934
+ var AUTO_NAME_SUFFIX = / \(\d+\)$/;
49935
+ function autoNameBase(name) {
49936
+ return name.replace(AUTO_NAME_SUFFIX, "");
49937
+ }
49938
+ function runSettingsOf(project) {
49939
+ const runSettings = {};
49940
+ for (const field of COPIED_RUN_SETTINGS) if (project[field] !== void 0) Object.assign(runSettings, { [field]: project[field] });
49941
+ return runSettings;
49942
+ }
49943
+ function requestFromLiveSession(live, name) {
49944
+ const repos = live.workspaceRepos && live.workspaceRepos.length >= 2 ? [...live.workspaceRepos] : void 0;
49945
+ return {
49946
+ name,
49947
+ path: repos?.[0] ?? live.path,
49948
+ repos,
49949
+ agent: live.agentId,
49950
+ dangerouslySkipPermissions: live.dangerouslySkipPermissions,
49951
+ unguarded: live.isMarkedUnguarded && !live.isGuardrailsReleased
49952
+ };
49953
+ }
49954
+ function requestFromProject(project, live, name) {
49955
+ return {
49956
+ name,
49957
+ path: project.repos?.[0] ?? project.path,
49958
+ repos: project.repos ? [...project.repos] : void 0,
49959
+ agent: project.agent,
49960
+ dangerouslySkipPermissions: project.dangerouslySkipPermissions,
49961
+ unguarded: project.unguarded === true && !live.isGuardrailsReleased,
49962
+ environment: project.environment?.name
49963
+ };
49964
+ }
49965
+ function planQuickSession({ live, project, sessionNames }) {
49966
+ const name = nextSuggestedName(autoNameBase(live.name), sessionNames);
49967
+ if (!project) return {
49968
+ request: requestFromLiveSession(live, name),
49969
+ runSettings: {}
49970
+ };
49971
+ return {
49972
+ request: requestFromProject(project, live, name),
49973
+ runSettings: runSettingsOf(project)
49974
+ };
49975
+ }
49976
+ //#endregion
49781
49977
  //#region server/settings-payload.ts
49782
49978
  function summarizeCustomAgents(declarations) {
49783
49979
  return declarations.map((declaration) => ({
@@ -50997,6 +51193,81 @@ function createChangeMapService({ sessions, runGit = runGitAsync, nowFn = Date.n
50997
51193
  return { build };
50998
51194
  }
50999
51195
  //#endregion
51196
+ //#region server/core/changes-watch-core.ts
51197
+ function decideWatchRequest(current, request) {
51198
+ if (request.sessionId === null) return {
51199
+ next: current !== null && current.holder === request.holder ? null : current,
51200
+ shouldCheckNow: false
51201
+ };
51202
+ const isRenewal = current !== null && current.holder === request.holder && current.sessionId === request.sessionId;
51203
+ return {
51204
+ next: {
51205
+ holder: request.holder,
51206
+ sessionId: request.sessionId,
51207
+ renewedAtMs: request.nowMs
51208
+ },
51209
+ shouldCheckNow: !isRenewal
51210
+ };
51211
+ }
51212
+ function decidePollTick(current, tick) {
51213
+ if (current === null) return {
51214
+ next: null,
51215
+ sessionIdToCheck: null
51216
+ };
51217
+ if (tick.nowMs - current.renewedAtMs > 1e4 || !tick.isHolderOpen) return {
51218
+ next: null,
51219
+ sessionIdToCheck: null
51220
+ };
51221
+ return {
51222
+ next: current,
51223
+ sessionIdToCheck: current.sessionId
51224
+ };
51225
+ }
51226
+ //#endregion
51227
+ //#region server/changes-watch.ts
51228
+ function createChangesWatch({ findSession, isHolderOpen, setIntervalFn = DEFAULT_TIMER_FNS.setIntervalFn, clearIntervalFn = DEFAULT_TIMER_FNS.clearIntervalFn, nowFn = Date.now }) {
51229
+ let watch = null;
51230
+ let pollTimer = null;
51231
+ function syncPollTimer() {
51232
+ if (watch === null && pollTimer !== null) {
51233
+ clearIntervalFn(pollTimer);
51234
+ pollTimer = null;
51235
+ return;
51236
+ }
51237
+ if (watch === null || pollTimer !== null) return;
51238
+ pollTimer = unrefTimer(setIntervalFn(pollWatchedSession, CHANGES_POLL_INTERVAL_MS));
51239
+ }
51240
+ function checkSession(sessionId) {
51241
+ const session = findSession(sessionId);
51242
+ if (session) {
51243
+ session.worktreeLifecycle.scheduleCheck();
51244
+ return;
51245
+ }
51246
+ watch = null;
51247
+ }
51248
+ function pollWatchedSession() {
51249
+ const holderIsOpen = watch !== null && isHolderOpen(watch.holder);
51250
+ const tick = decidePollTick(watch, {
51251
+ nowMs: nowFn(),
51252
+ isHolderOpen: holderIsOpen
51253
+ });
51254
+ watch = tick.next;
51255
+ if (tick.sessionIdToCheck !== null) checkSession(tick.sessionIdToCheck);
51256
+ syncPollTimer();
51257
+ }
51258
+ function request(holder, sessionId) {
51259
+ const decision = decideWatchRequest(watch, {
51260
+ holder,
51261
+ sessionId,
51262
+ nowMs: nowFn()
51263
+ });
51264
+ watch = decision.next;
51265
+ if (decision.shouldCheckNow && watch !== null) checkSession(watch.sessionId);
51266
+ syncPollTimer();
51267
+ }
51268
+ return { request };
51269
+ }
51270
+ //#endregion
51000
51271
  //#region server/control-handlers.ts
51001
51272
  function isInsideGitCheckout(folderPath) {
51002
51273
  const resolvedFolder = path.resolve(folderPath);
@@ -51282,6 +51553,12 @@ function requestValidationErrorReply(msg, message) {
51282
51553
  ok: false,
51283
51554
  error: message
51284
51555
  }),
51556
+ "quick-session": () => ({
51557
+ type: "add-session-result",
51558
+ requestId,
51559
+ ok: false,
51560
+ error: message
51561
+ }),
51285
51562
  "remove-session": () => ({
51286
51563
  type: "remove-session-result",
51287
51564
  requestId,
@@ -51354,7 +51631,7 @@ function parseSinceParam(url) {
51354
51631
  return Number.isFinite(n) ? n : null;
51355
51632
  }
51356
51633
  function registerControlHandlers(controlWss, deps) {
51357
- const { sessions, agentSessions = /* @__PURE__ */ new Map(), config, configStore, broadcastControl, generateProjectId, applyConfigReload, applySettingsReload, requestShutdown, requestRestart, handleClientFocus, buildHealthSnapshot, getUpdateStatus, getUpdateJournal = null, getPostTurnLeftoversNotice = null, recheckPostTurnLeftovers = null, checkNow = null, applyUpdate = null, noteRestartRequested = null, getRadarStatus, posthogReportsDir = null, posthogSetIssueStatus = null, radarArchiveInvestigation = null, getTeamReviewStatus = null, getMyPrsStatus = null, getIssuesStatus = null, githubStore = null, issues = null, teamReview = null, myPrs = null, getBenchmarkStatus = null, benchmarks = null, requestIssue = async () => ({
51634
+ const { sessions, agentSessions = /* @__PURE__ */ new Map(), markChildWorktreeDiscard = null, config, configStore, broadcastControl, generateProjectId, applyConfigReload, applySettingsReload, requestShutdown, requestRestart, handleClientFocus, buildHealthSnapshot, getUpdateStatus, getUpdateJournal = null, getPostTurnLeftoversNotice = null, recheckPostTurnLeftovers = null, checkNow = null, applyUpdate = null, noteRestartRequested = null, getRadarStatus, posthogReportsDir = null, posthogSetIssueStatus = null, radarArchiveInvestigation = null, getTeamReviewStatus = null, getMyPrsStatus = null, getIssuesStatus = null, githubStore = null, issues = null, teamReview = null, myPrs = null, getBenchmarkStatus = null, benchmarks = null, requestIssue = async () => ({
51358
51635
  isRateLimited: false,
51359
51636
  value: {
51360
51637
  ok: false,
@@ -51363,6 +51640,10 @@ function registerControlHandlers(controlWss, deps) {
51363
51640
  }
51364
51641
  }), issueProjectRepos = null, serverBuild = () => null, getUsageSessions = null, getUsageReport = null, requestUsageReport = null, getPlanLimits = null, controlReplayLog = null, getRtkInstallStatus = () => null, telegramDelivery = null, resolveRtkPath = () => getRtkPath(), conversationFs = fs, conversationGit = runGitForConversationHistory, conversationProjectsDir = claudeProjectsDir(process.env, os.homedir()), readTracePage = null, readPlanRevision = null, decidePlanReview = null, sessionDocs = null, coherenceFeed = null, coderEnv = null, remoteRepoGit = null, agentConnect = null, remoteSetup = null } = deps;
51365
51642
  const changeMaps = createChangeMapService({ sessions });
51643
+ const changesWatch = createChangesWatch({
51644
+ findSession: (id) => sessions.get(id) ?? agentSessions.get(id) ?? null,
51645
+ isHolderOpen: (ws) => ws.readyState === 1
51646
+ });
51366
51647
  function buildSettingsPayload$1() {
51367
51648
  return buildSettingsPayload({
51368
51649
  configStore,
@@ -51416,6 +51697,27 @@ function registerControlHandlers(controlWss, deps) {
51416
51697
  }
51417
51698
  return createAddedSessionOnceWorktreeCapable(msg, ws);
51418
51699
  }
51700
+ function handleQuickSession(msg, ws) {
51701
+ const source = findSession(msg);
51702
+ if (!source) {
51703
+ replyTo(ws, msg, "add-session-result", {
51704
+ ok: false,
51705
+ error: "The session to copy no longer exists."
51706
+ });
51707
+ return;
51708
+ }
51709
+ const plan = planQuickSession({
51710
+ live: source,
51711
+ project: config.projects.find((project) => project.id === source.id) ?? null,
51712
+ sessionNames: [...sessions.values(), ...agentSessions.values()].map((session) => session.name)
51713
+ });
51714
+ return handleAddSession({
51715
+ type: "add-session",
51716
+ requestId: msg.requestId,
51717
+ ...plan.request,
51718
+ runSettings: plan.runSettings
51719
+ }, ws);
51720
+ }
51419
51721
  function needsOwnWorktreeCheck(msg) {
51420
51722
  if (msg.repos || msg.runInPlace === true) return false;
51421
51723
  const projectPath = (msg.path || "").trim();
@@ -51447,7 +51749,8 @@ function registerControlHandlers(controlWss, deps) {
51447
51749
  dangerouslySkipPermissions: skipPerms,
51448
51750
  unguarded: msg.unguarded === true,
51449
51751
  requireExistingPath: !repos,
51450
- environment: remote?.environment
51752
+ environment: remote?.environment,
51753
+ runSettings: msg.runSettings
51451
51754
  });
51452
51755
  if (!created.ok) {
51453
51756
  refuseAddSession(msg, ws, { error: created.error });
@@ -51455,7 +51758,8 @@ function registerControlHandlers(controlWss, deps) {
51455
51758
  }
51456
51759
  if (msg.requestId) replyTo(ws, msg, "add-session-result", {
51457
51760
  ok: true,
51458
- error: null
51761
+ error: null,
51762
+ sessionId: created.project.id
51459
51763
  });
51460
51764
  console.log(`[control] Added session via UI: ${name}${skipPerms ? " (skip permissions)" : " (permission prompts)"}${remote ? ` (Coder environment ${remote.environment.name})` : ""}`);
51461
51765
  return created.project;
@@ -51614,37 +51918,64 @@ function registerControlHandlers(controlWss, deps) {
51614
51918
  if (sess.state !== STATES.DORMANT) return;
51615
51919
  sess.start();
51616
51920
  }
51921
+ const lastRemovalRefusalBySessionId = /* @__PURE__ */ new Map();
51922
+ function refuseRemoval(error, keptPaths) {
51923
+ return keptPaths ? {
51924
+ ok: false,
51925
+ error,
51926
+ canDiscardWork: true,
51927
+ keptPaths
51928
+ } : {
51929
+ ok: false,
51930
+ error,
51931
+ canDiscardWork: true
51932
+ };
51933
+ }
51934
+ function keptWorkRefusal(sess, firstKept, otherKeptCount, keptPaths) {
51935
+ const more = otherKeptCount > 0 ? ` and ${otherKeptCount} more` : "";
51936
+ return refuseRemoval(`"${sess.name}" has work not saved in ${firstKept.path} (${firstKept.reason})${more}. Removing it deletes that work.`, keptPaths);
51937
+ }
51938
+ async function findLocalRemovalRefusal(sess, confirmedKeptPaths) {
51939
+ if (!sess.isWorkspace && await sess.hasUnmergedWork()) return refuseRemoval(`"${sess.name}" has uncommitted changes or commits not merged into its base branch. Removing it deletes them.`);
51940
+ const keptPaths = sess.isWorkspace ? await sess.findWorkspaceKeptWork() : [];
51941
+ const [firstUnconfirmedKept, ...otherUnconfirmedKept] = keptPaths.filter((kept) => !confirmedKeptPaths.has(kept.path));
51942
+ if (firstUnconfirmedKept) return keptWorkRefusal(sess, firstUnconfirmedKept, otherUnconfirmedKept.length, keptPaths);
51943
+ if (sess.state === STATES.RUNNING) return refuseRemoval(`"${sess.name}" is working. Removing it stops the agent mid-task.`);
51944
+ return null;
51945
+ }
51617
51946
  async function removeSession(msg) {
51618
51947
  const sess = findSession(msg);
51619
51948
  if (!sess) return {
51620
51949
  ok: false,
51621
51950
  error: "Session not found"
51622
51951
  };
51952
+ const isDiscardingWork = msg.discardWork === true;
51953
+ const isDiscardingWorkspaceWork = sess.isWorkspace && isDiscardingWork;
51954
+ if (isDiscardingWorkspaceWork) sess.killSession();
51955
+ const refusal = await findLocalRemovalRefusal(sess, new Set(isDiscardingWorkspaceWork ? msg.confirmedKeptPaths ?? [] : []));
51956
+ const isRefusalConfirmed = isDiscardingWork && refusal?.error === lastRemovalRefusalBySessionId.get(sess.id);
51957
+ if (refusal && !isRefusalConfirmed) {
51958
+ lastRemovalRefusalBySessionId.set(sess.id, refusal.error);
51959
+ return refusal;
51960
+ }
51623
51961
  if (agentSessions.get(sess.id) === sess) {
51962
+ if (isDiscardingWork) markChildWorktreeDiscard?.(sess.id);
51963
+ lastRemovalRefusalBySessionId.delete(sess.id);
51624
51964
  sess.destroy();
51625
51965
  console.log(`[control] Removed spawned session via UI: ${sess.name}`);
51626
51966
  return { ok: true };
51627
51967
  }
51628
- const isDiscardingWorkspaceWork = sess.isWorkspace && msg.discardWork === true;
51629
- if (isDiscardingWorkspaceWork) sess.killSession();
51630
- const keptPaths = sess.isWorkspace ? await sess.findWorkspaceKeptWork() : [];
51631
- const confirmedKeptPaths = new Set(isDiscardingWorkspaceWork ? msg.confirmedKeptPaths ?? [] : []);
51632
- if (keptPaths.some((kept) => !confirmedKeptPaths.has(kept.path))) return {
51633
- ok: false,
51634
- error: "Workspace members hold work that is not saved",
51635
- canDiscardWork: true,
51636
- keptPaths
51637
- };
51638
51968
  if (config.projects.some((project) => project.id === sess.id && project.environment) && coderEnv) {
51639
51969
  sess.killSession();
51640
51970
  const settlement = await coderEnv.settleRemoval({
51641
51971
  projectId: sess.id,
51642
- discardRemoteWork: msg.discardWork === true
51972
+ discardRemoteWork: isDiscardingWork
51643
51973
  });
51974
+ if (!settlement.ok && settlement.canDiscardRemoteWork) return refuseRemoval(`${settlement.reason}. Removing "${sess.name}" deletes its Coder workspace and that work with it.`);
51644
51975
  if (!settlement.ok) return {
51645
51976
  ok: false,
51646
51977
  error: settlement.reason,
51647
- canDiscardWork: settlement.canDiscardRemoteWork
51978
+ canDiscardWork: false
51648
51979
  };
51649
51980
  }
51650
51981
  const freshConfig = configStore.save((cfg) => {
@@ -51655,6 +51986,7 @@ function registerControlHandlers(controlWss, deps) {
51655
51986
  error: `Could not save the removal of session "${sess.name}"`
51656
51987
  };
51657
51988
  if (isDiscardingWorkspaceWork) sess.confirmWorkspaceWorkDiscard();
51989
+ lastRemovalRefusalBySessionId.delete(sess.id);
51658
51990
  applyConfigReload(freshConfig);
51659
51991
  console.log(`[control] Removed session via UI: ${sess.name}`);
51660
51992
  return { ok: true };
@@ -52165,7 +52497,7 @@ function registerControlHandlers(controlWss, deps) {
52165
52497
  }
52166
52498
  return entries;
52167
52499
  }
52168
- function createProjectSession({ id = generateProjectId(), name, path: projectPath, repos, baseBranch, agent, dangerouslySkipPermissions, unguarded, requireExistingPath, environment }) {
52500
+ function createProjectSession({ id = generateProjectId(), name, path: projectPath, repos, baseBranch, agent, dangerouslySkipPermissions, unguarded, requireExistingPath, environment, runSettings }) {
52169
52501
  for (const [, session] of sessions) {
52170
52502
  if (session.name !== name) continue;
52171
52503
  return {
@@ -52199,6 +52531,7 @@ function registerControlHandlers(controlWss, deps) {
52199
52531
  error: missingFolderError(projectPath)
52200
52532
  };
52201
52533
  const project = {
52534
+ ...runSettings,
52202
52535
  id,
52203
52536
  name,
52204
52537
  path: resolvedPath
@@ -52877,6 +53210,7 @@ function registerControlHandlers(controlWss, deps) {
52877
53210
  }
52878
53211
  const handlers = {
52879
53212
  "add-session": handleAddSession,
53213
+ "quick-session": handleQuickSession,
52880
53214
  "list-conversations": handleListConversations,
52881
53215
  "resume-conversation": handleResumeConversation,
52882
53216
  "remove-session": handleRemoveSession,
@@ -52967,6 +53301,7 @@ function registerControlHandlers(controlWss, deps) {
52967
53301
  }));
52968
53302
  }
52969
53303
  },
53304
+ "watch-session-changes": (msg, ws) => changesWatch.request(ws, msg.id),
52970
53305
  "request-change-map": async (msg, ws) => {
52971
53306
  const s = findSession(msg);
52972
53307
  if (!s) return;
@@ -53291,6 +53626,9 @@ function registerControlHandlers(controlWss, deps) {
53291
53626
  stack: msg.stack
53292
53627
  });
53293
53628
  },
53629
+ "client-log": (msg) => {
53630
+ console.warn(`[dashboard] ${sanitizeOneLine(msg.scope, 64)}: ${sanitizeOneLine(msg.text, CLIENT_LOG_TEXT_MAX_CHARS)}`);
53631
+ },
53294
53632
  "dashboard-telemetry": captureDashboardTelemetry,
53295
53633
  "request-telemetry-deletion": async (msg, ws) => {
53296
53634
  const ok = await deps.telemetry?.requestDataDeletion?.() ?? false;
@@ -53385,15 +53723,37 @@ function registerControlHandlers(controlWss, deps) {
53385
53723
  });
53386
53724
  });
53387
53725
  });
53388
- return { buildSnapshot };
53726
+ function removeExitedSession(id) {
53727
+ removeSession({
53728
+ type: "remove-session",
53729
+ id
53730
+ }).then((removal) => {
53731
+ if (removal.ok) return;
53732
+ const sess = sessions.get(id);
53733
+ if (removal.canDiscardWork && sess) {
53734
+ broadcastControl({
53735
+ type: "session-close-confirm",
53736
+ id,
53737
+ mergeStatus: sess.mergeStatus
53738
+ });
53739
+ return;
53740
+ }
53741
+ console.warn(`[control] Could not remove session ${id} after its agent quit: ${removal.error}`);
53742
+ });
53743
+ }
53744
+ return {
53745
+ buildSnapshot,
53746
+ removeExitedSession
53747
+ };
53389
53748
  }
53390
53749
  //#endregion
53391
53750
  //#region server/backend/backend-control.ts
53392
53751
  function createBackendControl(dependencies) {
53393
53752
  const { controlWss, sessions, config, configStore, broadcastControl, controlReplayLog, laneAssembly, posthog, teamReview, myPrs, issues, benchmarks, usage, logger } = dependencies;
53394
- registerControlHandlers(controlWss, {
53753
+ const controlHandlers = registerControlHandlers(controlWss, {
53395
53754
  sessions,
53396
53755
  agentSessions: dependencies.agentSessions,
53756
+ markChildWorktreeDiscard: dependencies.markChildWorktreeDiscard,
53397
53757
  config,
53398
53758
  configStore,
53399
53759
  broadcastControl,
@@ -53463,6 +53823,7 @@ function createBackendControl(dependencies) {
53463
53823
  sendLaneSnapshotOnConnect("ingest", laneAssembly.currentIngest, true);
53464
53824
  sendLaneSnapshotOnConnect("session-docs", () => dependencies.sessionDocs, false);
53465
53825
  sendLaneSnapshotOnConnect("coherence-feed", () => dependencies.coherenceFeed, false);
53826
+ return { removeExitedSession: controlHandlers.removeExitedSession };
53466
53827
  }
53467
53828
  //#endregion
53468
53829
  //#region server/core/update-apply-core.ts
@@ -57247,6 +57608,7 @@ function createBackend(httpServer, options = {}) {
57247
57608
  const outcomes = createOutcomesLane();
57248
57609
  const recordOutcome = outcomes.record;
57249
57610
  let broadcastControl = null;
57611
+ let removeExitedSession = null;
57250
57612
  let agentApi = null;
57251
57613
  let gitWorkspace = null;
57252
57614
  const guardrailsRefusal = checkGuardrailsDependencies({ log: console });
@@ -57414,6 +57776,7 @@ function createBackend(httpServer, options = {}) {
57414
57776
  coherenceFeed,
57415
57777
  planReview: laneAssembly.planReview,
57416
57778
  closeSessionDataClients,
57779
+ removeExitedSession: (id) => removeExitedSession?.(id),
57417
57780
  telemetry,
57418
57781
  logger: console
57419
57782
  });
@@ -57602,10 +57965,11 @@ function createBackend(httpServer, options = {}) {
57602
57965
  spawn,
57603
57966
  beforeHandOff: updateApply.handOffStagedUpdate
57604
57967
  });
57605
- createBackendControl({
57968
+ ({removeExitedSession} = createBackendControl({
57606
57969
  controlWss,
57607
57970
  sessions,
57608
57971
  agentSessions,
57972
+ markChildWorktreeDiscard: (childId) => agentApi?.markChildWorktreeDiscard(childId),
57609
57973
  config,
57610
57974
  configStore,
57611
57975
  broadcastControl,
@@ -57648,7 +58012,7 @@ function createBackend(httpServer, options = {}) {
57648
58012
  serverBuild: () => serverBuild,
57649
58013
  telemetry,
57650
58014
  logger: console
57651
- });
58015
+ }));
57652
58016
  webSockets.attachDataConnection();
57653
58017
  const { handleUpgrade } = webSockets;
57654
58018
  httpServer.on("upgrade", handleUpgrade);