chainlesschain 0.162.151 → 0.162.153

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 (187) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/src/assets/web-panel/.build-hash +1 -1
  4. package/src/assets/web-panel/assets/{AIOps-DuEOzebi.js → AIOps-CBilhs1R.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-C6GiJa5H.js → ActionButton-Cf-RnC5Y.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-BBIiL_pO.js → Analytics-S8tkGhw0.js} +3 -3
  7. package/src/assets/web-panel/assets/{AppLayout-CuI2gZRy.js → AppLayout-CNXI3Bw5.js} +5 -5
  8. package/src/assets/web-panel/assets/{Audit-CbUjfr-K.js → Audit-DF2zVFZ0.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-CsSW9ljf.js → Backup-CMEiwQZL.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-kM3rLe7F.js → BaseInput-rwLw4K70.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-kfE51YN3.js → Chat-C478H8u9.js} +5 -5
  12. package/src/assets/web-panel/assets/ChatBubbleRenderer-DNQsKN61.js +1 -0
  13. package/src/assets/web-panel/assets/{Checkbox-jYb1uj-M.js → Checkbox-D-47X635.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-X9XiD5Lj.js → Codegen-Cb9Ihed5.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-BfbHu1xI.js → Col-CQsdzczt.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-c4oJMFS-.js → Community-DiqzeAy-.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-BFmnZpH7.js → Compact-Bq-APyyF.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-s9shVHBS.js → Compliance-Dnb1YxPr.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-C5da--TC.js → Cowork-CZljerdQ.js} +3 -3
  20. package/src/assets/web-panel/assets/{Cron-9kNbyNE4.js → Cron-gAdbZOq7.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-C1k3NJD4.js → Crosschain-DMPGXttD.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-DkheEvNK.js → DID-C7dBDAv8.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-C3FuSGmJ.js → Dashboard-ByR4VcF8.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-CAV6FMFD.js → Dropdown-Bc4tbiQN.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-Cc-Ulc4l.js → EmailListRenderer-BhUN2pDw.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-8CitHEtv.js → FamilyGuardDashboard-DpJuANCD.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-DFSZ5KDt.js → Federation-BEm4TvcE.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-CEWCtnG2.js → FormItemContext-JnkPkhiC.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-CwRzNzmX.js → GenericCardRenderer-BfCzFUIC.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-0rgDM7cJ.js → Git-1c0MWpmD.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-CfBKtK9F.js → Governance-C_j3EBpv.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-CzcUVvud.js → Inference-Cb7XRgtY.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-Dwc4YL4A.js → KnowledgeGraph-DoHPvHyK.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-DgFPwR2F.js → Logs-CYriKpy-.js} +2 -2
  35. package/src/assets/web-panel/assets/{Marketplace-DnpPTbGU.js → Marketplace-BT56-GD0.js} +1 -1
  36. package/src/assets/web-panel/assets/{McpTools-DRxxINyW.js → McpTools-B6XX_wnZ.js} +4 -4
  37. package/src/assets/web-panel/assets/{Memory-OhmW_6Z3.js → Memory-DRgNuaQc.js} +2 -2
  38. package/src/assets/web-panel/assets/{MobileBridge-DkTW-RK5.js → MobileBridge-B0qgvBN2.js} +1 -1
  39. package/src/assets/web-panel/assets/MobileProjects-CRRfswf7.js +1 -0
  40. package/src/assets/web-panel/assets/{Mtc--vmkL0AS.js → Mtc-DnSFj9jw.js} +4 -4
  41. package/src/assets/web-panel/assets/{MtcAudit-DGoFWjD4.js → MtcAudit-c0tuz1sm.js} +4 -4
  42. package/src/assets/web-panel/assets/{Multisig-B4kWgq95.js → Multisig-CVLBGioX.js} +3 -3
  43. package/src/assets/web-panel/assets/{NLProgramming-YQwvommE.js → NLProgramming-CFaqmNbx.js} +1 -1
  44. package/src/assets/web-panel/assets/{Notes-CgjtUADJ.js → Notes-BM_mNwU_.js} +3 -3
  45. package/src/assets/web-panel/assets/{NotificationSettings-6JDrpBG5.js → NotificationSettings-Sa1k3ReS.js} +1 -1
  46. package/src/assets/web-panel/assets/OrderTableRenderer-lWzmtqBh.js +1 -0
  47. package/src/assets/web-panel/assets/{Organization-8McOT_OF.js → Organization-C2blcq-P.js} +4 -4
  48. package/src/assets/web-panel/assets/{Overflow-DAZpSCGc.js → Overflow-B3PwOJnK.js} +1 -1
  49. package/src/assets/web-panel/assets/{P2P-B7l2ZWLy.js → P2P-DaB9T6tb.js} +2 -2
  50. package/src/assets/web-panel/assets/{PdhVaultBrowser-W1Ud-NAL.js → PdhVaultBrowser-BpEBZ72n.js} +5 -5
  51. package/src/assets/web-panel/assets/{Permissions-Czm_w9u_.js → Permissions-BTkWInyH.js} +4 -4
  52. package/src/assets/web-panel/assets/{PersonalDataHub-B4F0_ZVM.js → PersonalDataHub-LHEwNmyL.js} +2 -2
  53. package/src/assets/web-panel/assets/{Pipeline-B37aFiWv.js → Pipeline-DvWIxqH-.js} +1 -1
  54. package/src/assets/web-panel/assets/{Privacy-94KBnRrD.js → Privacy-BDbpBagU.js} +1 -1
  55. package/src/assets/web-panel/assets/{ProjectInit-B5h8_dlh.js → ProjectInit-DLeMDWWv.js} +2 -2
  56. package/src/assets/web-panel/assets/ProjectSettings-BK3NsxIz.js +2 -0
  57. package/src/assets/web-panel/assets/Projects-BPWPg9zA.js +1 -0
  58. package/src/assets/web-panel/assets/{Providers-B3cNWwJg.js → Providers-D2EvmPAd.js} +1 -1
  59. package/src/assets/web-panel/assets/{QrScannerModal-CHRvOw1R.js → QrScannerModal-DAcu2fNg.js} +1 -1
  60. package/src/assets/web-panel/assets/{QuickAsk-D1JMgFEd.js → QuickAsk-B7U850Yt.js} +1 -1
  61. package/src/assets/web-panel/assets/{Recommend-EYWGR79p.js → Recommend-bxNXLzOR.js} +1 -1
  62. package/src/assets/web-panel/assets/{RemoteSession-BAMC2pJt.js → RemoteSession-BsCjAfSJ.js} +2 -2
  63. package/src/assets/web-panel/assets/{Reputation-X2Hk1XG_.js → Reputation-DZ9LPu-R.js} +1 -1
  64. package/src/assets/web-panel/assets/{Row-Eq98LRtU.js → Row-cIYkCB3Y.js} +1 -1
  65. package/src/assets/web-panel/assets/{RssFeed-i76s6z_o.js → RssFeed-BxTNTtTp.js} +2 -2
  66. package/src/assets/web-panel/assets/{Search-D_Es7CAI.js → Search-DSar6GhE.js} +1 -1
  67. package/src/assets/web-panel/assets/{Security-kayD2e94.js → Security-oCbIGysL.js} +4 -4
  68. package/src/assets/web-panel/assets/{Services-Ctsm6ul8.js → Services-D8yojrNv.js} +2 -2
  69. package/src/assets/web-panel/assets/{Skeleton-CRNYlfdf.js → Skeleton-vTA6P1eL.js} +1 -1
  70. package/src/assets/web-panel/assets/{Skills-DkZYpF4-.js → Skills-BXLf_KgZ.js} +1 -1
  71. package/src/assets/web-panel/assets/{Sla-DXkoBcOP.js → Sla-Cpwxzz__.js} +1 -1
  72. package/src/assets/web-panel/assets/{SpeechSettings-DXi_GI1d.js → SpeechSettings-DcPN9kCb.js} +1 -1
  73. package/src/assets/web-panel/assets/{SyncSettings-rNKpfomn.js → SyncSettings-DY0U5Vuj.js} +2 -2
  74. package/src/assets/web-panel/assets/{Tasks-XF4uPtG-.js → Tasks-DKu3-sZJ.js} +1 -1
  75. package/src/assets/web-panel/assets/{Templates-i0Hzfeyu.js → Templates-MD3nfWGm.js} +1 -1
  76. package/src/assets/web-panel/assets/{Tenant-sMpHAi27.js → Tenant-DKVnyGXM.js} +1 -1
  77. package/src/assets/web-panel/assets/Terminal-DQMIZfWf.js +3 -0
  78. package/src/assets/web-panel/assets/{TimelineRenderer-yuC6K7Rf.js → TimelineRenderer-CugmNZTs.js} +1 -1
  79. package/src/assets/web-panel/assets/{Tokens-B8O8i0s6.js → Tokens-Cjvlttu6.js} +1 -1
  80. package/src/assets/web-panel/assets/{Trigger-Bv6yrlCr.js → Trigger-CzNOEcoI.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trust-C4mW95Ev.js → Trust-D5jg9iPA.js} +1 -1
  82. package/src/assets/web-panel/assets/{UkeySign-DV6yKaHn.js → UkeySign-59bMlvxY.js} +1 -1
  83. package/src/assets/web-panel/assets/{VideoEditing-UI479-sD.js → VideoEditing-DmCzSBqn.js} +1 -1
  84. package/src/assets/web-panel/assets/{Wallet-M5oV9EVP.js → Wallet-DoFe8V6W.js} +4 -4
  85. package/src/assets/web-panel/assets/{WebAuthn-DDyDHPDR.js → WebAuthn-9POLER-w.js} +5 -5
  86. package/src/assets/web-panel/assets/{WorkflowEditor-RoBv4rqk.js → WorkflowEditor-cFQH0Og6.js} +1 -1
  87. package/src/assets/web-panel/assets/{chat-Cw1mE5LS.js → chat-D3fR2NkZ.js} +1 -1
  88. package/src/assets/web-panel/assets/{colors-BFP62Gwf.js → colors-DiLEwE_P.js} +1 -1
  89. package/src/assets/web-panel/assets/{compact-item-17HL6pyC.js → compact-item-CGfFDdic.js} +1 -1
  90. package/src/assets/web-panel/assets/{createContext-D55X4fZX.js → createContext-BbIbOPL2.js} +1 -1
  91. package/src/assets/web-panel/assets/devWarning-B6FRgsmP.js +1 -0
  92. package/src/assets/web-panel/assets/{hasIn-D3E5mNsP.js → hasIn-DqyWp63_.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-DOjA8bvj.js → index-BCoDp6o_.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-tVRPgYGr.js → index-BKeRBUtO.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-RYZgFIwo.js → index-BKxvHCqz.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-Da27u6j0.js → index-BiLP6SNu.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-CFYGn88j.js → index-BtcjYHgn.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-paVubXzn.js → index-BtwvOuvO.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-D4LHSde4.js → index-ByE5tKjP.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-C_MfcrLf.js → index-C1S30j-Z.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DkBVYlE4.js → index-C2lZXIEA.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-ITeEHb8L.js → index-CH8gSMSA.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BC6zxOlU.js → index-CHpI6g_S.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-KtLJXn4s.js → index-CIleIMTT.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BY_xZ2jy.js → index-CToOzfR2.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-Bzpp2z2S.js → index-CZQshOyI.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-CvCFKojj.js → index-ComvO4hy.js} +1 -1
  108. package/src/assets/web-panel/assets/index-Cq411qtc.js +1 -0
  109. package/src/assets/web-panel/assets/{index-tUH_6bdJ.js → index-CweXQM71.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-Cdvk2_2q.js → index-CySlHabI.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-gAVxDiTZ.js → index-D16FSRMW.js} +1 -1
  112. package/src/assets/web-panel/assets/index-D1oX0DK3.js +1 -0
  113. package/src/assets/web-panel/assets/{index-CLEzsZ8A.js → index-D3vQv3Kq.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-BEa1RW4c.js → index-DH6qaU1a.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-BQmZg5si.js → index-DPxmTldu.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-ASPYTzMK.js → index-DQH--Uw5.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-uSsiwgZ2.js → index-Db9UJVjj.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CR9rNUvi.js → index-DdLwxj-F.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-Bq83UBDr.js → index-DdjXemK-.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-H9_X1Cg_.js → index-DzuGkFvy.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DD_qGBrt.js → index-FFlp8Jx9.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-BnGpft-Z.js → index-Km36XQ3z.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CjCwi7we.js → index-auI9fxYH.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DzG7mkgW.js → index-fCfaVIr7.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DtAnPBWP.js → index-hVGbmc7y.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DCLu84x-.js → index-kL8f4MRS.js} +1 -1
  127. package/src/assets/web-panel/assets/{index--44J50mc.js → index-ns6bNnGo.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CW6LLoJO.js → index-qHvMk0U3.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DIRvdwBX.js → index-rTrejDjk.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CGyTos4p.js → index-tLaW5UzZ.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-BgN5G5vF.js → index-xm1KHUEQ.js} +27 -27
  132. package/src/assets/web-panel/assets/{initDefaultProps-Ckp7xVZS.js → initDefaultProps-pg_7pnd6.js} +1 -1
  133. package/src/assets/web-panel/assets/{motion-DUZgCpn6.js → motion-B5GoJSZL.js} +1 -1
  134. package/src/assets/web-panel/assets/{move-B2rttglH.js → move-BaJoe2FW.js} +1 -1
  135. package/src/assets/web-panel/assets/{mtc-parser-BYWcLTuN.js → mtc-parser-CiQGbqtr.js} +1 -1
  136. package/src/assets/web-panel/assets/{omit-DhHqKeFx.js → omit-BFNEsKvU.js} +1 -1
  137. package/src/assets/web-panel/assets/{pickAttrs-ANpJaWMO.js → pickAttrs-YbSoANHm.js} +1 -1
  138. package/src/assets/web-panel/assets/{placementArrow-CfZWe7CA.js → placementArrow-C40MJPIH.js} +1 -1
  139. package/src/assets/web-panel/assets/{responsiveObserve-D7Xz2y-R.js → responsiveObserve-LaVz2zF6.js} +1 -1
  140. package/src/assets/web-panel/assets/{slide-DekqCBY9.js → slide-BkSoAGxF.js} +1 -1
  141. package/src/assets/web-panel/assets/{statusUtils-BET6XU7h.js → statusUtils-C4jWjohA.js} +1 -1
  142. package/src/assets/web-panel/assets/{styleChecker-qHmJjV62.js → styleChecker-BGqeIh-m.js} +1 -1
  143. package/src/assets/web-panel/assets/{useFlexGapSupport-BoMCTNyu.js → useFlexGapSupport-JsR5NMrM.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFs-TdW-NgFC.js → useFs-DOiP38RR.js} +1 -1
  145. package/src/assets/web-panel/assets/{usePersonalDataHub-Dyox7wCu.js → usePersonalDataHub-C-nC0ymt.js} +1 -1
  146. package/src/assets/web-panel/assets/{vnode-XUn5S8CP.js → vnode-BalilHOU.js} +1 -1
  147. package/src/assets/web-panel/assets/{zoom-Ls77i8hn.js → zoom-DjUELqks.js} +1 -1
  148. package/src/assets/web-panel/index.html +1 -1
  149. package/src/commands/agent.js +8 -1
  150. package/src/commands/eval.js +88 -23
  151. package/src/commands/plugin.js +10 -0
  152. package/src/commands/team.js +60 -3
  153. package/src/data/changelog.json +17 -2
  154. package/src/harness/mcp-client.js +115 -1
  155. package/src/harness/remote-command-ledger.js +60 -10
  156. package/src/lib/agent-sandbox.js +11 -5
  157. package/src/lib/agent-team/task-lease.js +28 -0
  158. package/src/lib/agent-team/team-runner.js +45 -0
  159. package/src/lib/config-manager.js +14 -1
  160. package/src/lib/eval/tasks.js +62 -41
  161. package/src/lib/eval/trend.js +7 -1
  162. package/src/lib/lsp/__tests__/lsp-client.test.js +12 -6
  163. package/src/lib/lsp/code-intelligence.js +55 -17
  164. package/src/lib/lsp/lsp-client.js +7 -1
  165. package/src/lib/plugin-runtime/install.js +20 -1
  166. package/src/lib/plugin-runtime/policy.js +13 -0
  167. package/src/lib/plugin-runtime/remote-source.js +34 -0
  168. package/src/lib/plugin-runtime/signature.js +79 -22
  169. package/src/lib/plugin-security.js +13 -14
  170. package/src/lib/sub-agent-context.js +28 -7
  171. package/src/lib/telemetry/span-recorder.js +30 -7
  172. package/src/repl/agent-repl.js +64 -21
  173. package/src/repl/permission-prompt.js +58 -0
  174. package/src/runtime/__tests__/auto-pin.test.js +27 -4
  175. package/src/runtime/agent-core.js +236 -1
  176. package/src/runtime/auto-pin.js +19 -0
  177. package/src/runtime/coding-agent-contract-shared.cjs +5 -0
  178. package/src/runtime/headless-runner.js +23 -5
  179. package/src/assets/web-panel/assets/ChatBubbleRenderer-Bg2FTW6A.js +0 -1
  180. package/src/assets/web-panel/assets/MobileProjects-DpCGV_lI.js +0 -1
  181. package/src/assets/web-panel/assets/OrderTableRenderer-PM6IlxjO.js +0 -1
  182. package/src/assets/web-panel/assets/ProjectSettings-lmeI3Lpm.js +0 -2
  183. package/src/assets/web-panel/assets/Projects-D5AYOasl.js +0 -1
  184. package/src/assets/web-panel/assets/Terminal-BoZvaYAl.js +0 -3
  185. package/src/assets/web-panel/assets/devWarning-CqbHYuRc.js +0 -1
  186. package/src/assets/web-panel/assets/index-CKBI1U5K.js +0 -1
  187. package/src/assets/web-panel/assets/index-CkLp6DTO.js +0 -1
