chainlesschain 0.162.198 → 0.163.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 (197) hide show
  1. package/bin/chainlesschain.js +14 -6
  2. package/package.json +5 -1
  3. package/scripts/command-lifecycle-report.mjs +94 -0
  4. package/scripts/postinstall.mjs +19 -3
  5. package/scripts/repair-node-pty.mjs +74 -0
  6. package/src/assets/web-panel/assets/{AIOps-CSN-D2xb.js → AIOps-CSy9BB6Z.js} +1 -1
  7. package/src/assets/web-panel/assets/{ActionButton-CBSMlGzv.js → ActionButton-CFyrEVfq.js} +1 -1
  8. package/src/assets/web-panel/assets/{Analytics-3yr3Nt2t.js → Analytics-8419vb47.js} +3 -3
  9. package/src/assets/web-panel/assets/{AppLayout-1b-o3lMH.js → AppLayout-CHu3Hkdx.js} +5 -5
  10. package/src/assets/web-panel/assets/{Artifacts-Dr8rJi17.js → Artifacts-DJnt57Fs.js} +1 -1
  11. package/src/assets/web-panel/assets/{Audit-2V689HC2.js → Audit-CHMq9ajE.js} +1 -1
  12. package/src/assets/web-panel/assets/{BackgroundAgents-DIxkNrD_.js → BackgroundAgents-Cyfa4ub2.js} +1 -1
  13. package/src/assets/web-panel/assets/{Backup-Pg6BcwrE.js → Backup-ACXUrUv7.js} +1 -1
  14. package/src/assets/web-panel/assets/{BaseInput-CLUpqyfH.js → BaseInput-DjC-3qRE.js} +1 -1
  15. package/src/assets/web-panel/assets/{Chat-qVS8rD4G.js → Chat-7_VDQ851.js} +6 -6
  16. package/src/assets/web-panel/assets/{ChatBubbleRenderer-ti49X12Q.js → ChatBubbleRenderer-B4zct0dY.js} +1 -1
  17. package/src/assets/web-panel/assets/{Checkbox-Bs9AaEay.js → Checkbox-DxbDl_rk.js} +1 -1
  18. package/src/assets/web-panel/assets/{Codegen-Dvc1mq8q.js → Codegen-BvZa5854.js} +1 -1
  19. package/src/assets/web-panel/assets/{Col-C4_biO7A.js → Col-CX5Ow2Zl.js} +1 -1
  20. package/src/assets/web-panel/assets/{Community-al25XQUV.js → Community-wFun-jSg.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compact-D-ZDB8M1.js → Compact-C6vJDuSn.js} +1 -1
  22. package/src/assets/web-panel/assets/{Compliance-6lIfDz1W.js → Compliance-Cm4sBytH.js} +1 -1
  23. package/src/assets/web-panel/assets/{Cowork-DdI48XMJ.js → Cowork-DiEcMwE8.js} +3 -3
  24. package/src/assets/web-panel/assets/{Cron-DF5HZd2g.js → Cron-RbeexsSQ.js} +2 -2
  25. package/src/assets/web-panel/assets/{Crosschain-DuxeSvt3.js → Crosschain-BBsyCKOp.js} +1 -1
  26. package/src/assets/web-panel/assets/{DID-B9yHkUTd.js → DID-DE36g7Hz.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dashboard-Z5EuI3IM.js → Dashboard-CdfLSTz1.js} +2 -2
  28. package/src/assets/web-panel/assets/{Dropdown-vuRfO3dY.js → Dropdown-CyaT6SyW.js} +1 -1
  29. package/src/assets/web-panel/assets/{EmailListRenderer-QFLCc1uL.js → EmailListRenderer-Nv_66bkM.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-BZ7EXkFJ.js → FamilyGuardDashboard-Di-Sb-Ad.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-DycIEg2s.js → Federation-B3mdht-U.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-Ba0H_7yG.js → FormItemContext-BeP93u4f.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer--JgSTK-C.js → GenericCardRenderer-CETLayUr.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-DEvTbldE.js → Git-Bsat6hgI.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-BJIljy18.js → Governance-YVmA7SwN.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-CVyW3G3q.js → Inference-DCa94nGl.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-v8-borge.js → KnowledgeGraph-CIKEU7T0.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-BCdS7gGo.js → Logs-DUxP0MnS.js} +2 -2
  39. package/src/assets/web-panel/assets/{MarkdownRenderer-CU-JB2Ns.js → MarkdownRenderer-Mw5o3e7M.js} +1 -1
  40. package/src/assets/web-panel/assets/{Marketplace-AN6tGA2B.js → Marketplace-BU0X2lqu.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-DGViXASN.js → McpTools-BSsg58nZ.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-Bpvmx9X4.js → Memory-CjqNIXlO.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-CTP-DOTC.js → MobileBridge-DSsa4doG.js} +1 -1
  44. package/src/assets/web-panel/assets/MobileProjects-DLl1qzid.js +1 -0
  45. package/src/assets/web-panel/assets/{Mtc-ndYr0M1s.js → Mtc-Du080G7t.js} +5 -5
  46. package/src/assets/web-panel/assets/{MtcAudit-Ci0-YK7W.js → MtcAudit-JzQk-arw.js} +2 -2
  47. package/src/assets/web-panel/assets/{Multisig-BehSTFW7.js → Multisig-BMVT5Uln.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-B91_YBLv.js → NLProgramming-D_38QYjs.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-BQlJ0-gq.js → Notes-DvbdjNm5.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-CDgYMjYK.js → NotificationSettings-DVHCW6ii.js} +1 -1
  51. package/src/assets/web-panel/assets/{OrderTableRenderer-BJkSlKeH.js → OrderTableRenderer-DmMBFD3g.js} +1 -1
  52. package/src/assets/web-panel/assets/{Organization-B-b3cWCp.js → Organization-DC-9pAmP.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-CILUL4nL.js → Overflow-BRxWq0Qq.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-BTCFBkF0.js → P2P-CUdzhyLH.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-BAR6AUx5.js → PdhVaultBrowser-CwG21s9P.js} +3 -3
  56. package/src/assets/web-panel/assets/{Permissions-RRf6HbWJ.js → Permissions-6bHd4zgK.js} +4 -4
  57. package/src/assets/web-panel/assets/{PersonalDataHub-BGTMiICa.js → PersonalDataHub-BXgTDCba.js} +4 -4
  58. package/src/assets/web-panel/assets/{Pipeline-945qY9YF.js → Pipeline-BFhKCBNj.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-DPZwI6lJ.js → Privacy-Byz9IqUF.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-BPH2NRKc.js → ProjectInit-B9LNoyoN.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-BZCRNCvb.js → ProjectSettings-DEj4eVdl.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-BTI__tBt.js → Projects-BAAvus06.js} +1 -1
  63. package/src/assets/web-panel/assets/Providers-Bu_pQsk6.js +1 -0
  64. package/src/assets/web-panel/assets/{QrScannerModal-N6rbqt1r.js → QrScannerModal-CeDey0SJ.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-DrwjPS7M.js → QuickAsk-exUvRIgX.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-Cog9Wd99.js → Recommend-4hJWmtSI.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-DC9pynjM.js → RemoteSession-BmYUpl0m.js} +2 -2
  68. package/src/assets/web-panel/assets/{Reputation-D4th4gKS.js → Reputation-B_txYAyY.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-ogiWR6v9.js → Row-BPtqOqGh.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-uYlk-2Oj.js → RssFeed-CyWTxmq0.js} +3 -3
  71. package/src/assets/web-panel/assets/{Search-DYzzwvtM.js → Search-cItU1tmC.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-Da7YOyX6.js → Security-B0Z9_BUt.js} +4 -4
  73. package/src/assets/web-panel/assets/{Services-CLI1VM1X.js → Services-Dzpz2uFp.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-DK77dzDC.js → Skeleton-CBtoylP8.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-C_z7Lmhl.js → Skills-Cw9RJiVn.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-D6413Q8L.js → Sla-D2vLfvgl.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-C07ydbj2.js → SpeechSettings-I9dKbcOU.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-DGOm2W22.js → SyncSettings-BOju53RT.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-Cr_PVyLM.js → Tasks-C3LBy_7x.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-BhL2mZ0t.js → Templates-C2ttpPql.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-CPk5oyUr.js → Tenant-XQ6Qg8-Q.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-ClhqUsqV.js → Terminal-DYB9dUnS.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-BCC7MV5a.js → TimelineRenderer-gShtO4I8.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-DD1Jt4oO.js → Tokens-BvoJTCJg.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-BCydFvN2.js → Trigger-BwYRTMY_.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-DDHT1noa.js → Trust-C5rt6fCF.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-CWPZC7oI.js → UkeySign-DPBrHUgL.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-9Ea0nJR0.js → VideoEditing-BcxywO_K.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-BjxhLxTf.js → Wallet-CZvTpsPz.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-C6uCye67.js → WebAuthn-LI_jAuOx.js} +4 -4
  91. package/src/assets/web-panel/assets/{WorkflowEditor-d2g4reYo.js → WorkflowEditor-B2a6bANB.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-frTc6ScX.js → chat-B6DPMfRB.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-B5K6lG3v.js → colors-IpLhw9T8.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-Cdn46r8D.js → compact-item-BzodimsI.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-DU1jqVQi.js → createContext-DL2jaWH5.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-CZB0EDsa.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-DdNH-aW_.js → hasIn-C4Geudre.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-CHmkkdfT.js → index-B5Sn7CtW.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-Cj6P9Nst.js → index-B6w4fpSI.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-CQorP1Ng.js → index-BRj6YKuI.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-cYaWV4Mq.js → index-BX4pKudW.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-kVO_MDm-.js → index-BaTvPxY0.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-D23xGYjM.js → index-BbWRxWM2.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-Be4OtL-N.js → index-BeZhISVl.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-32ajXmTb.js → index-Bi6Zkv5M.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-NmEXVjzt.js → index-BvKoSvko.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-7ehytj1K.js → index-C3LzRvkw.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-gg3QPC3i.js → index-CAjyUjZl.js} +3 -3
  109. package/src/assets/web-panel/assets/index-CI7k8Sk9.js +1 -0
  110. package/src/assets/web-panel/assets/{index-CGiwfwB9.js → index-COxGCo8v.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DIVyTmZ3.js → index-CQBPhJlk.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-CUoNAmE8.js → index-CQPOCB4h.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-t_OBzIP4.js → index-CTlmw_cr.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-VDM2KKo9.js → index-CVFXYmUe.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DftZuyA7.js → index-C_SxaIPI.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-BcGwGIaR.js → index-CaKKxqCI.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-HjCvXHf5.js → index-CcgoKNXN.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-mgU3Q-lN.js → index-CczBR6Du.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DM5FmPZU.js → index-CeUnSSEP.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-D4l82Me1.js → index-CnwHp5Oi.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-BwlIxAmX.js → index-DGBRBg3D.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-BVLL-mq_.js → index-DHdD0Y7h.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-BXKhhx9V.js → index-DMY1waPC.js} +1 -1
  124. package/src/assets/web-panel/assets/index-DPTHBSR8.js +1 -0
  125. package/src/assets/web-panel/assets/{index-LaivuXyF.js → index-DREx4gaS.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CtRPi4YC.js → index-DXQ2OtXt.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-DRzBBdQ0.js → index-DZU7Y67X.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-PjAS0sIZ.js → index-DZtKnnTW.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-MM4Zz2OE.js → index-DlABpgCv.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-BoFak7le.js → index-Dl_QAtzq.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-D1qIC4GR.js → index-DnBybYhx.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-D4miNkWv.js → index-DoyIjk6r.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-DtBCCkC4.js → index-DvEnrn8M.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-BC4eGkar.js → index-DvOzjf2F.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-yZRuZpwK.js → index-EjW1R_a7.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-Dca_i7H8.js → index-F-SCUTee.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-DwLTRNdo.js → initDefaultProps-CW5mTl3w.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-BchZDXnh.js → motion-BtjIT9np.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-e8M-zZFl.js → move-DZv4fZAV.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-Ci40fQb3.js → mtc-parser-BwCix1O-.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-C7110_f2.js → omit-BW72HDUD.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-skteMgnM.js → pickAttrs-DBW2jcMc.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-MGZ-lh2B.js → placementArrow-D3YmWlIS.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-N4Sd7uy-.js → responsiveObserve-CL4-a-9Q.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-C7HDGRaa.js → slide-Cw9zIbXQ.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-BhRexlgy.js → statusUtils-mMLVioo-.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-ChEoQkN2.js → styleChecker-BK8857AH.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-CDbG1s2Y.js → useFlexGapSupport-C1iSaJij.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-CUIx0tcJ.js → useFs-D3riGOaP.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-bkO7L7ec.js → usePersonalDataHub-Bwqvmz4X.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-B_ZvABIG.js → vnode-Byk4zzkf.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-D5shjpS8.js → zoom-D7INFTp2.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/command-help-index.json +1 -1
  155. package/src/commands/mcp.js +119 -0
  156. package/src/commands/session-show.js +8 -10
  157. package/src/commands/session.js +60 -52
  158. package/src/data/changelog.json +40 -1
  159. package/src/gateways/ws/session-protocol.js +14 -4
  160. package/src/gateways/ws/ws-agent-handler.js +31 -0
  161. package/src/harness/jsonl-session-store.js +1147 -130
  162. package/src/harness/mcp-client.js +44 -11
  163. package/src/harness/session-index.js +80 -80
  164. package/src/harness/session-list-index.js +147 -2
  165. package/src/lib/background-interaction-journal.js +2 -2
  166. package/src/lib/command-lifecycle-report.js +516 -0
  167. package/src/lib/mcp-stdio-environment.js +48 -0
  168. package/src/lib/mcp-stdio-executable-identity.js +552 -17
  169. package/src/lib/mcp-stdio-package-materialization.js +1424 -0
  170. package/src/lib/packer/native-update-state.js +979 -1
  171. package/src/lib/packer/pack-update-applier.js +1050 -125
  172. package/src/lib/packer/pkg-config-generator.js +1 -0
  173. package/src/lib/paths.js +53 -0
  174. package/src/lib/process-execution-broker/index.js +180 -37
  175. package/src/lib/process-execution-broker/platform-sandbox.js +291 -24
  176. package/src/lib/recent-session.js +17 -17
  177. package/src/lib/secure-file-identity.js +47 -0
  178. package/src/lib/secure-fs.js +21 -2
  179. package/src/lib/session-anti-rollback-anchor.js +766 -0
  180. package/src/lib/session-host-lease.js +492 -0
  181. package/src/lib/session-persistence-failure.js +109 -0
  182. package/src/lib/session-picker.js +26 -3
  183. package/src/lib/session-search.js +25 -11
  184. package/src/lib/side-effect-ledger-store.js +2 -2
  185. package/src/lib/skill-execution-authority.js +13 -9
  186. package/src/lib/turn-binding-store.js +2 -2
  187. package/src/repl/agent-repl.js +309 -39
  188. package/src/runtime/agent-core.js +88 -5
  189. package/src/runtime/cleanup-deadline.js +143 -0
  190. package/src/runtime/headless-runner.js +357 -139
  191. package/src/runtime/headless-stream.js +207 -28
  192. package/src/runtime/output-backpressure.js +53 -0
  193. package/src/assets/web-panel/assets/MobileProjects-C8qfktxn.js +0 -1
  194. package/src/assets/web-panel/assets/Providers-DDCf_nIw.js +0 -1
  195. package/src/assets/web-panel/assets/devWarning-CP-jEUyw.js +0 -1
  196. package/src/assets/web-panel/assets/index-CzrCHrFy.js +0 -1
  197. package/src/assets/web-panel/assets/index-OJsGskZw.js +0 -1
@@ -98,6 +98,7 @@ import {
98
98
  isVerifiedSessionHostSnapshot,
99
99
  readSessionHostResumeState,
100
100
  } from "../lib/session-host-snapshot.js";
101
+ import { acquireSessionHostLease } from "../lib/session-host-lease.js";
101
102
  import { classifyStreamRetryReason } from "../lib/stream-retry.js";
102
103
  import {
103
104
  SideEffectLedger,
@@ -125,6 +126,14 @@ import {
125
126
  } from "./session-slash-commands.js";
126
127
  import { extractPluginUsageAttribution } from "../lib/plugin-usage-attribution.js";
127
128
  import { createHeadlessOutputBackpressure } from "./output-backpressure.js";
129
+ import {
130
+ cleanupDeadlineError,
131
+ createCleanupDeadline,
132
+ } from "./cleanup-deadline.js";
133
+ import {
134
+ createSessionPersistenceFailure,
135
+ projectSessionPersistenceFailure,
136
+ } from "../lib/session-persistence-failure.js";
128
137
 
129
138
  function invalidMcpRecoveryTransaction(capability, expected) {
130
139
  const error = new TypeError(
@@ -889,6 +898,7 @@ async function runTurn(
889
898
  })
890
899
  .start(opId);
891
900
  sideEffects.persist();
901
+ sideEffects.assert?.();
892
902
  }
893
903
  }
894
904
  break;
@@ -1048,7 +1058,7 @@ async function runTurn(
1048
1058
  * writeOut, writeErr, expandFileRefs }
1049
1059
  * @returns {Promise<{exitCode:number, turns:number}>}
1050
1060
  */
1051
- function createHeadlessStreamCleanupScope({ input }) {
1061
+ function createHeadlessStreamCleanupScope({ input, timeoutMs, onReport }) {
1052
1062
  let mcpClient = null;
1053
1063
  let remoteApproval = null;
1054
1064
  let inputCancel = null;
@@ -1130,15 +1140,29 @@ function createHeadlessStreamCleanupScope({ input }) {
1130
1140
  cleanup() {
1131
1141
  if (!cleanupPromise) {
1132
1142
  cleanupPromise = (async () => {
1143
+ const deadline = createCleanupDeadline({
1144
+ timeoutMs,
1145
+ label: "headless-stream-cleanup",
1146
+ });
1133
1147
  // Stop the live stdin owner before network/process resources. A
1134
1148
  // flowing stdin iterator can otherwise keep the process alive after
1135
1149
  // an early return or exception.
1136
1150
  requestStop();
1137
- await interactionCleanupPromise;
1138
- await runBestEffort(() => outputCleanup?.(reason));
1139
- await runBestEffort(() => mcpClient?.disconnectAll?.());
1140
- await runBestEffort(() => remoteApproval?.close?.());
1141
- await runBestEffort(() => sessionEnd?.(reason));
1151
+ await deadline.run("interactions", () => interactionCleanupPromise);
1152
+ await deadline.run("output-coalescer", () => outputCleanup?.(reason));
1153
+ await deadline.run("mcp", () => mcpClient?.disconnectAll?.());
1154
+ await deadline.run("remote-approval", () =>
1155
+ remoteApproval?.close?.(),
1156
+ );
1157
+ await deadline.run("session-end", () => sessionEnd?.(reason));
1158
+ const report = deadline.report();
1159
+ try {
1160
+ onReport?.(report);
1161
+ } catch {
1162
+ // Metrics/reporting cannot change cleanup semantics.
1163
+ }
1164
+ if (report.timedOut) throw cleanupDeadlineError(report);
1165
+ return report;
1142
1166
  })();
1143
1167
  }
1144
1168
  return cleanupPromise;
@@ -1146,11 +1170,68 @@ function createHeadlessStreamCleanupScope({ input }) {
1146
1170
  };
1147
1171
  }
1148
1172
 
1173
+ const STREAM_SESSION_ID = Symbol("streamSessionId");
1174
+ const STREAM_SESSION_HOST_LEASE = Symbol("streamSessionHostLease");
1175
+
1176
+ async function withStreamSessionHostLease(options, deps, streamCleanup, task) {
1177
+ const sessionId =
1178
+ options.sessionId || `headless-stream-${Date.now()}-${process.pid}`;
1179
+ const persist = Boolean(options.sessionId) && options.ephemeral !== true;
1180
+ const hasInjectedSessionStore =
1181
+ typeof deps.sessionHasPersistedEvidence === "function" ||
1182
+ typeof deps.sessionExists === "function" ||
1183
+ typeof deps.rebuildMessages === "function" ||
1184
+ typeof deps.appendEvent === "function" ||
1185
+ typeof deps.appendAuthorityEvent === "function" ||
1186
+ typeof deps.readVerifiedEvents === "function" ||
1187
+ typeof deps.readVerifiedProjection === "function";
1188
+ const acquireHostLease =
1189
+ deps.acquireSessionHostLease ||
1190
+ (!hasInjectedSessionStore ? acquireSessionHostLease : null);
1191
+ let lease = null;
1192
+ let onLeaseAbort = null;
1193
+ try {
1194
+ if (persist && typeof acquireHostLease === "function") {
1195
+ lease = acquireHostLease(sessionId, { hostKind: "headless-stream" });
1196
+ if (lease?.signal) {
1197
+ onLeaseAbort = () => {
1198
+ streamCleanup.setReason("session_host_lease_lost");
1199
+ streamCleanup.requestStop();
1200
+ };
1201
+ lease.signal.addEventListener("abort", onLeaseAbort, { once: true });
1202
+ if (lease.signal.aborted) onLeaseAbort();
1203
+ }
1204
+ }
1205
+ const scopedOptions = lease?.signal
1206
+ ? {
1207
+ ...options,
1208
+ signal: options.signal
1209
+ ? AbortSignal.any([options.signal, lease.signal])
1210
+ : lease.signal,
1211
+ }
1212
+ : options;
1213
+ return await task(scopedOptions, {
1214
+ ...deps,
1215
+ [STREAM_SESSION_ID]: sessionId,
1216
+ [STREAM_SESSION_HOST_LEASE]: lease,
1217
+ });
1218
+ } finally {
1219
+ if (lease?.signal && onLeaseAbort) {
1220
+ lease.signal.removeEventListener("abort", onLeaseAbort);
1221
+ }
1222
+ lease?.release?.();
1223
+ }
1224
+ }
1225
+
1149
1226
  export async function runAgentHeadlessStream(options = {}, deps = {}) {
1150
1227
  const trustedWorkspaceRoot = options.cwd || process.cwd();
1151
1228
  const input = deps.input || process.stdin;
1152
1229
  const pipeState = { closed: false };
1153
- const streamCleanup = createHeadlessStreamCleanupScope({ input });
1230
+ const streamCleanup = createHeadlessStreamCleanupScope({
1231
+ input,
1232
+ timeoutMs: deps.cleanupDeadlineMs,
1233
+ onReport: deps.onCleanupReport,
1234
+ });
1154
1235
  const stdout = deps.stdout || process.stdout;
1155
1236
  const stderr = deps.stderr || process.stderr;
1156
1237
  const shouldInstallPipeSafety =
@@ -1175,6 +1256,7 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
1175
1256
  writeOut: deps.writeOut,
1176
1257
  writeErr: deps.writeErr,
1177
1258
  maxQueuedBytes: deps.outputBackpressureMaxBytes,
1259
+ drainTimeoutMs: deps.outputBackpressureTimeoutMs,
1178
1260
  onFailure: (error) => {
1179
1261
  outputAbort?.abort(error);
1180
1262
  if (error?.code === "EPIPE") handlePipeClosed();
@@ -1218,17 +1300,27 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
1218
1300
  : null;
1219
1301
 
1220
1302
  outcome = await runWithHostHooksV2Workspace(trustedWorkspaceRoot, () =>
1221
- runAgentHeadlessStreamInWorkspace(
1303
+ withStreamSessionHostLease(
1222
1304
  runtimeOptions,
1223
1305
  runtimeDeps,
1224
- pipeState,
1225
1306
  streamCleanup,
1307
+ (scopedOptions, scopedDeps) =>
1308
+ runAgentHeadlessStreamInWorkspace(
1309
+ scopedOptions,
1310
+ scopedDeps,
1311
+ pipeState,
1312
+ streamCleanup,
1313
+ ),
1226
1314
  ),
1227
1315
  );
1228
1316
  } catch (error) {
1229
1317
  failure = error;
1230
1318
  } finally {
1231
- await streamCleanup.cleanup();
1319
+ try {
1320
+ await streamCleanup.cleanup();
1321
+ } catch (error) {
1322
+ failure ||= error;
1323
+ }
1232
1324
  try {
1233
1325
  await outputFlow.wait();
1234
1326
  } catch (error) {
@@ -1239,7 +1331,7 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
1239
1331
  disposePipeSafety?.();
1240
1332
  }
1241
1333
 
1242
- if (pipeState.closed) {
1334
+ if (pipeState.closed && failure?.isCleanupDeadlineFailure !== true) {
1243
1335
  return { ...(outcome || { turns: 0 }), exitCode: 0 };
1244
1336
  }
1245
1337
  if (failure) throw failure;
@@ -1260,8 +1352,11 @@ async function runAgentHeadlessStreamInWorkspace(
1260
1352
  const writeErr = deps.writeErr;
1261
1353
 
1262
1354
  const sessionId =
1263
- options.sessionId || `headless-stream-${Date.now()}-${process.pid}`;
1355
+ deps[STREAM_SESSION_ID] ||
1356
+ options.sessionId ||
1357
+ `headless-stream-${Date.now()}-${process.pid}`;
1264
1358
  const persist = Boolean(options.sessionId) && options.ephemeral !== true;
1359
+ const sessionHostLease = deps[STREAM_SESSION_HOST_LEASE] || null;
1265
1360
  const traceId = resolveTraceId(options, process.env, deps);
1266
1361
  const fieldGate = {
1267
1362
  seq: true,
@@ -1649,6 +1744,7 @@ async function runAgentHeadlessStreamInWorkspace(
1649
1744
  (hasInjectedSessionStore ? () => true : jsonlAppendEvent),
1650
1745
  appendAuthorityEvent:
1651
1746
  deps.appendAuthorityEvent ||
1747
+ deps.appendEvent ||
1652
1748
  (hasInjectedSessionStore
1653
1749
  ? unavailableAuthorityCapability("appendAuthorityEvent")
1654
1750
  : jsonlAppendAuthorityEvent),
@@ -1709,6 +1805,7 @@ async function runAgentHeadlessStreamInWorkspace(
1709
1805
  return persisted;
1710
1806
  },
1711
1807
  nextOpId: () => `${sideEffectRunNonce}:${sideEffectSeq++}`,
1808
+ assert: () => sessionHostLease?.assert?.(),
1712
1809
  }
1713
1810
  : null;
1714
1811
 
@@ -1781,7 +1878,7 @@ async function runAgentHeadlessStreamInWorkspace(
1781
1878
  if (!turnBindingFeed?.isDirty()) return true;
1782
1879
  if (turnBindingPersistenceError) return false;
1783
1880
  try {
1784
- const persisted = store.appendEvent(
1881
+ const persisted = store.appendAuthorityEvent(
1785
1882
  sessionId,
1786
1883
  TURN_BINDING_EVENT,
1787
1884
  turnBindingLog.toJSON(),
@@ -2197,18 +2294,41 @@ async function runAgentHeadlessStreamInWorkspace(
2197
2294
  }),
2198
2295
  "startSession",
2199
2296
  );
2200
- } catch {
2297
+ } catch (error) {
2201
2298
  const code = "CC_SESSION_PERSISTENCE_START_FAILED";
2299
+ const persistenceError = createSessionPersistenceFailure(error, {
2300
+ sessionId,
2301
+ operation: "session-start",
2302
+ });
2303
+ const persistence = projectSessionPersistenceFailure(persistenceError, {
2304
+ phase: "before-model",
2305
+ });
2306
+ if (persistence) {
2307
+ try {
2308
+ deps.onPersistenceFailure?.(persistence);
2309
+ } catch {
2310
+ // Observability cannot change persistence semantics.
2311
+ }
2312
+ }
2202
2313
  emit({
2203
2314
  type: "result",
2204
- subtype: "error_session_persistence",
2315
+ subtype: persistence
2316
+ ? "error_persistence"
2317
+ : "error_session_persistence",
2205
2318
  is_error: true,
2206
- code,
2319
+ code: persistence?.code || code,
2207
2320
  error: "Canonical stream session could not be created",
2208
2321
  session_id: sessionId,
2322
+ ...(persistence ? { persistence } : {}),
2209
2323
  });
2210
- writeErr(`${code}: canonical stream session creation was refused\n`);
2211
- return { exitCode: 1, turns: 0 };
2324
+ writeErr(
2325
+ `${persistence?.code || code}: canonical stream session creation was refused\n`,
2326
+ );
2327
+ return {
2328
+ exitCode: 1,
2329
+ turns: 0,
2330
+ ...(persistence ? { persistence } : {}),
2331
+ };
2212
2332
  }
2213
2333
  }
2214
2334
  }
@@ -2675,6 +2795,7 @@ async function runAgentHeadlessStreamInWorkspace(
2675
2795
  : null;
2676
2796
 
2677
2797
  let sawError = false;
2798
+ let terminalPersistenceFailure = null;
2678
2799
  // Session-scoped tool-call correlation ids ("tu-<n>", additive protocol-v1
2679
2800
  // field): one counter across ALL turns so ids never repeat within a session.
2680
2801
  // Gated by the capability handshake (docs/PROTOCOL.md §1.3): a client that
@@ -2819,6 +2940,7 @@ async function runAgentHeadlessStreamInWorkspace(
2819
2940
  await deps.outputFlow?.wait?.();
2820
2941
  const parsed = await nextEvent();
2821
2942
  if (parsed == null) break; // stdin closed
2943
+ sessionHostLease?.assert?.();
2822
2944
  if (turnBindingPersistenceError) {
2823
2945
  emitTurnBindingFailure();
2824
2946
  sawError = true;
@@ -3307,14 +3429,44 @@ async function runAgentHeadlessStreamInWorkspace(
3307
3429
  }
3308
3430
 
3309
3431
  messages.push({ role: "user", content: turnContent });
3432
+ let persistenceFailure = null;
3310
3433
  if (persist) {
3311
3434
  try {
3312
3435
  store.appendUserMessage(sessionId, turnContent);
3313
- } catch {
3314
- /* best-effort */
3436
+ } catch (error) {
3437
+ const persistenceError = createSessionPersistenceFailure(error, {
3438
+ sessionId,
3439
+ operation: "user-turn-append",
3440
+ });
3441
+ persistenceFailure = projectSessionPersistenceFailure(
3442
+ persistenceError,
3443
+ { phase: "before-model" },
3444
+ );
3445
+ if (persistenceFailure) {
3446
+ try {
3447
+ deps.onPersistenceFailure?.(persistenceFailure);
3448
+ } catch {
3449
+ // Observability cannot change persistence semantics.
3450
+ }
3451
+ }
3315
3452
  }
3316
3453
  }
3317
3454
  turns += 1;
3455
+ if (persistenceFailure) {
3456
+ terminalPersistenceFailure = persistenceFailure;
3457
+ sawError = true;
3458
+ emit({
3459
+ type: "result",
3460
+ subtype: "error_persistence",
3461
+ is_error: true,
3462
+ code: persistenceFailure.code,
3463
+ error: "Session user turn was not durably persisted",
3464
+ session_id: sessionId,
3465
+ turn: turns,
3466
+ persistence: persistenceFailure,
3467
+ });
3468
+ break;
3469
+ }
3318
3470
  turnBindingFeed?.beginTurn(messages.length, {
3319
3471
  worktreeId: options.worktreeId ?? null,
3320
3472
  });
@@ -3494,8 +3646,23 @@ async function runAgentHeadlessStreamInWorkspace(
3494
3646
  durationMs: call.durationMs,
3495
3647
  });
3496
3648
  }
3497
- } catch {
3498
- /* best-effort */
3649
+ } catch (error) {
3650
+ const persistenceError = createSessionPersistenceFailure(error, {
3651
+ sessionId,
3652
+ operation: "assistant-turn-append",
3653
+ });
3654
+ persistenceFailure = projectSessionPersistenceFailure(
3655
+ persistenceError,
3656
+ { phase: "after-model" },
3657
+ );
3658
+ if (persistenceFailure) {
3659
+ terminalPersistenceFailure = persistenceFailure;
3660
+ try {
3661
+ deps.onPersistenceFailure?.(persistenceFailure);
3662
+ } catch {
3663
+ // Observability cannot change persistence semantics.
3664
+ }
3665
+ }
3499
3666
  }
3500
3667
  }
3501
3668
 
@@ -3504,7 +3671,10 @@ async function runAgentHeadlessStreamInWorkspace(
3504
3671
  outcome.endReason === "max_turns";
3505
3672
  const costStopped = outcome.endReason === "cost-budget-exhausted";
3506
3673
  const isError =
3507
- exhausted || costStopped || outcome.endReason === "no-response";
3674
+ exhausted ||
3675
+ costStopped ||
3676
+ outcome.endReason === "no-response" ||
3677
+ Boolean(persistenceFailure);
3508
3678
  if (isError) sawError = true;
3509
3679
 
3510
3680
  if (costStopped) {
@@ -3523,14 +3693,17 @@ async function runAgentHeadlessStreamInWorkspace(
3523
3693
  ? "error_max_turns"
3524
3694
  : costStopped
3525
3695
  ? "error_max_budget"
3526
- : isError
3527
- ? "error"
3528
- : "success",
3696
+ : persistenceFailure
3697
+ ? "error_persistence"
3698
+ : isError
3699
+ ? "error"
3700
+ : "success",
3529
3701
  is_error: isError,
3530
3702
  result: outcome.finalText,
3531
3703
  session_id: sessionId,
3532
3704
  turn: turns,
3533
3705
  usage: outcome.usage,
3706
+ ...(persistenceFailure ? { persistence: persistenceFailure } : {}),
3534
3707
  });
3535
3708
 
3536
3709
  // --json-schema (P2): emit this turn's structured verdict right after its
@@ -3550,7 +3723,7 @@ async function runAgentHeadlessStreamInWorkspace(
3550
3723
  }
3551
3724
 
3552
3725
  // Session-wide cost cap reached → stop accepting further turns.
3553
- if (costStopped) break;
3726
+ if (costStopped || persistenceFailure) break;
3554
3727
 
3555
3728
  // While planning, blocked tool calls grew the plan during this turn —
3556
3729
  // push the fresh snapshot so the panel's plan card stays live.
@@ -3580,5 +3753,11 @@ async function runAgentHeadlessStreamInWorkspace(
3580
3753
  if (!pipeState.closed) {
3581
3754
  emit({ type: "system", subtype: "end", session_id: sessionId, turns });
3582
3755
  }
3583
- return { exitCode: pipeState.closed ? 0 : sawError ? 1 : 0, turns };
3756
+ return {
3757
+ exitCode: pipeState.closed ? 0 : sawError ? 1 : 0,
3758
+ turns,
3759
+ ...(terminalPersistenceFailure
3760
+ ? { persistence: terminalPersistenceFailure }
3761
+ : {}),
3762
+ };
3584
3763
  }
@@ -1,6 +1,15 @@
1
1
  import { Buffer } from "node:buffer";
2
2
 
3
3
  const DEFAULT_MAX_QUEUED_BYTES = 1024 * 1024;
4
+ const HOST_OUTPUT_DRAIN_TIMEOUT_MS = 30_000;
5
+
6
+ function normalizeDrainTimeoutMs(value) {
7
+ return Number.isFinite(value) &&
8
+ value > 0 &&
9
+ value <= HOST_OUTPUT_DRAIN_TIMEOUT_MS
10
+ ? Math.max(1, Math.floor(value))
11
+ : HOST_OUTPUT_DRAIN_TIMEOUT_MS;
12
+ }
4
13
 
5
14
  function outputError(code, message, details = {}) {
6
15
  const error = new Error(message);
@@ -29,6 +38,7 @@ export function createWritableBackpressureGate(
29
38
  {
30
39
  label = "output",
31
40
  maxQueuedBytes = DEFAULT_MAX_QUEUED_BYTES,
41
+ drainTimeoutMs,
32
42
  onFailure = null,
33
43
  } = {},
34
44
  ) {
@@ -43,6 +53,7 @@ export function createWritableBackpressureGate(
43
53
  ? maxQueuedBytes
44
54
  : DEFAULT_MAX_QUEUED_BYTES;
45
55
  const queue = [];
56
+ const outputDrainTimeoutMs = normalizeDrainTimeoutMs(drainTimeoutMs);
46
57
  let queuedBytes = 0;
47
58
  let blocked = false;
48
59
  let failure = null;
@@ -51,6 +62,14 @@ export function createWritableBackpressureGate(
51
62
  let rejectWait = null;
52
63
  let disposed = false;
53
64
  let backpressureCount = 0;
65
+ let drainTimer = null;
66
+ let blockedAt = null;
67
+
68
+ const clearDrainDeadline = () => {
69
+ if (drainTimer !== null) clearTimeout(drainTimer);
70
+ drainTimer = null;
71
+ blockedAt = null;
72
+ };
54
73
 
55
74
  const notifyCallback = (callback, error) => {
56
75
  if (typeof callback !== "function") return;
@@ -75,6 +94,7 @@ export function createWritableBackpressureGate(
75
94
  waitPromise.catch(() => {});
76
95
  };
77
96
  const finishWait = () => {
97
+ clearDrainDeadline();
78
98
  const resolve = resolveWait;
79
99
  waitPromise = null;
80
100
  resolveWait = null;
@@ -83,6 +103,7 @@ export function createWritableBackpressureGate(
83
103
  };
84
104
  const fail = (error) => {
85
105
  if (failure) return;
106
+ clearDrainDeadline();
86
107
  failure = error;
87
108
  blocked = false;
88
109
  const discarded = queue.splice(0);
@@ -96,6 +117,25 @@ export function createWritableBackpressureGate(
96
117
  // Failure notification must never replace the original stream error.
97
118
  }
98
119
  };
120
+ const startDrainDeadline = () => {
121
+ if (drainTimer !== null || failure || disposed) return;
122
+ blockedAt = Date.now();
123
+ drainTimer = setTimeout(() => {
124
+ const elapsedMs = Math.max(0, Date.now() - blockedAt);
125
+ fail(
126
+ outputError(
127
+ "CC_OUTPUT_BACKPRESSURE_TIMEOUT",
128
+ `${label} did not drain within ${outputDrainTimeoutMs} ms`,
129
+ {
130
+ timeoutMs: outputDrainTimeoutMs,
131
+ elapsedMs,
132
+ queuedBytes,
133
+ queuedChunks: queue.length,
134
+ },
135
+ ),
136
+ );
137
+ }, outputDrainTimeoutMs);
138
+ };
99
139
  const writeNative = (chunk, encoding, callback) => {
100
140
  let accepted;
101
141
  try {
@@ -121,6 +161,7 @@ export function createWritableBackpressureGate(
121
161
  blocked = true;
122
162
  backpressureCount += 1;
123
163
  ensureWait();
164
+ startDrainDeadline();
124
165
  }
125
166
  return accepted !== false;
126
167
  };
@@ -199,6 +240,9 @@ export function createWritableBackpressureGate(
199
240
  queuedBytes,
200
241
  queuedChunks: queue.length,
201
242
  backpressureCount,
243
+ drainTimeoutMs: outputDrainTimeoutMs,
244
+ blockedForMs:
245
+ blockedAt === null ? 0 : Math.max(0, Date.now() - blockedAt),
202
246
  failed: failure != null,
203
247
  failureCode: failure?.code || null,
204
248
  });
@@ -274,12 +318,14 @@ export function installOutputBackpressure({
274
318
  stdout = process.stdout,
275
319
  stderr = process.stderr,
276
320
  maxQueuedBytes,
321
+ drainTimeoutMs,
277
322
  onFailure,
278
323
  } = {}) {
279
324
  if (stdout === stderr) {
280
325
  const shared = installWritableBackpressureGate(stdout, {
281
326
  label: "output",
282
327
  maxQueuedBytes,
328
+ drainTimeoutMs,
283
329
  onFailure,
284
330
  });
285
331
  return {
@@ -294,6 +340,7 @@ export function installOutputBackpressure({
294
340
  const out = installWritableBackpressureGate(stdout, {
295
341
  label: "stdout",
296
342
  maxQueuedBytes,
343
+ drainTimeoutMs,
297
344
  onFailure,
298
345
  });
299
346
  let err;
@@ -301,6 +348,7 @@ export function installOutputBackpressure({
301
348
  err = installWritableBackpressureGate(stderr, {
302
349
  label: "stderr",
303
350
  maxQueuedBytes,
351
+ drainTimeoutMs,
304
352
  onFailure,
305
353
  });
306
354
  } catch (error) {
@@ -336,6 +384,7 @@ export function createHeadlessOutputBackpressure({
336
384
  writeOut = null,
337
385
  writeErr = null,
338
386
  maxQueuedBytes,
387
+ drainTimeoutMs,
339
388
  onFailure,
340
389
  } = {}) {
341
390
  const out = writeOut
@@ -343,6 +392,7 @@ export function createHeadlessOutputBackpressure({
343
392
  : createWritableBackpressureGate(stdout, {
344
393
  label: "stdout",
345
394
  maxQueuedBytes,
395
+ drainTimeoutMs,
346
396
  onFailure,
347
397
  });
348
398
  const err = writeErr
@@ -350,6 +400,7 @@ export function createHeadlessOutputBackpressure({
350
400
  : createWritableBackpressureGate(stderr, {
351
401
  label: "stderr",
352
402
  maxQueuedBytes,
403
+ drainTimeoutMs,
353
404
  onFailure,
354
405
  });
355
406
 
@@ -364,3 +415,5 @@ export function createHeadlessOutputBackpressure({
364
415
  },
365
416
  };
366
417
  }
418
+
419
+ export const MAX_OUTPUT_DRAIN_TIMEOUT_MS = HOST_OUTPUT_DRAIN_TIMEOUT_MS;
@@ -1 +0,0 @@
1
- import{I as n,J as g,c as l,K as r,N as u,P as h,U as o,R as t,Q as b}from"./vendor-Bn1JzzAn.js";import{_ as v,b as m}from"./index-gg3QPC3i.js";import{a8 as y,M}from"./icons-DG5UD-6K.js";const B={__name:"MobileProjects",setup(p,{expose:i}){i();const c=u(),{t:e}=m();function a(){c.push("/projects")}function _(){c.push("/mobile-bridge")}const s={router:c,t:e,goToProjects:a,goToMobileBridge:_,get useRouter(){return u},get useI18n(){return m},get MobileOutlined(){return M},get FolderOutlined(){return y}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}},O={class:"mobile-projects-placeholder"},x={class:"title"},k={class:"subtitle"},w={class:"explainer"};function D(p,i,c,e,a,_){const s=n("a-alert"),d=n("a-button"),f=n("a-space"),P=n("a-empty"),j=n("a-card");return h(),g("div",O,[l(j,null,{default:r(()=>[l(P,{description:!1},{image:r(()=>[l(e.MobileOutlined,{style:{fontSize:"64px",color:"#bfbfbf"}})]),default:r(()=>[o("h2",x,t(e.t("mobileProjects.title")),1),o("p",k,t(e.t("mobileProjects.subtitle")),1),l(s,{message:e.t("mobileProjects.v02Banner"),type:"info","show-icon":"",class:"banner"},null,8,["message"]),o("div",w,[o("h3",null,t(e.t("mobileProjects.currentDirection")),1),o("p",null,t(e.t("mobileProjects.currentDirectionBody")),1),o("ul",null,[o("li",null,t(e.t("mobileProjects.stepPhone")),1),o("li",null,t(e.t("mobileProjects.stepTap")),1),o("li",null,t(e.t("mobileProjects.stepPull")),1)]),o("h3",null,t(e.t("mobileProjects.reverseDirection")),1),o("p",null,t(e.t("mobileProjects.reverseDirectionBody")),1)]),l(f,{class:"actions"},{default:r(()=>[l(d,{type:"primary",onClick:e.goToProjects},{default:r(()=>[l(e.FolderOutlined),b(" "+t(e.t("mobileProjects.viewLocalProjects")),1)]),_:1}),l(d,{onClick:e.goToMobileBridge},{default:r(()=>[l(e.MobileOutlined),b(" "+t(e.t("mobileProjects.checkBridge")),1)]),_:1})]),_:1})]),_:1})]),_:1})])}const I=v(B,[["render",D],["__scopeId","data-v-9262cc45"],["__file","/tmp/cc-web-panel-qGOFsD/repo/packages/web-panel/src/views/MobileProjects.vue"]]);export{I as default};
@@ -1 +0,0 @@
1
- import{E as q,r as k,I as m,J as T,U as d,c as i,K as l,V as u,S,F as R,Z as N,o as I,a as A,P as g,Q as x,R as C,_ as D}from"./vendor-Bn1JzzAn.js";import{u as M,_ as E,d as _}from"./index-gg3QPC3i.js";import{a as H,b as W,c as j}from"./parsers-UEvh_ShA.js";import{R as J}from"./icons-DG5UD-6K.js";const B=q("providers",()=>{const F=k(!1),o=k(null),v=k([]),e=k([]),w=k(null);async function U(){const s=M();F.value=!0;try{const{output:f}=await s.execute("llm providers",15e3);v.value=H(f);const p=v.value.find(h=>h.active);p&&(w.value=p.name);const{output:b}=await s.execute("llm models",15e3);e.value=W(b)}catch(f){console.error("Failed to load providers:",f)}finally{F.value=!1}}async function y(s){await M().execute(`llm switch ${s}`,1e4),v.value.forEach(p=>p.active=p.name===s),w.value=s}async function a(s){const f=M();o.value=s;try{const{output:p,exitCode:b}=await f.execute("llm test",3e4),h=v.value.find(K=>K.name===s);return h&&(h.status=b===0?"ok":"error"),b===0}catch{const p=v.value.find(b=>b.name===s);return p&&(p.status="error"),!1}finally{o.value=null}}return{loading:F,testing:o,providers:v,localModels:e,activeProvider:w,loadProviders:U,switchProvider:y,testProvider:a}}),Q={__name:"Providers",setup(F,{expose:o}){o();const v=B(),e=M(),w=k(!1),U=k(!1),y=k(!1),a=A({provider:void 0,model:"",apiKey:"",baseUrl:"",temperature:.7,maxTokens:4096});let s={};const f=["ollama","openai","anthropic","volcengine","deepseek","gemini","groq","mistral","custom","zhipu"],p={ollama:"Ollama(本地)",openai:"OpenAI",anthropic:"Anthropic",volcengine:"火山引擎(豆包)",deepseek:"DeepSeek",gemini:"Google Gemini",groq:"Groq",mistral:"Mistral",custom:"Custom(自定义)",zhipu:"智谱 AI"},b=f.map(n=>({value:n,label:p[n]||n}));async function h(n){try{await v.switchProvider(n),_.success(`已切换到 ${n}`)}catch(t){_.error(`切换失败: ${t.message}`)}}async function K(n){await v.testProvider(n)?_.success(`${n} 连接正常`):_.warning(`${n} 连接失败,请检查配置`)}async function z(){w.value=!0;try{const{output:n}=await e.execute("config list",15e3),t=j(n);t.provider&&(a.provider=t.provider),t.model&&(a.model=t.model),t.apiKey&&(a.apiKey=t.apiKey),t.baseUrl&&(a.baseUrl=t.baseUrl),t.temperature!==void 0&&(a.temperature=t.temperature),t.maxTokens!==void 0&&(a.maxTokens=t.maxTokens),s={provider:t.provider??"",model:t.model??"",apiKey:t.apiKey??"",baseUrl:t.baseUrl??"",temperature:t.temperature??a.temperature,maxTokens:t.maxTokens??a.maxTokens},_.success("配置已加载")}catch(n){_.error(`加载配置失败: ${n.message}`)}finally{w.value=!1}}async function O(){U.value=!0;const n=[],t=[];try{if(a.provider&&a.provider!==s.provider)try{await e.execute(`config set llm.provider ${a.provider}`,1e4),t.push("provider")}catch(c){n.push(`provider: ${c.message}`)}if(a.model&&a.model!==s.model)try{await e.execute(`config set llm.model ${a.model}`,1e4),t.push("model")}catch(c){n.push(`model: ${c.message}`)}if(a.apiKey&&a.apiKey!==s.apiKey)try{await e.execute(`config set llm.apiKey ${a.apiKey}`,1e4),t.push("apiKey")}catch(c){n.push(`apiKey: ${c.message}`)}if(a.baseUrl!==void 0&&a.baseUrl!==s.baseUrl)try{await e.execute(`config set llm.baseUrl ${a.baseUrl}`,1e4),t.push("baseUrl")}catch(c){n.push(`baseUrl: ${c.message}`)}if(a.temperature!==s.temperature)try{await e.execute(`config set llm.temperature ${a.temperature}`,1e4),t.push("temperature")}catch(c){n.push(`temperature: ${c.message}`)}if(a.maxTokens!==s.maxTokens)try{await e.execute(`config set llm.maxTokens ${a.maxTokens}`,1e4),t.push("maxTokens")}catch(c){n.push(`maxTokens: ${c.message}`)}n.length>0?_.warning(`部分配置保存失败: ${n.join("; ")}`):t.length>0?(_.success(`已保存 ${t.length} 项配置`),s={...a},(t.includes("apiKey")||t.includes("provider")||t.includes("baseUrl")||t.includes("model"))&&(y.value=!0),t.includes("provider")&&v.loadProviders()):_.info("没有检测到配置变更")}catch(c){_.error(`保存配置失败: ${c.message}`)}finally{U.value=!1}}function P(){a.provider=s.provider||void 0,a.model=s.model||"",a.apiKey=s.apiKey||"",a.baseUrl=s.baseUrl||"",a.temperature=s.temperature??.7,a.maxTokens=s.maxTokens??4096}I(()=>{v.loadProviders(),z()});const L={providersStore:v,ws:e,configLoading:w,configSaving:U,showRestartHint:y,configForm:a,get loadedConfig(){return s},set loadedConfig(n){s=n},knownProviders:f,providerLabels:p,providerOptions:b,switchProvider:h,test:K,loadConfig:z,saveConfig:O,resetForm:P,onMounted:I,reactive:A,ref:k,get ReloadOutlined(){return J},get message(){return _},get useProvidersStore(){return B},get useWsStore(){return M},get parseLlmConfigOutput(){return j}};return Object.defineProperty(L,"__isScriptSetup",{enumerable:!1,value:!0}),L}},Z={style:{display:"flex","align-items":"center","justify-content":"space-between","margin-bottom":"24px"}},X={key:1,style:{"text-align":"center",padding:"60px"}},Y={class:"providers-grid"},$={style:{display:"flex","align-items":"center",gap:"12px","margin-bottom":"12px"}},ee={style:{"font-size":"24px"}},oe={style:{flex:"1"}},ae={style:{color:"#e0e0e0","font-weight":"500"}},te={style:{color:"var(--text-secondary)","font-size":"11px","font-family":"monospace"}},re={style:{display:"flex",gap:"8px","justify-content":"flex-end"}},se={key:0,style:{"margin-top":"24px"}},ne={style:{color:"#ccc","font-family":"monospace","font-size":"13px"}},ie={style:{display:"flex","align-items":"center","justify-content":"space-between","margin-bottom":"16px"}},le={class:"config-grid"},de={style:{display:"flex","align-items":"center",gap:"12px"}},ce={style:{display:"flex",gap:"12px","justify-content":"flex-end","margin-top":"16px"}};function me(F,o,v,e,w,U){const y=m("a-button"),a=m("a-alert"),s=m("a-spin"),f=m("a-tag"),p=m("a-badge"),b=m("a-card"),h=m("a-list-item"),K=m("a-list"),z=m("a-divider"),O=m("a-select"),P=m("a-form-item"),L=m("a-input"),n=m("a-input-password"),t=m("a-slider"),c=m("a-input-number"),G=m("a-form");return g(),T("div",null,[d("div",Z,[o[10]||(o[10]=d("div",null,[d("h2",{class:"page-title"},"LLM 配置"),d("p",{class:"page-sub"},"管理 AI 服务提供商")],-1)),i(y,{type:"primary",ghost:"",loading:e.providersStore.loading,onClick:o[0]||(o[0]=r=>e.providersStore.loadProviders())},{icon:l(()=>[i(e.ReloadOutlined)]),default:l(()=>[o[9]||(o[9]=x(" 刷新 ",-1))]),_:1},8,["loading"])]),u(" Active Provider Banner "),e.providersStore.activeProvider?(g(),S(a,{key:0,type:"success",style:{"margin-bottom":"20px",background:"rgba(41,162,112,.08)","border-color":"rgba(41,162,112,.3)"},"show-icon":""},{message:l(()=>[d("span",null,[o[11]||(o[11]=x("当前激活:",-1)),d("strong",null,C(e.providersStore.activeProvider),1)])]),_:1})):u("v-if",!0),u(" Loading "),e.providersStore.loading?(g(),T("div",X,[i(s,{size:"large"}),o[12]||(o[12]=d("div",{style:{color:"var(--text-muted)","margin-top":"12px"}},"加载 LLM 信息中...",-1))])):(g(),T(R,{key:2},[u(" Providers Grid "),d("div",null,[d("div",Y,[(g(!0),T(R,null,N(e.providersStore.providers,r=>(g(),S(b,{key:r.name,class:D(["provider-card",{active:r.active}]),style:{background:"var(--bg-card)"},size:"small"},{default:l(()=>[d("div",$,[d("span",ee,C(r.icon),1),d("div",oe,[d("div",ae,C(r.label),1),d("div",te,C(r.name),1)]),d("div",null,[r.active?(g(),S(f,{key:0,color:"green"},{default:l(()=>[...o[13]||(o[13]=[x("活跃",-1)])]),_:1})):r.status==="ok"?(g(),S(p,{key:1,status:"success",text:""})):r.status==="error"?(g(),S(p,{key:2,status:"error",text:""})):u("v-if",!0)])]),d("div",re,[i(y,{size:"small",style:{background:"var(--bg-card-hover)","border-color":"var(--border-color)"},loading:e.providersStore.testing===r.name,onClick:V=>e.test(r.name)},{default:l(()=>[...o[14]||(o[14]=[x(" 测试 ",-1)])]),_:1},8,["loading","onClick"]),r.active?(g(),S(f,{key:1,color:"green",style:{margin:"0","line-height":"24px"}},{default:l(()=>[...o[16]||(o[16]=[x("当前",-1)])]),_:1})):(g(),S(y,{key:0,size:"small",type:"primary",ghost:"",onClick:V=>e.switchProvider(r.name)},{default:l(()=>[...o[15]||(o[15]=[x(" 切换 ",-1)])]),_:1},8,["onClick"]))])]),_:2},1032,["class"]))),128))]),u(" Local Models (Ollama) "),e.providersStore.localModels.length?(g(),T("div",se,[o[17]||(o[17]=d("h3",{style:{color:"#ccc","font-size":"15px","margin-bottom":"12px"}}," 本地模型(Ollama) ",-1)),i(K,{"data-source":e.providersStore.localModels,size:"small",style:{background:"var(--bg-card)","border-radius":"8px",border:"1px solid var(--border-color)"}},{renderItem:l(({item:r})=>[i(h,{style:{padding:"10px 16px","border-color":"#252525"}},{actions:l(()=>[i(f,{color:"cyan",style:{"font-size":"10px"}},{default:l(()=>[x(C(r.size||"local"),1)]),_:2},1024)]),default:l(()=>[d("span",ne,C(r.name),1)]),_:2},1024)]),_:1},8,["data-source"])])):u("v-if",!0),u(" LLM Parameter Settings "),i(z,{style:{"border-color":"var(--border-color)",margin:"32px 0 24px"}}),e.showRestartHint?(g(),S(a,{key:1,type:"warning","show-icon":"",closable:"",style:{"margin-bottom":"16px"},message:"配置已保存,但当前聊天会话仍在用旧 key",description:"桌面端的 LLM 会话只在新建会话时重读配置。请新建一个 Chat,或重启应用,新 key/Provider 才会生效。",onClose:o[1]||(o[1]=r=>e.showRestartHint=!1)})):u("v-if",!0),d("div",ie,[o[19]||(o[19]=d("h3",{class:"section-title"},"LLM 参数设置",-1)),i(y,{size:"small",loading:e.configLoading,onClick:e.loadConfig,style:{background:"var(--bg-card-hover)","border-color":"var(--border-color)"}},{icon:l(()=>[i(e.ReloadOutlined)]),default:l(()=>[o[18]||(o[18]=x(" 加载配置 ",-1))]),_:1},8,["loading"])]),i(b,{class:"config-card",style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:l(()=>[i(G,{model:e.configForm,layout:"vertical",class:"config-form"},{default:l(()=>[d("div",le,[u(" Provider "),i(P,{label:"Provider(提供商)"},{default:l(()=>[i(O,{value:e.configForm.provider,"onUpdate:value":o[2]||(o[2]=r=>e.configForm.provider=r),placeholder:"选择 LLM 提供商",options:e.providerOptions,style:{width:"100%"},disabled:e.configSaving},null,8,["value","options","disabled"])]),_:1}),u(" Model "),i(P,{label:"Model(模型名称)"},{default:l(()=>[i(L,{value:e.configForm.model,"onUpdate:value":o[3]||(o[3]=r=>e.configForm.model=r),placeholder:"例如 doubao-seed-1-6-251015","allow-clear":"",disabled:e.configSaving},null,8,["value","disabled"])]),_:1}),u(" API Key "),i(P,{label:"API Key"},{default:l(()=>[i(n,{value:e.configForm.apiKey,"onUpdate:value":o[4]||(o[4]=r=>e.configForm.apiKey=r),placeholder:"输入 API Key",disabled:e.configSaving},null,8,["value","disabled"])]),_:1}),u(" Base URL "),i(P,{label:"Base URL"},{default:l(()=>[i(L,{value:e.configForm.baseUrl,"onUpdate:value":o[5]||(o[5]=r=>e.configForm.baseUrl=r),placeholder:"例如 https://ark.cn-beijing.volces.com/api/v3","allow-clear":"",disabled:e.configSaving},null,8,["value","disabled"])]),_:1}),u(" Temperature "),i(P,{label:"Temperature(温度)"},{default:l(()=>[d("div",de,[i(t,{value:e.configForm.temperature,"onUpdate:value":o[6]||(o[6]=r=>e.configForm.temperature=r),min:0,max:2,step:.1,style:{flex:"1"},disabled:e.configSaving},null,8,["value","disabled"]),i(c,{value:e.configForm.temperature,"onUpdate:value":o[7]||(o[7]=r=>e.configForm.temperature=r),min:0,max:2,step:.1,precision:1,style:{width:"80px"},disabled:e.configSaving},null,8,["value","disabled"])])]),_:1}),u(" Max Tokens "),i(P,{label:"Max Tokens(最大输出长度)"},{default:l(()=>[i(c,{value:e.configForm.maxTokens,"onUpdate:value":o[8]||(o[8]=r=>e.configForm.maxTokens=r),min:256,max:128e3,step:256,style:{width:"100%"},placeholder:"4096",disabled:e.configSaving},null,8,["value","disabled"])]),_:1})]),d("div",ce,[i(y,{onClick:e.resetForm,disabled:e.configSaving,style:{background:"var(--bg-card-hover)","border-color":"var(--border-color)"}},{default:l(()=>[...o[20]||(o[20]=[x(" 重置 ",-1)])]),_:1},8,["disabled"]),i(y,{type:"primary",loading:e.configSaving,onClick:e.saveConfig},{default:l(()=>[...o[21]||(o[21]=[x(" 保存配置 ",-1)])]),_:1},8,["loading"])])]),_:1},8,["model"])]),_:1})])],2112))])}const ge=E(Q,[["render",me],["__scopeId","data-v-64155d06"],["__file","/tmp/cc-web-panel-qGOFsD/repo/packages/web-panel/src/views/Providers.vue"]]);export{ge as default};
@@ -1 +0,0 @@
1
- import{Q as r}from"./index-gg3QPC3i.js";const o=((n,a,e)=>{r(n,`[ant-design-vue: ${a}] ${e}`)});export{o as d};
@@ -1 +0,0 @@
1
- import{A as o}from"./Row-ogiWR6v9.js";import{a0 as t}from"./index-gg3QPC3i.js";import"./vendor-Bn1JzzAn.js";import"./responsiveObserve-N4Sd7uy-.js";import"./useFlexGapSupport-CDbG1s2Y.js";import"./styleChecker-ChEoQkN2.js";import"./index-HjCvXHf5.js";import"./icons-DG5UD-6K.js";const l=t(o);export{l as default};
@@ -1 +0,0 @@
1
- import{C as o}from"./Col-C4_biO7A.js";import{a0 as t}from"./index-gg3QPC3i.js";import"./vendor-Bn1JzzAn.js";import"./index-HjCvXHf5.js";import"./icons-DG5UD-6K.js";const s=t(o);export{s as default};