chainlesschain 0.163.2 → 0.163.3

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 (185) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/assets/{AIOps-DnGsmsqJ.js → AIOps-DIY6KxV-.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-CrO6fcQ7.js → ActionButton-BXH0muPt.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-DsBdOaP2.js → Analytics-D39w8vmg.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-DmQslKUB.js → AppLayout-CUU1zvLs.js} +5 -5
  6. package/src/assets/web-panel/assets/{Artifacts-BvyrT_QQ.js → Artifacts-D8azHO3T.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-prndoLiC.js → Audit-D0tAwXTg.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-DOTFyA55.js → BackgroundAgents-C29mhJll.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-9zOnPp_8.js → Backup-D6Aa1Gro.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-C4PC6sAG.js → BaseInput-B1uoHbPQ.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-BBAF-W9v.js → Chat-Bs4DLOR5.js} +6 -6
  12. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CWhvvloO.js → ChatBubbleRenderer-DUYIBSle.js} +1 -1
  13. package/src/assets/web-panel/assets/{Checkbox-BI9iculd.js → Checkbox-CNcBPEa4.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-3DP9BCKb.js → Codegen-CIY89763.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-df-2TnJX.js → Col-CsPYFmgo.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-CHs8gG_A.js → Community-BBocEge4.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-CDfF6q7V.js → Compact-TQ8Ux0Lf.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-CthrDnO7.js → Compliance-DfBsZTft.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-HjIqsWJw.js → Cowork-Cg-I6FVH.js} +2 -2
  20. package/src/assets/web-panel/assets/{Cron-BKc196fb.js → Cron-DTQzfRTp.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-CJnjdc8W.js → Crosschain-DGxEKGpR.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-BHUy-8Q2.js → DID-DLZ1RDSr.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-QDB7sKeY.js → Dashboard-XneICKNI.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-DStcVK11.js → Dropdown-BRU00J1-.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-BwSUskMJ.js → EmailListRenderer-BzCbJuAy.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-DgF_kurT.js → FamilyGuardDashboard-D7BRyNBG.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-k8wvv-wN.js → Federation-D9DeFIhW.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-C11qoq2r.js → FormItemContext-6rAtA9Ko.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-BIIpr9kg.js → GenericCardRenderer-8Hqy80pU.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-BlA1exTe.js → Git-Cmvkj1rt.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-CYa1ZYM4.js → Governance-BRiQUjjw.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-6_kKVIt6.js → Inference-CKN_EzVf.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-CB4AwxYy.js → KnowledgeGraph-BCDHwpwQ.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-xf7nHFAe.js → Logs-DK9ovhaB.js} +2 -2
  35. package/src/assets/web-panel/assets/MarkdownRenderer-D53pHiHy.js +1 -0
  36. package/src/assets/web-panel/assets/{Marketplace-aPg8e4Jt.js → Marketplace-BILPGakp.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-C-TNlVUf.js → McpTools-DTVCOr9-.js} +5 -5
  38. package/src/assets/web-panel/assets/{Memory-DMTPIpGa.js → Memory-Hzc1iow4.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-BxyvveRq.js → MobileBridge-GXfgnGYV.js} +1 -1
  40. package/src/assets/web-panel/assets/{MobileProjects-DyPCrAyQ.js → MobileProjects-B-3TJWsS.js} +1 -1
  41. package/src/assets/web-panel/assets/{Mtc-BdhqNXp6.js → Mtc-DwSJMWtK.js} +5 -5
  42. package/src/assets/web-panel/assets/{MtcAudit-Cz-HFxzW.js → MtcAudit-D2uxf-DA.js} +5 -5
  43. package/src/assets/web-panel/assets/{Multisig-CIUaFNsx.js → Multisig-DG6kbKK0.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-CWe6-J17.js → NLProgramming-f5p49EDU.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-vYAKeviU.js → Notes-FUgHyzSD.js} +3 -3
  46. package/src/assets/web-panel/assets/{NotificationSettings-DQL9-2d7.js → NotificationSettings-DCHGee7e.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-DnXj1jBn.js → OrderTableRenderer-Dm6LlIoa.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-B3spU8AN.js → Organization-BawA7qAg.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-DgEwo7vm.js → Overflow-D6a5wZU1.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-hujMRH8X.js → P2P-K8WavwnA.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-C_qhdg9h.js → PdhVaultBrowser-4JAJYaqx.js} +3 -3
  52. package/src/assets/web-panel/assets/{Permissions-vp7LMcSf.js → Permissions-BDWvi8PD.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-Dxr5Hgnq.js → PersonalDataHub-DF_K4E9i.js} +3 -3
  54. package/src/assets/web-panel/assets/{Pipeline-DEPZqqH4.js → Pipeline-BYeZlesI.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-DTpDiKPe.js → Privacy-BIHlgnIc.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-jDJsRWmF.js → ProjectInit-Cvf-6B5P.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-Dhor5RWH.js → ProjectSettings-CnwfJrRz.js} +2 -2
  58. package/src/assets/web-panel/assets/Projects-b-jPXzF4.js +1 -0
  59. package/src/assets/web-panel/assets/{Providers-BGs47s1a.js → Providers-CxC7JuYv.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-CjIw-wIb.js → QrScannerModal-VLf3gAfL.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-DX6jcqoi.js → QuickAsk-B5vGjRiF.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-DopXkhar.js → Recommend--UW4iYs-.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-BLvqJE9c.js → RemoteSession-DMSPcfKR.js} +2 -2
  64. package/src/assets/web-panel/assets/{Reputation-DhRj2Me7.js → Reputation-kQXlEHmj.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-DQ53vuPq.js → Row-CxGu3pit.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-BslvwiBD.js → RssFeed-Bi5lo8MZ.js} +2 -2
  67. package/src/assets/web-panel/assets/{Search-DJKBDNKZ.js → Search-Cq_H5RTh.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-COhpxHER.js → Security-YFbmkaQS.js} +3 -3
  69. package/src/assets/web-panel/assets/{Services-dbulD6cI.js → Services-DLOGdaLm.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-ciIVNfhC.js → Skeleton-CteIxb3D.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-AiRTkTCk.js → Skills-CccopaIZ.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-DDMcWYBc.js → Sla-AzfEQKX1.js} +1 -1
  73. package/src/assets/web-panel/assets/{SpeechSettings-BPxWbpXO.js → SpeechSettings-ekGo5l77.js} +1 -1
  74. package/src/assets/web-panel/assets/{SyncSettings-BoEOXCyg.js → SyncSettings-BmZmAgYH.js} +2 -2
  75. package/src/assets/web-panel/assets/Tasks-D7q3Z4uL.js +1 -0
  76. package/src/assets/web-panel/assets/{Templates-UowY8Ixe.js → Templates-CX1Tgeka.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-DauSLQXN.js → Tenant-Zc59jF4i.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-DBj7Jneq.js → Terminal-CXOD7y83.js} +2 -2
  79. package/src/assets/web-panel/assets/{TimelineRenderer-UMrPwoZC.js → TimelineRenderer-B1aBHPBo.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-4ea96-bn.js → Tokens-zALlOq_U.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger--ISCqt4b.js → Trigger-CQfJMXaq.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-D4GVimRJ.js → Trust-BU0RcM-w.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-Ci-nXRQc.js → UkeySign-IFZ3HsbH.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-Cjk7mKPw.js → VideoEditing-BzslgW0v.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-BgOLOO3Z.js → Wallet-BZAcQNS6.js} +2 -2
  86. package/src/assets/web-panel/assets/{WebAuthn-CCX0K29i.js → WebAuthn-CBK1DMi0.js} +4 -4
  87. package/src/assets/web-panel/assets/{WorkflowEditor-Ch3zgIsE.js → WorkflowEditor-BlMTPzO-.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-DKOU_2Vb.js → chat-B51-8QVn.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-6OVo4u3C.js → colors-504RTByU.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-BH78Hlsq.js → compact-item-C-GP6IQM.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-CFRpSbbC.js → createContext-DOkIj7ID.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-kB0nCNwN.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-DNQhgcVi.js → hasIn-DN7V-_FW.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-dDkoL4Pe.js → index--n-ZciV3.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-CaYqY35Z.js → index-7jIqHbzw.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-BYrnm5Ob.js → index-B2-x9bS8.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-sm7W8AXy.js → index-BFIFJ5Dr.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DKN2noIF.js → index-B_vGU-Js.js} +1 -1
  99. package/src/assets/web-panel/assets/{index--rq90rL9.js → index-Bkxhaeta.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-CFPJ8yzF.js → index-By6u5IV1.js} +1 -1
  101. package/src/assets/web-panel/assets/index-Bya64sZE.js +1 -0
  102. package/src/assets/web-panel/assets/{index-caye7AOE.js → index-C0k_Nqg9.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BxRy5LPR.js → index-C3TSohzc.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-BepBTpa8.js → index-C4DV_5uA.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-D84id2Y4.js → index-C8UltbXK.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-Y9MJv28e.js → index-C9_48OzU.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-Bb6kDrUx.js → index-CKTfZyfU.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CrcLHN2F.js → index-CP2A226L.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-CkNEMANR.js → index-CUhQpiYv.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-Cu3L4r5l.js → index-CX78k-qf.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DaDgdJYj.js → index-CYopNjcJ.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-Du0rnksC.js → index-Cao5DZy7.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BaVE6E8y.js → index-CfiEM64n.js} +3 -3
  114. package/src/assets/web-panel/assets/{index-BujsOZfc.js → index-ConjaJro.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-hPY0fFrd.js → index-CqcLo5WV.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-BDSR7ecX.js → index-CySTJKeq.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BHa4WyTZ.js → index-D1phyca8.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-nbfHl1oV.js → index-D9LyiN-L.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-CkqHgG-b.js → index-DA2f1UV3.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-Eag8e_mA.js → index-DAOpQvl_.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-cdf7fd7d.js → index-DE-hmI2l.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-bKm3TUDp.js → index-DEMPUVa3.js} +1 -1
  123. package/src/assets/web-panel/assets/index-D_FWpDZM.js +1 -0
  124. package/src/assets/web-panel/assets/{index-7TC3S8SN.js → index-DaA__-q1.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DvHGtNnF.js → index-FcV8J_Qz.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-B_Z-YoxX.js → index-P2mfY27Z.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-AuBhLqOm.js → index-et5JIPHO.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-D3RtTT4K.js → index-f4Bo4KXm.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CNuCHHQT.js → index-kAqQXfP6.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-BkN3iTTp.js → index-kt_5rfcZ.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-BnnXQot_.js → index-so8eIIxF.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-HNGGVF6o.js → index-yYTQZypF.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-BZ9w6jPL.js → initDefaultProps-CPYEIdpV.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-BnwUiOho.js → motion-Cjim9pxs.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-ByUKJnNm.js → move-DuU-cgz3.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-V7yK1KEl.js → mtc-parser-DJHNAkta.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-BEXBBt4j.js → omit-DSQBgdBj.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-qDm_46Gi.js → pickAttrs-CTmT_j5m.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-BIbhEo_0.js → placementArrow-Lfm6v-r4.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-NbPbDgA_.js → responsiveObserve-CgrcPcDi.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-BnUWglZ0.js → slide-CuE3110i.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-BX8_wZI5.js → statusUtils-DiK5nbpf.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-BV4OycQX.js → styleChecker-DPEJdQaZ.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-Od_H5llY.js → useFlexGapSupport-CnnodGmp.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-BWI-PyiX.js → useFs-DWF84Yav.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-BqMuhG3g.js → usePersonalDataHub-a5b5Dw2f.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-DNd23z6f.js → vnode-DAluzXOq.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-Cjaxnm7l.js → zoom-Dokg7uAZ.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/command-help-index.json +1 -1
  151. package/src/commands/agenda.js +6 -5
  152. package/src/commands/agent.js +237 -75
  153. package/src/commands/agents.js +6 -0
  154. package/src/commands/background-session.js +11 -1
  155. package/src/commands/mcp.js +217 -30
  156. package/src/data/changelog.json +14 -1
  157. package/src/harness/mcp-client.js +242 -42
  158. package/src/harness/worktree-isolator.js +26 -3
  159. package/src/lib/agent-worktree.js +41 -2
  160. package/src/lib/background-agent-supervisor.js +790 -186
  161. package/src/lib/background-command-argv.js +318 -0
  162. package/src/lib/background-launch-profile.js +1 -0
  163. package/src/lib/background-phase-reporter.js +22 -2
  164. package/src/lib/background-worktree-policy.js +109 -0
  165. package/src/lib/cowork-mcp-tools.js +51 -6
  166. package/src/lib/cowork-task-runner.js +1 -0
  167. package/src/lib/mcp-headers-helper.js +76 -8
  168. package/src/lib/mcp-sandbox-policy.js +155 -0
  169. package/src/lib/mcp-stdio-execution-authority.js +163 -0
  170. package/src/lib/mcp-stdio-workspace-authority.js +252 -0
  171. package/src/lib/plugin-runtime/sandbox-policy.js +42 -2
  172. package/src/lib/process-execution-broker/index.js +179 -104
  173. package/src/lib/process-execution-broker/platform-sandbox.js +942 -168
  174. package/src/lib/process-tree-termination.js +17 -1
  175. package/src/lib/skill-mcp.js +65 -4
  176. package/src/lib/web-fetch.js +4 -4
  177. package/src/runtime/agent-runtime.js +61 -8
  178. package/src/runtime/mcp-config.js +235 -28
  179. package/src/workers/background-agent-worker.js +492 -71
  180. package/src/assets/web-panel/assets/MarkdownRenderer-Bf3DEqP6.js +0 -1
  181. package/src/assets/web-panel/assets/Projects-08xUDZGt.js +0 -1
  182. package/src/assets/web-panel/assets/Tasks-CEYFJwmr.js +0 -1
  183. package/src/assets/web-panel/assets/devWarning-DEMblAIm.js +0 -1
  184. package/src/assets/web-panel/assets/index-BTvq-36D.js +0 -1
  185. package/src/assets/web-panel/assets/index-hUpvk6Jl.js +0 -1
@@ -16,12 +16,15 @@ import { readFileSync, writeSync } from "node:fs";
16
16
  import { randomBytes } from "node:crypto";
17
17
  import {
18
18
  DEFAULT_HEARTBEAT_INTERVAL_MS,
19
+ DEFAULT_HEARTBEAT_STALE_MS,
19
20
  backgroundAgentsDir,
21
+ claimBackgroundAgentHeartbeat,
22
+ insertArgumentsBeforeOptionTerminator,
23
+ mutateBackgroundAgentState,
20
24
  openBackgroundLogFile,
21
25
  readBackgroundAgentState,
22
26
  removeJobFile,
23
27
  stopBackgroundAgentChildTree,
24
- writeBackgroundAgentState,
25
28
  } from "../lib/background-agent-supervisor.js";
26
29
  import { startBackgroundSessionServer } from "../lib/background-session-transport.js";
27
30
  import { idlePhaseFor } from "../lib/background-agent-phase.js";
@@ -32,6 +35,11 @@ import {
32
35
  updateBackgroundInteractionJournal,
33
36
  } from "../lib/background-interaction-journal.js";
34
37
  import executionBroker from "../lib/process-execution-broker/index.js";
38
+ import { agentPrintArgument } from "../lib/background-command-argv.js";
39
+ import {
40
+ shouldRetryOwnedProcessTreeTermination,
41
+ terminateOwnedProcessTree,
42
+ } from "../lib/process-tree-termination.js";
35
43
 
36
44
  const jobFile = process.argv[2];
37
45
  let job;
@@ -46,6 +54,8 @@ let lastExit = { code: 0, signal: null };
46
54
  let transportState = null;
47
55
  let detachInteractionHandler = null;
48
56
  let interactionJournal = null;
57
+ let turnLaunchUncertainty = null;
58
+ let turnLaunchSettlement = null;
49
59
  const promptQueue = [];
50
60
  // P0-2: 保存 pending 的交互请求,等 attach 客户端连接后转发
51
61
  const pendingInteractions = new Map();
@@ -75,51 +85,106 @@ function persistInteractionSettlement(requestId, binding, outcome) {
75
85
  }
76
86
 
77
87
  function mergeState(patch) {
78
- const current = readBackgroundAgentState(job.id) || { id: job.id };
79
- const next = { ...current, id: job.id, ...patch };
80
- writeBackgroundAgentState(next);
81
- return next;
88
+ return mutateBackgroundAgentState(job.id, (current) => {
89
+ if (!current || current.status !== "running" || current.stopRequestedAt) {
90
+ return null;
91
+ }
92
+ return { ...current, id: job.id, ...patch };
93
+ }).state;
82
94
  }
83
95
 
84
96
  function writeHeartbeat() {
85
- const current = readBackgroundAgentState(job.id) || { id: job.id };
86
- if (current.status && current.status !== "running") return false;
87
- writeBackgroundAgentState({
88
- ...current,
89
- id: job.id,
97
+ const mutation = claimBackgroundAgentHeartbeat(job.id, {
98
+ workerGeneration: job.workerGeneration,
90
99
  pid: process.pid,
91
100
  workerPid: process.pid,
92
- agentPid: child?.pid ?? current.agentPid ?? null,
93
- status: "running",
101
+ ...(child?.pid ? { agentPid: child.pid } : {}),
102
+ ...(turnLaunchUncertainty || {}),
94
103
  heartbeatAt: Date.now(),
95
104
  // Re-assert the transport endpoint so a launcher write racing the
96
105
  // worker's initial merge self-heals within one heartbeat.
97
106
  ...(transportState ? { transport: transportState } : {}),
98
107
  });
99
- return true;
108
+ const applied =
109
+ mutation.applied &&
110
+ mutation.state?.status === "running" &&
111
+ Number(mutation.state.workerPid) === process.pid &&
112
+ (!mutation.state.workerGeneration ||
113
+ mutation.state.workerGeneration === job.workerGeneration);
114
+ if (applied && turnLaunchSettlement?.termination?.confirmed === true) {
115
+ scheduleTurnLaunchSettlementPersistence(0);
116
+ }
117
+ return applied;
118
+ }
119
+
120
+ async function waitForLaunchFinalization() {
121
+ const deadline = Date.now() + DEFAULT_HEARTBEAT_STALE_MS;
122
+ for (;;) {
123
+ const current = readBackgroundAgentState(job.id);
124
+ if (!current) return "terminal";
125
+ if (current.status && current.status !== "running") return "terminal";
126
+ if (current.launchFinalizationUncertain !== true) return "ready";
127
+ if (Date.now() >= deadline) {
128
+ mergeState({
129
+ status: "failed",
130
+ endedAt: Date.now(),
131
+ exitCode: 1,
132
+ error: "background launcher did not finalize process ownership",
133
+ phase: null,
134
+ transport: null,
135
+ launchFinalizationUncertain: false,
136
+ });
137
+ return "timeout";
138
+ }
139
+ await new Promise((resolve) => setTimeout(resolve, 25));
140
+ }
100
141
  }
101
142
 
102
143
  function finalize(code, signal, errorMessage) {
144
+ // A launch settlement owns the worker lifetime until its tree/no-spawn
145
+ // result is durably recorded. Transport detach, a queued prompt, or a fatal
146
+ // callback must not exit through finalize and strand that retry protocol.
147
+ if (turnLaunchSettlement) return;
103
148
  if (finalized) return;
104
149
  finalized = true;
105
150
  clearInterval(heartbeat);
106
- const current = readBackgroundAgentState(job.id) || { id: job.id };
107
- // An external `cc daemon stop` already recorded its own terminal status —
108
- // don't overwrite it; just clear the dead transport endpoint.
109
- if (!current.status || current.status === "running") {
110
- writeBackgroundAgentState({
111
- ...current,
112
- id: job.id,
113
- status: errorMessage ? "failed" : code === 0 ? "completed" : "failed",
114
- endedAt: Date.now(),
115
- exitCode: errorMessage ? (code ?? 1) : code,
116
- signal: signal || null,
117
- ...(errorMessage ? { error: errorMessage } : {}),
118
- phase: null,
119
- transport: null,
151
+ try {
152
+ mutateBackgroundAgentState(job.id, (current) => {
153
+ if (!current) return null;
154
+ const ownsRecord =
155
+ (!current.workerGeneration ||
156
+ current.workerGeneration === job.workerGeneration) &&
157
+ (Number(current.workerClaimedPid) === process.pid ||
158
+ (current.workerClaimedPid == null &&
159
+ Number(current.workerPid ?? current.pid) === process.pid));
160
+ if (!ownsRecord) return null;
161
+ // An external stop/remove owns an already-terminal or deleted record.
162
+ if (current.status !== "running") {
163
+ return { ...current, phase: null, transport: null };
164
+ }
165
+ return {
166
+ ...current,
167
+ id: job.id,
168
+ status: errorMessage ? "failed" : code === 0 ? "completed" : "failed",
169
+ endedAt: Date.now(),
170
+ exitCode: errorMessage ? (code ?? 1) : code,
171
+ signal: signal || null,
172
+ ...(errorMessage ? { error: errorMessage } : {}),
173
+ phase: null,
174
+ transport: null,
175
+ };
120
176
  });
121
- } else {
122
- writeBackgroundAgentState({ ...current, phase: null, transport: null });
177
+ } catch (error) {
178
+ try {
179
+ writeSync(
180
+ 2,
181
+ `[background-agent-worker] final state persistence failed: ${
182
+ error?.message || String(error)
183
+ }\n`,
184
+ );
185
+ } catch {
186
+ /* inherited stderr may already be closed */
187
+ }
123
188
  }
124
189
  const done = () => {
125
190
  try {
@@ -137,43 +202,351 @@ function finalize(code, signal, errorMessage) {
137
202
  }
138
203
  }
139
204
 
205
+ function scheduleTurnLaunchSettlementRetry(context, delayMs = 250) {
206
+ if (
207
+ !context ||
208
+ turnLaunchSettlement !== context ||
209
+ context.retryTimer ||
210
+ (context.termination?.confirmed !== true &&
211
+ context.terminationRetryBlocked === true)
212
+ ) {
213
+ return;
214
+ }
215
+ context.retryTimer = setTimeout(
216
+ () => {
217
+ context.retryTimer = null;
218
+ if (turnLaunchSettlement !== context) return;
219
+ if (context.termination?.confirmed === true) {
220
+ persistConfirmedTurnLaunchSettlement(context);
221
+ } else {
222
+ void settleUncertainTurnLaunch(context);
223
+ }
224
+ },
225
+ Math.max(0, delayMs),
226
+ );
227
+ }
228
+
229
+ function scheduleTurnLaunchSettlementPersistence(delayMs = 100) {
230
+ const context = turnLaunchSettlement;
231
+ if (!context || context.termination?.confirmed !== true) return;
232
+ scheduleTurnLaunchSettlementRetry(context, delayMs);
233
+ }
234
+
235
+ function persistConfirmedTurnLaunchSettlement(context) {
236
+ try {
237
+ mutateBackgroundAgentState(job.id, (current) => {
238
+ const sameWorker =
239
+ current?.workerGeneration === job.workerGeneration &&
240
+ Number(current?.workerClaimedPid) === process.pid;
241
+ const tokenMatches =
242
+ current?.turnLaunchToken === context.turnLaunchToken ||
243
+ current?.turnLaunchIntent?.token === context.turnLaunchToken;
244
+ const ownedPid = Number(context.owned?.pid);
245
+ if (
246
+ !current ||
247
+ (!tokenMatches && !sameWorker) ||
248
+ (Number.isInteger(ownedPid) &&
249
+ ownedPid > 0 &&
250
+ current.agentPid != null &&
251
+ Number(current.agentPid) !== ownedPid)
252
+ ) {
253
+ return null;
254
+ }
255
+ return {
256
+ ...current,
257
+ status: current.stopRequestedAt ? "stopped" : "failed",
258
+ endedAt: current.endedAt || Date.now(),
259
+ exitCode: current.exitCode ?? 1,
260
+ error: `background turn launch failed after spawn: ${
261
+ context.error?.message || "unknown post-spawn failure"
262
+ }`,
263
+ phase: null,
264
+ transport: null,
265
+ turnLaunchIntent: null,
266
+ turnLaunchResolution: {
267
+ token: context.turnLaunchToken,
268
+ attempt: context.turnLaunchAttempt,
269
+ outcome: context.owned ? "terminated" : "not-spawned",
270
+ ...(context.owned ? { agentPid: ownedPid } : {}),
271
+ resolvedAt: Date.now(),
272
+ },
273
+ turnLaunchFinalizationUncertain: false,
274
+ turnLaunchToken: null,
275
+ turnLaunchError: null,
276
+ turnLaunchTermination: {
277
+ confirmed: true,
278
+ treeMode: context.termination.treeMode || null,
279
+ closed: context.termination.closed === true,
280
+ treeTerminated: context.termination.treeTerminated === true,
281
+ settledAt: Date.now(),
282
+ },
283
+ };
284
+ });
285
+ // A missing or incompatible record must not be recreated or retargeted.
286
+ // The owned tree is already confirmed gone, so it is safe for this worker
287
+ // to close even though the retained record (if any) stays fail-closed.
288
+ clearInterval(context.keeper);
289
+ turnLaunchUncertainty = null;
290
+ turnLaunchSettlement = null;
291
+ child = null;
292
+ finalize(
293
+ 1,
294
+ null,
295
+ context.error?.message || "background turn launch failed",
296
+ );
297
+ } catch {
298
+ scheduleTurnLaunchSettlementPersistence();
299
+ }
300
+ }
301
+
302
+ async function settleUncertainTurnLaunch(context) {
303
+ if (!context || turnLaunchSettlement !== context || context.settling) return;
304
+ if (context.termination?.confirmed === true) {
305
+ persistConfirmedTurnLaunchSettlement(context);
306
+ return;
307
+ }
308
+ if (
309
+ !shouldRetryOwnedProcessTreeTermination(context.owned, context.termination)
310
+ ) {
311
+ context.terminationRetryBlocked = true;
312
+ return;
313
+ }
314
+ context.settling = true;
315
+ try {
316
+ context.termination = await terminateOwnedProcessTree(context.owned, {
317
+ treeMode: process.platform === "win32" ? "windows-tree" : "posix-group",
318
+ });
319
+ } catch (error) {
320
+ context.terminationError = error?.message || String(error);
321
+ } finally {
322
+ context.settling = false;
323
+ }
324
+ if (context.termination?.confirmed === true) {
325
+ persistConfirmedTurnLaunchSettlement(context);
326
+ return;
327
+ }
328
+ if (
329
+ !shouldRetryOwnedProcessTreeTermination(context.owned, context.termination)
330
+ ) {
331
+ // The root is closed but descendants were not proven gone. Its numeric
332
+ // pid/pgid can now be reused, so another taskkill/kill would risk an
333
+ // unrelated process tree. Retain the durable uncertainty and the keeper;
334
+ // only explicit recovery with stronger identity evidence may proceed.
335
+ context.terminationRetryBlocked = true;
336
+ return;
337
+ }
338
+ context.terminationAttempts = Number(context.terminationAttempts || 0) + 1;
339
+ const retryMs = Math.min(
340
+ 5_000,
341
+ 250 * 2 ** Math.min(context.terminationAttempts, 4),
342
+ );
343
+ scheduleTurnLaunchSettlementRetry(context, retryMs);
344
+ }
345
+
346
+ function beginTurnLaunchSettlement({
347
+ owned,
348
+ error,
349
+ turnLaunchToken,
350
+ turnLaunchAttempt,
351
+ agentStartedAt,
352
+ }) {
353
+ child = owned || null;
354
+ phase = "turn_launch_uncertain";
355
+ const ownedPid = Number(owned?.pid);
356
+ turnLaunchUncertainty = {
357
+ ...(owned
358
+ ? { agentPid: ownedPid, agentStartedAt: agentStartedAt || Date.now() }
359
+ : {}),
360
+ phase,
361
+ turnLaunchIntent: null,
362
+ turnLaunchResolution: {
363
+ token: turnLaunchToken,
364
+ attempt: turnLaunchAttempt,
365
+ outcome: owned ? "spawned" : "not-spawned",
366
+ ...(owned ? { agentPid: ownedPid } : {}),
367
+ resolvedAt: Date.now(),
368
+ },
369
+ turnLaunchFinalizationUncertain: true,
370
+ turnLaunchError: error?.message || String(error),
371
+ turnLaunchToken,
372
+ };
373
+ const settlement = {
374
+ owned,
375
+ error,
376
+ turnLaunchToken,
377
+ turnLaunchAttempt,
378
+ termination: owned
379
+ ? null
380
+ : {
381
+ confirmed: true,
382
+ treeMode: "none",
383
+ closed: true,
384
+ treeTerminated: true,
385
+ },
386
+ terminationAttempts: 0,
387
+ terminationRetryBlocked: false,
388
+ settling: false,
389
+ retryTimer: null,
390
+ keeper: null,
391
+ };
392
+ settlement.keeper = setInterval(() => {
393
+ if (turnLaunchSettlement !== settlement) return;
394
+ if (settlement.termination?.confirmed === true) {
395
+ scheduleTurnLaunchSettlementPersistence(0);
396
+ } else if (settlement.terminationRetryBlocked !== true) {
397
+ scheduleTurnLaunchSettlementRetry(settlement, 0);
398
+ }
399
+ }, 1_000);
400
+ turnLaunchSettlement = settlement;
401
+ try {
402
+ mutateBackgroundAgentState(job.id, (current) =>
403
+ current ? { ...current, ...turnLaunchUncertainty } : null,
404
+ );
405
+ } catch {
406
+ // The durable prepare record remains the stop/cleanup fence. Settlement
407
+ // retries both tree termination and the final confirmation write.
408
+ }
409
+ if (settlement.termination?.confirmed === true) {
410
+ persistConfirmedTurnLaunchSettlement(settlement);
411
+ } else {
412
+ void settleUncertainTurnLaunch(settlement);
413
+ }
414
+ return "uncertain";
415
+ }
416
+
140
417
  function startTurn(argv, promptText) {
418
+ if (!writeHeartbeat()) return false;
419
+ const nextTurn = turnCount + 1;
420
+ const turnLaunchToken = randomBytes(16).toString("hex");
421
+ let turnLaunchAttempt = 0;
422
+ let prepared;
423
+ try {
424
+ prepared = mutateBackgroundAgentState(job.id, (current) => {
425
+ if (
426
+ !current ||
427
+ current.status !== "running" ||
428
+ current.stopRequestedAt ||
429
+ current.turnLaunchIntent ||
430
+ current.turnLaunchFinalizationUncertain === true ||
431
+ Number(current.workerPid) !== process.pid ||
432
+ Number(current.workerClaimedPid) !== process.pid ||
433
+ (current.workerGeneration &&
434
+ current.workerGeneration !== job.workerGeneration)
435
+ ) {
436
+ return null;
437
+ }
438
+ turnLaunchAttempt =
439
+ Math.max(0, Number(current.turnLaunchAttempt) || 0) + 1;
440
+ return {
441
+ ...current,
442
+ phase: "turn_launching",
443
+ turnLaunchAttempt,
444
+ turnLaunchIntent: {
445
+ token: turnLaunchToken,
446
+ attempt: turnLaunchAttempt,
447
+ workerPid: process.pid,
448
+ workerGeneration: job.workerGeneration,
449
+ preparedAt: Date.now(),
450
+ },
451
+ heartbeatAt: Date.now(),
452
+ };
453
+ });
454
+ } catch (error) {
455
+ if (turnLaunchAttempt > 0) {
456
+ // The atomic rename may have committed even when strict lock release
457
+ // reports ownership loss. Resolve that window as an explicit no-spawn
458
+ // attempt instead of exiting with a durable intent and no settlement.
459
+ return beginTurnLaunchSettlement({
460
+ owned: null,
461
+ error,
462
+ turnLaunchToken,
463
+ turnLaunchAttempt,
464
+ agentStartedAt: null,
465
+ });
466
+ }
467
+ throw error;
468
+ }
469
+ if (!prepared.applied) return false;
470
+
471
+ let spawned = null;
472
+ let agentStartedAt = null;
473
+ try {
474
+ const mutation = mutateBackgroundAgentState(job.id, (current) => {
475
+ if (
476
+ !current ||
477
+ current.status !== "running" ||
478
+ current.stopRequestedAt ||
479
+ current.turnLaunchIntent?.token !== turnLaunchToken ||
480
+ Number(current.turnLaunchIntent?.attempt) !== turnLaunchAttempt ||
481
+ Number(current.workerPid) !== process.pid ||
482
+ Number(current.workerClaimedPid) !== process.pid ||
483
+ (current.workerGeneration &&
484
+ current.workerGeneration !== job.workerGeneration)
485
+ ) {
486
+ return null;
487
+ }
488
+ // The prepare intent is already durable. Keep the second state lock
489
+ // through native spawn and pid commit so a stopper sees either the
490
+ // unresolved intent or the exact child identity it must reap.
491
+ agentStartedAt = Date.now();
492
+ spawned = executionBroker.spawn(
493
+ process.execPath,
494
+ [job.cliEntry, ...argv],
495
+ {
496
+ cwd: job.cwd,
497
+ env: { ...process.env, CC_BACKGROUND_AGENT_ID: job.id },
498
+ stdio: ["ignore", log.fd, log.fd, "ipc"],
499
+ windowsHide: true,
500
+ origin: "background-agent:turn",
501
+ policy: "allow",
502
+ scope: "background-agent",
503
+ shell: false,
504
+ detached: process.platform !== "win32",
505
+ },
506
+ );
507
+ return {
508
+ ...current,
509
+ status: "running",
510
+ phase: "turn",
511
+ turnCount: nextTurn,
512
+ pendingApprovals: 0,
513
+ pendingQuestion: null,
514
+ uncertainSideEffects: 0,
515
+ agentPid: spawned.pid,
516
+ agentStartedAt,
517
+ turnLaunchIntent: null,
518
+ turnLaunchResolution: {
519
+ token: turnLaunchToken,
520
+ attempt: turnLaunchAttempt,
521
+ outcome: "spawned",
522
+ agentPid: spawned.pid,
523
+ resolvedAt: Date.now(),
524
+ },
525
+ heartbeatAt: Date.now(),
526
+ };
527
+ });
528
+ if (!mutation.applied) {
529
+ return beginTurnLaunchSettlement({
530
+ owned: null,
531
+ error: new Error("background turn was stopped before native spawn"),
532
+ turnLaunchToken,
533
+ turnLaunchAttempt,
534
+ agentStartedAt: null,
535
+ });
536
+ }
537
+ } catch (error) {
538
+ const owned = spawned || error?.spawnedProcess;
539
+ return beginTurnLaunchSettlement({
540
+ owned,
541
+ error,
542
+ turnLaunchToken,
543
+ turnLaunchAttempt,
544
+ agentStartedAt,
545
+ });
546
+ }
547
+ child = spawned;
141
548
  phase = "turn";
142
- turnCount++;
143
- child = executionBroker.spawn(process.execPath, [job.cliEntry, ...argv], {
144
- cwd: job.cwd,
145
- env: { ...process.env, CC_BACKGROUND_AGENT_ID: job.id },
146
- stdio: ["ignore", log.fd, log.fd, "ipc"], // P0-2: 开启 IPC 通道用于人机交互
147
- windowsHide: true,
148
- origin: "background-agent:turn",
149
- policy: "allow",
150
- scope: "background-agent",
151
- shell: false,
152
- // POSIX: give the agent child its own process group so an orphan reclaim
153
- // (worker crashed → supervisor kills the recorded agentPid) or /stop can
154
- // signal the WHOLE agent tree via -pid. Windows reaps via taskkill /T.
155
- detached: process.platform !== "win32",
156
- });
157
- mergeState({
158
- status: "running",
159
- phase,
160
- turnCount,
161
- // A fresh turn has nothing pending; also clears a stale count left behind
162
- // if the previous turn's child was hard-killed mid-approval (the child's
163
- // phase reporter clears on settle, but SIGKILL never settles).
164
- pendingApprovals: 0,
165
- // The incoming prompt IS the user's reply to any parked question, and the
166
- // uncertain-side-effect annotation only covers the verify turn it was
167
- // raised in — both reset at the turn boundary.
168
- pendingQuestion: null,
169
- uncertainSideEffects: 0,
170
- agentPid: child.pid,
171
- // Identity anchor for the supervisor's orphan reclaim (Gap 2): pairs
172
- // with agentPid the way startedAt pairs with the worker pid, so a
173
- // pid-reusing stranger is never killed in the worker's name.
174
- agentStartedAt: Date.now(),
175
- heartbeatAt: Date.now(),
176
- });
549
+ turnCount = nextTurn;
177
550
  server?.broadcast({
178
551
  type: "turn-started",
179
552
  turn: turnCount,
@@ -305,6 +678,7 @@ function startTurn(argv, promptText) {
305
678
  child = null;
306
679
  finalize(1, null, error.message);
307
680
  });
681
+ return true;
308
682
  }
309
683
 
310
684
  function maybeContinue() {
@@ -312,13 +686,22 @@ function maybeContinue() {
312
686
  // External stop marked the session terminal while a turn was in flight —
313
687
  // don't start another turn against a stopped session.
314
688
  const current = readBackgroundAgentState(job.id);
315
- if (current?.status && current.status !== "running") {
689
+ if (!current || current.status !== "running") {
316
690
  finalize(lastExit.code, lastExit.signal);
317
691
  return;
318
692
  }
319
693
  if (promptQueue.length && Array.isArray(job.followUpArgv)) {
320
694
  const text = promptQueue.shift();
321
- startTurn([...job.followUpArgv, "-p", text], text);
695
+ if (
696
+ !startTurn(
697
+ insertArgumentsBeforeOptionTerminator(job.followUpArgv, [
698
+ agentPrintArgument(text),
699
+ ]),
700
+ text,
701
+ )
702
+ ) {
703
+ finalize(lastExit.code, lastExit.signal);
704
+ }
322
705
  return;
323
706
  }
324
707
  if (server && server.clientCount() > 0) {
@@ -359,6 +742,13 @@ function getStatus() {
359
742
 
360
743
  async function main() {
361
744
  job = JSON.parse(readFileSync(jobFile, "utf8"));
745
+ // Claim before opening logs, recovering interactions or creating the pipe.
746
+ // A stopped/removed/differently-generated record must produce no worker
747
+ // side effects and must never be recreated by bootstrap merges.
748
+ if (!writeHeartbeat()) {
749
+ removeJobFile(jobFile);
750
+ return;
751
+ }
362
752
  removeJobFile(jobFile);
363
753
  log = openBackgroundLogFile(job.id);
364
754
  interactionJournal = loadBackgroundInteractionJournal(job.sessionId, job.id);
@@ -477,14 +867,34 @@ async function main() {
477
867
  server = null;
478
868
  }
479
869
 
480
- writeHeartbeat();
870
+ if (!writeHeartbeat()) {
871
+ // A list/stop/remove writer may have terminalized the record before this
872
+ // worker claimed it. Never execute the task after losing ownership of the
873
+ // session id; close any best-effort transport and exit without rewriting
874
+ // the terminal status.
875
+ finalize(0, null);
876
+ return;
877
+ }
481
878
  heartbeat = setInterval(() => {
482
879
  try {
483
880
  if (!writeHeartbeat()) {
881
+ if (turnLaunchSettlement) {
882
+ // The owned tree is already in explicit settlement. Keep the worker
883
+ // alive until confirmed termination evidence is durably recorded;
884
+ // an external stopper may still terminate this worker directly.
885
+ return;
886
+ }
484
887
  clearInterval(heartbeat);
485
- // External stop: the child tree is being killed by the stopper; make
486
- // sure the worker itself never lingers holding the pipe.
487
- if (!child) finalize(lastExit.code, lastExit.signal);
888
+ // External stop owns the terminal fence. Reap our current detached
889
+ // child as a second line of defence, then stop holding the pipe.
890
+ if (child?.pid) {
891
+ try {
892
+ stopBackgroundAgentChildTree(child.pid);
893
+ } catch {
894
+ /* the stopper may already have reaped it */
895
+ }
896
+ }
897
+ finalize(lastExit.code, lastExit.signal);
488
898
  }
489
899
  } catch {
490
900
  /* do not let heartbeat persistence kill the worker */
@@ -492,7 +902,18 @@ async function main() {
492
902
  }, DEFAULT_HEARTBEAT_INTERVAL_MS);
493
903
  heartbeat.unref?.();
494
904
 
495
- startTurn(job.argv, null);
905
+ const launchReadiness = await waitForLaunchFinalization();
906
+ if (launchReadiness !== "ready") {
907
+ finalize(launchReadiness === "timeout" ? 1 : 0, null);
908
+ return;
909
+ }
910
+ // Launch finalization can take long enough for an external stop/remove to
911
+ // win after bootstrap. Re-claim immediately before the first native turn.
912
+ if (!writeHeartbeat()) {
913
+ finalize(0, null);
914
+ return;
915
+ }
916
+ if (!startTurn(job.argv, null)) finalize(0, null);
496
917
  }
497
918
 
498
919
  main().catch((error) => {
@@ -1 +0,0 @@
1
- import{P as c,J as p,b as a}from"./vendor-Bn1JzzAn.js";import{r as s}from"./markdown-Yo_c6Krv.js";import{_ as d}from"./index-BaVE6E8y.js";const _={__name:"MarkdownRenderer",props:{content:{type:String,default:""}},setup(t,{expose:o}){o();const e=t,r=a(()=>s(e.content||"")),n={props:e,rendered:r,computed:a,get renderMarkdown(){return s}};return Object.defineProperty(n,"__isScriptSetup",{enumerable:!1,value:!0}),n}},i=["innerHTML"];function m(t,o,e,r,n,u){return c(),p("div",{class:"markdown-content",innerHTML:r.rendered},null,8,i)}const w=d(_,[["render",m],["__scopeId","data-v-0b0b9f63"],["__file","/tmp/cc-web-panel-RQ6CTa/repo/packages/web-panel/src/components/MarkdownRenderer.vue"]]);export{w as M};