chainlesschain 0.162.159 → 0.162.161

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 (199) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/src/assets/web-panel/assets/{AIOps-ByIiF5bT.js → AIOps-DMn528q-.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-NlgSFZq5.js → ActionButton-D9ZcDCJL.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-D17cOUcb.js → Analytics-A_K-8PX0.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-B4mEZcbl.js → AppLayout-D4pFW3X6.js} +5 -5
  7. package/src/assets/web-panel/assets/{Artifacts-CASsmyQw.js → Artifacts-Dz46COAd.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-DYAia2e2.js → Audit-cbMjbyg0.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-C1lvYUSu.js → BackgroundAgents-Dtf88GAj.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-B6agK6bA.js → Backup-C5KRxn52.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-DM43R2vy.js → BaseInput-Dd2UK3BN.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-Dtdp3eXp.js → Chat-lptKTFdG.js} +6 -6
  13. package/src/assets/web-panel/assets/{ChatBubbleRenderer-BL5c_OQ1.js → ChatBubbleRenderer-C2KLtwHz.js} +1 -1
  14. package/src/assets/web-panel/assets/{Checkbox-D2xf7uZt.js → Checkbox-_yspG6rG.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-D3j45jJL.js → Codegen-BGq_GAha.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-voPJ9fUZ.js → Col-CePor71g.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-DEsyTESF.js → Community-CLOWhIT7.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-OHV_QXLD.js → Compact-CivJt2vT.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-eDTJWC-J.js → Compliance-Btmo1GGE.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-BBvy-6d1.js → Cowork-Ct35OlG4.js} +2 -2
  21. package/src/assets/web-panel/assets/{Cron-Dw2eoJxu.js → Cron-CTc2GmhB.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-DQHms_Bh.js → Crosschain-ZtiBETk1.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-Cyu7Id1c.js → DID-BNqMQQXw.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-sIDzkG92.js → Dashboard-BmzZd-9V.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-DUW3T2ey.js → Dropdown-CMVgvP2M.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-CECELXW8.js → EmailListRenderer-CcqQFAfT.js} +1 -1
  27. package/src/assets/web-panel/assets/{FamilyGuardDashboard-BIZR37ov.js → FamilyGuardDashboard-CTqB1_4V.js} +1 -1
  28. package/src/assets/web-panel/assets/{Federation-BEZIQX84.js → Federation-CiKOOzlb.js} +1 -1
  29. package/src/assets/web-panel/assets/{FormItemContext-BcdUMznL.js → FormItemContext-Wk-OT0gr.js} +1 -1
  30. package/src/assets/web-panel/assets/{GenericCardRenderer-DsN_fr5H.js → GenericCardRenderer-DbEQT6ue.js} +1 -1
  31. package/src/assets/web-panel/assets/{Git-63LhjBx2.js → Git-0ZvCPSD9.js} +2 -2
  32. package/src/assets/web-panel/assets/{Governance-CYtQtIcH.js → Governance-CmVuKkPb.js} +1 -1
  33. package/src/assets/web-panel/assets/{Inference-BwR6UUox.js → Inference-CTWE3Jwg.js} +1 -1
  34. package/src/assets/web-panel/assets/{KnowledgeGraph-D9lVNTUA.js → KnowledgeGraph-CBEIF00L.js} +1 -1
  35. package/src/assets/web-panel/assets/{Logs-C4q5h7Ut.js → Logs-DLhxDwVG.js} +2 -2
  36. package/src/assets/web-panel/assets/MarkdownRenderer-DxywvhTU.js +1 -0
  37. package/src/assets/web-panel/assets/{Marketplace-Plksliuw.js → Marketplace-BgsCBrnc.js} +1 -1
  38. package/src/assets/web-panel/assets/{McpTools-DZUFfeuG.js → McpTools-ClBUGDS2.js} +3 -3
  39. package/src/assets/web-panel/assets/{Memory-NoDYt29V.js → Memory-CnG_ZnYw.js} +2 -2
  40. package/src/assets/web-panel/assets/{MobileBridge-CEXGTkdh.js → MobileBridge-BUOAbR1Z.js} +1 -1
  41. package/src/assets/web-panel/assets/{MobileProjects-DnbJkbZo.js → MobileProjects-Dnt_9-WB.js} +1 -1
  42. package/src/assets/web-panel/assets/{Mtc-DTAa0cwy.js → Mtc-CLjt4kCD.js} +5 -5
  43. package/src/assets/web-panel/assets/{MtcAudit-CVV7LnNS.js → MtcAudit-f24U9Aes.js} +2 -2
  44. package/src/assets/web-panel/assets/{Multisig-BqqGrjt_.js → Multisig-GrmGQbSq.js} +3 -3
  45. package/src/assets/web-panel/assets/{NLProgramming-C4WP8DRp.js → NLProgramming-DADaWn-n.js} +1 -1
  46. package/src/assets/web-panel/assets/{Notes-Zo4DJUVI.js → Notes-xtf5RX6C.js} +3 -3
  47. package/src/assets/web-panel/assets/{NotificationSettings-DBcjRaz2.js → NotificationSettings-Cd27Rgtx.js} +1 -1
  48. package/src/assets/web-panel/assets/OrderTableRenderer-fXRxlDjl.js +1 -0
  49. package/src/assets/web-panel/assets/{Organization-BT9WPBOX.js → Organization-joCFlNB0.js} +4 -4
  50. package/src/assets/web-panel/assets/{Overflow-D6b4bZ3q.js → Overflow-B1HoURq0.js} +1 -1
  51. package/src/assets/web-panel/assets/{P2P-Cw3OsYx-.js → P2P-DiwsKbT7.js} +2 -2
  52. package/src/assets/web-panel/assets/{PdhVaultBrowser-C0nyiK2b.js → PdhVaultBrowser-Xe-BsW6S.js} +3 -3
  53. package/src/assets/web-panel/assets/{Permissions-zVBZEB_C.js → Permissions-C23qi8kl.js} +3 -3
  54. package/src/assets/web-panel/assets/{PersonalDataHub-BOspsFew.js → PersonalDataHub-BS1syX2f.js} +2 -2
  55. package/src/assets/web-panel/assets/{Pipeline-CQWfZ4XH.js → Pipeline-DRYwwDyh.js} +1 -1
  56. package/src/assets/web-panel/assets/{Privacy-C2oGJ_WL.js → Privacy-BQKaDHPH.js} +1 -1
  57. package/src/assets/web-panel/assets/{ProjectInit-BZMR4qY1.js → ProjectInit-BC6F9xiG.js} +2 -2
  58. package/src/assets/web-panel/assets/{ProjectSettings-DAujoP63.js → ProjectSettings-ClFPc1Nd.js} +2 -2
  59. package/src/assets/web-panel/assets/Projects-Dn-f5aYe.js +1 -0
  60. package/src/assets/web-panel/assets/{Providers-D_RGHM-v.js → Providers-CLWuOUNt.js} +1 -1
  61. package/src/assets/web-panel/assets/{QrScannerModal-Mf6KfL2J.js → QrScannerModal-DiqULTxb.js} +1 -1
  62. package/src/assets/web-panel/assets/{QuickAsk-5D8URoI_.js → QuickAsk-9A03P-E_.js} +1 -1
  63. package/src/assets/web-panel/assets/{Recommend-Df4kC8Gy.js → Recommend-CJZAnbq_.js} +1 -1
  64. package/src/assets/web-panel/assets/{RemoteSession-DGi3f3vO.js → RemoteSession-C9A1R77h.js} +2 -2
  65. package/src/assets/web-panel/assets/{Reputation-jmkGFNWb.js → Reputation-BIZc6Rky.js} +1 -1
  66. package/src/assets/web-panel/assets/{Row-DP6Pcu3m.js → Row-DfIPNtuG.js} +1 -1
  67. package/src/assets/web-panel/assets/{RssFeed-D60hSuPO.js → RssFeed-C5znFcQ1.js} +3 -3
  68. package/src/assets/web-panel/assets/{Search-0mf1BQUK.js → Search-DSs2z3OX.js} +1 -1
  69. package/src/assets/web-panel/assets/{Security-CfZtLFYV.js → Security-CV6LcrLY.js} +4 -4
  70. package/src/assets/web-panel/assets/{Services-D9zpZLWz.js → Services-cmhoX0Xj.js} +2 -2
  71. package/src/assets/web-panel/assets/{Skeleton-D1_44eMD.js → Skeleton-tCsg2po7.js} +1 -1
  72. package/src/assets/web-panel/assets/{Skills-cVFa8zkz.js → Skills-BK1KUDiy.js} +1 -1
  73. package/src/assets/web-panel/assets/{Sla-Cinpzc3L.js → Sla-yRgyeA82.js} +1 -1
  74. package/src/assets/web-panel/assets/{SpeechSettings-bqdiJE_P.js → SpeechSettings-c1mo1mlp.js} +1 -1
  75. package/src/assets/web-panel/assets/{SyncSettings-Dgl_SLgj.js → SyncSettings-koIAfuT3.js} +2 -2
  76. package/src/assets/web-panel/assets/{Tasks-DawWAEhy.js → Tasks-DkkreAaB.js} +1 -1
  77. package/src/assets/web-panel/assets/{Templates-Ca0nY651.js → Templates-fy5Ctf9M.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tenant-CgaGEhLm.js → Tenant-Bw70Jf6S.js} +1 -1
  79. package/src/assets/web-panel/assets/{Terminal-D-9EnpRx.js → Terminal-BKh6Rx-4.js} +2 -2
  80. package/src/assets/web-panel/assets/{TimelineRenderer-CSOxDHZ6.js → TimelineRenderer-Dg54WP0c.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tokens-BpwLZpL3.js → Tokens-BvvD5SxJ.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trigger-DgowwBK5.js → Trigger-B7Ug9x4e.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trust-BZutapjE.js → Trust-BjvuMORY.js} +1 -1
  84. package/src/assets/web-panel/assets/{UkeySign-QZPt8_Sp.js → UkeySign-CZqhkx8p.js} +1 -1
  85. package/src/assets/web-panel/assets/{VideoEditing-DlQx5UDJ.js → VideoEditing-ClR50lhX.js} +1 -1
  86. package/src/assets/web-panel/assets/{Wallet-ZfdTgtWA.js → Wallet-DlfppYjx.js} +4 -4
  87. package/src/assets/web-panel/assets/{WebAuthn-CAp0y_Cr.js → WebAuthn-BirgVr8B.js} +5 -5
  88. package/src/assets/web-panel/assets/{WorkflowEditor-BVITZEmr.js → WorkflowEditor-B8DP_bax.js} +1 -1
  89. package/src/assets/web-panel/assets/{chat-CC2tPaNg.js → chat-DA8AUZzL.js} +1 -1
  90. package/src/assets/web-panel/assets/{colors-31brc9CA.js → colors-C38pLGp1.js} +1 -1
  91. package/src/assets/web-panel/assets/{compact-item-DLMkC9C-.js → compact-item-81rtr98o.js} +1 -1
  92. package/src/assets/web-panel/assets/{createContext-BMtveI6F.js → createContext-D34ixq8t.js} +1 -1
  93. package/src/assets/web-panel/assets/devWarning-CHDIEOeN.js +1 -0
  94. package/src/assets/web-panel/assets/{hasIn-DbD6WHW2.js → hasIn-D4bzqTrZ.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-BoO4WEJB.js → index-9qoVpPt6.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-CJhREOlG.js → index-B0QArPQt.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-BnFLzejT.js → index-B8mkLM4x.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-Bbc2JeQG.js → index-BIP62a6r.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CFXKbOek.js → index-BP-zkXK8.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-C-cGlCDW.js → index-BS3M5H9V.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-AaIKG60c.js → index-BXd2_LmH.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CEXa-4zd.js → index-BlxEphl7.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DZl-UXB6.js → index-BqIhLAbA.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-BOM-VFlv.js → index-BtGxuQrO.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-CcVszn2b.js → index-BvD7b2IK.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-C21pdBqs.js → index-BvL_3J_n.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DJvxFyIz.js → index-COe_cOLJ.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-ALvoNTRF.js → index-CP5alL4t.js} +1 -1
  109. package/src/assets/web-panel/assets/index-CY1NURWZ.js +1 -0
  110. package/src/assets/web-panel/assets/{index-Dm0byjm1.js → index-CbhE3j5j.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-WQUO2vvK.js → index-Cd3KuNK5.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-bdaJwTXJ.js → index-CoVgZw_b.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-COHHQ9cU.js → index-CuS-UPoj.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-C7LHNw_N.js → index-D0Ih7Hwn.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-Cod97Urs.js → index-D3zCCZRS.js} +3 -3
  116. package/src/assets/web-panel/assets/{index-Cwbqh0KZ.js → index-D6GfvEQG.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BKAB6-6V.js → index-DBFSo1NF.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CEwjBA9q.js → index-DFHa1HIg.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DndNnYc0.js → index-DFyWKOBD.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-3oBsXZmF.js → index-DMgnRwrK.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-C_eUKGYP.js → index-DUQLXLQM.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CUmLMFsy.js → index-D_2VYPr1.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-BPpS-lGb.js → index-DakfFZ-k.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-ep6JchNG.js → index-Ddk0e_Pi.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-D7cV0tu0.js → index-DkHqMnn3.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-jG6h22Qg.js → index-Dmo3dFHb.js} +1 -1
  127. package/src/assets/web-panel/assets/index-DokUYqpq.js +1 -0
  128. package/src/assets/web-panel/assets/{index-C1PfeI88.js → index-DvfCEJG-.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-ntVQqSML.js → index-E1OJRXs4.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CWgfipcC.js → index-F76w1NiL.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-BiRQUoyE.js → index-ZRJRItm0.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-BFRLmCR3.js → index-fI5sXMLg.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-D67kIagl.js → index-tKiC8T-4.js} +1 -1
  134. package/src/assets/web-panel/assets/{initDefaultProps-D5UoBRhN.js → initDefaultProps-ByyvflIR.js} +1 -1
  135. package/src/assets/web-panel/assets/{motion-DltOw0CR.js → motion-B3FQm2By.js} +1 -1
  136. package/src/assets/web-panel/assets/{move-_oPkk5zj.js → move-BSfns6Ef.js} +1 -1
  137. package/src/assets/web-panel/assets/{mtc-parser-EES8ROCS.js → mtc-parser-CTG1Ieri.js} +1 -1
  138. package/src/assets/web-panel/assets/{omit-B-_39x_M.js → omit-DObM_2j6.js} +1 -1
  139. package/src/assets/web-panel/assets/{pickAttrs-l6D0yJHz.js → pickAttrs-DOfelQ1t.js} +1 -1
  140. package/src/assets/web-panel/assets/{placementArrow-DIeUK31L.js → placementArrow-CHZILds_.js} +1 -1
  141. package/src/assets/web-panel/assets/{responsiveObserve-dG4EzUQo.js → responsiveObserve-REbucKSx.js} +1 -1
  142. package/src/assets/web-panel/assets/{slide-DWFzYGdH.js → slide-C6EZzD7o.js} +1 -1
  143. package/src/assets/web-panel/assets/{statusUtils-CECdTA5H.js → statusUtils-BxkWS-g3.js} +1 -1
  144. package/src/assets/web-panel/assets/{styleChecker-D6kP-mMK.js → styleChecker-Chklyoq6.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFlexGapSupport-BWfna_rd.js → useFlexGapSupport-CRVwKrrI.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFs-Bb-j6rzo.js → useFs-DV24ik_J.js} +1 -1
  147. package/src/assets/web-panel/assets/{usePersonalDataHub-D5OIsYM4.js → usePersonalDataHub-C7vIo4Pg.js} +1 -1
  148. package/src/assets/web-panel/assets/{vnode-DNpwzFTM.js → vnode-By-v5GlF.js} +1 -1
  149. package/src/assets/web-panel/assets/{zoom-vNLpFQBW.js → zoom-B1w9Am3r.js} +1 -1
  150. package/src/assets/web-panel/index.html +1 -1
  151. package/src/commands/agenda.js +15 -1
  152. package/src/commands/agent.js +72 -6
  153. package/src/commands/background-session.js +46 -2
  154. package/src/commands/mcp.js +46 -0
  155. package/src/commands/session.js +70 -0
  156. package/src/data/changelog.json +12 -2
  157. package/src/gateways/ws/background-agent-protocol.js +88 -14
  158. package/src/harness/jsonl-session-store.js +70 -1
  159. package/src/harness/mcp-client.js +50 -0
  160. package/src/lib/agent-authority.js +251 -0
  161. package/src/lib/agent-sandbox.js +68 -0
  162. package/src/lib/agents.js +12 -4
  163. package/src/lib/api-key-helper.js +62 -0
  164. package/src/lib/background-agent-phase.js +100 -0
  165. package/src/lib/background-agent-supervisor.js +320 -8
  166. package/src/lib/backpressure-policy.js +105 -0
  167. package/src/lib/capability-negotiation.js +212 -0
  168. package/src/lib/credential-guard.js +11 -0
  169. package/src/lib/credential-proxy.js +182 -0
  170. package/src/lib/dependency-install-policy.js +130 -0
  171. package/src/lib/event-seq-replay.js +167 -0
  172. package/src/lib/exit-codes.cjs +77 -0
  173. package/src/lib/goal-condition-engine.js +369 -0
  174. package/src/lib/headless-manifest.js +188 -0
  175. package/src/lib/hook-runner.cjs +70 -4
  176. package/src/lib/ide-context-redaction.js +130 -0
  177. package/src/lib/ide-context.js +128 -13
  178. package/src/lib/jsonl-session-store.js +2 -0
  179. package/src/lib/llm-config-defaults.js +24 -8
  180. package/src/lib/project-instructions.js +98 -1
  181. package/src/lib/project-mcp-trust.js +87 -0
  182. package/src/lib/remote-path-mapping.js +229 -0
  183. package/src/lib/schedule-planner.js +136 -0
  184. package/src/lib/sensitive-file-guard.js +51 -0
  185. package/src/lib/sub-agent-context.js +7 -3
  186. package/src/repl/bg-dashboard.js +13 -12
  187. package/src/runtime/agent-core.js +113 -10
  188. package/src/runtime/coding-agent-contract-shared.cjs +19 -2
  189. package/src/runtime/headless-runner.js +66 -7
  190. package/src/runtime/headless-stream.js +224 -12
  191. package/src/runtime/mcp-config.js +32 -1
  192. package/src/runtime/system-prompt.js +3 -0
  193. package/src/workers/background-agent-worker.js +37 -2
  194. package/src/assets/web-panel/assets/MarkdownRenderer-DexLlXfN.js +0 -1
  195. package/src/assets/web-panel/assets/OrderTableRenderer-BCQel9bD.js +0 -1
  196. package/src/assets/web-panel/assets/Projects-DvH_P2Uq.js +0 -1
  197. package/src/assets/web-panel/assets/devWarning-CB8pPOtd.js +0 -1
  198. package/src/assets/web-panel/assets/index-BhXiaiev.js +0 -1
  199. package/src/assets/web-panel/assets/index-WpaYaE3D.js +0 -1
