chainlesschain 0.165.3 → 0.165.4

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 (203) hide show
  1. package/README.md +151 -29
  2. package/package.json +2 -2
  3. package/src/assets/web-panel/assets/{AIOps-BiHNUlbU.js → AIOps-C__nnraW.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-D-UFjDRQ.js → ActionButton-CsKWHEZ-.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-DazVsDgW.js → Analytics-BhIjfjWO.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-DXh9UfNJ.js → AppLayout-BjuXFzWZ.js} +5 -5
  7. package/src/assets/web-panel/assets/{Artifacts-CZ6tsceY.js → Artifacts-k6whDkZJ.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-RyxnBr_h.js → Audit-C4FBMYRh.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-BWS51Q6X.js → BackgroundAgents-C_vRrSXk.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-BRtPcUul.js → Backup-CngFZeVp.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-CGd4vZYY.js → BaseInput-B_H9EBRm.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-h8ijVwCg.js → Chat-DLEC5kt7.js} +4 -4
  13. package/src/assets/web-panel/assets/ChatBubbleRenderer-xijcWkJe.js +1 -0
  14. package/src/assets/web-panel/assets/{Checkbox-NyF6dPl8.js → Checkbox-m3ClR4xh.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-Ci4OOxr5.js → Codegen-CmLSFrgp.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-CwTkc9BM.js → Col-DFGQteHN.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-DW_tM82m.js → Community-EUUVORHE.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-DEvHRV4S.js → Compact-2PSg0Yr7.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-BbjBEEfD.js → Compliance-CcKur7gB.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-10IXBaBa.js → Cowork-DK_Fezfa.js} +2 -2
  21. package/src/assets/web-panel/assets/{Cron-BZkbpd5I.js → Cron-Dbw89xl7.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-CFQ8L_6v.js → Crosschain-CH66h_Ec.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-BDF6AkXe.js → DID-D1igRb17.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-CoOdWMi4.js → Dashboard-DVAsrobk.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-DEsGmu8Y.js → Dropdown-Dl7W8AQs.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-BS89SWlK.js → EmailListRenderer-D5tpaEQC.js} +1 -1
  27. package/src/assets/web-panel/assets/{FamilyGuardDashboard-C1FpCHiI.js → FamilyGuardDashboard-O_VQf8gq.js} +1 -1
  28. package/src/assets/web-panel/assets/{Federation-BzvpVmLA.js → Federation-BTVcgS9n.js} +1 -1
  29. package/src/assets/web-panel/assets/{FormItemContext-BeC259PQ.js → FormItemContext-BRnkJAIz.js} +1 -1
  30. package/src/assets/web-panel/assets/{GenericCardRenderer-azgG3bmV.js → GenericCardRenderer-8OWSCkDj.js} +1 -1
  31. package/src/assets/web-panel/assets/{Git-BmSSowc5.js → Git-WXLYTQj2.js} +2 -2
  32. package/src/assets/web-panel/assets/{Governance-CTBCSyQZ.js → Governance-BezaUhtc.js} +1 -1
  33. package/src/assets/web-panel/assets/{Inference-DA5xyk4a.js → Inference-CuRay3Gu.js} +1 -1
  34. package/src/assets/web-panel/assets/{KnowledgeGraph-D1gPHNig.js → KnowledgeGraph-DfWLDW1m.js} +1 -1
  35. package/src/assets/web-panel/assets/{Logs-BPmLf1AR.js → Logs-C55y2pPY.js} +2 -2
  36. package/src/assets/web-panel/assets/MarkdownRenderer-hDpWdiBc.js +1 -0
  37. package/src/assets/web-panel/assets/{Marketplace-DtUFcR0E.js → Marketplace-Dk08Uycg.js} +1 -1
  38. package/src/assets/web-panel/assets/{McpTools-DS_kqBv-.js → McpTools-C11fSB5V.js} +3 -3
  39. package/src/assets/web-panel/assets/{Memory-Fvh7XL7V.js → Memory-mr0eZc97.js} +2 -2
  40. package/src/assets/web-panel/assets/{MobileBridge-C7itAP45.js → MobileBridge-C0iCSRbb.js} +1 -1
  41. package/src/assets/web-panel/assets/MobileProjects-CY-xMG8Z.js +1 -0
  42. package/src/assets/web-panel/assets/{Mtc-B57MiNLK.js → Mtc-Bplqc_Wc.js} +6 -6
  43. package/src/assets/web-panel/assets/{MtcAudit-BXfCUcM7.js → MtcAudit-BlzwsoSM.js} +4 -4
  44. package/src/assets/web-panel/assets/{Multisig-yaJ-ZcF6.js → Multisig-BBLmTty6.js} +3 -3
  45. package/src/assets/web-panel/assets/{NLProgramming-CoaUCKrO.js → NLProgramming-DtT1uf1W.js} +1 -1
  46. package/src/assets/web-panel/assets/{Notes-BKLM_65R.js → Notes-DcqQAxTK.js} +3 -3
  47. package/src/assets/web-panel/assets/{NotificationSettings-DoDtK9uZ.js → NotificationSettings-cb0kWoZe.js} +1 -1
  48. package/src/assets/web-panel/assets/{OrderTableRenderer-BJ28TGr-.js → OrderTableRenderer-kw9HZQNN.js} +1 -1
  49. package/src/assets/web-panel/assets/{Organization-MuGsdoIb.js → Organization-DlTlbkUN.js} +4 -4
  50. package/src/assets/web-panel/assets/{Overflow-BLUN9J4R.js → Overflow-pp1qs-oY.js} +1 -1
  51. package/src/assets/web-panel/assets/{P2P-DWuoBUPd.js → P2P-BESLnyYz.js} +2 -2
  52. package/src/assets/web-panel/assets/{PdhVaultBrowser-CUi37YPj.js → PdhVaultBrowser-B-J1mGuf.js} +3 -3
  53. package/src/assets/web-panel/assets/{Permissions-BYQg2pcr.js → Permissions-B36PeT1_.js} +4 -4
  54. package/src/assets/web-panel/assets/{PersonalDataHub-CAxoV2xu.js → PersonalDataHub-CTK2ad-3.js} +6 -6
  55. package/src/assets/web-panel/assets/{Pipeline-B33wGvIO.js → Pipeline-zJNGXsac.js} +1 -1
  56. package/src/assets/web-panel/assets/{Privacy-A8yXTORP.js → Privacy-b9fz0Qf0.js} +1 -1
  57. package/src/assets/web-panel/assets/{ProjectInit-D49I2I1O.js → ProjectInit-DjZbZgiB.js} +2 -2
  58. package/src/assets/web-panel/assets/{ProjectSettings-Ci73jJDw.js → ProjectSettings-C-hHJXlD.js} +2 -2
  59. package/src/assets/web-panel/assets/Projects-BC9KSDM6.js +1 -0
  60. package/src/assets/web-panel/assets/Providers-Dz-CAYYU.js +1 -0
  61. package/src/assets/web-panel/assets/{QrScannerModal-Brza0ykJ.js → QrScannerModal-A0yoQ3-3.js} +1 -1
  62. package/src/assets/web-panel/assets/{QuickAsk-DFydhjxL.js → QuickAsk-DrFgFJNC.js} +1 -1
  63. package/src/assets/web-panel/assets/{Recommend-DLF8_NhA.js → Recommend-KC8hF1g4.js} +1 -1
  64. package/src/assets/web-panel/assets/{RemoteSession-dyuStW3x.js → RemoteSession-DGTPIk6u.js} +3 -3
  65. package/src/assets/web-panel/assets/{Reputation-5F3tA6yw.js → Reputation-QmbwM7Yk.js} +1 -1
  66. package/src/assets/web-panel/assets/{Row-Ca2A57S5.js → Row-BxjJylia.js} +1 -1
  67. package/src/assets/web-panel/assets/{RssFeed-B0bxBkq_.js → RssFeed-B7Wda1J6.js} +3 -3
  68. package/src/assets/web-panel/assets/{Search-CFNvHalZ.js → Search-_plQ_YSA.js} +1 -1
  69. package/src/assets/web-panel/assets/{Security-DSoH3Hav.js → Security-CD2YJZfx.js} +4 -4
  70. package/src/assets/web-panel/assets/{Services-BHpfEmBQ.js → Services-qQE7NmwE.js} +2 -2
  71. package/src/assets/web-panel/assets/{Skeleton-Dsh-QNmn.js → Skeleton-DgQqkFf7.js} +1 -1
  72. package/src/assets/web-panel/assets/{Skills-BhT1NkSU.js → Skills-C4C0oFFt.js} +1 -1
  73. package/src/assets/web-panel/assets/{Sla-DY9snPeJ.js → Sla-Px2N2B5c.js} +1 -1
  74. package/src/assets/web-panel/assets/{SpeechSettings-CWaX0_Cx.js → SpeechSettings-DN6C3lQd.js} +1 -1
  75. package/src/assets/web-panel/assets/{SyncSettings-B690y_TC.js → SyncSettings-jm5aH_m7.js} +2 -2
  76. package/src/assets/web-panel/assets/{Tasks-2N-w3zWd.js → Tasks-DlkJcv67.js} +1 -1
  77. package/src/assets/web-panel/assets/{Templates-BjwQOQYC.js → Templates-DyrTHUBs.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tenant-CUqHErxY.js → Tenant-mC434PtL.js} +1 -1
  79. package/src/assets/web-panel/assets/{Terminal-C13rXvNy.js → Terminal-o0_s3NgK.js} +2 -2
  80. package/src/assets/web-panel/assets/{TimelineRenderer-CpbWcya_.js → TimelineRenderer-DAGlAXOw.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tokens-BXHLGXYC.js → Tokens-BnulS_bs.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trigger-1e5i65o3.js → Trigger-suQbVXYM.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trust-FLGqNHs5.js → Trust-DbIJAPo5.js} +1 -1
  84. package/src/assets/web-panel/assets/{UkeySign-BbaR_LJB.js → UkeySign-CQNpbIHi.js} +1 -1
  85. package/src/assets/web-panel/assets/{VideoEditing-NOp4RIov.js → VideoEditing-D8aWCERk.js} +1 -1
  86. package/src/assets/web-panel/assets/{Wallet-B7DW7bG4.js → Wallet-CuLpYfZc.js} +3 -3
  87. package/src/assets/web-panel/assets/{WebAuthn-BptSUWix.js → WebAuthn-CsfG8ZMc.js} +5 -5
  88. package/src/assets/web-panel/assets/{WorkflowEditor-CAJnDOXS.js → WorkflowEditor-BYsEAZbd.js} +1 -1
  89. package/src/assets/web-panel/assets/{chat-I8LgG1-Z.js → chat-FT4Um3-I.js} +1 -1
  90. package/src/assets/web-panel/assets/{colors-CWe7SOVD.js → colors-CKbS_Wlt.js} +1 -1
  91. package/src/assets/web-panel/assets/{compact-item-Cx3u3CA3.js → compact-item-CFJtzuJM.js} +1 -1
  92. package/src/assets/web-panel/assets/{createContext-CgD5ArwY.js → createContext-B9kSRW6K.js} +1 -1
  93. package/src/assets/web-panel/assets/devWarning-DJZ0gAMu.js +1 -0
  94. package/src/assets/web-panel/assets/{hasIn-BfQWiXN8.js → hasIn-DR-x0Xpi.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-DAVy98u7.js → index-7jHr_A_k.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-DlIyt1qF.js → index-B3ZX81mK.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-CWZ3REg6.js → index-B7osrXqy.js} +3 -3
  98. package/src/assets/web-panel/assets/{index-DGMYTN5W.js → index-BGbPnC5x.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-DFb-XIKy.js → index-BI5hP_qy.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-CAUnl4Jv.js → index-BK3TiKVq.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-BUAR7RY-.js → index-BVPU43b1.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-Cd79NQAx.js → index-BW-t9n-q.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BiI-xPRH.js → index-BfFCQHL3.js} +1 -1
  104. package/src/assets/web-panel/assets/index-Bizb4hkw.js +1 -0
  105. package/src/assets/web-panel/assets/{index-B6yChzt1.js → index-Bt4fS2eL.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-e8BM1yY1.js → index-BwR7yc2h.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-V-kIHzAV.js → index-Bzz0C1BZ.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-Bx7BNIRH.js → index-C2JvmYRc.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-87gMxqhN.js → index-CGaXUsIs.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-Cy_cCJlr.js → index-CJmIQ9XR.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-C1UjHdgZ.js → index-C_enk9I_.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-Bi24S7Dw.js → index-Cr2FLUsD.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-CcX4FSPf.js → index-CvrCCqJt.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-DmrdUwzU.js → index-D4LfPvWA.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-Dcdm_Z2c.js → index-DMGmg497.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-DCJEY2T0.js → index-DShSkww-.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-C0ztiqtB.js → index-DTxNy0ZU.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-C-rIKccl.js → index-DW4BWjTk.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-CdRkCwm4.js → index-DWdqx7zI.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-C0nDKhWv.js → index-Dap9c3eD.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CQDKYbnv.js → index-DcfxhKXR.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-BuEQSorC.js → index-DdkIhfi-.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-3iKP9OTJ.js → index-DeSgw-WV.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-Doc0Ftpd.js → index-DiNUEpSQ.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BREnPKGo.js → index-DjEP7WkH.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-CNYFQxAW.js → index-DtkFqPVA.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-DslTuqro.js → index-KqDaCApw.js} +1 -1
  128. package/src/assets/web-panel/assets/index-OHSl-xCh.js +1 -0
  129. package/src/assets/web-panel/assets/{index-CMu16vPC.js → index-OSzjTzGM.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-DsQcURkA.js → index-QBSeNVO3.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-DeizoQVZ.js → index-WE08gMJP.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-B1cX4Rxu.js → index-r2VI1Ikk.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-DmgtY58H.js → index-tqSEHPRT.js} +1 -1
  134. package/src/assets/web-panel/assets/{initDefaultProps-DiBszVdG.js → initDefaultProps-Dd7n7VgI.js} +1 -1
  135. package/src/assets/web-panel/assets/{motion-BGIFFozv.js → motion-BwxouRw1.js} +1 -1
  136. package/src/assets/web-panel/assets/{move-D5W7mp7B.js → move-DObN0PG9.js} +1 -1
  137. package/src/assets/web-panel/assets/{mtc-parser-JFIlxJ7F.js → mtc-parser-B3nOUQc7.js} +1 -1
  138. package/src/assets/web-panel/assets/{omit-CQ3o6LIU.js → omit-o9WU2Nbl.js} +1 -1
  139. package/src/assets/web-panel/assets/{pickAttrs-R8MIlXo3.js → pickAttrs-CL_vvfQ_.js} +1 -1
  140. package/src/assets/web-panel/assets/{placementArrow-sW7ylSky.js → placementArrow-CYrM2tyK.js} +1 -1
  141. package/src/assets/web-panel/assets/{responsiveObserve-Cnl39Vbz.js → responsiveObserve-k_06cQ96.js} +1 -1
  142. package/src/assets/web-panel/assets/{slide-sn8tFd14.js → slide-CPKG0pxS.js} +1 -1
  143. package/src/assets/web-panel/assets/{statusUtils-IKKY_QxZ.js → statusUtils-BDDEeLTw.js} +1 -1
  144. package/src/assets/web-panel/assets/{styleChecker-BNpV4Nqs.js → styleChecker-Cmb7RTh7.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFlexGapSupport-BWyT_eoU.js → useFlexGapSupport-e2IedC4N.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFs-D09p6_U9.js → useFs-CE_gxVnm.js} +1 -1
  147. package/src/assets/web-panel/assets/{usePersonalDataHub-CzW3TkJZ.js → usePersonalDataHub-BkMIIKMz.js} +1 -1
  148. package/src/assets/web-panel/assets/{vnode-3s3WoAKB.js → vnode-DW886XV1.js} +1 -1
  149. package/src/assets/web-panel/assets/{zoom-Cjy_673s.js → zoom-Dwo_adaf.js} +1 -1
  150. package/src/assets/web-panel/index.html +1 -1
  151. package/src/command-help-index.json +3 -3
  152. package/src/commands/agent.js +105 -35
  153. package/src/commands/artifacts.js +363 -33
  154. package/src/commands/cowork.js +202 -36
  155. package/src/commands/session-budget.js +155 -0
  156. package/src/commands/session-location.js +948 -0
  157. package/src/commands/session.js +72 -46
  158. package/src/data/changelog.json +13 -0
  159. package/src/gateways/ws/artifact-protocol.js +77 -13
  160. package/src/gateways/ws/session-protocol.js +391 -24
  161. package/src/gateways/ws/ws-agent-handler.js +191 -14
  162. package/src/gateways/ws/ws-server.js +14 -3
  163. package/src/gateways/ws/ws-session-gateway.js +101 -5
  164. package/src/harness/jsonl-session-store.js +1210 -0
  165. package/src/lib/agent-team/team-runner.js +43 -13
  166. package/src/lib/artifact-access-ledger.js +461 -0
  167. package/src/lib/artifact-cleanup-ledger.js +861 -0
  168. package/src/lib/artifact-deletion-ledger.js +677 -0
  169. package/src/lib/artifact-store.js +256 -51
  170. package/src/lib/command-lifecycle-report.js +8 -4
  171. package/src/lib/cowork-adapter.js +9 -5
  172. package/src/lib/cowork-task-runner.js +20 -0
  173. package/src/lib/cowork-workflow.js +178 -20
  174. package/src/lib/direct-model-usage.js +62 -22
  175. package/src/lib/dynamic-workflow-runtime.js +3184 -111
  176. package/src/lib/execution-location-result-apply.js +339 -0
  177. package/src/lib/execution-location-result-artifact.js +271 -0
  178. package/src/lib/execution-location-result-review.js +253 -0
  179. package/src/lib/execution-location-result-store.js +331 -0
  180. package/src/lib/execution-location-result.js +617 -0
  181. package/src/lib/execution-location-target.js +236 -1
  182. package/src/lib/managed-tool-checkpoint.js +47 -4
  183. package/src/lib/process-execution-broker/workspace-transaction.js +3 -0
  184. package/src/lib/session-budget-production-root.js +376 -0
  185. package/src/lib/session-budget-runtime.js +109 -18
  186. package/src/lib/session-budget-usage.js +63 -0
  187. package/src/lib/session-host-snapshot.js +19 -2
  188. package/src/lib/session-resource-budget.js +766 -105
  189. package/src/lib/sub-agent-context.js +69 -22
  190. package/src/lib/web-ui-server.js +12 -1
  191. package/src/repl/agent-repl.js +237 -16
  192. package/src/runtime/agent-core.js +123 -0
  193. package/src/runtime/headless-runner.js +135 -46
  194. package/src/runtime/headless-stream.js +133 -25
  195. package/src/runtime/policies/agent-policy.js +10 -0
  196. package/src/assets/web-panel/assets/ChatBubbleRenderer-D7tcdDS9.js +0 -1
  197. package/src/assets/web-panel/assets/MarkdownRenderer-SVLOg49H.js +0 -1
  198. package/src/assets/web-panel/assets/MobileProjects-DGbP36-3.js +0 -1
  199. package/src/assets/web-panel/assets/Projects-CF-yD6Cn.js +0 -1
  200. package/src/assets/web-panel/assets/Providers-D-etEhg5.js +0 -1
  201. package/src/assets/web-panel/assets/devWarning-DLv_872g.js +0 -1
  202. package/src/assets/web-panel/assets/index-CdiGCibe.js +0 -1
  203. package/src/assets/web-panel/assets/index-D_0z-gyz.js +0 -1