@@ -1443,6 +1443,8 @@ export async function executeTool(name, args, context = {}) {
1443
1443
  subAgentBudget: context.subAgentBudget || null,
1444
1444
  interactiveApproval: context.interactiveApproval || false,
1445
1445
  settingsHooks: context.settingsHooks || null,
1446
+ signal: context.signal || null,
1447
+ backgroundSubAgents: context.backgroundSubAgents || null,
1446
1448
  });
1447
1449
  } catch (err) {
1448
1450
  if (hookDb) {
@@ -1541,7 +1543,10 @@ export async function executeTool(name, args, context = {}) {
1541
1543
  name === "spawn_sub_agent" &&
1542
1544
  context.settingsHooks &&
1543
1545
  toolResult &&
1544
- typeof toolResult === "object"
1546
+ typeof toolResult === "object" &&
1547
+ // Background spawns return a "running" handle here — their SubagentStop
1548
+ // fires later, when the RESULT is drained into the conversation.
1549
+ !(toolResult.background === true && toolResult.status === "running")
1545
1550
  ) {
1546
1551
  try {
1547
1552
  const outcome = runObserveHooks(
@@ -2056,6 +2061,8 @@ async function executeToolInner(
2056
2061
  subAgentBudget = null,
2057
2062
  interactiveApproval = false,
2058
2063
  settingsHooks = null,
2064
+ signal = null,
2065
+ backgroundSubAgents = null,
2059
2066
  },
2060
2067
  ) {
2061
2068
  const localToolDescriptor =
@@ -2777,6 +2784,8 @@ async function executeToolInner(
2777
2784
  subAgentDepth,
2778
2785
  subAgentBudget,
2779
2786
  settingsHooks,
2787
+ signal,
2788
+ backgroundSubAgents,
2780
2789
  }),
2781
2790
  );
2782
2791
  }
@@ -3703,6 +3712,46 @@ export function safeStringifyToolResult(value) {
3703
3712
  * @param {object} ctx - { skillLoader, cwd, parentMessages, interaction, sessionId }
3704
3713
  * @returns {Promise<object>}
3705
3714
  */
3715
+ /**
3716
+ * Remove and return every SETTLED background sub-agent entry from the run's
3717
+ * map. Called by agentLoop before each LLM call (deliver fresh results) and
3718
+ * after the end-of-run wait (deliver stragglers).
3719
+ */
3720
+ function _takeSettledBackgroundSubAgents(map) {
3721
+ const done = [];
3722
+ for (const [id, entry] of map) {
3723
+ if (entry.settled) {
3724
+ done.push(entry);
3725
+ map.delete(id);
3726
+ }
3727
+ }
3728
+ return done;
3729
+ }
3730
+
3731
+ /**
3732
+ * Render a settled background sub-agent's outcome as the user-role message
3733
+ * injected into the parent conversation (the only channel that reaches the
3734
+ * model between turns — there is no open tool_call to attach a result to).
3735
+ */
3736
+ function _backgroundSubAgentResultText(entry) {
3737
+ const o = entry.outcome || {};
3738
+ const status = o.error ? "FAILED" : "completed";
3739
+ const summary =
3740
+ (o.result && o.result.summary) || o.error || "(no output from sub-agent)";
3741
+ const tools =
3742
+ o.result && Array.isArray(o.result.toolsUsed) && o.result.toolsUsed.length
3743
+ ? `\nTools used: ${o.result.toolsUsed.join(", ")}`
3744
+ : "";
3745
+ const feedback = entry.hookFeedback
3746
+ ? `\nHook feedback: ${entry.hookFeedback}`
3747
+ : "";
3748
+ return (
3749
+ `[Background sub-agent "${entry.role}" (${entry.id}) ${status}]\n` +
3750
+ `Task: ${entry.task}\n` +
3751
+ `Result:\n${summary}${tools}${feedback}`
3752
+ );
3753
+ }
3754
+
3706
3755
  async function _executeSpawnSubAgent(args, ctx) {
3707
3756
  // Nesting cap: refuse before any context/registry work.
3708
3757
  const currentDepth = ctx.subAgentDepth || 0;
@@ -3897,6 +3946,88 @@ async function _executeSpawnSubAgent(args, ctx) {
3897
3946
  }
3898
3947
  }
3899
3948
 
3949
+ // ── Background mode (Claude-Code 2.1.198 parity) ────────────────────────
3950
+ // Return a running handle immediately; the parent loop keeps working and
3951
+ // drains the result into the conversation when it settles (agentLoop also
3952
+ // refuses to finish while any background sub-agent is still running). Only
3953
+ // available when the calling loop provided the per-run map — a bare
3954
+ // executeTool() without it falls through to the blocking path.
3955
+ if (args.background === true && ctx.backgroundSubAgents instanceof Map) {
3956
+ // Cancel with the parent: forward the loop's abort signal so killing the
3957
+ // run doesn't orphan a detached child mid-LLM-call.
3958
+ subCtx._signal = subCtx._signal || ctx.signal || null;
3959
+ if (registry) {
3960
+ try {
3961
+ registry.register(subCtx);
3962
+ } catch (_err) {
3963
+ // Registry not available — non-critical
3964
+ }
3965
+ }
3966
+ emit("sub-agent.started", {
3967
+ task: subCtx.task,
3968
+ background: true,
3969
+ allowedTools: allowedTools || null,
3970
+ maxIterations: subCtx.maxIterations,
3971
+ createdAt: subCtx.createdAt,
3972
+ });
3973
+ const entry = {
3974
+ id: subCtx.id,
3975
+ role: subCtx.role,
3976
+ task: subCtx.task,
3977
+ settled: false,
3978
+ outcome: null,
3979
+ hookFeedback: null,
3980
+ promise: null,
3981
+ };
3982
+ // Settle-capture wrapper: the stored promise NEVER rejects, so an
3983
+ // unconsumed handle can't surface as an unhandled rejection.
3984
+ entry.promise = subCtx
3985
+ .run(task)
3986
+ .then(
3987
+ (result) => ({ result, error: null }),
3988
+ (err) => {
3989
+ subCtx.forceComplete(err.message);
3990
+ return { result: subCtx.result, error: err.message };
3991
+ },
3992
+ )
3993
+ .then((outcome) => {
3994
+ entry.settled = true;
3995
+ entry.outcome = outcome;
3996
+ if (registry) {
3997
+ try {
3998
+ registry.complete(subCtx.id, outcome.result);
3999
+ } catch (_err) {
4000
+ // Non-critical
4001
+ }
4002
+ }
4003
+ emit(outcome.error ? "sub-agent.failed" : "sub-agent.completed", {
4004
+ status: subCtx.status,
4005
+ background: true,
4006
+ ...(outcome.error
4007
+ ? { error: outcome.error }
4008
+ : {
4009
+ summary: outcome.result?.summary,
4010
+ toolsUsed: outcome.result?.toolsUsed,
4011
+ iterationCount: outcome.result?.iterationCount,
4012
+ tokenCount: outcome.result?.tokenCount,
4013
+ artifactCount: outcome.result?.artifacts?.length || 0,
4014
+ }),
4015
+ completedAt: subCtx.completedAt,
4016
+ });
4017
+ return outcome;
4018
+ });
4019
+ ctx.backgroundSubAgents.set(subCtx.id, entry);
4020
+ return {
4021
+ success: true,
4022
+ background: true,
4023
+ status: "running",
4024
+ subAgentId: subCtx.id,
4025
+ role: subCtx.role,
4026
+ parentSessionId,
4027
+ note: "Sub-agent is running in the background. Its result will be delivered to you automatically in a later turn — continue with other work; the run will not finish before the result arrives.",
4028
+ };
4029
+ }
4030
+
3900
4031
  try {
3901
4032
  // Notify registry if available
3902
4033
  if (registry) {
@@ -5385,7 +5516,17 @@ export async function* agentLoop(messages, options) {
5385
5516
  spawned: 0,
5386
5517
  max: MAX_SUB_AGENTS_PER_RUN,
5387
5518
  },
5519
+ // Abort signal — forwarded to background sub-agents so cancelling the
5520
+ // parent run also cancels children still running detached.
5521
+ signal,
5522
+ // Background sub-agents spawned THIS loop (spawn_sub_agent background:true).
5523
+ // id → { id, role, task, promise, settled, outcome }. Results are drained
5524
+ // into `messages` before each LLM call; the loop refuses to finish while
5525
+ // any are still running (it waits, injects, and gives the model one more
5526
+ // turn) so a background result can never be silently lost.
5527
+ backgroundSubAgents: new Map(),
5388
5528
  };
5529
+ const backgroundSubAgents = toolContext.backgroundSubAgents;
5389
5530
 
5390
5531
  throwIfAborted(signal);
5391
5532
 
@@ -5490,6 +5631,18 @@ export async function* agentLoop(messages, options) {
5490
5631
  const runId =
5491
5632
  options.runId ||
5492
5633
  `run-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
5634
+ // Workflow-tracing attributes (Claude-Code 2.1.202): stamp the run id (and
5635
+ // an optional caller-provided workflow name) onto EVERY span this run emits,
5636
+ // so a collector can group one run's model/tool spans into one workflow.
5637
+ if (recorder && typeof recorder.setDefaultAttribute === "function") {
5638
+ recorder.setDefaultAttribute("workflow.run_id", runId);
5639
+ if (options.workflowName) {
5640
+ recorder.setDefaultAttribute(
5641
+ "workflow.name",
5642
+ String(options.workflowName),
5643
+ );
5644
+ }
5645
+ }
5493
5646
  yield {
5494
5647
  type: "run-started",
5495
5648
  runId,
@@ -5657,6 +5810,52 @@ export async function* agentLoop(messages, options) {
5657
5810
  }
5658
5811
  }
5659
5812
 
5813
+ // Deliver background sub-agent results that settled since the last turn:
5814
+ // inject them as user-role context so THIS LLM call sees them. (There is
5815
+ // no open tool_call to attach a late result to — the spawn call already
5816
+ // returned its "running" handle.)
5817
+ if (backgroundSubAgents.size > 0) {
5818
+ for (const entry of _takeSettledBackgroundSubAgents(
5819
+ backgroundSubAgents,
5820
+ )) {
5821
+ // SubagentStop fires at RESULT time for background spawns (the
5822
+ // spawn-time handle skips it); a block reason rides along as feedback.
5823
+ if (options.settingsHooks) {
5824
+ try {
5825
+ const outcome = runObserveHooks(
5826
+ options.settingsHooks,
5827
+ "SubagentStop",
5828
+ {
5829
+ stop_hook_active: false,
5830
+ session_id: options.sessionId || null,
5831
+ subagent_response: JSON.stringify(
5832
+ entry.outcome?.result || { error: entry.outcome?.error },
5833
+ ).substring(0, 2000),
5834
+ },
5835
+ { cwd: toolContext.cwd },
5836
+ );
5837
+ if (outcome.decision === "block" && outcome.reason) {
5838
+ entry.hookFeedback = outcome.reason;
5839
+ }
5840
+ } catch (_err) {
5841
+ // SubagentStop hooks are best-effort
5842
+ }
5843
+ }
5844
+ messages.push({
5845
+ role: "user",
5846
+ content: _backgroundSubAgentResultText(entry),
5847
+ });
5848
+ yield {
5849
+ type: "background-sub-agent-result",
5850
+ runId,
5851
+ subAgentId: entry.id,
5852
+ role: entry.role,
5853
+ error: entry.outcome?.error || null,
5854
+ summary: entry.outcome?.result?.summary || null,
5855
+ };
5856
+ }
5857
+ }
5858
+
5660
5859
  // Turn-scoped context injection (open-agents prepareCall parity).
5661
5860
  // prepareCall runs fresh each iteration and returns an ephemeral
5662
5861
  // system-message supplement that is NOT persisted to messages history.
@@ -5736,6 +5935,42 @@ export async function* agentLoop(messages, options) {
5736
5935
  const toolCalls = msg.tool_calls;
5737
5936
 
5738
5937
  if (!toolCalls || toolCalls.length === 0) {
5938
+ // A final answer while background sub-agents are still outstanding is
5939
+ // premature — their results must not be silently lost. Wait for ALL of
5940
+ // them, inject the results, and give the model one more turn to fold
5941
+ // them into its real final answer. The iteration budget is the backstop
5942
+ // if it keeps spawning more.
5943
+ if (backgroundSubAgents.size > 0) {
5944
+ yield {
5945
+ type: "waiting-background-sub-agents",
5946
+ runId,
5947
+ count: backgroundSubAgents.size,
5948
+ };
5949
+ await Promise.all(
5950
+ [...backgroundSubAgents.values()].map((e) => e.promise),
5951
+ );
5952
+ throwIfAborted(signal);
5953
+ messages.push({ role: "assistant", content: msg.content || "" });
5954
+ for (const entry of _takeSettledBackgroundSubAgents(
5955
+ backgroundSubAgents,
5956
+ )) {
5957
+ messages.push({
5958
+ role: "user",
5959
+ content:
5960
+ _backgroundSubAgentResultText(entry) +
5961
+ "\n\nAll background sub-agents have finished. Incorporate their results and give your final answer.",
5962
+ });
5963
+ yield {
5964
+ type: "background-sub-agent-result",
5965
+ runId,
5966
+ subAgentId: entry.id,
5967
+ role: entry.role,
5968
+ error: entry.outcome?.error || null,
5969
+ summary: entry.outcome?.result?.summary || null,
5970
+ };
5971
+ }
5972
+ continue;
5973
+ }
5739
5974
  // Surface the final answer's extended-thinking reasoning (Anthropic, when
5740
5975
  // --think is on) so non-streaming consumers (the REPL) can show it. The
5741
5976
  // streaming path forwards reasoning live via onThinking instead.
@@ -23,6 +23,25 @@
23
23
 
24
24
  const DEFAULT_MAX_PIN_TOKENS = 2000;
25
25
 
26
+ /**
27
+ * Resolve the EFFECTIVE auto-pin setting from (highest precedence first):
28
+ * 1. an explicit CLI flag (`--auto-pin` → force on),
29
+ * 2. the CC_AUTO_PIN env var ("1" on / "0" off),
30
+ * 3. the config value (`context.autoPin`: true | false | {…}),
31
+ * 4. the default — **ON** (product decision 2026-07-07): pinning the
32
+ * original task through compaction costs a bounded slice of context
33
+ * (maxPinTokens, default 2000) but prevents goal drift in long sessions.
34
+ * Opt out with CC_AUTO_PIN=0 or `context.autoPin: false` in config.
35
+ */
36
+ export function resolveAutoPinOption({ flag, env, config } = {}) {
37
+ if (flag === true) return true;
38
+ const e = env !== undefined ? env : process.env.CC_AUTO_PIN;
39
+ if (e === "0") return false;
40
+ if (e === "1") return true;
41
+ if (config !== undefined && config !== null) return config;
42
+ return true;
43
+ }
44
+
26
45
  /**
27
46
  * Normalize the opt-in value into a config object, or null when auto-pin is off.
28
47
  * Accepts: falsy (off), `true` (defaults on), or a config object
@@ -588,6 +588,11 @@ const CODING_AGENT_TOOL_CONTRACTS = Object.freeze([
588
588
  description:
589
589
  "Optional declarative profile (from sub-agent-profiles). When set, seeds systemPrompt / tool allowlist / iteration cap. Explicit `tools` overrides the profile allowlist.",
590
590
  },
591
+ background: {
592
+ type: "boolean",
593
+ description:
594
+ "Run the sub-agent in the BACKGROUND: the call returns immediately with a running handle and you continue working; the sub-agent's result is delivered to you automatically in a later turn (the run waits for stragglers before finishing). Use for independent subtasks you don't need before your next step.",
595
+ },
591
596
  },
592
597
  required: ["task"],
593
598
  },
@@ -890,6 +890,24 @@ export async function runAgentHeadless(options = {}, deps = {}) {
890
890
  }
891
891
  }
892
892
 
893
+ // Resolve auto-pin (flag > env > config > default-on). Config read is
894
+ // best-effort — a broken config file must not take headless down.
895
+ let _autoPinResolved;
896
+ {
897
+ const { resolveAutoPinOption } = await import("./auto-pin.js");
898
+ let _autoPinCfg;
899
+ try {
900
+ const { loadConfig } = await import("../lib/config-manager.js");
901
+ _autoPinCfg = loadConfig()?.context?.autoPin;
902
+ } catch {
903
+ _autoPinCfg = undefined;
904
+ }
905
+ _autoPinResolved = resolveAutoPinOption({
906
+ flag: options.autoPin === true,
907
+ config: _autoPinCfg,
908
+ });
909
+ }
910
+
893
911
  const loopOptions = {
894
912
  model,
895
913
  provider,
@@ -906,11 +924,11 @@ export async function runAgentHeadless(options = {}, deps = {}) {
906
924
  additionalDirectories,
907
925
  sandbox: options.sandbox || null,
908
926
  sessionId,
909
- // Auto-pin (OPT-IN, off by default): pin the original task through
910
- // compaction. Enable via --auto-pin or CC_AUTO_PIN=1. Falsy → agent-core
911
- // passes no pin predicate and compaction is byte-identical.
912
- autoPin:
913
- options.autoPin === true || process.env.CC_AUTO_PIN === "1" || undefined,
927
+ // Auto-pin (default ON since 2026-07-07): pin the original task through
928
+ // compaction. Precedence: --auto-pin flag > CC_AUTO_PIN ("1"/"0") >
929
+ // config context.autoPin > default on. Falsy agent-core passes no pin
930
+ // predicate and compaction is byte-identical.
931
+ autoPin: _autoPinResolved,
914
932
  autoCheckpoint: options.autoCheckpoint || false,
915
933
  checkpointSession: options.checkpointSession || sessionId,
916
934
  hookDb: db,
@@ -1 +0,0 @@
1
- import{I as h,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-BMxUs6UX.js";import{_ as k}from"./index-BgN5G5vF.js";import"./icons-BsDmGpcT.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(),f=String(e.getMonth()+1).padStart(2,"0"),g=String(e.getDate()).padStart(2,"0"),b=String(e.getHours()).padStart(2,"0"),v=String(e.getMinutes()).padStart(2,"0");return`${p}-${f}-${g} ${b}:${v}`}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"},q={class:"meta"},M={class:"actor"},R={class:"time"},V={class:"body"};function D(c,d,t,r,i,l){const o=h("a-tag");return u(),S("div",{class:B(["chat-row",{mine:r.isMine}])},[n("div",T,[n("div",q,[n("span",M,a(r.actorLabel),1),n("span",R,a(r.formattedTime),1)]),n("div",V,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 A=k(N,[["render",D],["__scopeId","data-v-49238629"],["__file","/tmp/cc-web-panel-v9Hwrq/repo/packages/web-panel/src/components/pdh/renderers/ChatBubbleRenderer.vue"]]);export{A as default};
@@ -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-BMxUs6UX.js";import{_ as v,b as m}from"./index-BgN5G5vF.js";import{a7 as y,M}from"./icons-BsDmGpcT.js";const B={__name:"MobileProjects",setup(p,{expose:i}){i();const c=u(),{t:e}=m();function a(){c.push("/projects")}function _(){c.push("/mobile-bridge")}const s={router:c,t:e,goToProjects:a,goToMobileBridge:_,get useRouter(){return u},get useI18n(){return m},get MobileOutlined(){return M},get FolderOutlined(){return y}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}},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 N=v(B,[["render",T],["__scopeId","data-v-9262cc45"],["__file","/tmp/cc-web-panel-v9Hwrq/repo/packages/web-panel/src/views/MobileProjects.vue"]]);export{N as default};
@@ -1 +0,0 @@
1
- import{I as h,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 a}from"./vendor-BMxUs6UX.js";import{_ as S}from"./index-BgN5G5vF.js";import"./icons-BsDmGpcT.js";const k={__name:"OrderTableRenderer",props:{event:{type:Object,required:!0}},setup(p,{expose:r}){r();const o=p,e=a(()=>o.event.content||{}),d=a(()=>o.event.extra||{}),m=a(()=>d.value.merchant||e.value.merchant||e.value.counterparty||"—"),c=a(()=>e.value.title||e.value.name||e.value.itemName||e.value.text||"—"),y=a(()=>{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=a(()=>d.value.orderNo||e.value.orderNo||e.value.orderId),f=a(()=>e.value.status||e.value.state),w=a(()=>{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"}),b=a(()=>{if(!o.event.occurredAt)return"";const t=new Date(o.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:o,c:e,e:d,merchantText:m,itemText:c,amountText:y,orderNo:T,statusText:f,statusColor:w,formattedTime:b,computed:a};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"},I={class:"row amount-row"},j={class:"val amount"},q={key:0,class:"row"},A={class:"val mono"},F={key:1,class:"row"};function H(p,r,o,e,d,m){const c=h("a-tag");return l(),u("div",N,[s("div",C,[s("span",O,n(e.formattedTime),1),i(c,{color:"gold"},{default:v(()=>[_(n(o.event.source.adapter),1)]),_:1}),i(c,null,{default:v(()=>[_(n(o.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",I,[r[2]||(r[2]=s("span",{class:"key"},"金额",-1)),s("span",j,n(e.amountText),1)]),e.orderNo?(l(),u("div",q,[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",F,[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",H],["__scopeId","data-v-5ed5524d"],["__file","/tmp/cc-web-panel-v9Hwrq/repo/packages/web-panel/src/components/pdh/renderers/OrderTableRenderer.vue"]]);export{K as default};
@@ -1,2 +0,0 @@
1
- import{I as u,J as z,U as y,c as n,K as r,a as I,r as P,o as M,b as h,P as B,Q as j,S as A,V as F}from"./vendor-BMxUs6UX.js";import{t as J,_ as L,u as N,d as v}from"./index-BgN5G5vF.js";import{a7 as W,R as q}from"./icons-BsDmGpcT.js";const c=Object.freeze({rootPath:"",maxSizeMB:1e3,autoSync:!1,syncIntervalSeconds:300});function U(o){if(typeof o=="boolean")return o;const e=String(o).trim().toLowerCase();return e==="true"||e==="1"||e==="yes"||e==="on"}function C(o,e){if(typeof o=="number"&&Number.isFinite(o))return o;const a=parseFloat(o);return Number.isFinite(a)?a:e}function R(o){const e={...c};if(!o)return e;const a=o.trim();if(!a||/key not found/i.test(a))return e;const t=J(a);if(t&&typeof t=="object"&&!Array.isArray(t))return t.rootPath!==void 0&&(e.rootPath=String(t.rootPath||"")),t.maxSizeMB!==void 0&&(e.maxSizeMB=C(t.maxSizeMB,c.maxSizeMB)),t.autoSync!==void 0&&(e.autoSync=U(t.autoSync)),t.syncIntervalSeconds!==void 0&&(e.syncIntervalSeconds=C(t.syncIntervalSeconds,c.syncIntervalSeconds)),e;const _=a.split(`
2
- `);for(const d of _){const p=d.trim().match(/^(?:project\.)?(rootPath|maxSizeMB|autoSync|syncIntervalSeconds)\s*[=:]\s*(.+)$/i);if(!p)continue;const f=p[1],i=p[2].trim();f==="rootPath"?e.rootPath=i:f==="maxSizeMB"?e.maxSizeMB=C(i,c.maxSizeMB):f==="autoSync"?e.autoSync=U(i):f==="syncIntervalSeconds"&&(e.syncIntervalSeconds=C(i,c.syncIntervalSeconds))}return e}function O(o,e){const a={};for(const t of Object.keys(c))o[t]!==e[t]&&(a[t]=e[t]);return a}const H={__name:"ProjectSettings",setup(o,{expose:e}){e();const a=N(),t=P(!1),_=P(!1),d=I({...c}),s=P({...c}),p=h(()=>Object.keys(O(s.value,d)).length>0);async function f(){t.value=!0;try{const{output:m}=await a.execute("config get project",1e4),g=R(m);Object.assign(d,g),s.value={...g}}catch(m){/key not found/i.test(m.message)?(Object.assign(d,c),s.value={...c}):v.error("加载配置失败: "+m.message)}finally{t.value=!1}}function i(){Object.assign(d,s.value)}async function x(){const m=O(s.value,d),g=Object.keys(m);if(g.length===0){v.info("没有需要保存的修改");return}_.value=!0;let b=0,S=0;for(const l of g){const D=m[l],E=String(D).replace(/"/g,'\\"'),T=`config set project.${l} "${E}"`;try{const{output:w,exitCode:V}=await a.execute(T,1e4);V!==0||/error|failed|失败/i.test(w)?(S++,v.error(`保存 ${l} 失败: ${w.slice(0,80)}`)):b++}catch(w){S++,v.error(`保存 ${l} 失败: ${w.message}`)}}_.value=!1,S===0?(v.success(`保存成功(${b} 项)`),s.value={...d}):b>0&&(v.warning(`部分保存成功:${b} 成功 / ${S} 失败`),await f())}M(()=>{f()});const k={ws:a,loading:t,saving:_,form:d,baseline:s,isDirty:p,loadConfig:f,resetForm:i,saveConfig:x,reactive:I,ref:P,computed:h,onMounted:M,get ReloadOutlined(){return q},get FolderOutlined(){return W},get message(){return v},get useWsStore(){return N},get parseProjectConfig(){return R},get diffProjectConfig(){return O},get PROJECT_DEFAULTS(){return c}};return Object.defineProperty(k,"__isScriptSetup",{enumerable:!1,value:!0}),k}},K={style:{display:"flex","align-items":"center","justify-content":"space-between","margin-bottom":"24px"}},Q={style:{color:"var(--text-primary)"}},G={key:0,style:{color:"#faad14","font-size":"12px","margin-left":"8px"}};function X(o,e,a,t,_,d){const s=u("a-button"),p=u("a-alert"),f=u("a-input"),i=u("a-form-item"),x=u("a-input-number"),k=u("a-switch"),m=u("a-space"),g=u("a-form"),b=u("a-spin"),S=u("a-card");return B(),z("div",null,[y("div",K,[e[5]||(e[5]=y("div",null,[y("h2",{class:"page-title"},"项目存储配置"),y("p",{class:"page-sub"},"根目录 / 配额 / 自动同步")],-1)),n(s,{loading:t.loading,onClick:t.loadConfig},{icon:r(()=>[n(t.ReloadOutlined)]),default:r(()=>[e[4]||(e[4]=j(" 刷新 ",-1))]),_:1},8,["loading"])]),n(p,{message:"仅 Web 模式",description:"目录选择器(原生文件对话框)仅在桌面端可用,本页面需手动输入路径。修改根目录后需重启桌面应用生效;web 端只影响后端配置文件。",type:"info","show-icon":"",closable:"",style:{"margin-bottom":"16px"}}),n(S,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{title:r(()=>[y("span",Q,[n(t.FolderOutlined,{style:{"margin-right":"8px"}}),e[6]||(e[6]=j("项目存储 ",-1))])]),default:r(()=>[n(b,{spinning:t.loading},{default:r(()=>[n(g,{"label-col":{span:6},"wrapper-col":{span:18},style:{"max-width":"720px"}},{default:r(()=>[n(i,{label:"项目根目录"},{extra:r(()=>[...e[7]||(e[7]=[y("span",{style:{color:"var(--text-muted)","font-size":"11px"}}," 需绝对路径;修改后重启桌面应用生效 ",-1)])]),default:r(()=>[n(f,{value:t.form.rootPath,"onUpdate:value":e[0]||(e[0]=l=>t.form.rootPath=l),placeholder:"项目文件存储的根目录绝对路径",disabled:t.saving},null,8,["value","disabled"])]),_:1}),n(i,{label:"最大项目大小"},{default:r(()=>[n(x,{value:t.form.maxSizeMB,"onUpdate:value":e[1]||(e[1]=l=>t.form.maxSizeMB=l),min:100,max:1e4,step:100,"addon-after":"MB",style:{width:"220px"},disabled:t.saving},null,8,["value","disabled"])]),_:1}),n(i,{label:"自动同步"},{default:r(()=>[n(k,{checked:t.form.autoSync,"onUpdate:checked":e[2]||(e[2]=l=>t.form.autoSync=l),disabled:t.saving},null,8,["checked","disabled"]),e[8]||(e[8]=y("span",{style:{"margin-left":"12px",color:"var(--text-secondary)","font-size":"12px"}}," 自动同步项目到后端服务器 ",-1))]),_:1}),t.form.autoSync?(B(),A(i,{key:0,label:"同步间隔"},{default:r(()=>[n(x,{value:t.form.syncIntervalSeconds,"onUpdate:value":e[3]||(e[3]=l=>t.form.syncIntervalSeconds=l),min:60,max:3600,step:60,"addon-after":"秒",style:{width:"220px"},disabled:t.saving},null,8,["value","disabled"])]),_:1})):F("v-if",!0),n(i,{"wrapper-col":{offset:6,span:18}},{default:r(()=>[n(m,null,{default:r(()=>[n(s,{onClick:t.resetForm,disabled:t.saving||t.loading},{default:r(()=>[...e[9]||(e[9]=[j(" 重置 ",-1)])]),_:1},8,["disabled"]),n(s,{type:"primary",loading:t.saving,disabled:!t.isDirty,onClick:t.saveConfig},{default:r(()=>[...e[10]||(e[10]=[j(" 保存配置 ",-1)])]),_:1},8,["loading","disabled"]),t.isDirty?(B(),z("span",G," 有未保存的修改 ")):F("v-if",!0)]),_:1})]),_:1})]),_:1})]),_:1},8,["spinning"])]),_:1})])}const ee=L(H,[["render",X],["__scopeId","data-v-f4cc2f66"],["__file","/tmp/cc-web-panel-v9Hwrq/repo/packages/web-panel/src/views/ProjectSettings.vue"]]);export{ee 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-BMxUs6UX.js";import{_ as we,b as re,u as ie,d}from"./index-BgN5G5vF.js";import{u as de}from"./useShellMode-CgR0wCYM.js";import{aM as ke,aN as Fe,aO as be,f as je,a4 as Ce,a7 as xe,as as Oe,R as Se}from"./icons-BsDmGpcT.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"}],M=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 H(o){switch(o){case"synced":return"green";case"pending":return"orange";case"conflict":return"red";case"error":return"red";default:return"default"}}function K(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 Q(o){return{onClick:()=>V(o)}}async function V(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 G(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:M,filteredProjects:J,statusColor:g,syncColor:H,formatTime:K,loadAll:C,onRowClick:Q,openDetail:V,onDelete:G,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"),M=i("a-popconfirm"),J=i("a-table"),g=i("a-descriptions-item"),H=i("a-descriptions"),K=i("a-divider"),C=i("a-empty"),Q=i("a-list-item"),V=i("a-list"),G=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(M,{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(H,{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(K,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(G,{spinning:e.filesLoading},{default:a(()=>[!e.files.length&&!e.filesLoading?(p(),x(C,{key:0,description:"无文件 (点上方按钮新建)"})):(p(),x(V,{key:1,size:"small","data-source":e.files},{renderItem:a(({item:n})=>[t(Q,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(M,{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-v9Hwrq/repo/packages/web-panel/src/views/Projects.vue"]]);export{We as default};
@@ -1,3 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./xterm-BZcWGsqw.js","./markdown-CsiA8-E5.js","./markdown-Dfs9RUU9.css","./addon-fit-CK6X9sAG.js","./xterm-DFuMZ0ql.css"])))=>i.map(i=>d[i]);
2
- import{u as fe,_ as me,d as V,e as U}from"./index-BgN5G5vF.js";import{I as z,J as x,U as _,Q as q,S as K,K as T,V as R,c as A,F as Q,Z as Y,R as E,o as Z,f as G,w as $,n as D,b as ee,r as S,P as y,_ as ve,a2 as we,a3 as he,a4 as _e}from"./vendor-BMxUs6UX.js";import{R as ye,b as pe,as as ge}from"./icons-BsDmGpcT.js";const k=new Map,C=new Map,N=new Set,F=new Set;let te=!1;function xe(c){te||(te=!0,c.onMessage(o=>{if(!(!o||typeof o.type!="string")){if(o.type==="terminal.stdout"){const{sessionId:s,data:e,seq:i}=o.payload||{};if(!s)return;let w;try{const d=atob(e||""),f=new Uint8Array(d.length);for(let n=0;n<d.length;n++)f[n]=d.charCodeAt(n);w=new TextDecoder("utf-8").decode(f)}catch{w=""}const u={sessionId:s,data:w,seq:i};k.get(s)?.forEach(d=>d(u)),N.forEach(d=>d(u))}else if(o.type==="terminal.exit"){const{sessionId:s,exitCode:e,signal:i}=o.payload||{};if(!s)return;const w={sessionId:s,exitCode:e,signal:i};C.get(s)?.forEach(u=>u(w)),F.forEach(u=>u(w))}}}))}function ne(c){const o=new TextEncoder().encode(c);let s="";for(let e=0;e<o.length;e++)s+=String.fromCharCode(o[e]);return btoa(s)}function ae(c){const o=atob(c||""),s=new Uint8Array(o.length);for(let e=0;e<o.length;e++)s[e]=o.charCodeAt(e);return new TextDecoder("utf-8").decode(s)}function oe(){const c=fe();xe(c);async function o(n={}){const a=await c.sendRaw({type:"terminal.create",payload:{shell:n.shell,cwd:n.cwd,env:n.env,cols:n.cols,rows:n.rows}});if(a.ok===!1)throw new Error(a.error||"terminal_create_failed");return a.result??a}async function s(){const n=await c.sendRaw({type:"terminal.list",payload:{}});if(n.ok===!1)throw new Error(n.error||"terminal_list_failed");const a=n.result??n;return Array.isArray(a.sessions)?a.sessions:[]}async function e(n,a){const r=await c.sendRaw({type:"terminal.stdin",payload:{sessionId:n,data:ne(String(a))}});if(r.ok===!1)throw new Error(r.error||"terminal_stdin_failed");return r.result??r}async function i(n,a,r){const h=await c.sendRaw({type:"terminal.resize",payload:{sessionId:n,cols:a,rows:r}});if(h.ok===!1)throw new Error(h.error||"terminal_resize_failed");return h.result??h}async function w(n){const a=await c.sendRaw({type:"terminal.close",payload:{sessionId:n}});if(a.ok===!1)throw new Error(a.error||"terminal_close_failed");return a.result??a}async function u(n,a=0){const r=await c.sendRaw({type:"terminal.history",payload:{sessionId:n,fromSeq:a}});if(r.ok===!1)throw new Error(r.error||"terminal_history_failed");const h=r.result??r;return{truncated:!!h.truncated,chunks:(h.chunks||[]).map(L=>({seq:L.seq,data:ae(L.data)}))}}function d(n,a){return n?(k.has(n)||k.set(n,new Set),k.get(n).add(a),()=>{k.get(n)?.delete(a),k.get(n)?.size===0&&k.delete(n)}):(N.add(a),()=>N.delete(a))}function f(n,a){return n?(C.has(n)||C.set(n,new Set),C.get(n).add(a),()=>{C.get(n)?.delete(a),C.get(n)?.size===0&&C.delete(n)}):(F.add(a),()=>F.delete(a))}return{create:o,list:s,stdin:e,resize:i,close:w,history:u,onStdout:d,onExit:f,_internal:{stdoutSubs:k,exitSubs:C,toBase64Utf8:ne,fromBase64Utf8:ae}}}const Se={__name:"Terminal",setup(c,{expose:o}){o();const s=oe(),e=S([]),i=S(null),w=S("pwsh"),u=S(!1),d=S(!1),f=S(""),n=S(""),a=S([]),r=[{value:"pwsh",label:"PowerShell"},{value:"cmd",label:"CMD"},{value:"bash",label:"Bash"},{value:"wsl",label:"WSL"}],h=ee(()=>e.value.find(t=>t.id===i.value));function L(t){return t?t.slice(0,8):""}let O=null,M=null;async function I(){if(O)return{xtermMod:O,fitAddonMod:M};try{O=await U(()=>import("./xterm-BZcWGsqw.js").then(t=>t.x),__vite__mapDeps([0,1,2]),import.meta.url),M=await U(()=>import("./addon-fit-CK6X9sAG.js").then(t=>t.a),__vite__mapDeps([3,1,2]),import.meta.url),await U(()=>Promise.resolve({}),__vite__mapDeps([4]),import.meta.url)}catch(t){throw n.value="xterm 资源加载失败:"+(t?.message||"未知错误"),t}return{xtermMod:O,fitAddonMod:M}}async function B(t){await D();const{xtermMod:l,fitAddonMod:p}=await I(),b=a.value.find(v=>v?.dataset?.sessionId===t.id);if(!b)return;const m=new l.Terminal({cursorBlink:!0,fontFamily:'Consolas, "Courier New", monospace',fontSize:13,theme:{background:"#1e1e1e",foreground:"#d4d4d4"},convertEol:!1}),P=new p.FitAddon;m.loadAddon(P),m.open(b);try{P.fit()}catch{}t.xterm=m,t.fitAddon=P;const ie=m.onData(v=>{s.stdin(t.id,v).catch(g=>{String(g?.message||"").includes("dangerous_keyword_blocked")?V.warning("该命令被桌面端拦截(高危关键字)"):V.error("stdin 失败: "+(g?.message||g))})}),ce=s.onStdout(t.id,({data:v,seq:g})=>{t.lastSeq=g,m.write(v)}),de=s.onExit(t.id,({exitCode:v,signal:g})=>{t.alive=!1,t.exitCode=v,t.signal=g,m.writeln(`\r
3
- \x1B[33m[session exited, code=${v}, signal=${g??"-"}]\x1B[0m`)});t.offs=()=>{try{ie.dispose?.()}catch{}ce(),de()};try{const{chunks:v,truncated:g}=await s.history(t.id,0);g&&m.writeln("\x1B[2m[history truncated — earlier output was evicted]\x1B[0m");for(const J of v)m.write(J.data),t.lastSeq=J.seq}catch(v){m.writeln(`\x1B[31m[history fetch failed: ${v?.message||v}]\x1B[0m`)}const H=new ResizeObserver(()=>{try{P.fit(),s.resize(t.id,m.cols,m.rows).catch(()=>{})}catch{}});H.observe(b);const ue=t.offs;t.offs=()=>{try{H.disconnect()}catch{}ue()}}async function re(){u.value=!0,f.value="";try{const t=await s.create({shell:w.value,cols:80,rows:24}),l={id:t.sessionId,shell:t.shell,cwd:"",alive:!0,lastSeq:0,exitCode:null,xterm:null,fitAddon:null,offs:()=>{}};e.value.push(l),i.value=l.id,await B(l)}catch(t){f.value=t?.message||String(t)}finally{u.value=!1}}async function se(t){try{await s.close(t)}catch(l){f.value=l?.message||String(l)}setTimeout(()=>W(t),500)}function W(t){const l=e.value.findIndex(b=>b.id===t);if(l===-1)return;const p=e.value[l];try{p.offs?.()}catch{}try{p.xterm?.dispose?.()}catch{}e.value.splice(l,1),i.value===t&&(i.value=e.value[0]?.id||null)}function le(t){i.value=t,D(()=>{const l=e.value.find(p=>p.id===t);try{l?.fitAddon?.fit()}catch{}})}async function X(){d.value=!0,f.value="";try{const t=await s.list();for(const l of t){const p=e.value.find(m=>m.id===l.id);if(p){p.alive=l.alive,p.lastSeq=l.lastSeq;continue}const b={id:l.id,shell:l.shell,cwd:l.cwd,alive:l.alive,lastSeq:l.lastSeq,exitCode:null,xterm:null,fitAddon:null,offs:()=>{}};e.value.push(b),await B(b)}!i.value&&e.value.length>0&&(i.value=e.value[0].id)}catch(t){f.value=t?.message||String(t)}finally{d.value=!1}}Z(async()=>{await X()}),G(()=>{for(const t of e.value){try{t.offs?.()}catch{}try{t.xterm?.dispose?.()}catch{}}}),$(i,()=>{D(()=>{const t=h.value;try{t?.fitAddon?.fit()}catch{}})});const j={term:s,sessions:e,activeId:i,newShell:w,creating:u,loadingList:d,error:f,warning:n,xtermContainers:a,shellOptions:r,active:h,shortId:L,get xtermMod(){return O},set xtermMod(t){O=t},get fitAddonMod(){return M},set fitAddonMod(t){M=t},loadXterm:I,mountXterm:B,onCreate:re,onClose:se,removeSession:W,activate:le,refreshList:X,ref:S,computed:ee,onMounted:Z,onBeforeUnmount:G,nextTick:D,watch:$,get message(){return V},get PlusOutlined(){return ge},get CloseOutlined(){return pe},get ReloadOutlined(){return ye},get useTerminal(){return oe}};return Object.defineProperty(j,"__isScriptSetup",{enumerable:!1,value:!0}),j}},be={class:"terminal-page"},ke={class:"terminal-header"},Ce={class:"page-sub"},Ae={class:"terminal-body"},Ee={class:"session-tabs"},Oe=["onClick"],Te={class:"session-shell"},Re={class:"session-id"},Me={key:0,class:"session-empty"},ze={class:"xterm-host"},Le=["data-session-id"],Pe={key:0,class:"xterm-placeholder"},qe={key:1,class:"terminal-footer"},De={key:0,class:"footer-exit"};function Be(c,o,s,e,i,w){const u=z("a-tag"),d=z("a-select"),f=z("a-button"),n=z("a-space"),a=z("a-alert");return y(),x("div",be,[_("div",ke,[_("div",null,[o[3]||(o[3]=_("h2",{class:"page-title"},"远程终端",-1)),_("p",Ce,[o[2]||(o[2]=q(" 桌面端托管的 PTY 会话;Android 端可远程操控同一通道 ",-1)),e.warning?(y(),K(u,{key:0,color:"orange",style:{"margin-left":"8px"}},{default:T(()=>[q(E(e.warning),1)]),_:1})):R("v-if",!0)])]),A(n,null,{default:T(()=>[A(d,{value:e.newShell,"onUpdate:value":o[0]||(o[0]=r=>e.newShell=r),style:{width:"130px"},size:"small",options:e.shellOptions},null,8,["value"]),A(f,{type:"primary",size:"small",loading:e.creating,onClick:e.onCreate},{icon:T(()=>[A(e.PlusOutlined)]),default:T(()=>[o[4]||(o[4]=q(" 新会话 ",-1))]),_:1},8,["loading"]),A(f,{size:"small",loading:e.loadingList,onClick:e.refreshList},{icon:T(()=>[A(e.ReloadOutlined)]),default:T(()=>[o[5]||(o[5]=q(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),e.error?(y(),K(a,{key:0,message:e.error,type:"error","show-icon":"",closable:"",style:{"margin-bottom":"12px"},onClose:o[1]||(o[1]=r=>e.error="")},null,8,["message"])):R("v-if",!0),_("div",Ae,[_("div",Ee,[(y(!0),x(Q,null,Y(e.sessions,r=>(y(),x("div",{key:r.id,class:ve(["session-tab",{active:r.id===e.activeId,dead:!r.alive}]),onClick:h=>e.activate(r.id)},[_("span",Te,E(r.shell),1),_("span",Re,E(e.shortId(r.id)),1),A(e.CloseOutlined,{class:"session-close",onClick:we(h=>e.onClose(r.id),["stop"])},null,8,["onClick"])],10,Oe))),128)),e.sessions.length===0?(y(),x("div",Me,' 点击 "新会话" 创建第一个终端 ')):R("v-if",!0)]),_("div",ze,[(y(!0),x(Q,null,Y(e.sessions,r=>he((y(),x("div",{key:r.id,ref_for:!0,ref:"xtermContainers","data-session-id":r.id,class:"xterm-container"},null,8,Le)),[[_e,r.id===e.activeId]])),128)),e.sessions.length===0?(y(),x("div",Pe,[...o[6]||(o[6]=[_("span",null,"无活跃会话",-1)])])):R("v-if",!0)])]),e.active?(y(),x("div",qe,[_("span",null,E(e.active.shell)+" · "+E(e.active.cwd||"(默认 cwd)")+" · seq "+E(e.active.lastSeq),1),e.active.alive?R("v-if",!0):(y(),x("span",De,"已退出 (code="+E(e.active.exitCode??"-")+")",1))])):R("v-if",!0)])}const Fe=me(Se,[["render",Be],["__scopeId","data-v-65366a29"],["__file","/tmp/cc-web-panel-v9Hwrq/repo/packages/web-panel/src/views/Terminal.vue"]]);export{Fe as default};
@@ -1 +0,0 @@
1
- import{Q as r}from"./index-BgN5G5vF.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-Eq98LRtU.js";import{a0 as t}from"./index-BgN5G5vF.js";import"./vendor-BMxUs6UX.js";import"./responsiveObserve-D7Xz2y-R.js";import"./useFlexGapSupport-BoMCTNyu.js";import"./styleChecker-qHmJjV62.js";import"./index-C_MfcrLf.js";import"./icons-BsDmGpcT.js";const l=t(o);export{l as default};
@@ -1 +0,0 @@
1
- import{C as o}from"./Col-BfbHu1xI.js";import{a0 as t}from"./index-BgN5G5vF.js";import"./vendor-BMxUs6UX.js";import"./index-C_MfcrLf.js";import"./icons-BsDmGpcT.js";const s=t(o);export{s as default};