@@ -16,6 +16,11 @@
16
16
  * not duplicate (or fork) `runAgentHeadless`'s internals.
17
17
  */
18
18
 
19
+ import { randomUUID } from "node:crypto";
20
+ import {
21
+ approvalBindingDigest,
22
+ verifyApprovalBinding,
23
+ } from "../lib/agent-authority.js";
19
24
  import { bootstrap } from "./bootstrap.js";
20
25
  import { buildSystemPrompt, agentLoop as coreAgentLoop } from "./agent-core.js";
21
26
  import { composeSystemPrompt } from "./system-prompt.js";
@@ -43,6 +48,18 @@ import {
43
48
  makePermissionPromptConfirmer,
44
49
  } from "./mcp-config.js";
45
50
  import { maybeApplyToolSearch } from "./mcp-tool-search.js";
51
+ import {
52
+ STREAM_PROTOCOL_VERSION,
53
+ computePolicyDigest,
54
+ computeToolsHash,
55
+ buildLoadedSources,
56
+ buildAgentCapabilities,
57
+ } from "../lib/headless-manifest.js";
58
+ import {
59
+ negotiateProtocol,
60
+ buildServerOffer,
61
+ applyNegotiationToGate,
62
+ } from "../lib/capability-negotiation.js";
46
63
  import { IterationBudget } from "../lib/iteration-budget.js";