@@ -109,6 +109,16 @@ import {
109
109
  readSessionHostResumeState,
110
110
  } from "../lib/session-host-snapshot.js";
111
111
  import { acquireSessionHostLease } from "../lib/session-host-lease.js";
112
+ import {
113
+ openProductionSessionBudgetRoot,
114
+ sessionBudgetAdmissionError,
115
+ } from "../lib/session-budget-production-root.js";
116
+ import {
117
+ beginSessionBudgetUsage,
118
+ markSessionBudgetUsageUnknown,
119
+ recordSessionBudgetUsage,
120
+ rejectSessionBudgetUsageUnknown,
121
+ } from "../lib/session-budget-usage.js";
112
122
  import { classifyStreamRetryReason } from "../lib/stream-retry.js";
113
123
  import {
114
124
  SideEffectLedger,
@@ -809,6 +819,7 @@ async function runTurn(
809
819
  waitForOutput,
810
820
  persistUsageEvent,
811
821
  persistToolEvent,
822
+ sessionBudget,
812
823
  now = Date.now,
813
824
  },
814
825
  ) {
@@ -1008,6 +1019,11 @@ async function runTurn(
1008
1019
  }
1009
1020
  case "token-usage":
1010
1021
  if (event.ledgerPersisted !== true) persistUsageEvent?.(event);
1022
+ recordSessionBudgetUsage(
1023
+ sessionBudget,
1024
+ event,
1025
+ "headless usage settlement",
1026
+ );
1011
1027
  // 用量归因: attributed child-loop usage (sub-agent / isolated skill)
1012
1028
  // is forwarded on the stream (same wire shape) and counted toward the
1013
1029
  // cost budget, but stays out of the turn's `usage` envelope, which
@@ -1044,6 +1060,15 @@ async function runTurn(
1044
1060
  case "model-usage-started":
1045
1061
  case "model-usage-unknown":
1046
1062
  if (event.ledgerPersisted !== true) persistUsageEvent?.(event);
1063
+ if (event.type === "model-usage-started") {
1064
+ beginSessionBudgetUsage(
1065
+ sessionBudget,
1066
+ event,
1067
+ "headless provider call",
1068
+ );
1069
+ } else if (markSessionBudgetUsageUnknown(sessionBudget, event)) {
1070
+ rejectSessionBudgetUsageUnknown(event, "headless provider call");
1071
+ }
1047
1072
  break;
1048
1073
  case "compaction-usage-unknown":
1049
1074
  if (event.ledgerPersisted !== true) {
@@ -1053,6 +1078,12 @@ async function runTurn(
1053
1078
  code: event.code || "provider_transport_outcome_unknown",
1054
1079
  });
1055
1080
  }
1081
+ if (markSessionBudgetUsageUnknown(sessionBudget, event)) {
1082
+ rejectSessionBudgetUsageUnknown(
1083
+ event,
1084
+ "headless semantic compaction",
1085
+ );
1086
+ }
1056
1087
  emit({
1057
1088
  type: "compaction_usage_unknown",
1058
1089
  provider: event.provider,
@@ -1249,6 +1280,7 @@ async function withStreamSessionHostLease(options, deps, streamCleanup, task) {
1249
1280
  deps.acquireSessionHostLease ||
1250
1281
  (!hasInjectedSessionStore ? acquireSessionHostLease : null);
1251
1282
  let lease = null;
1283
+ let budgetRoot = null;
1252
1284
  let onLeaseAbort = null;
1253
1285
  try {
1254
1286
  if (persist && typeof acquireHostLease === "function") {
@@ -1262,7 +1294,7 @@ async function withStreamSessionHostLease(options, deps, streamCleanup, task) {
1262
1294
  if (lease.signal.aborted) onLeaseAbort();
1263
1295
  }
1264
1296
  }
1265
- const scopedOptions = lease?.signal
1297
+ let scopedOptions = lease?.signal
1266
1298
  ? {
1267
1299
  ...options,
1268
1300
  signal: options.signal
@@ -1270,12 +1302,28 @@ async function withStreamSessionHostLease(options, deps, streamCleanup, task) {
1270
1302
  : lease.signal,
1271
1303
  }
1272
1304
  : options;
1305
+ budgetRoot = openProductionSessionBudgetRoot(
1306
+ persist ? sessionId : null,
1307
+ options.sessionBudgetRoot,
1308
+ {
1309
+ persist,
1310
+ signal: scopedOptions.signal || null,
1311
+ table: options.sessionBudgetRoot?.table,
1312
+ open: deps.openSessionBudget,
1313
+ store: deps.sessionBudgetStore,
1314
+ registry: deps.sessionBudgetRegistry,
1315
+ },
1316
+ );
1317
+ if (budgetRoot.enabled) {
1318
+ scopedOptions = { ...scopedOptions, ...budgetRoot.options };
1319
+ }
1273
1320
  return await task(scopedOptions, {
1274
1321
  ...deps,
1275
1322
  [STREAM_SESSION_ID]: sessionId,
1276
1323
  [STREAM_SESSION_HOST_LEASE]: lease,
1277
1324
  });
1278
1325
  } finally {
1326
+ budgetRoot?.close?.();
1279
1327
  if (lease?.signal && onLeaseAbort) {
1280
1328
  lease.signal.removeEventListener("abort", onLeaseAbort);
1281
1329
  }
@@ -1646,8 +1694,9 @@ async function runAgentHeadlessStreamInWorkspace(
1646
1694
  const { loadHooks, projectHookTrustNotice, attachAuthorityErrors } =
1647
1695
  await import("../lib/settings-hooks.cjs");
1648
1696
  const loaded = loadHooks({ cwd, settingsFile: options.settingsFile });
1649
- const { mergePluginHooks } =
1650
- await import("../lib/plugin-runtime/hooks.js");
1697
+ const { mergePluginHooks } = await import(
1698
+ "../lib/plugin-runtime/hooks.js"
1699
+ );
1651
1700
  const effectiveHooks = mergePluginHooks(
1652
1701
  attachAuthorityErrors(loaded.hooks, loaded.authorityErrors),
1653
1702
  { cwd },
@@ -1728,8 +1777,9 @@ async function runAgentHeadlessStreamInWorkspace(
1728
1777
  });
1729
1778
 
1730
1779
  if (managedSettings) {
1731
- const { assertManagedPermissionMode } =
1732
- await import("../lib/settings-loader.cjs");
1780
+ const { assertManagedPermissionMode } = await import(
1781
+ "../lib/settings-loader.cjs"
1782
+ );
1733
1783
  assertManagedPermissionMode(options.permissionMode, managedSettings);
1734
1784
  }
1735
1785
  const perm = resolvePermissionMode(options.permissionMode);
@@ -2217,8 +2267,9 @@ async function runAgentHeadlessStreamInWorkspace(
2217
2267
  : null;
2218
2268
  if (!instructionExcludes) {
2219
2269
  try {
2220
- const { readStringArraySetting } =
2221
- await import("../lib/settings-loader.cjs");
2270
+ const { readStringArraySetting } = await import(
2271
+ "../lib/settings-loader.cjs"
2272
+ );
2222
2273
  const fromSettings = readStringArraySetting("instructionExcludes", {
2223
2274
  cwd,
2224
2275
  settingsFile: options.settingsFile,
@@ -2283,8 +2334,9 @@ async function runAgentHeadlessStreamInWorkspace(
2283
2334
  // Best-effort; no-op when project memory is off or no hook is registered.
2284
2335
  if (settingsHooks && _loadedInstructions) {
2285
2336
  try {
2286
- const { runInstructionsLoadedHooks } =
2287
- await import("../lib/settings-hook-events.js");
2337
+ const { runInstructionsLoadedHooks } = await import(
2338
+ "../lib/settings-hook-events.js"
2339
+ );
2288
2340
  const ctx = runInstructionsLoadedHooks(settingsHooks, {
2289
2341
  files: _loadedInstructions.files,
2290
2342
  cwd,
@@ -2324,8 +2376,9 @@ async function runAgentHeadlessStreamInWorkspace(
2324
2376
  // settings.json SessionStart hooks → inject session context once (observe-only).
2325
2377
  if (settingsHooks) {
2326
2378
  try {
2327
- const { runSessionStartHooks } =
2328
- await import("../lib/settings-hook-events.js");
2379
+ const { runSessionStartHooks } = await import(
2380
+ "../lib/settings-hook-events.js"
2381
+ );
2329
2382
  const ctx = runSessionStartHooks(settingsHooks, {
2330
2383
  source: "startup",
2331
2384
  cwd,
@@ -2696,8 +2749,9 @@ async function runAgentHeadlessStreamInWorkspace(
2696
2749
  // the single-prompt runner + the REPL /add-dir path. Best-effort.
2697
2750
  if (hostMcp?.mcpClient && additionalDirectories.length > 0) {
2698
2751
  try {
2699
- const { notifyMcpRootsChanged, workspaceRootDirs } =
2700
- await import("../repl/add-dir.js");
2752
+ const { notifyMcpRootsChanged, workspaceRootDirs } = await import(
2753
+ "../repl/add-dir.js"
2754
+ );
2701
2755
  notifyMcpRootsChanged(
2702
2756
  [hostMcp.mcpClient],
2703
2757
  workspaceRootDirs(options.cwd || process.cwd(), additionalDirectories),
@@ -2798,6 +2852,7 @@ async function runAgentHeadlessStreamInWorkspace(
2798
2852
  cwd,
2799
2853
  additionalDirectories,
2800
2854
  sessionId,
2855
+ sessionBudget: options.sessionBudget || null,
2801
2856
  sessionHostSnapshot: canonicalResume?.snapshot || null,
2802
2857
  // Auto-checkpoint (Claude-Code parity): snapshot the work tree before each
2803
2858
  // mutating tool so a stream consumer (e.g. the IDE chat panel) can rewind.
@@ -3281,13 +3336,19 @@ async function runAgentHeadlessStreamInWorkspace(
3281
3336
  maxOutputTokens: options.compactionMaxOutputTokens,
3282
3337
  summaryInputMaxChars: options.compactionInputMaxChars,
3283
3338
  onProviderCallStart: () => {
3284
- persistUsageEvent?.({
3339
+ const event = {
3285
3340
  type: "model-usage-started",
3286
3341
  callId: compactionCallId,
3287
3342
  provider,
3288
3343
  model,
3289
3344
  source: "semantic-compaction",
3290
- });
3345
+ };
3346
+ persistUsageEvent?.(event);
3347
+ beginSessionBudgetUsage(
3348
+ options.sessionBudget,
3349
+ event,
3350
+ "headless semantic compaction",
3351
+ );
3291
3352
  compactionProviderStarted = true;
3292
3353
  return compactionCallId;
3293
3354
  },
@@ -3296,14 +3357,21 @@ async function runAgentHeadlessStreamInWorkspace(
3296
3357
  if (isAbortError(error) || options.signal?.aborted) throw error;
3297
3358
  if (error?.runtimeLedgerPersistence === true) throw error;
3298
3359
  if (compactionProviderStarted) {
3299
- persistUsageEvent?.({
3360
+ const event = {
3300
3361
  type: "model-usage-unknown",
3301
3362
  callId: compactionCallId,
3302
3363
  provider,
3303
3364
  model,
3304
3365
  source: "semantic-compaction",
3305
3366
  code: "provider_call_failed",
3306
- });
3367
+ };
3368
+ persistUsageEvent?.(event);
3369
+ if (markSessionBudgetUsageUnknown(options.sessionBudget, event)) {
3370
+ rejectSessionBudgetUsageUnknown(
3371
+ event,
3372
+ "headless semantic compaction",
3373
+ );
3374
+ }
3307
3375
  }
3308
3376
  emit({
3309
3377
  type: "compaction-degraded",
@@ -3316,14 +3384,21 @@ async function runAgentHeadlessStreamInWorkspace(
3316
3384
  emit({ type: "compaction-degraded", ...degradedEvent });
3317
3385
  }
3318
3386
  if (usageUnknownEvent) {
3319
- persistUsageEvent?.({
3387
+ const event = {
3320
3388
  type: "model-usage-unknown",
3321
3389
  callId: compactionCallId,
3322
3390
  provider: usageUnknownEvent.provider || provider,
3323
3391
  model: usageUnknownEvent.model || model,
3324
3392
  source: "semantic-compaction",
3325
3393
  code: "provider_transport_outcome_unknown",
3326
- });
3394
+ };
3395
+ persistUsageEvent?.(event);
3396
+ if (markSessionBudgetUsageUnknown(options.sessionBudget, event)) {
3397
+ rejectSessionBudgetUsageUnknown(
3398
+ event,
3399
+ "headless semantic compaction",
3400
+ );
3401
+ }
3327
3402
  emit({
3328
3403
  type: "compaction_usage_unknown",
3329
3404
  ...usageUnknownEvent,
@@ -3344,12 +3419,18 @@ async function runAgentHeadlessStreamInWorkspace(
3344
3419
  }
3345
3420
  let costExceeded = false;
3346
3421
  if (usageEvent) {
3347
- persistUsageEvent?.({
3422
+ const event = {
3348
3423
  type: "token-usage",
3349
3424
  callId: compactionCallId,
3350
3425
  ...usageEvent,
3351
3426
  source: "semantic-compaction",
3352
- });
3427
+ };
3428
+ persistUsageEvent?.(event);
3429
+ recordSessionBudgetUsage(
3430
+ options.sessionBudget,
3431
+ event,
3432
+ "headless semantic compaction usage settlement",
3433
+ );
3353
3434
  emit({ type: "token_usage", ...usageEvent });
3354
3435
  if (costBudget) {
3355
3436
  costBudget.add(usageEvent);
@@ -3609,8 +3690,9 @@ async function runAgentHeadlessStreamInWorkspace(
3609
3690
  // session can honour the user's standing preferences ("越用越聪明"
3610
3691
  // flywheel). Best-effort — a learning ledger must never break the chat.
3611
3692
  try {
3612
- const { appendFeedback } =
3613
- await import("../lib/pdh-feedback-ledger.js");
3693
+ const { appendFeedback } = await import(
3694
+ "../lib/pdh-feedback-ledger.js"
3695
+ );
3614
3696
  appendFeedback({ sessionId, turnId, kind, comment });
3615
3697
  } catch {
3616
3698
  /* persistence is best-effort */
@@ -3741,8 +3823,9 @@ async function runAgentHeadlessStreamInWorkspace(
3741
3823
  // settings.json UserPromptSubmit hooks. block → skip this turn; context → inject.
3742
3824
  if (settingsHooks) {
3743
3825
  try {
3744
- const { runUserPromptSubmitHooks } =
3745
- await import("../lib/settings-hook-events.js");
3826
+ const { runUserPromptSubmitHooks } = await import(
3827
+ "../lib/settings-hook-events.js"
3828
+ );
3746
3829
  const ups = runUserPromptSubmitHooks(settingsHooks, {
3747
3830
  prompt: userContent,
3748
3831
  cwd,
@@ -3958,6 +4041,7 @@ async function runAgentHeadlessStreamInWorkspace(
3958
4041
  now: deps.now || Date.now,
3959
4042
  persistUsageEvent,
3960
4043
  persistToolEvent,
4044
+ sessionBudget: options.sessionBudget || null,
3961
4045
  },
3962
4046
  );
3963
4047
  } catch (err) {
@@ -4001,6 +4085,30 @@ async function runAgentHeadlessStreamInWorkspace(
4001
4085
  break;
4002
4086
  }
4003
4087
  }
4088
+ if (
4089
+ err?.code === "CC_SESSION_BUDGET_EXHAUSTED" ||
4090
+ err?.code === "CC_SESSION_BUDGET_USAGE_UNKNOWN" ||
4091
+ options.sessionBudget?.signal?.aborted === true
4092
+ ) {
4093
+ const budgetReason =
4094
+ options.sessionBudget?.reason?.() ||
4095
+ err.budgetReason ||
4096
+ "session-aborted";
4097
+ emit({
4098
+ type: "result",
4099
+ subtype: "error_session_budget",
4100
+ is_error: true,
4101
+ code: err.code,
4102
+ error:
4103
+ err?.code === "CC_SESSION_BUDGET_USAGE_UNKNOWN"
4104
+ ? err.message
4105
+ : sessionBudgetAdmissionError(budgetReason, "run").message,
4106
+ budget_reason: budgetReason,
4107
+ turn: turns,
4108
+ });
4109
+ sawError = true;
4110
+ break;
4111
+ }
4004
4112
  const isAbort =
4005
4113
  err?.name === "AbortError" || /abort/i.test(err?.message || "");
4006
4114
  if (isAbort && !options.signal?.aborted) {
@@ -49,6 +49,16 @@ export function resolveAgentPolicy({
49
49
  : [],
50
50
  worktreeId:
51
51
  overrides.worktreeId == null ? null : String(overrides.worktreeId),
52
+ sessionBudgetRoot:
53
+ overrides.sessionBudgetRoot &&
54
+ typeof overrides.sessionBudgetRoot === "object"
55
+ ? Object.freeze({
56
+ ...overrides.sessionBudgetRoot,
57
+ limits: Object.freeze({
58
+ ...(overrides.sessionBudgetRoot.limits || {}),
59
+ }),
60
+ })
61
+ : null,
52
62
  ...(overrides.observabilityScope &&
53
63
  typeof overrides.observabilityScope === "object"
54
64
  ? { observabilityScope: { ...overrides.observabilityScope } }
@@ -1 +0,0 @@
1
- import{I as v,P as u,J as S,U as n,R as a,S as y,K as C,Q as w,V as x,_ as B,b as s}from"./vendor-Bn1JzzAn.js";import{_ as k}from"./index-CWZ3REg6.js";import"./icons-DG5UD-6K.js";const N={__name:"ChatBubbleRenderer",props:{event:{type:Object,required:!0}},setup(c,{expose:d}){d();const t=c,r=s(()=>{const e=t.event.content||{};return e.text||e.body||e.message||e.title||JSON.stringify(e).slice(0,200)}),i=s(()=>{const e=t.event.content||{};return e.from||e.sender||e.senderName||t.event.actor||"(unknown)"}),l=s(()=>{const e=(t.event.actor||"").toLowerCase();return e.includes("self")||e==="me"||e.endsWith("_self")}),o=s(()=>{const e=t.event.source.adapter||"";return e.startsWith("messaging-qq")?"magenta":e==="wechat"?"green":"blue"}),m=s(()=>{if(!t.event.occurredAt)return"";try{const e=new Date(t.event.occurredAt),p=e.getFullYear(),g=String(e.getMonth()+1).padStart(2,"0"),f=String(e.getDate()).padStart(2,"0"),b=String(e.getHours()).padStart(2,"0"),h=String(e.getMinutes()).padStart(2,"0");return`${p}-${g}-${f} ${b}:${h}`}catch{return""}}),_={props:t,messageText:r,actorLabel:i,isMine:l,adapterColor:o,formattedTime:m,computed:s};return Object.defineProperty(_,"__isScriptSetup",{enumerable:!1,value:!0}),_}},T={class:"bubble"},M={class:"meta"},R={class:"actor"},V={class:"time"},q={class:"body"};function D(c,d,t,r,i,l){const o=v("a-tag");return u(),S("div",{class:B(["chat-row",{mine:r.isMine}])},[n("div",T,[n("div",M,[n("span",R,a(r.actorLabel),1),n("span",V,a(r.formattedTime),1)]),n("div",q,a(r.messageText),1),t.event.source.adapter?(u(),y(o,{key:0,class:"src",color:r.adapterColor},{default:C(()=>[w(a(t.event.source.adapter),1)]),_:1},8,["color"])):x("v-if",!0)])],2)}const j=k(N,[["render",D],["__scopeId","data-v-49238629"],["__file","/tmp/cc-web-panel-NWBgwS/repo/packages/web-panel/src/components/pdh/renderers/ChatBubbleRenderer.vue"]]);export{j as default};
@@ -1 +0,0 @@
1
- import{P as c,J as p,b as s}from"./vendor-Bn1JzzAn.js";import{r as a}from"./markdown-Yo_c6Krv.js";import{_ as d}from"./index-CWZ3REg6.js";const _={__name:"MarkdownRenderer",props:{content:{type:String,default:""}},setup(t,{expose:o}){o();const e=t,r=s(()=>a(e.content||"")),n={props:e,rendered:r,computed:s,get renderMarkdown(){return a}};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-NWBgwS/repo/packages/web-panel/src/components/MarkdownRenderer.vue"]]);export{w as M};
@@ -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-CWZ3REg6.js";import{a8 as y,M as B}from"./icons-DG5UD-6K.js";const M={__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 B},get FolderOutlined(){return y}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}},x={class:"mobile-projects-placeholder"},O={class:"title"},w={class:"subtitle"},k={class:"explainer"};function T(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",x,[l(j,null,{default:r(()=>[l(P,{description:!1},{image:r(()=>[l(e.MobileOutlined,{style:{fontSize:"64px",color:"#bfbfbf"}})]),default:r(()=>[o("h2",O,t(e.t("mobileProjects.title")),1),o("p",w,t(e.t("mobileProjects.subtitle")),1),l(s,{message:e.t("mobileProjects.v02Banner"),type:"info","show-icon":"",class:"banner"},null,8,["message"]),o("div",k,[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 C=v(M,[["render",T],["__scopeId","data-v-9262cc45"],["__file","/tmp/cc-web-panel-NWBgwS/repo/packages/web-panel/src/views/MobileProjects.vue"]]);export{C as default};
@@ -1 +0,0 @@
1
- import{I as i,J as I,U,R as s,Q as r,c as t,K as a,V as _,S as x,o as oe,b as ee,r as u,P as p,F as ne,a2 as ge}from"./vendor-Bn1JzzAn.js";import{_ as we,b as re,u as ie,d}from"./index-CWZ3REg6.js";import{u as de}from"./useShellMode-CgR0wCYM.js";import{aN as ke,aO as Fe,aP as be,f as je,a5 as Ce,a8 as xe,at as Oe,R as Se}from"./icons-DG5UD-6K.js";const Pe={__name:"Projects",setup(se,{expose:l}){l();const{t:te}=re(),e=ie(),{isEmbedded:W}=de();async function w(o,f,ye,ae=8e3){if(W){const Z=await e.sendRaw({...f,type:o},ae);if(!Z?.ok){const $=Z?.error;throw new Error(typeof $=="string"?$:$?.message||`${o} failed`)}return Z.result}return e.executeJson(ye,ae)}const T=u(!1),y=u([]),O=u(""),S=u(""),P=u(!1),v=u(null),h=u([]),k=u(!1),E=u(!1),L=u(!1),F=u({name:"",description:"",type:"document",rootPath:""}),z=[{title:"ID",key:"id",width:110},{title:"名称",key:"name"},{title:"类型",key:"project_type",width:120},{title:"状态",key:"status",width:100},{title:"同步",key:"sync_status",width:100},{title:"更新",key:"updated_at",width:160},{title:"操作",key:"actions",width:180,fixed:"right"}],V=ee(()=>{const o={active:0,draft:0,completed:0,archived:0};for(const f of y.value)o[f.status]!==void 0&&(o[f.status]+=1);return o}),J=ee(()=>y.value.filter(o=>!(O.value&&o.status!==O.value||S.value&&!o.name.toLowerCase().includes(S.value.toLowerCase()))));function g(o){switch(o){case"active":return"green";case"draft":return"default";case"completed":return"cyan";case"archived":return"gold";default:return"default"}}function K(o){switch(o){case"synced":return"green";case"pending":return"orange";case"conflict":return"red";case"error":return"red";default:return"default"}}function Q(o){return!o&&o!==0?"-":new Date(typeof o=="number"?o:parseInt(o,10)).toLocaleString("zh-CN",{hour12:!1})}async function C(){T.value=!0;try{const o=await w("project.list",{limit:500},"project list --limit 500 --json",1e4);y.value=Array.isArray(o?.projects)?o.projects:Array.isArray(o)?o:[]}catch(o){d.error("加载失败: "+(o.message||o)),y.value=[]}finally{T.value=!1}}function G(o){return{onClick:()=>M(o)}}async function M(o){v.value=o,P.value=!0,k.value=!0,h.value=[];try{const f=await w("project.listFiles",{projectId:o.id,limit:200},`project list-files ${o.id} --json`,8e3);h.value=Array.isArray(f?.files)?f.files:[]}catch{h.value=[]}finally{k.value=!1}}async function H(o){try{(await w("project.delete",{id:o.id},`project delete ${o.id} --json`,8e3))?.ok?(d.success(`已删除项目 '${o.name}'`),P.value=!1,await C()):d.error("删除失败")}catch(f){d.error(f.message||String(f))}}function X(){F.value={name:"",description:"",type:"document",rootPath:""},E.value=!0}async function B(){if(!F.value.name.trim()){d.warning("请输入项目名称");return}L.value=!0;try{const o=await w("project.init",{name:F.value.name.trim(),description:F.value.description||null,projectType:F.value.type,rootPath:F.value.rootPath||null},`project init "${F.value.name.trim()}" --type ${F.value.type} --json`,8e3);o?.id?(d.success(`已创建项目 '${o.name}'`),E.value=!1,await C()):d.error("创建失败")}catch(o){d.error(o.message||String(o))}finally{L.value=!1}}const b=u(!1),D=u(!1),j=u({path:"",content:""}),A=u(!1),m=u(!1),R=u({path:""}),n=u(!1),c=u(null),N=u(""),Y=u(!1);function ue(){j.value={path:"",content:""},b.value=!0}function ce(){R.value={path:""},A.value=!0}async function q(){if(v.value){k.value=!0;try{const o=await w("project.listFiles",{projectId:v.value.id,limit:200},`project list-files ${v.value.id} --json`,8e3);h.value=Array.isArray(o?.files)?o.files:[]}catch(o){d.error("刷新文件失败: "+(o.message||o))}finally{k.value=!1}}}async function fe(){if(!j.value.path.trim()){d.warning("请输入文件路径");return}if(v.value){D.value=!0;try{const o=await w("project.createFile",{projectId:v.value.id,filePath:j.value.path.trim(),content:j.value.content||""},`project create-file ${v.value.id} "${j.value.path.trim()}" --json`,8e3);o?.id?(d.success(`已创建文件 '${o.file_name}'`),b.value=!1,await q(),await C()):d.error("创建文件失败")}catch(o){d.error(o.message||String(o))}finally{D.value=!1}}}async function pe(){if(!R.value.path.trim()){d.warning("请输入文件夹路径");return}if(v.value){m.value=!0;try{const o=await w("project.createFolder",{projectId:v.value.id,folderPath:R.value.path.trim()},`project create-folder ${v.value.id} "${R.value.path.trim()}" --json`,8e3);o?.id?(d.success(`已创建文件夹 '${o.file_name}'`),A.value=!1,await q(),await C()):d.error("创建文件夹失败")}catch(o){d.error(o.message||String(o))}finally{m.value=!1}}}async function ve(o){try{(await w("project.deleteFile",{fileId:o.id},`project delete-file ${o.id} --json`,8e3))?.deleted?(d.success(`已删除 '${o.file_name}'`),await q(),await C()):d.error("删除失败")}catch(f){d.error(f.message||String(f))}}async function me(o){if(o.is_folder){d.info("文件夹无内容可编辑");return}try{const f=await w("project.getFile",{fileId:o.id},`project get-file ${o.id} --json`,8e3);c.value=o,N.value=f?.content||"",n.value=!0}catch(f){d.error("读取文件失败: "+(f.message||f))}}async function _e(){if(c.value){Y.value=!0;try{(await w("project.writeFile",{fileId:c.value.id,content:N.value},`project write-file ${c.value.id} --json`,8e3))?.id?(d.success("已保存"),n.value=!1,await q()):d.error("保存失败")}catch(o){d.error(o.message||String(o))}finally{Y.value=!1}}}oe(()=>{C()});const le={t:te,ws:e,isEmbedded:W,callProjectTopic:w,loading:T,projects:y,statusFilter:O,nameFilter:S,detailOpen:P,detail:v,files:h,filesLoading:k,createOpen:E,creating:L,newProject:F,columns:z,countByStatus:V,filteredProjects:J,statusColor:g,syncColor:K,formatTime:Q,loadAll:C,onRowClick:G,openDetail:M,onDelete:H,onShowCreate:X,onCreate:B,createFileOpen:b,creatingFile:D,newFile:j,createFolderOpen:A,creatingFolder:m,newFolder:R,editFileOpen:n,editingFile:c,editFileContent:N,savingFile:Y,openCreateFile:ue,openCreateFolder:ce,refreshFiles:q,onCreateFile:fe,onCreateFolder:pe,onDeleteFile:ve,openEditFile:me,onSaveFile:_e,ref:u,computed:ee,onMounted:oe,get ReloadOutlined(){return Se},get PlusOutlined(){return Oe},get FolderOutlined(){return xe},get FileTextOutlined(){return Ce},get CheckCircleOutlined(){return je},get CheckSquareOutlined(){return be},get FileAddOutlined(){return Fe},get FolderAddOutlined(){return ke},get message(){return d},get useI18n(){return re},get useWsStore(){return ie},get useShellMode(){return de}};return Object.defineProperty(le,"__isScriptSetup",{enumerable:!1,value:!0}),le}},ze={style:{display:"flex","align-items":"center","justify-content":"space-between","margin-bottom":"24px"}},Ae={class:"page-title"},Ie={class:"page-sub"},Ue={class:"filter-bar",style:{"margin-bottom":"12px",display:"flex",gap:"12px","align-items":"center"}},he={key:0,style:{"font-size":"12px",color:"#888"}},De={key:0,style:{color:"#888","font-size":"12px"}},Re={key:0},Be={key:1,style:{color:"#888"}},Te=["onClick"],Ee={key:0,style:{color:"#888","font-size":"12px"}};function Le(se,l,te,e,W,w){const T=i("router-link"),y=i("a-button"),O=i("a-space"),S=i("a-statistic"),P=i("a-card"),v=i("a-col"),h=i("a-row"),k=i("a-radio-button"),E=i("a-radio-group"),L=i("a-input-search"),F=i("a-alert"),z=i("a-tag"),V=i("a-popconfirm"),J=i("a-table"),g=i("a-descriptions-item"),K=i("a-descriptions"),Q=i("a-divider"),C=i("a-empty"),G=i("a-list-item"),M=i("a-list"),H=i("a-spin"),X=i("a-drawer"),B=i("a-input"),b=i("a-form-item"),D=i("a-textarea"),j=i("a-form"),A=i("a-modal"),m=i("a-select-option"),R=i("a-select");return p(),I("div",null,[U("div",ze,[U("div",null,[U("h2",Ae,s(e.t("projects.title")),1),U("p",Ie,[l[17]||(l[17]=r("桌面 / CLI / 手机 三端共享同一份项目数据,Phase 3d sync 自动同步 (",-1)),t(T,{to:"/project-init"},{default:a(()=>[...l[16]||(l[16]=[r("项目初始化 / 环境设置",-1)])]),_:1}),l[18]||(l[18]=r(")",-1))])]),t(O,null,{default:a(()=>[t(y,{loading:e.loading,onClick:e.loadAll},{icon:a(()=>[t(e.ReloadOutlined)]),default:a(()=>[l[19]||(l[19]=r(" 刷新 ",-1))]),_:1},8,["loading"]),t(y,{type:"primary",onClick:e.onShowCreate},{icon:a(()=>[t(e.PlusOutlined)]),default:a(()=>[l[20]||(l[20]=r(" 新建项目 ",-1))]),_:1})]),_:1})]),_(" Stats "),t(h,{gutter:[16,16],style:{"margin-bottom":"20px"}},{default:a(()=>[t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"总项目",value:e.projects.length,"value-style":{color:"#1677ff",fontSize:"20px"}},{prefix:a(()=>[t(e.FolderOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"活跃",value:e.countByStatus.active,"value-style":{color:"#52c41a",fontSize:"20px"}},{prefix:a(()=>[t(e.CheckCircleOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"草稿",value:e.countByStatus.draft,"value-style":{color:"#8c8c8c",fontSize:"20px"}},{prefix:a(()=>[t(e.FileTextOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"已完成",value:e.countByStatus.completed,"value-style":{color:"#13c2c2",fontSize:"20px"}},{prefix:a(()=>[t(e.CheckSquareOutlined)]),_:1},8,["value"])]),_:1})]),_:1})]),_:1}),_(" Filter "),U("div",Ue,[t(E,{value:e.statusFilter,"onUpdate:value":l[0]||(l[0]=n=>e.statusFilter=n),size:"small","button-style":"solid"},{default:a(()=>[t(k,{value:""},{default:a(()=>[...l[21]||(l[21]=[r("全部",-1)])]),_:1}),t(k,{value:"active"},{default:a(()=>[...l[22]||(l[22]=[r("活跃",-1)])]),_:1}),t(k,{value:"draft"},{default:a(()=>[...l[23]||(l[23]=[r("草稿",-1)])]),_:1}),t(k,{value:"completed"},{default:a(()=>[...l[24]||(l[24]=[r("已完成",-1)])]),_:1}),t(k,{value:"archived"},{default:a(()=>[...l[25]||(l[25]=[r("已归档",-1)])]),_:1})]),_:1},8,["value"]),t(L,{value:e.nameFilter,"onUpdate:value":l[1]||(l[1]=n=>e.nameFilter=n),placeholder:"按名称过滤",style:{"max-width":"260px"},"allow-clear":""},null,8,["value"])]),!e.projects.length&&!e.loading?(p(),x(F,{key:0,type:"info",message:"还没有项目",description:'运行 `cc project init <name>` 或点击右上角"新建项目"按钮创建。桌面 / CLI / 手机三端共享同一份数据。',"show-icon":"",style:{"margin-bottom":"16px"}})):_("v-if",!0),e.projects.length||e.loading?(p(),x(J,{key:1,columns:e.columns,"data-source":e.filteredProjects,loading:e.loading,pagination:{pageSize:20,showSizeChanger:!0},"row-key":"id","custom-row":e.onRowClick},{bodyCell:a(({column:n,record:c})=>[n.key==="id"?(p(),I("code",he,s(c.id.slice(0,8))+"…",1)):n.key==="name"?(p(),I(ne,{key:1},[U("strong",null,s(c.name),1),c.description?(p(),I("div",De,s(c.description),1)):_("v-if",!0)],64)):n.key==="project_type"?(p(),x(z,{key:2},{default:a(()=>[r(s(c.project_type),1)]),_:2},1024)):n.key==="status"?(p(),x(z,{key:3,color:e.statusColor(c.status)},{default:a(()=>[r(s(c.status),1)]),_:2},1032,["color"])):n.key==="sync_status"?(p(),x(z,{key:4,color:e.syncColor(c.sync_status)},{default:a(()=>[r(s(c.sync_status||"unknown"),1)]),_:2},1032,["color"])):n.key==="updated_at"?(p(),I(ne,{key:5},[r(s(e.formatTime(c.updated_at)),1)],64)):n.key==="actions"?(p(),x(O,{key:6,onClick:l[2]||(l[2]=ge(()=>{},["stop"]))},{default:a(()=>[t(y,{size:"small",onClick:N=>e.openDetail(c)},{default:a(()=>[...l[26]||(l[26]=[r("详情",-1)])]),_:1},8,["onClick"]),t(V,{title:`删除项目 '${c.name}' ?`,"ok-text":"删除","ok-type":"danger","cancel-text":"取消",onConfirm:N=>e.onDelete(c)},{default:a(()=>[t(y,{size:"small",danger:""},{default:a(()=>[...l[27]||(l[27]=[r("删除",-1)])]),_:1})]),_:1},8,["title","onConfirm"])]),_:2},1024)):_("v-if",!0)]),_:1},8,["data-source","loading"])):_("v-if",!0),_(" Detail drawer "),t(X,{open:e.detailOpen,"onUpdate:open":l[3]||(l[3]=n=>e.detailOpen=n),title:e.detail?.name||"项目详情",width:"640",placement:"right"},{default:a(()=>[e.detail?(p(),x(K,{key:0,column:1,bordered:"",size:"small"},{default:a(()=>[t(g,{label:"ID"},{default:a(()=>[U("code",null,s(e.detail.id),1)]),_:1}),t(g,{label:"名称"},{default:a(()=>[r(s(e.detail.name),1)]),_:1}),t(g,{label:"描述"},{default:a(()=>[r(s(e.detail.description||"-"),1)]),_:1}),t(g,{label:"类型"},{default:a(()=>[t(z,null,{default:a(()=>[r(s(e.detail.project_type),1)]),_:1})]),_:1}),t(g,{label:"状态"},{default:a(()=>[t(z,{color:e.statusColor(e.detail.status)},{default:a(()=>[r(s(e.detail.status),1)]),_:1},8,["color"])]),_:1}),t(g,{label:"同步状态"},{default:a(()=>[t(z,{color:e.syncColor(e.detail.sync_status)},{default:a(()=>[r(s(e.detail.sync_status||"unknown"),1)]),_:1},8,["color"])]),_:1}),t(g,{label:"用户"},{default:a(()=>[r(s(e.detail.user_id),1)]),_:1}),t(g,{label:"根路径"},{default:a(()=>[e.detail.root_path?(p(),I("code",Re,s(e.detail.root_path),1)):(p(),I("span",Be,"(无)"))]),_:1}),t(g,{label:"文件数"},{default:a(()=>[r(s(e.detail.file_count||0),1)]),_:1}),t(g,{label:"创建"},{default:a(()=>[r(s(e.formatTime(e.detail.created_at)),1)]),_:1}),t(g,{label:"更新"},{default:a(()=>[r(s(e.formatTime(e.detail.updated_at)),1)]),_:1})]),_:1})):_("v-if",!0),t(Q,null,{default:a(()=>[...l[28]||(l[28]=[r("文件",-1)])]),_:1}),_(" Sub-phase 7.3 (2026-05-17): 文件 CRUD toolbar "),t(O,{style:{"margin-bottom":"12px"}},{default:a(()=>[t(y,{size:"small",type:"primary",disabled:!e.detail,onClick:e.openCreateFile},{default:a(()=>[t(e.FileAddOutlined),l[29]||(l[29]=r(" 新建文件 ",-1))]),_:1},8,["disabled"]),t(y,{size:"small",disabled:!e.detail,onClick:e.openCreateFolder},{default:a(()=>[t(e.FolderAddOutlined),l[30]||(l[30]=r(" 新建文件夹 ",-1))]),_:1},8,["disabled"])]),_:1}),t(H,{spinning:e.filesLoading},{default:a(()=>[!e.files.length&&!e.filesLoading?(p(),x(C,{key:0,description:"无文件 (点上方按钮新建)"})):(p(),x(M,{key:1,size:"small","data-source":e.files},{renderItem:a(({item:n})=>[t(G,null,{extra:a(()=>[t(O,null,{default:a(()=>[n.file_size?(p(),I("span",Ee,s(n.file_size)+" B",1)):_("v-if",!0),t(V,{title:`删除 ${n.is_folder?"文件夹":"文件"} '${n.file_name}' ?`,"ok-text":"删除","ok-type":"danger","cancel-text":"取消",onConfirm:c=>e.onDeleteFile(n)},{default:a(()=>[t(y,{size:"small",danger:""},{default:a(()=>[...l[31]||(l[31]=[r("×",-1)])]),_:1})]),_:1},8,["title","onConfirm"])]),_:2},1024)]),default:a(()=>[U("span",{style:{cursor:"pointer"},onClick:c=>e.openEditFile(n)},s(n.is_folder?"📁":"📄")+" "+s(n.file_path),9,Te)]),_:2},1024)]),_:1},8,["data-source"]))]),_:1},8,["spinning"])]),_:1},8,["open","title"]),_(" Sub-phase 7.3: Create file modal "),t(A,{open:e.createFileOpen,"onUpdate:open":l[6]||(l[6]=n=>e.createFileOpen=n),title:"新建文件","confirm-loading":e.creatingFile,"ok-text":"创建","cancel-text":"取消",onOk:e.onCreateFile},{default:a(()=>[t(j,{layout:"vertical"},{default:a(()=>[t(b,{label:"文件路径(项目内)",required:""},{default:a(()=>[t(B,{value:e.newFile.path,"onUpdate:value":l[4]||(l[4]=n=>e.newFile.path=n),placeholder:"例如 README.md 或 src/main.kt"},null,8,["value"])]),_:1}),t(b,{label:"初始内容(可选)"},{default:a(()=>[t(D,{value:e.newFile.content,"onUpdate:value":l[5]||(l[5]=n=>e.newFile.content=n),rows:6,placeholder:"留空创建空文件"},null,8,["value"])]),_:1})]),_:1})]),_:1},8,["open","confirm-loading"]),_(" Sub-phase 7.3: Create folder modal "),t(A,{open:e.createFolderOpen,"onUpdate:open":l[8]||(l[8]=n=>e.createFolderOpen=n),title:"新建文件夹","confirm-loading":e.creatingFolder,"ok-text":"创建","cancel-text":"取消",onOk:e.onCreateFolder},{default:a(()=>[t(j,{layout:"vertical"},{default:a(()=>[t(b,{label:"文件夹路径(项目内)",required:""},{default:a(()=>[t(B,{value:e.newFolder.path,"onUpdate:value":l[7]||(l[7]=n=>e.newFolder.path=n),placeholder:"例如 src/utils"},null,8,["value"])]),_:1})]),_:1})]),_:1},8,["open","confirm-loading"]),_(" Sub-phase 7.3: Edit file content modal "),t(A,{open:e.editFileOpen,"onUpdate:open":l[10]||(l[10]=n=>e.editFileOpen=n),title:`编辑 ${e.editingFile?.file_name||""}`,"confirm-loading":e.savingFile,"ok-text":"保存","cancel-text":"取消",onOk:e.onSaveFile,width:"720"},{default:a(()=>[t(D,{value:e.editFileContent,"onUpdate:value":l[9]||(l[9]=n=>e.editFileContent=n),rows:18,"auto-size":{minRows:12,maxRows:24},style:{"font-family":"monospace"}},null,8,["value"])]),_:1},8,["open","title","confirm-loading"]),_(" Create modal "),t(A,{open:e.createOpen,"onUpdate:open":l[15]||(l[15]=n=>e.createOpen=n),title:"新建项目","confirm-loading":e.creating,"ok-text":"创建","cancel-text":"取消",onOk:e.onCreate},{default:a(()=>[t(j,{layout:"vertical"},{default:a(()=>[t(b,{label:"项目名称",required:""},{default:a(()=>[t(B,{value:e.newProject.name,"onUpdate:value":l[11]||(l[11]=n=>e.newProject.name=n),placeholder:"例如:旅行计划-上海"},null,8,["value"])]),_:1}),t(b,{label:"描述"},{default:a(()=>[t(D,{value:e.newProject.description,"onUpdate:value":l[12]||(l[12]=n=>e.newProject.description=n),rows:2},null,8,["value"])]),_:1}),t(b,{label:"类型"},{default:a(()=>[t(R,{value:e.newProject.type,"onUpdate:value":l[13]||(l[13]=n=>e.newProject.type=n)},{default:a(()=>[t(m,{value:"document"},{default:a(()=>[...l[32]||(l[32]=[r("文档 (document)",-1)])]),_:1}),t(m,{value:"data"},{default:a(()=>[...l[33]||(l[33]=[r("数据 (data)",-1)])]),_:1}),t(m,{value:"web"},{default:a(()=>[...l[34]||(l[34]=[r("Web",-1)])]),_:1}),t(m,{value:"app"},{default:a(()=>[...l[35]||(l[35]=[r("应用 (app)",-1)])]),_:1}),t(m,{value:"presentation"},{default:a(()=>[...l[36]||(l[36]=[r("演示文稿",-1)])]),_:1}),t(m,{value:"spreadsheet"},{default:a(()=>[...l[37]||(l[37]=[r("表格",-1)])]),_:1}),t(m,{value:"design"},{default:a(()=>[...l[38]||(l[38]=[r("设计",-1)])]),_:1}),t(m,{value:"code"},{default:a(()=>[...l[39]||(l[39]=[r("代码",-1)])]),_:1}),t(m,{value:"workflow"},{default:a(()=>[...l[40]||(l[40]=[r("工作流",-1)])]),_:1}),t(m,{value:"knowledge"},{default:a(()=>[...l[41]||(l[41]=[r("知识库",-1)])]),_:1})]),_:1},8,["value"])]),_:1}),t(b,{label:"根路径 (可选)"},{default:a(()=>[t(B,{value:e.newProject.rootPath,"onUpdate:value":l[14]||(l[14]=n=>e.newProject.rootPath=n),placeholder:"留空则仅元数据"},null,8,["value"])]),_:1})]),_:1})]),_:1},8,["open","confirm-loading"])])}const We=we(Pe,[["render",Le],["__scopeId","data-v-019ac5aa"],["__file","/tmp/cc-web-panel-NWBgwS/repo/packages/web-panel/src/views/Projects.vue"]]);export{We as default};
@@ -1 +0,0 @@
1
- import{E as G,r as k,I as m,J as F,U as d,c as i,K as l,V as u,S as P,F as R,Z as q,o as I,a as A,P as g,Q as x,R as C,_ as E}from"./vendor-Bn1JzzAn.js";import{u as M,_ as H,d as _}from"./index-CWZ3REg6.js";import{a as W,b as D,c as B}from"./parsers-UEvh_ShA.js";import{R as J}from"./icons-DG5UD-6K.js";const j=G("providers",()=>{const K=k(!1),o=k(null),v=k([]),e=k([]),w=k(null);async function U(){const s=M();K.value=!0;try{const{output:f}=await s.execute("llm providers",15e3);v.value=W(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=D(b)}catch(f){console.error("Failed to load providers:",f)}finally{K.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(L=>L.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:K,testing:o,providers:v,localModels:e,activeProvider:w,loadProviders:U,switchProvider:y,testProvider:a}}),Q={__name:"Providers",setup(K,{expose:o}){o();const v=j(),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 L(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=B(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 S(){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 T={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:L,loadConfig:z,saveConfig:O,resetForm:S,onMounted:I,reactive:A,ref:k,get ReloadOutlined(){return J},get message(){return _},get useProvidersStore(){return j},get useWsStore(){return M},get parseLlmConfigOutput(){return B}};return Object.defineProperty(T,"__isScriptSetup",{enumerable:!1,value:!0}),T}},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(K,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"),L=m("a-list"),z=m("a-divider"),O=m("a-select"),S=m("a-form-item"),T=m("a-input"),n=m("a-input-password"),t=m("a-slider"),c=m("a-input-number"),N=m("a-form");return g(),F("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(),P(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(),F("div",X,[i(s,{size:"large"}),o[12]||(o[12]=d("div",{style:{color:"var(--text-muted)","margin-top":"12px"}},"加载 LLM 信息中...",-1))])):(g(),F(R,{key:2},[u(" Providers Grid "),d("div",null,[d("div",Y,[(g(!0),F(R,null,q(e.providersStore.providers,r=>(g(),P(b,{key:r.name,class:E(["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(),P(f,{key:0,color:"green"},{default:l(()=>[...o[13]||(o[13]=[x("活跃",-1)])]),_:1})):r.status==="ok"?(g(),P(p,{key:1,status:"success",text:""})):r.status==="error"?(g(),P(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(),P(f,{key:1,color:"green",style:{margin:"0","line-height":"24px"}},{default:l(()=>[...o[16]||(o[16]=[x("当前",-1)])]),_:1})):(g(),P(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(),F("div",se,[o[17]||(o[17]=d("h3",{style:{color:"#ccc","font-size":"15px","margin-bottom":"12px"}}," 本地模型(Ollama) ",-1)),i(L,{"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(),P(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(N,{model:e.configForm,layout:"vertical",class:"config-form"},{default:l(()=>[d("div",le,[u(" Provider "),i(S,{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(S,{label:"Model(模型名称)"},{default:l(()=>[i(T,{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(S,{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(S,{label:"Base URL"},{default:l(()=>[i(T,{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(S,{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(S,{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=H(Q,[["render",me],["__scopeId","data-v-64155d06"],["__file","/tmp/cc-web-panel-NWBgwS/repo/packages/web-panel/src/views/Providers.vue"]]);export{ge as default};
@@ -1 +0,0 @@
1
- import{Q as r}from"./index-CWZ3REg6.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-Ca2A57S5.js";import{a0 as t}from"./index-CWZ3REg6.js";import"./vendor-Bn1JzzAn.js";import"./responsiveObserve-Cnl39Vbz.js";import"./useFlexGapSupport-BWyT_eoU.js";import"./styleChecker-BNpV4Nqs.js";import"./index-C0ztiqtB.js";import"./icons-DG5UD-6K.js";const l=t(o);export{l as default};
@@ -1 +0,0 @@
1
- import{C as o}from"./Col-CwTkc9BM.js";import{a0 as t}from"./index-CWZ3REg6.js";import"./vendor-Bn1JzzAn.js";import"./index-C0ztiqtB.js";import"./icons-DG5UD-6K.js";const s=t(o);export{s as default};