47
64
  import { CostBudget } from "../lib/cost-budget.js";
48
65
  import {
@@ -80,6 +97,30 @@ export function resolveStreamCoalesceMs(options = {}, env = {}) {
80
97
  return n;
81
98
  }
82
99
 
100
+ /** Basic wire-safe trace-id sanitizer: keep only id-friendly chars, cap length
101
+ * (so an injected id can't smuggle whitespace/newlines into NDJSON or blow up
102
+ * a log line). Non-string / empty after trimming → falsy so a fresh one mints. */
103
+ function sanitizeTraceId(value) {
104
+ if (typeof value !== "string") return null;
105
+ const cleaned = value.trim().replace(/[^A-Za-z0-9._:-]/g, "");
106
+ return cleaned ? cleaned.slice(0, 128) : null;
107
+ }
108
+
109
+ /**
110
+ * Resolve the run's cross-event trace id (additive protocol-v1, §1.2.1).
111
+ * Precedence: explicit `options.traceId` > `CC_TRACE_ID` env > a freshly
112
+ * minted per-process id. Callers may inject `deps.genTraceId` for
113
+ * deterministic tests. The result is sanitized so an externally supplied id
114
+ * stays a safe single NDJSON token.
115
+ */
116
+ export function resolveTraceId(options = {}, env = {}, deps = {}) {
117
+ const supplied =
118
+ sanitizeTraceId(options.traceId) || sanitizeTraceId(env.CC_TRACE_ID);
119
+ if (supplied) return supplied;
120
+ const gen = deps.genTraceId || (() => `tr-${randomUUID()}`);
121
+ return gen();
122
+ }
123
+
83
124
  /**
84
125
  * Coalescer for the NDJSON output stream. Every line still flows through `emit`,
85
126
  * but consecutive partial-message text/thinking deltas are buffered and flushed
@@ -91,14 +132,41 @@ export function resolveStreamCoalesceMs(options = {}, env = {}) {
91
132
  *
92
133
  * The flush timer is `unref()`d so it never holds the process open. Pure aside
93
134
  * from the injected `writeOut`/timer seams, so it unit-tests deterministically.
135
+ *
136
+ * Every emitted NDJSON line is stamped with a monotonic 1-based `seq`
137
+ * (additive protocol-v1 field, agent-sdk docs/PROTOCOL.md §1.2.1) — the
138
+ * coalescer is the single output choke point, so numbering here covers every
139
+ * line including batched delta runs (one seq per LINE, not per token).
140
+ * `stampSeq:false` restores the unstamped legacy output.
141
+ *
142
+ * When a `traceId` is provided, every line is ALSO stamped with `trace_id` —
143
+ * a run-scoped cross-event correlation id (additive protocol-v1, §1.2.1). It
144
+ * is opt-in (default: absent, legacy shape) so the IDE bridge can thread its
145
+ * own id end-to-end (CC_TRACE_ID / --trace-id) while unstamped callers stay
146
+ * byte-identical.
94
147
  */
95
148
  export function createStreamCoalescer({
96
149
  writeOut,
97
150
  coalesceMs = 50,
98
151
  setTimer,
99
152
  clearTimer,
153
+ stampSeq = true,
154
+ traceId = null,
155
+ fieldGate = null,
100
156
  } = {}) {
101
- const rawEmit = (obj) => writeOut(JSON.stringify(obj) + "\n");
157
+ let seq = 0;
158
+ // `fieldGate` (if provided) is read LIVE per line so a capability
159
+ // negotiation arriving mid-stream (client `hello`) can suppress an additive
160
+ // field the client said it can't parse. Absent / undefined key = stamp (so
161
+ // the default path is byte-for-byte unchanged); only an explicit `false`
162
+ // suppresses. See lib/capability-negotiation.js applyNegotiationToGate.
163
+ const gateOn = (field) => !fieldGate || fieldGate[field] !== false;
164
+ const rawEmit = (obj) => {
165
+ let line = obj;
166
+ if (traceId && gateOn("trace_id")) line = { ...line, trace_id: traceId };
167
+ if (stampSeq && gateOn("seq")) line = { ...line, seq: ++seq };
168
+ writeOut(JSON.stringify(line) + "\n");
169
+ };
102
170
  const startTimer =
103
171
  setTimer ||
104
172
  ((fn, ms) => {
@@ -236,6 +304,19 @@ export function parseInputEvent(line) {
236
304
  } catch {
237
305
  return { error: `invalid JSON line: ${trimmed.slice(0, 80)}` };
238
306
  }
307
+ // Capability handshake (agent-sdk docs/PROTOCOL.md §1.3): an optional first
308
+ // line by which the client announces the protocol range + wire features it
309
+ // understands, so the CLI can negotiate a common level and step down on
310
+ // disagreement. {"type":"hello","protocol_version":2,"features":[...]}
311
+ if (obj && typeof obj === "object" && obj.type === "hello") {
312
+ const offer = {};
313
+ if (obj.protocol_version !== undefined)
314
+ offer.protocolVersion = obj.protocol_version;
315
+ if (obj.min_protocol_version !== undefined)
316
+ offer.minProtocolVersion = obj.min_protocol_version;
317
+ if (obj.features !== undefined) offer.features = obj.features;
318
+ return { hello: offer };
319
+ }
239
320
  // Plan-mode control events (chat-panel plan UI):
240
321
  // {"type":"plan","action":"enter"|"approve"|"reject"}
241
322
  if (obj && typeof obj === "object" && obj.type === "plan") {
@@ -258,7 +339,17 @@ export function parseInputEvent(line) {
258
339
  // {"type":"approval","id":"appr-1","approve":true|false}
259
340
  if (obj && typeof obj === "object" && obj.type === "approval") {
260
341
  if (!obj.id) return null;
261
- return { approval: { id: String(obj.id), approve: obj.approve === true } };
342
+ return {
343
+ approval: {
344
+ id: String(obj.id),
345
+ approve: obj.approve === true,
346
+ // Optional approval binding (authority §"权限来源与跨 Agent 授权边界"):
347
+ // when present it must match the digest the matching approval_request
348
+ // advertised, so a stale/mis-routed/param-substituted verdict can't
349
+ // green-light a different tool call. Absent → legacy behavior.
350
+ binding: typeof obj.binding === "string" ? obj.binding : null,
351
+ },
352
+ };
262
353
  }
263
354
  // Answer to an ask_user_question (panel QuickPick for interactive questions):
264
355
  // {"type":"answer","id":"q-1","answer":<string|string[]|null>}
@@ -440,7 +531,11 @@ export async function* readJsonLines(input, opts = {}) {
440
531
  * Run a single turn through the core agent loop, emitting NDJSON events.
441
532
  * Returns the turn outcome so the caller can grow history + the result line.
442
533
  */
443
- async function runTurn(messages, loopOptions, { runLoop, emit, costBudget }) {
534
+ async function runTurn(
535
+ messages,
536
+ loopOptions,
537
+ { runLoop, emit, costBudget, nextToolUseId },
538
+ ) {
444
539
  const usage = {
445
540
  input_tokens: 0,
446
541
  output_tokens: 0,
@@ -476,16 +571,31 @@ async function runTurn(messages, loopOptions, { runLoop, emit, costBudget }) {
476
571
  }
477
572
  for await (const event of runLoop(messages, loopOptions)) {
478
573
  switch (event.type) {
479
- case "tool-executing":
480
- toolCalls.push({ tool: event.tool, args: event.args });
481
- emit({ type: "tool_use", tool: event.tool, args: event.args });
574
+ case "tool-executing": {
575
+ // Additive protocol-v1 correlation id ("tu-<n>", session-scoped —
576
+ // agent-sdk docs/PROTOCOL.md §1.2.1): the matching tool_result below
577
+ // echoes the same id so UIs can pair calls without adjacency.
578
+ const toolUseId = nextToolUseId ? nextToolUseId() : undefined;
579
+ toolCalls.push({ id: toolUseId, tool: event.tool, args: event.args });
580
+ emit({
581
+ type: "tool_use",
582
+ ...(toolUseId ? { id: toolUseId } : {}),
583
+ tool: event.tool,
584
+ args: event.args,
585
+ });
482
586
  break;
587
+ }
483
588
  case "tool-result": {
484
589
  const err = event.error || event.result?.error || null;
485
- if (toolCalls.length > 0)
486
- toolCalls[toolCalls.length - 1].is_error = Boolean(err);
590
+ // The loop runs tools serially, so this result settles the most
591
+ // recent tool_use (same adjacency rule the is_error attribution
592
+ // below has always used).
593
+ const lastCall =
594
+ toolCalls.length > 0 ? toolCalls[toolCalls.length - 1] : null;
595
+ if (lastCall) lastCall.is_error = Boolean(err);
487
596
  emit({
488
597
  type: "tool_result",
598
+ ...(lastCall?.id ? { id: lastCall.id } : {}),
489
599
  tool: event.tool,
490
600
  is_error: Boolean(err),
491
601
  error: err,
@@ -661,6 +771,18 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
661
771
  if (!deps.writeOut && !deps.writeErr) {
662
772
  installPipeSafety();
663
773
  }
774
+ // Run-scoped cross-event trace id (additive protocol-v1, docs/PROTOCOL.md
775
+ // §1.2.1): one id stamped on EVERY stdout line so a consumer can correlate
776
+ // the whole run across Webview → Bridge → CLI logs, transcripts and
777
+ // diagnostic bundles. The IDE bridge may thread its own id through
778
+ // `--trace-id` / options.traceId / CC_TRACE_ID; otherwise a per-process id
779
+ // is minted (unique even when two runs resume the same session_id).
780
+ const traceId = resolveTraceId(options, process.env, deps);
781
+ // Live field-gate for the capability handshake (docs/PROTOCOL.md §1.3): a
782
+ // client `hello` narrowing the wire features flips these to suppress the
783
+ // additive fields it can't parse. All true by default = current behavior
784
+ // byte-for-byte; the coalescer reads it per line.
785
+ const fieldGate = { seq: true, trace_id: true, tool_use_id: true };
664
786
  // Batch consecutive partial-message text/thinking deltas into one stream_event
665
787
  // line (Claude-Code 2.1.191 streaming-CPU optimization). `emit` flushes any
666
788
  // pending deltas before writing a non-delta line, so ordering is preserved;
@@ -670,6 +792,8 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
670
792
  createStreamCoalescer({
671
793
  writeOut,
672
794
  coalesceMs: resolveStreamCoalesceMs(options, process.env),
795
+ traceId,
796
+ fieldGate,
673
797
  });
674
798
  const emit = streamCoalescer.emit;
675
799
 
@@ -718,7 +842,9 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
718
842
  deps.appendAssistantMessage || jsonlAppendAssistantMessage,
719
843
  rebuildMessages: deps.rebuildMessages || jsonlRebuildMessages,
720
844
  };
721
- const persist = Boolean(options.sessionId);
845
+ // --ephemeral forces persistence OFF even with an explicit session id (the
846
+ // id is kept for event correlation only; nothing is written or replayed).
847
+ const persist = Boolean(options.sessionId) && options.ephemeral !== true;
722
848
 
723
849
  // ── Interactive approvals (--interactive-approvals; chat-panel UX) ────────
724
850
  // CONFIRM-tier decisions (risky shell via the ApprovalGate, settings/hook
@@ -735,9 +861,32 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
735
861
  Number(process.env.CC_APPROVAL_TIMEOUT_MS) > 0
736
862
  ? Number(process.env.CC_APPROVAL_TIMEOUT_MS)
737
863
  : 120000;
738
- const settleApproval = (id, approve, via) => {
864
+ const settleApproval = (id, approve, via, incomingBinding = null) => {
739
865
  const p = pendingApprovals.get(id);
740
866
  if (!p) return;
867
+ // Approval binding (authority §"权限来源与跨 Agent 授权边界"): an *approve*
868
+ // verdict that carries a binding which does NOT match the one the request
869
+ // advertised is stale / mis-routed / argument-tampered — reject it (deny,
870
+ // fail closed) instead of green-lighting a different or changed tool call.
871
+ // A verdict with no binding stays backward-compatible; a deny always wins.
872
+ if (
873
+ approve === true &&
874
+ incomingBinding &&
875
+ p.binding &&
876
+ !verifyApprovalBinding(p.binding, incomingBinding)
877
+ ) {
878
+ pendingApprovals.delete(id);
879
+ clearTimeout(p.timer);
880
+ emit({
881
+ type: "approval_resolved",
882
+ id,
883
+ approved: false,
884
+ via: "binding-mismatch",
885
+ session_id: sessionId,
886
+ });
887
+ p.resolve(false);
888
+ return;
889
+ }
741
890
  pendingApprovals.delete(id);
742
891
  clearTimeout(p.timer);
743
892
  emit({
@@ -752,12 +901,22 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
752
901
  const interactiveConfirm = (ctx = {}) =>
753
902
  new Promise((resolve) => {
754
903
  const id = `appr-${++approvalSeq}`;
904
+ // Bind this approval request to the exact call it authorizes: the request
905
+ // id, its normalized arguments, and the policy/rule in force. The digest
906
+ // rides on `approval_request` so a UI/relay can echo it back on approve,
907
+ // letting settleApproval reject a verdict meant for a different call.
908
+ const binding = approvalBindingDigest({
909
+ toolCallId: id,
910
+ args:
911
+ ctx.args ?? (ctx.command != null ? { command: ctx.command } : null),
912
+ policyDigest: ctx.rule || ctx.riskLevel || ctx.risk || null,
913
+ });
755
914
  const timer = setTimeout(
756
915
  () => settleApproval(id, false, "timeout"),
757
916
  approvalTimeoutMs,
758
917
  );
759
918
  timer.unref?.();
760
- pendingApprovals.set(id, { resolve, timer });
919
+ pendingApprovals.set(id, { resolve, timer, binding });
761
920
  emit({
762
921
  type: "approval_request",
763
922
  id,
@@ -767,6 +926,7 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
767
926
  risk: ctx.riskLevel || ctx.risk || null,
768
927
  rule: ctx.rule || null,
769
928
  reason: ctx.reason || null,
929
+ binding,
770
930
  });
771
931
  });
772
932
 
@@ -961,11 +1121,31 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
961
1121
  emit({
962
1122
  type: "system",
963
1123
  subtype: "init",
1124
+ // Deterministic-headless manifest (gap-analysis 2026-07-11): protocol
1125
+ // version + persistence + live sources + policy/tool digests. The init
1126
+ // event fires BEFORE MCP resolution here (stream consumers expect it
1127
+ // promptly), so `mcp` in loaded_sources reflects the run's MCP intent
1128
+ // (config file / registry auto-connect enabled), not connection outcome.
1129
+ protocol_version: STREAM_PROTOCOL_VERSION,
964
1130
  session_id: sessionId,
1131
+ session_persistence: persist,
965
1132
  model,
966
1133
  provider,
967
1134
  permission_mode: options.permissionMode || "default",
968
1135
  tools: enabledToolNames,
1136
+ tools_hash: computeToolsHash(enabledToolNames),
1137
+ policy_digest: computePolicyDigest({
1138
+ permissionMode: options.permissionMode,
1139
+ allowedTools: options.allowedTools,
1140
+ disallowedTools: disabledTools,
1141
+ permissionRules,
1142
+ }),
1143
+ loaded_sources: buildLoadedSources({
1144
+ permissionRules,
1145
+ settingsHooks,
1146
+ mcp: Boolean(options.mcpConfig) || options.useRegisteredMcp !== false,
1147
+ enabledToolNames,
1148
+ }),
969
1149
  input_format: "stream-json",
970
1150
  additional_directories: additionalDirectories,
971
1151
  resumed_messages: resumedMessages,
@@ -1207,6 +1387,13 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
1207
1387
 
1208
1388
  let turns = 0;
1209
1389
  let sawError = false;
1390
+ // Session-scoped tool-call correlation ids ("tu-<n>", additive protocol-v1
1391
+ // field): one counter across ALL turns so ids never repeat within a session.
1392
+ // Gated by the capability handshake (docs/PROTOCOL.md §1.3): a client that
1393
+ // negotiated tool_use_id off gets undefined (no `id` field emitted).
1394
+ let toolUseCounter = 0;
1395
+ const nextToolUseId = () =>
1396
+ fieldGate.tool_use_id === false ? undefined : `tu-${++toolUseCounter}`;
1210
1397
  // Version-skew notice (friendly reminder): a chat-panel agent process is
1211
1398
  // long-lived, so if cc was updated on disk while it kept running, it's still
1212
1399
  // executing stale in-memory code (a fixed bug then looks "not fixed"). Checked
@@ -1235,6 +1422,30 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
1235
1422
  for await (const line of readJsonLines(input)) {
1236
1423
  const parsed = parseInputEvent(line);
1237
1424
  if (parsed == null) continue;
1425
+ if (parsed.hello) {
1426
+ // Capability handshake (docs/PROTOCOL.md §1.3): negotiate the client's
1427
+ // offer against this CLI's, apply the agreed feature set to the live
1428
+ // field-gate, and echo the result. Never queued (it's out-of-band
1429
+ // control, like interrupt/approval). Incompatible (ok:false) leaves
1430
+ // the gate untouched — the CLI keeps its safe baseline.
1431
+ const negotiated = negotiateProtocol(
1432
+ buildServerOffer(buildAgentCapabilities()),
1433
+ parsed.hello,
1434
+ );
1435
+ applyNegotiationToGate(negotiated, fieldGate);
1436
+ emit({
1437
+ type: "system",
1438
+ subtype: "negotiated",
1439
+ session_id: sessionId,
1440
+ protocol_version: negotiated.agreedVersion,
1441
+ features: negotiated.features,
1442
+ downgraded: negotiated.downgraded,
1443
+ disabled_features: negotiated.disabledFeatures,
1444
+ ok: negotiated.ok,
1445
+ reason: negotiated.reason,
1446
+ });
1447
+ continue;
1448
+ }
1238
1449
  if (parsed.interrupt) {
1239
1450
  currentAbort?.abort();
1240
1451
  continue;
@@ -1245,6 +1456,7 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
1245
1456
  parsed.approval.id,
1246
1457
  parsed.approval.approve,
1247
1458
  parsed.approval.approve ? "user-approve" : "user-deny",
1459
+ parsed.approval.binding,
1248
1460
  );
1249
1461
  continue;
1250
1462
  }
@@ -1707,7 +1919,7 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
1707
1919
  // Resume-degenerate role merge for the first live model call only.
1708
1920
  mergeRoles: mergeRolesThisTurn,
1709
1921
  },
1710
- { runLoop, emit, costBudget },
1922
+ { runLoop, emit, costBudget, nextToolUseId },
1711
1923
  );
1712
1924
  } catch (err) {
1713
1925
  currentAbort = null;
@@ -631,17 +631,48 @@ export async function loadProjectMcp(opts = {}, deps = {}) {
631
631
  if (root) files.push(path.join(root, ".mcp.json"));
632
632
  files.push(path.join(cwd, ".mcp.json"));
633
633
 
634
+ // Fingerprint trust (gap 2026-07-11): the --project-mcp opt-in covers the
635
+ // file as last seen. First use records a sha256; a CHANGED file is refused
636
+ // (fail-closed) until re-trusted via CC_PROJECT_MCP_TRUST=1 or
637
+ // `cc mcp trust-project`. Injectable for tests.
638
+ const trust =
639
+ deps.projectMcpTrust ||
640
+ (await import("../lib/project-mcp-trust.js").catch(() => null));
641
+
634
642
  const servers = {};
635
643
  const seenFiles = [];
636
644
  for (const file of files) {
637
645
  if (!fileExists(file)) continue;
646
+ let content;
638
647
  let raw;
639
648
  try {
640
- raw = JSON.parse(readFile(file));
649
+ content = readFile(file);
650
+ raw = JSON.parse(content);
641
651
  } catch (err) {
642
652
  writeErr(` mcp: ignoring malformed ${file} (${err.message})\n`);
643
653
  continue;
644
654
  }
655
+ if (trust) {
656
+ try {
657
+ const check = trust.checkProjectMcpTrust(file, content);
658
+ if (check.status === "changed") {
659
+ if (trust.projectMcpRetrustRequested(env)) {
660
+ trust.recordProjectMcpTrust(file, content);
661
+ writeErr(` mcp: ${file} re-trusted (CC_PROJECT_MCP_TRUST).\n`);
662
+ } else {
663
+ writeErr(
664
+ ` mcp: SKIPPING ${file} — its content changed since it was last trusted. ` +
665
+ `Review the diff, then re-trust with CC_PROJECT_MCP_TRUST=1 or \`cc mcp trust-project\`.\n`,
666
+ );
667
+ continue;
668
+ }
669
+ } else if (check.status === "first-use") {
670
+ trust.recordProjectMcpTrust(file, content);
671
+ }
672
+ } catch {
673
+ /* trust bookkeeping is best-effort; the opt-in gate above still holds */
674
+ }
675
+ }
645
676
  const parsed = parseMcpServers(raw);
646
677
  if (Object.keys(parsed).length > 0) {
647
678
  Object.assign(servers, parsed); // later file (cwd) overrides earlier (root)
@@ -70,6 +70,9 @@ export function composeSystemPrompt(base, opts = {}) {
70
70
  cwd,
71
71
  home: opts.projectMemoryHome,
72
72
  deps: opts.projectMemoryDeps,
73
+ // Large-monorepo reduction lever: subtrees whose instruction/rule/@import
74
+ // files never load (config `instructionExcludes`, forwarded by the caller).
75
+ instructionExcludes: opts.instructionExcludes,
73
76
  });
74
77
  if (block) result = result ? `${result}\n\n${block}` : block;
75
78
  }
@@ -38,6 +38,12 @@ let lastExit = { code: 0, signal: null };
38
38
  let transportState = null;
39
39
  const promptQueue = [];
40
40
 
41
+ // Backpressure (Gap 4): an attached client can push prompts faster than
42
+ // turns drain — an unbounded queue grows without limit and every entry is a
43
+ // future agent turn. Past the cap the prompt is REJECTED (the transport
44
+ // relays the throw as {type:"error", message}) instead of silently queued.
45
+ const MAX_PROMPT_QUEUE = 100;
46
+
41
47
  function mergeState(patch) {
42
48
  const current = readBackgroundAgentState(job.id) || { id: job.id };
43
49
  const next = { ...current, id: job.id, ...patch };
@@ -109,12 +115,20 @@ function startTurn(argv, promptText) {
109
115
  env: { ...process.env, CC_BACKGROUND_AGENT_ID: job.id },
110
116
  stdio: ["ignore", log.fd, log.fd],
111
117
  windowsHide: true,
118
+ // POSIX: give the agent child its own process group so an orphan reclaim
119
+ // (worker crashed → supervisor kills the recorded agentPid) or /stop can
120
+ // signal the WHOLE agent tree via -pid. Windows reaps via taskkill /T.
121
+ detached: process.platform !== "win32",
112
122
  });
113
123
  mergeState({
114
124
  status: "running",
115
125
  phase,
116
126
  turnCount,
117
127
  agentPid: child.pid,
128
+ // Identity anchor for the supervisor's orphan reclaim (Gap 2): pairs
129
+ // with agentPid the way startedAt pairs with the worker pid, so a
130
+ // pid-reusing stranger is never killed in the worker's name.
131
+ agentStartedAt: Date.now(),
118
132
  heartbeatAt: Date.now(),
119
133
  });
120
134
  server?.broadcast({
@@ -150,7 +164,12 @@ function maybeContinue() {
150
164
  }
151
165
  if (server && server.clientCount() > 0) {
152
166
  phase = "idle";
153
- mergeState({ phase, agentPid: null, heartbeatAt: Date.now() });
167
+ mergeState({
168
+ phase,
169
+ agentPid: null,
170
+ agentStartedAt: null,
171
+ heartbeatAt: Date.now(),
172
+ });
154
173
  server.broadcast({ type: "idle", turn: turnCount });
155
174
  return;
156
175
  }
@@ -188,13 +207,29 @@ async function main() {
188
207
  "this session was launched without follow-up support — start a new one with cc agent --bg",
189
208
  );
190
209
  }
210
+ if (promptQueue.length >= MAX_PROMPT_QUEUE) {
211
+ throw new Error(
212
+ `prompt queue full (${MAX_PROMPT_QUEUE} pending) — wait for queued turns to drain before sending more`,
213
+ );
214
+ }
191
215
  promptQueue.push(text);
192
216
  const queued = promptQueue.length;
193
217
  if (!child) maybeContinue();
194
218
  return { queued };
195
219
  },
196
220
  onStop: () => {
197
- child?.kill("SIGTERM");
221
+ if (!child) return;
222
+ if (process.platform !== "win32") {
223
+ // The agent child is detached into its own group — signal the
224
+ // whole tree, not just the top-level CLI process.
225
+ try {
226
+ process.kill(-child.pid, "SIGTERM");
227
+ } catch {
228
+ child.kill("SIGTERM");
229
+ }
230
+ } else {
231
+ child.kill("SIGTERM");
232
+ }
198
233
  },
199
234
  onClientChange: (count) => {
200
235
  // Last client detached while the session is idle → nothing left to
@@ -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-Cod97Urs.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-o6vTWF/repo/packages/web-panel/src/components/MarkdownRenderer.vue"]]);export{w as M};
@@ -1 +0,0 @@
1
- import{I as w,P as l,J as u,U as s,R as n,c as i,K as v,Q as _,V as g,b as o}from"./vendor-Bn1JzzAn.js";import{_ as S}from"./index-Cod97Urs.js";import"./icons-DG5UD-6K.js";const k={__name:"OrderTableRenderer",props:{event:{type:Object,required:!0}},setup(p,{expose:r}){r();const a=p,e=o(()=>a.event.content||{}),d=o(()=>a.event.extra||{}),m=o(()=>d.value.merchant||e.value.merchant||e.value.counterparty||"—"),c=o(()=>e.value.title||e.value.name||e.value.itemName||e.value.text||"—"),y=o(()=>{const t=e.value.amount??e.value.price??e.value.total;return t==null?"—":`${e.value.currency||"¥"} ${typeof t=="number"?t.toFixed(2):t}`}),T=o(()=>d.value.orderNo||e.value.orderNo||e.value.orderId),f=o(()=>e.value.status||e.value.state),b=o(()=>{const t=(f.value||"").toLowerCase();return t.includes("成功")||t.includes("succe")||t.includes("paid")?"green":t.includes("退")||t.includes("refund")?"orange":t.includes("失败")||t.includes("fail")?"red":"default"}),h=o(()=>{if(!a.event.occurredAt)return"";const t=new Date(a.event.occurredAt);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`}),x={props:a,c:e,e:d,merchantText:m,itemText:c,amountText:y,orderNo:T,statusText:f,statusColor:b,formattedTime:h,computed:o};return Object.defineProperty(x,"__isScriptSetup",{enumerable:!1,value:!0}),x}},N={class:"order-card"},C={class:"head"},O={class:"time"},V={class:"row"},R={class:"val"},B={class:"row"},D={class:"val"},F={class:"row amount-row"},I={class:"val amount"},j={key:0,class:"row"},A={class:"val mono"},M={key:1,class:"row"};function P(p,r,a,e,d,m){const c=w("a-tag");return l(),u("div",N,[s("div",C,[s("span",O,n(e.formattedTime),1),i(c,{color:"gold"},{default:v(()=>[_(n(a.event.source.adapter),1)]),_:1}),i(c,null,{default:v(()=>[_(n(a.event.subtype),1)]),_:1})]),s("div",V,[r[0]||(r[0]=s("span",{class:"key"},"商户",-1)),s("span",R,n(e.merchantText),1)]),s("div",B,[r[1]||(r[1]=s("span",{class:"key"},"商品/项目",-1)),s("span",D,n(e.itemText),1)]),s("div",F,[r[2]||(r[2]=s("span",{class:"key"},"金额",-1)),s("span",I,n(e.amountText),1)]),e.orderNo?(l(),u("div",j,[r[3]||(r[3]=s("span",{class:"key"},"单号",-1)),s("span",A,n(e.orderNo),1)])):g("v-if",!0),e.statusText?(l(),u("div",M,[r[4]||(r[4]=s("span",{class:"key"},"状态",-1)),i(c,{color:e.statusColor},{default:v(()=>[_(n(e.statusText),1)]),_:1},8,["color"])])):g("v-if",!0)])}const K=S(k,[["render",P],["__scopeId","data-v-5ed5524d"],["__file","/tmp/cc-web-panel-o6vTWF/repo/packages/web-panel/src/components/pdh/renderers/OrderTableRenderer.vue"]]);export{K 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-Cod97Urs.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 B=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(){B.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{B.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 T(){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),q=u(""),Y=u(!1);function ue(){j.value={path:"",content:""},b.value=!0}function ce(){R.value={path:""},A.value=!0}async function N(){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 N(),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 N(),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 N(),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,q.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:q.value},`project write-file ${c.value.id} --json`,8e3))?.id?(d.success("已保存"),n.value=!1,await N()):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:B,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:T,createFileOpen:b,creatingFile:D,newFile:j,createFolderOpen:A,creatingFolder:m,newFolder:R,editFileOpen:n,editingFile:c,editFileContent:q,savingFile:Y,openCreateFile:ue,openCreateFolder:ce,refreshFiles:N,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},Te={key:1,style:{color:"#888"}},Be=["onClick"],Ee={key:0,style:{color:"#888","font-size":"12px"}};function Le(se,l,te,e,W,w){const B=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"),T=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(B,{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:q=>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:q=>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",Te,"(无)"))]),_: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,Be)]),_: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(T,{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(T,{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(T,{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(T,{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-o6vTWF/repo/packages/web-panel/src/views/Projects.vue"]]);export{We as default};
@@ -1 +0,0 @@
1
- import{Q as r}from"./index-Cod97Urs.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-DP6Pcu3m.js";import{a0 as t}from"./index-Cod97Urs.js";import"./vendor-Bn1JzzAn.js";import"./responsiveObserve-dG4EzUQo.js";import"./useFlexGapSupport-BWfna_rd.js";import"./styleChecker-D6kP-mMK.js";import"./index-Bbc2JeQG.js";import"./icons-DG5UD-6K.js";const l=t(o);export{l as default};
@@ -1 +0,0 @@
1
- import{C as o}from"./Col-voPJ9fUZ.js";import{a0 as t}from"./index-Cod97Urs.js";import"./vendor-Bn1JzzAn.js";import"./index-Bbc2JeQG.js";import"./icons-DG5UD-6K.js";const s=t(o);export{s as default};