chainlesschain 0.162.48 → 0.162.60

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 (177) hide show
  1. package/bin/chainlesschain.js +1 -1
  2. package/package.json +2 -2
  3. package/src/assets/web-panel/assets/{AIOps-BeMOUkMq.js → AIOps-a2cSbSEu.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-DrRegmIt.js → ActionButton-DwvSB5Pp.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-BM7hvUn8.js → Analytics-BqaRaBDD.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-BfLLYSz_.js → AppLayout-Beck7v8t.js} +5 -5
  7. package/src/assets/web-panel/assets/{Audit-BpiPR-rs.js → Audit-UtJhPdXJ.js} +1 -1
  8. package/src/assets/web-panel/assets/{Backup-BLq4IRI9.js → Backup-HVZhcdll.js} +1 -1
  9. package/src/assets/web-panel/assets/{BaseInput-Bv89IFrM.js → BaseInput-DRY_ZGmj.js} +1 -1
  10. package/src/assets/web-panel/assets/{Chat-BUM9MdnH.js → Chat-D7Vuwfe2.js} +4 -4
  11. package/src/assets/web-panel/assets/{ChatBubbleRenderer-rH_t53ZW.js → ChatBubbleRenderer-BS2q_hPX.js} +1 -1
  12. package/src/assets/web-panel/assets/{Checkbox-82jih_zU.js → Checkbox-B406i7N1.js} +1 -1
  13. package/src/assets/web-panel/assets/{Codegen-ygmM1mNL.js → Codegen-BvTCqHi3.js} +1 -1
  14. package/src/assets/web-panel/assets/{Col-CqXc8_ft.js → Col-DRiyxTQP.js} +1 -1
  15. package/src/assets/web-panel/assets/{Community-CqPPfyR3.js → Community-DWmhxHQa.js} +1 -1
  16. package/src/assets/web-panel/assets/{Compact-LR8Z206-.js → Compact-DO1HBZEz.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compliance-D4alm_Gx.js → Compliance-D4j-VHwS.js} +1 -1
  18. package/src/assets/web-panel/assets/{Cowork-D-DLVanT.js → Cowork-BGBkWtat.js} +3 -3
  19. package/src/assets/web-panel/assets/{Cron-UDtmjvd4.js → Cron-Xa9PtMUQ.js} +2 -2
  20. package/src/assets/web-panel/assets/{Crosschain-iqbVDPNE.js → Crosschain-wVWs4lqN.js} +1 -1
  21. package/src/assets/web-panel/assets/{DID-DzdUfzc9.js → DID-DTkqiRuT.js} +2 -2
  22. package/src/assets/web-panel/assets/{Dashboard-DvKp1skY.js → Dashboard-d9STUbrr.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dropdown-S6ORlfef.js → Dropdown-CrdxS-C8.js} +1 -1
  24. package/src/assets/web-panel/assets/{EmailListRenderer-mJViHjiq.js → EmailListRenderer-D78XHUEp.js} +1 -1
  25. package/src/assets/web-panel/assets/{FamilyGuardDashboard-A4Lu5m_e.js → FamilyGuardDashboard-iAeSETIP.js} +1 -1
  26. package/src/assets/web-panel/assets/{Federation-Bv-6737r.js → Federation-CTV1Sxqs.js} +1 -1
  27. package/src/assets/web-panel/assets/{FormItemContext-DNcZoiWu.js → FormItemContext-BtwNuQKK.js} +1 -1
  28. package/src/assets/web-panel/assets/{GenericCardRenderer-B_a0l9U4.js → GenericCardRenderer-CdEgHjkl.js} +1 -1
  29. package/src/assets/web-panel/assets/{Git-BbVAsh_N.js → Git-BTo-PJr_.js} +2 -2
  30. package/src/assets/web-panel/assets/{Governance-ChxUMZEU.js → Governance-DquOG94r.js} +1 -1
  31. package/src/assets/web-panel/assets/{Inference-Buu_bAQ-.js → Inference-DDtcBxRB.js} +1 -1
  32. package/src/assets/web-panel/assets/{KnowledgeGraph-BMmMjxEu.js → KnowledgeGraph-KUOmNj5C.js} +1 -1
  33. package/src/assets/web-panel/assets/{Logs-BeGHcPEC.js → Logs-HKm7kRs7.js} +2 -2
  34. package/src/assets/web-panel/assets/{Marketplace-CP2Qg_xJ.js → Marketplace-IxrOcbFB.js} +1 -1
  35. package/src/assets/web-panel/assets/{McpTools-C42B4JYb.js → McpTools-D6a1LM3S.js} +4 -4
  36. package/src/assets/web-panel/assets/{Memory-D5VeitFY.js → Memory-lFkD2ZuM.js} +2 -2
  37. package/src/assets/web-panel/assets/{MobileBridge-BouoJ2FQ.js → MobileBridge-xwuQTps5.js} +2 -2
  38. package/src/assets/web-panel/assets/MobileProjects-BYr1D3WO.js +1 -0
  39. package/src/assets/web-panel/assets/{Mtc-Chn6ES5y.js → Mtc-BXpJGrjm.js} +6 -6
  40. package/src/assets/web-panel/assets/{MtcAudit-D0_Q6GEn.js → MtcAudit-CWttaim1.js} +2 -2
  41. package/src/assets/web-panel/assets/{Multisig-BWaCi_wo.js → Multisig-jKgTuVLS.js} +3 -3
  42. package/src/assets/web-panel/assets/{NLProgramming-CoSEiroa.js → NLProgramming-xl4RDzQj.js} +1 -1
  43. package/src/assets/web-panel/assets/{Notes-CiqCbDw3.js → Notes-DPBOvscE.js} +3 -3
  44. package/src/assets/web-panel/assets/{NotificationSettings-BXmzKL9F.js → NotificationSettings-8TkIkRo3.js} +1 -1
  45. package/src/assets/web-panel/assets/{OrderTableRenderer-BhlKyGrE.js → OrderTableRenderer-Dwa-XtoE.js} +1 -1
  46. package/src/assets/web-panel/assets/{Organization-CAVgSxyI.js → Organization-CJ0xVwZM.js} +4 -4
  47. package/src/assets/web-panel/assets/{Overflow-BIVUo8YB.js → Overflow-V7VuUslt.js} +1 -1
  48. package/src/assets/web-panel/assets/{P2P-DX-Ov-eJ.js → P2P-BxuccEGq.js} +2 -2
  49. package/src/assets/web-panel/assets/PdhVaultBrowser-DaP2Q5kU.js +7 -0
  50. package/src/assets/web-panel/assets/{Permissions-CANl-V55.js → Permissions-CPJFF0zU.js} +3 -3
  51. package/src/assets/web-panel/assets/{PersonalDataHub-BE90gjUO.js → PersonalDataHub-Cmn2uiuw.js} +4 -4
  52. package/src/assets/web-panel/assets/{Pipeline-Ck8lV8Pn.js → Pipeline-0zX89_iz.js} +1 -1
  53. package/src/assets/web-panel/assets/{Privacy-BBYUDK4T.js → Privacy-DROUg3XE.js} +1 -1
  54. package/src/assets/web-panel/assets/{ProjectInit-DcbOrnbt.js → ProjectInit-c5KESOK4.js} +2 -2
  55. package/src/assets/web-panel/assets/{ProjectSettings-DZ6-whxP.js → ProjectSettings-BfiCcnb_.js} +2 -2
  56. package/src/assets/web-panel/assets/Projects-BtZH5-Eh.js +1 -0
  57. package/src/assets/web-panel/assets/{Providers-VWoO_Y9u.js → Providers-C9Rr_dOk.js} +1 -1
  58. package/src/assets/web-panel/assets/{QuickAsk-RJfSXWYg.js → QuickAsk-Du4p90W6.js} +1 -1
  59. package/src/assets/web-panel/assets/{Recommend-Y7MWWkXa.js → Recommend-B-DQenTl.js} +1 -1
  60. package/src/assets/web-panel/assets/{Reputation-nG8nut3l.js → Reputation-DvwlAVRZ.js} +1 -1
  61. package/src/assets/web-panel/assets/{Row-DAio6Dx2.js → Row-rTnbvkP-.js} +1 -1
  62. package/src/assets/web-panel/assets/{RssFeed-DwY72Lc7.js → RssFeed-DwvsqWbB.js} +3 -3
  63. package/src/assets/web-panel/assets/{Search-qGG6AUWY.js → Search-U_Xj5SvF.js} +1 -1
  64. package/src/assets/web-panel/assets/{Security-Djsmom8n.js → Security-CdjsVDQ8.js} +4 -4
  65. package/src/assets/web-panel/assets/{Services-DTEgHkUO.js → Services-DUd3mFXk.js} +2 -2
  66. package/src/assets/web-panel/assets/{Skeleton-R5xY0J9Y.js → Skeleton-CA2gCJmY.js} +1 -1
  67. package/src/assets/web-panel/assets/{Skills-CFaRLO3o.js → Skills-BIw7Rb-m.js} +1 -1
  68. package/src/assets/web-panel/assets/{Sla-B5bzoY1I.js → Sla-vySPesC0.js} +1 -1
  69. package/src/assets/web-panel/assets/{SpeechSettings-B_al6SiQ.js → SpeechSettings-EniuTjBJ.js} +1 -1
  70. package/src/assets/web-panel/assets/{SyncSettings-DkUU63oJ.js → SyncSettings-DkrqbzYS.js} +2 -2
  71. package/src/assets/web-panel/assets/{Tasks-C2y4XdrQ.js → Tasks-oyPnWRbw.js} +1 -1
  72. package/src/assets/web-panel/assets/{Templates-CcYJxTNB.js → Templates-C2Kvn60U.js} +1 -1
  73. package/src/assets/web-panel/assets/{Tenant-B0_sIpl2.js → Tenant-x6jVMx4D.js} +1 -1
  74. package/src/assets/web-panel/assets/{Terminal-B_waZb0O.js → Terminal-C2nZbPBs.js} +2 -2
  75. package/src/assets/web-panel/assets/{TimelineRenderer-DuMkErBx.js → TimelineRenderer-BF6HAETd.js} +1 -1
  76. package/src/assets/web-panel/assets/{Tokens-BXjPA6rV.js → Tokens-B-KcVAin.js} +1 -1
  77. package/src/assets/web-panel/assets/{Trigger-BMAAx3Uu.js → Trigger-B-Caiptm.js} +1 -1
  78. package/src/assets/web-panel/assets/{Trust-BPeNXpsi.js → Trust-_8sq7pJp.js} +1 -1
  79. package/src/assets/web-panel/assets/{UkeySign-A0qabV14.js → UkeySign-CLveUEgo.js} +1 -1
  80. package/src/assets/web-panel/assets/{VideoEditing-BMLfYykd.js → VideoEditing-iVc9jxt9.js} +1 -1
  81. package/src/assets/web-panel/assets/{Wallet-BfDI3zjs.js → Wallet-D1n5pidD.js} +4 -4
  82. package/src/assets/web-panel/assets/{WebAuthn-BCnZEScW.js → WebAuthn-CA8kubXb.js} +4 -4
  83. package/src/assets/web-panel/assets/{WorkflowEditor-DvtS5Asf.js → WorkflowEditor-BXWwd_fB.js} +1 -1
  84. package/src/assets/web-panel/assets/{chat-CDJZtBM7.js → chat-DUNkQr1A.js} +1 -1
  85. package/src/assets/web-panel/assets/{colors-fbH1Saco.js → colors-Dz5ozTcp.js} +1 -1
  86. package/src/assets/web-panel/assets/{compact-item-CuZFa9l8.js → compact-item-CZ5-JSLh.js} +1 -1
  87. package/src/assets/web-panel/assets/{createContext-CQuPOqqD.js → createContext-CFxlcPug.js} +1 -1
  88. package/src/assets/web-panel/assets/devWarning-BMRVR8Xp.js +1 -0
  89. package/src/assets/web-panel/assets/{hasIn-CDZlDrhJ.js → hasIn-CqWIkHJm.js} +1 -1
  90. package/src/assets/web-panel/assets/{index-BivMeInw.js → index-3elHm6lI.js} +1 -1
  91. package/src/assets/web-panel/assets/{index-DvBgQoaw.js → index-8l5LLWxH.js} +1 -1
  92. package/src/assets/web-panel/assets/{index-BJCXJCUA.js → index-BBq1ySIt.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-CNmJrCxV.js → index-BI2EU3hC.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-BSy0noke.js → index-BJt6sNTF.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-oe9ZPRtQ.js → index-BLLSLAC3.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-C6epsHef.js → index-BLNgGXeg.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-COSyGm80.js → index-BO-yo7Jv.js} +1 -1
  98. package/src/assets/web-panel/assets/index-BT2s_zxU.js +1 -0
  99. package/src/assets/web-panel/assets/{index-DGAK9Dj4.js → index-BiAcVeea.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DjgZRX0_.js → index-C2SoMbLc.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-CQ5FVEji.js → index-C5XUilwu.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-Bt1j0mjJ.js → index-C5zhjact.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BKaue5Pv.js → index-CBeASfAD.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-Bz5_6E63.js → index-CD7UjlnE.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-Cr_shi_7.js → index-CDq8IVvv.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-Dkuecn17.js → index-CE-gpaY9.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-CkhudJH0.js → index-CL6wt2JN.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-kGzPbvry.js → index-CLu3Oyef.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-D365qmj8.js → index-C_WWTpLE.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-Deqod8La.js → index-CbcHBDYj.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DwAiu9LT.js → index-CguUaiiY.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-WDQkyh-E.js → index-Ci1-8q-g.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BNEG9-EK.js → index-CvMZxZOn.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-CnfR7qmj.js → index-D6Nkerss.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CdiNFWPp.js → index-DEzYXMgc.js} +1 -1
  116. package/src/assets/web-panel/assets/{index--SCX46Az.js → index-DF0hXW5L.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BhZkMMey.js → index-DGAjS_D9.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CD9ml9ZJ.js → index-DO6mf95c.js} +1 -1
  119. package/src/assets/web-panel/assets/index-DOTL6NDc.js +1 -0
  120. package/src/assets/web-panel/assets/{index-DNN-xBWV.js → index-DUyhvh0L.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-ycBlRXAf.js → index-DW18L-o6.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CAzMdnkI.js → index-Dc-5Ulgt.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CzeRvhia.js → index-DvUlrMy-.js} +3 -3
  124. package/src/assets/web-panel/assets/{index-BdORz0iZ.js → index-FsYDYVUk.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-CmeO_DfK.js → index-GVbsyUQm.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BzIDfObk.js → index-noQc_RpT.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-14gri6Vh.js → index-rR060KAF.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-DhFyStIG.js → index-xaZX6ZDL.js} +1 -1
  129. package/src/assets/web-panel/assets/{initDefaultProps-DHRWNV-y.js → initDefaultProps-PIetywTX.js} +1 -1
  130. package/src/assets/web-panel/assets/{motion-MJ2jhdVO.js → motion-gQJEK3wO.js} +1 -1
  131. package/src/assets/web-panel/assets/{move-Bly0QFE5.js → move-ML1nRxts.js} +1 -1
  132. package/src/assets/web-panel/assets/{omit-DkoMB0pZ.js → omit-wUWsw3YL.js} +1 -1
  133. package/src/assets/web-panel/assets/{pickAttrs-9M-gsXIc.js → pickAttrs-A0Wlomih.js} +1 -1
  134. package/src/assets/web-panel/assets/{placementArrow-Bnht1xci.js → placementArrow-C5RKYdxT.js} +1 -1
  135. package/src/assets/web-panel/assets/{responsiveObserve-B0Cn1i64.js → responsiveObserve-DIxNVSJl.js} +1 -1
  136. package/src/assets/web-panel/assets/{slide-BdI4DDyM.js → slide-B-tNesVu.js} +1 -1
  137. package/src/assets/web-panel/assets/{statusUtils-DdBktcMD.js → statusUtils-CftzO200.js} +1 -1
  138. package/src/assets/web-panel/assets/{styleChecker-aYEwS4Pw.js → styleChecker-CMgvWu90.js} +1 -1
  139. package/src/assets/web-panel/assets/{useFlexGapSupport-y8cUyKiP.js → useFlexGapSupport-sxqoDNhZ.js} +1 -1
  140. package/src/assets/web-panel/assets/{useFs-Bk1SrPFp.js → useFs-CowEXz4v.js} +1 -1
  141. package/src/assets/web-panel/assets/{usePersonalDataHub-Dp04zAB3.js → usePersonalDataHub-6ISRG7V-.js} +1 -1
  142. package/src/assets/web-panel/assets/{vnode-B52a38TC.js → vnode-C2mnXfmw.js} +1 -1
  143. package/src/assets/web-panel/assets/{zoom-DFwyL43U.js → zoom-DMsur0jx.js} +1 -1
  144. package/src/assets/web-panel/index.html +1 -1
  145. package/src/commands/agent.js +66 -28
  146. package/src/harness/mcp-client.js +48 -2
  147. package/src/lib/agent-core.js +2 -0
  148. package/src/lib/llm-pricing.js +9 -0
  149. package/src/lib/mcp-client.js +1 -0
  150. package/src/lib/permission-rules.cjs +11 -1
  151. package/src/lib/personal-data-hub-wiring.js +24 -0
  152. package/src/lib/repl-multiline.js +64 -0
  153. package/src/lib/repl-rewind.js +65 -2
  154. package/src/lib/repl-vim.js +445 -0
  155. package/src/lib/safe-mode.js +17 -3
  156. package/src/lib/skill-loader.js +45 -1
  157. package/src/lib/slash-commands.js +13 -3
  158. package/src/lib/status-line.cjs +33 -3
  159. package/src/repl/agent-repl.js +427 -23
  160. package/src/repl/config-summary.js +59 -0
  161. package/src/repl/conversation-export.js +133 -0
  162. package/src/repl/doctor-status.js +114 -0
  163. package/src/repl/memory-status.js +45 -0
  164. package/src/repl/permissions-status.js +51 -0
  165. package/src/repl/recent-sessions.js +46 -0
  166. package/src/repl/session-cost.js +216 -0
  167. package/src/runtime/agent-core.js +23 -8
  168. package/src/runtime/fallback-model.js +125 -30
  169. package/src/runtime/headless-runner.js +2 -0
  170. package/src/runtime/headless-stream.js +2 -0
  171. package/src/runtime/mcp-config.js +14 -3
  172. package/src/assets/web-panel/assets/MobileProjects-mAJsyk7U.js +0 -1
  173. package/src/assets/web-panel/assets/PdhVaultBrowser-6clRu-J6.js +0 -7
  174. package/src/assets/web-panel/assets/Projects-DO25SEFT.js +0 -1
  175. package/src/assets/web-panel/assets/devWarning-mhGhHpNs.js +0 -1
  176. package/src/assets/web-panel/assets/index-DGBjZXvW.js +0 -1
  177. package/src/assets/web-panel/assets/index-DujMkFuc.js +0 -1
@@ -921,9 +921,8 @@ export async function executeTool(name, args, context = {}) {
921
921
  settingsVerdict.decision !== "allow" &&
922
922
  args?.path
923
923
  ) {
924
- const { sensitiveFileReason } = await import(
925
- "../lib/sensitive-file-guard.js"
926
- );
924
+ const { sensitiveFileReason } =
925
+ await import("../lib/sensitive-file-guard.js");
927
926
  const sensReason = sensitiveFileReason(args.path);
928
927
  if (sensReason) {
929
928
  const confirm = context.permissionConfirm || context.shellConfirm || null;
@@ -1409,10 +1408,18 @@ async function executeToolInner(
1409
1408
  cwd: task.cwd,
1410
1409
  shell: true,
1411
1410
  windowsHide: true,
1412
- // Same CC_SESSION_ID correlation as the foreground path.
1411
+ // Same agent-identity env as the foreground path: CLAUDECODE marks
1412
+ // "running under the agent"; the session id correlates work to the
1413
+ // run (CC_SESSION_ID + CLAUDE_CODE_SESSION_ID for Claude-Code parity).
1413
1414
  env: {
1414
1415
  ...process.env,
1415
- ...(sessionId ? { CC_SESSION_ID: String(sessionId) } : {}),
1416
+ CLAUDECODE: "1",
1417
+ ...(sessionId
1418
+ ? {
1419
+ CC_SESSION_ID: String(sessionId),
1420
+ CLAUDE_CODE_SESSION_ID: String(sessionId),
1421
+ }
1422
+ : {}),
1416
1423
  },
1417
1424
  // POSIX: own process group so check_shell{kill}/teardown can signal
1418
1425
  // the whole tree (shell + its grandchild command). No-op on Windows
@@ -1471,11 +1478,19 @@ async function executeToolInner(
1471
1478
  encoding: "utf8",
1472
1479
  timeout: _resolveShellTimeout(args.timeout),
1473
1480
  maxBuffer: 1024 * 1024,
1474
- // CC_SESSION_ID (Claude-Code CLAUDE_CODE_SESSION_ID parity,
1475
- // 2.1.132): lets scripts/hooks correlate work to the agent session.
1481
+ // Agent-identity env for shell subprocesses (Claude-Code 2.1.132
1482
+ // parity): CLAUDECODE=1 marks "running under the agent"; CC_SESSION_ID
1483
+ // + its CLAUDE_CODE_SESSION_ID mirror let scripts/hooks correlate work
1484
+ // to the agent session (the mirror is what CC-targeting tools expect).
1476
1485
  env: {
1477
1486
  ...process.env,
1478
- ...(sessionId ? { CC_SESSION_ID: String(sessionId) } : {}),
1487
+ CLAUDECODE: "1",
1488
+ ...(sessionId
1489
+ ? {
1490
+ CC_SESSION_ID: String(sessionId),
1491
+ CLAUDE_CODE_SESSION_ID: String(sessionId),
1492
+ }
1493
+ : {}),
1479
1494
  },
1480
1495
  });
1481
1496
  return attachDescriptor(
@@ -1,18 +1,28 @@
1
1
  /**
2
2
  * `--fallback-model` support — Claude-Code parity for unattended runs.
3
3
  *
4
- * Wraps the agent loop's LLM call so a single request that fails with a
5
- * *retryable* error (overload / rate-limit / transient network) is transparently
6
- * re-issued once with a backup model. Because it sits at the chatFn seam
7
- * (`agentLoop` uses `options.chatFn || chatWithTools`), fallback needs no changes
8
- * to the runners — the wrapped fn is passed in via `options.chatFn`.
4
+ * Wraps the agent loop's LLM call so a request that fails with a *retryable*
5
+ * error (overload / rate-limit / transient network) or because the primary
6
+ * model is *not found* (decommissioned / mistyped id) is transparently
7
+ * re-issued against a chain of up to a few backup models, in order. Because it
8
+ * sits at the chatFn seam (`agentLoop` uses `options.chatFn || chatWithTools`),
9
+ * fallback needs no changes to the runners — the wrapped fn is passed in via
10
+ * `options.chatFn`.
9
11
  *
10
- * Same-provider only: the fallback swaps `options.model`, keeping the configured
12
+ * Parity reference: Claude Code 2.1.166 added an ordered fallback chain (up to
13
+ * 3 models) and 2.1.152 switches to the configured fallback when the primary
14
+ * model is "not found".
15
+ *
16
+ * Same-provider only: each hop swaps `options.model`, keeping the configured
11
17
  * provider / baseUrl / apiKey. Cross-provider fallback is a larger feature.
12
18
  */
13
19
 
14
20
  import { chatWithTools } from "./agent-core.js";
15
21
 
22
+ // Claude Code caps the fallback chain at 3 backups; mirror that here so a
23
+ // mis-configured comma list can't fan out into an unbounded retry storm.
24
+ const MAX_FALLBACK_MODELS = 3;
25
+
16
26
  // Heuristics for "try again on a different model" — overloaded backends,
17
27
  // rate limits, and transient connectivity. Deliberately conservative: a 4xx
18
28
  // that is not 429 (bad request / auth) is NOT retried.
@@ -36,6 +46,22 @@ const RETRYABLE_PATTERNS = [
36
46
  /network error/i,
37
47
  ];
38
48
 
49
+ // A primary model that no longer exists (decommissioned / typo / not enabled
50
+ // for this key) is NOT transient, but it IS exactly the case the fallback
51
+ // chain exists for. Detected separately from RETRYABLE so an auth/quota 4xx
52
+ // (which a different model would also hit) is still surfaced, not masked.
53
+ const MODEL_NOT_FOUND_PATTERNS = [
54
+ /model[^a-z]*not[^a-z]*found/i,
55
+ /model_not_found/i,
56
+ /no such model/i,
57
+ /unknown model/i,
58
+ /model .* does not exist/i,
59
+ /does not exist.*model/i,
60
+ /invalid model/i,
61
+ /model .* is not (?:available|supported)/i,
62
+ /unsupported model/i,
63
+ ];
64
+
39
65
  /**
40
66
  * Decide whether an error from an LLM call warrants a fallback retry.
41
67
  * @param {any} err
@@ -64,46 +90,115 @@ export function isRetryableModelError(err) {
64
90
  }
65
91
 
66
92
  /**
67
- * Build a chatFn that retries once on the fallback model.
93
+ * Decide whether an error means the *primary model is unavailable* (not found /
94
+ * decommissioned / not enabled), which a different model in the chain might
95
+ * resolve. Kept separate from {@link isRetryableModelError} so generic 4xx
96
+ * (auth / quota / bad request) is never silently retried.
97
+ * @param {any} err
98
+ * @returns {boolean}
99
+ */
100
+ export function isModelNotFoundError(err) {
101
+ if (!err) return false;
102
+ const status =
103
+ typeof err.status === "number"
104
+ ? err.status
105
+ : typeof err.statusCode === "number"
106
+ ? err.statusCode
107
+ : null;
108
+ // A bare 404 from a model endpoint almost always means "this model id".
109
+ if (status === 404) return true;
110
+
111
+ const parts = [
112
+ err.message,
113
+ typeof err.code === "string" ? err.code : "",
114
+ err.cause?.message,
115
+ err.cause?.code,
116
+ ]
117
+ .filter(Boolean)
118
+ .join(" ");
119
+ return MODEL_NOT_FOUND_PATTERNS.some((re) => re.test(parts));
120
+ }
121
+
122
+ /**
123
+ * Normalize a fallback-model spec into an ordered, de-duplicated list.
124
+ * Accepts a single string, a comma-separated string, an array (whose entries
125
+ * may themselves be comma-separated), or nullish. Trims, drops empties, removes
126
+ * duplicates (first wins), and caps at {@link MAX_FALLBACK_MODELS}.
127
+ * @param {string|string[]|null|undefined} input
128
+ * @returns {string[]}
129
+ */
130
+ export function normalizeFallbackModels(input) {
131
+ if (input == null) return [];
132
+ const raw = Array.isArray(input) ? input : [input];
133
+ const out = [];
134
+ for (const entry of raw) {
135
+ if (typeof entry !== "string") continue;
136
+ for (const piece of entry.split(",")) {
137
+ const m = piece.trim();
138
+ if (m && !out.includes(m)) out.push(m);
139
+ if (out.length >= MAX_FALLBACK_MODELS) return out;
140
+ }
141
+ }
142
+ return out;
143
+ }
144
+
145
+ /**
146
+ * Build a chatFn that walks an ordered fallback chain when the primary fails.
147
+ *
148
+ * On a retryable error (or a model-not-found error) the call is re-issued
149
+ * against the next distinct model in the chain; this repeats down the chain
150
+ * until one succeeds or the chain is exhausted (then the last error is thrown).
151
+ * A fallback equal to the model just tried is skipped (no wasted round-trip).
68
152
  *
69
153
  * @param {object} opts
70
- * @param {string} opts.fallbackModel backup model name (required)
154
+ * @param {string|string[]} [opts.fallbackModels] ordered backup model(s)
155
+ * @param {string} [opts.fallbackModel] single backup (back-compat)
71
156
  * @param {Function} [opts.baseChatFn=chatWithTools] underlying LLM call
72
- * @param {Function} [opts.isRetryable] error predicate (testing seam)
73
- * @param {Function} [opts.onFallback] notified ({from,to,error}) on retry
157
+ * @param {Function} [opts.isRetryable] transient-error predicate (seam)
158
+ * @param {Function} [opts.isModelNotFound] missing-model predicate (seam)
159
+ * @param {Function} [opts.onFallback] notified ({from,to,error}) per hop
74
160
  * @returns {Function} a (messages, options) => Promise<result> chatFn
75
161
  */
76
162
  export function makeFallbackChatFn(opts = {}) {
77
- const fallbackModel = opts.fallbackModel;
163
+ const models = normalizeFallbackModels(
164
+ opts.fallbackModels != null ? opts.fallbackModels : opts.fallbackModel,
165
+ );
78
166
  const baseChatFn = opts.baseChatFn || chatWithTools;
79
167
  const isRetryable = opts.isRetryable || isRetryableModelError;
168
+ const isModelNotFound = opts.isModelNotFound || isModelNotFoundError;
80
169
  const onFallback = opts.onFallback;
81
170
 
82
171
  return async function chatWithFallback(messages, options = {}) {
83
172
  try {
84
173
  return await baseChatFn(messages, options);
85
- } catch (err) {
86
- const primaryModel = options.model;
87
- // Skip a no-op retry when the fallback is the same model as the primary.
88
- if (
89
- !fallbackModel ||
90
- fallbackModel === primaryModel ||
91
- !isRetryable(err)
92
- ) {
93
- throw err;
94
- }
95
- if (typeof onFallback === "function") {
174
+ } catch (firstErr) {
175
+ let err = firstErr;
176
+ let lastTried = options.model;
177
+ for (const candidate of models) {
178
+ // Skip a no-op hop (fallback identical to the model just attempted).
179
+ if (!candidate || candidate === lastTried) continue;
180
+ // Only advance the chain for transient failures or a missing primary;
181
+ // a real bad-request / auth error is surfaced immediately.
182
+ if (!isRetryable(err) && !isModelNotFound(err)) throw err;
183
+ if (typeof onFallback === "function") {
184
+ try {
185
+ onFallback({
186
+ from: lastTried,
187
+ to: candidate,
188
+ error: err?.message || String(err),
189
+ });
190
+ } catch {
191
+ // Notification is best-effort — never mask the retry.
192
+ }
193
+ }
194
+ lastTried = candidate;
96
195
  try {
97
- onFallback({
98
- from: primaryModel,
99
- to: fallbackModel,
100
- error: err?.message || String(err),
101
- });
102
- } catch {
103
- // Notification is best-effort — never mask the retry.
196
+ return await baseChatFn(messages, { ...options, model: candidate });
197
+ } catch (nextErr) {
198
+ err = nextErr;
104
199
  }
105
200
  }
106
- return await baseChatFn(messages, { ...options, model: fallbackModel });
201
+ throw err;
107
202
  }
108
203
  };
109
204
  }
@@ -527,6 +527,8 @@ export async function runAgentHeadless(options = {}, deps = {}) {
527
527
  includeRegistered: options.useRegisteredMcp !== false,
528
528
  ide: options.ide,
529
529
  cwd: options.cwd || process.cwd(),
530
+ // advertise the session id to spawned stdio MCP servers
531
+ sessionId,
530
532
  },
531
533
  {
532
534
  writeErr,
@@ -460,6 +460,8 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
460
460
  includeRegistered: options.useRegisteredMcp !== false,
461
461
  ide: options.ide,
462
462
  cwd: options.cwd || process.cwd(),
463
+ // advertise the session id to spawned stdio MCP servers
464
+ sessionId,
463
465
  },
464
466
  {
465
467
  writeErr,
@@ -91,6 +91,13 @@ export async function setupMcpFromConfig(servers, deps = {}) {
91
91
  connected,
92
92
  } = result;
93
93
 
94
+ // Advertise the agent session id to stdio MCP servers spawned below
95
+ // (CC_SESSION_ID / CLAUDE_CODE_SESSION_ID + CLAUDECODE marker). Idempotent —
96
+ // safe when an accumulating `into` client was already given one.
97
+ if (deps.sessionId != null && typeof mcpClient.setSessionId === "function") {
98
+ mcpClient.setSessionId(deps.sessionId);
99
+ }
100
+
94
101
  for (const [name, cfg] of Object.entries(servers)) {
95
102
  // Skip a name already connected — an earlier batch (ad-hoc --mcp-config)
96
103
  // wins over a later one (registered) on a clash.
@@ -385,13 +392,17 @@ export async function resolveAgentMcp(args = {}, deps = {}) {
385
392
  const doFile = deps.loadMcpConfig || loadMcpConfig;
386
393
  const doReg = deps.loadRegisteredMcp || loadRegisteredMcp;
387
394
  const doIde = deps.loadIdeMcp || loadIdeMcp;
395
+ // Thread the agent session id down to setupMcpFromConfig so spawned stdio MCP
396
+ // servers get CC_SESSION_ID / CLAUDE_CODE_SESSION_ID (Claude-Code parity).
397
+ const fwd =
398
+ args.sessionId != null ? { ...deps, sessionId: args.sessionId } : deps;
388
399
  let result = null;
389
400
  if (args.mcpConfigPath) {
390
- result = await doFile(args.mcpConfigPath, deps); // fail-fast on bad file
401
+ result = await doFile(args.mcpConfigPath, fwd); // fail-fast on bad file
391
402
  }
392
403
  if (args.includeRegistered !== false && args.db) {
393
404
  result = await doReg(args.db, {
394
- ...deps,
405
+ ...fwd,
395
406
  all: args.allRegistered === true,
396
407
  into: result || undefined,
397
408
  });
@@ -402,7 +413,7 @@ export async function resolveAgentMcp(args = {}, deps = {}) {
402
413
  if (args.ide === true || inIde) {
403
414
  result = await doIde(
404
415
  { cwd: args.cwd, env, force: args.ide === true },
405
- { ...deps, into: result || undefined },
416
+ { ...fwd, into: result || undefined },
406
417
  );
407
418
  }
408
419
  }
@@ -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-BvqAck49.js";import{_ as v,b as m}from"./index-CzeRvhia.js";import{a7 as y,M}from"./icons-DP3uiYxy.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"},T={class:"subtitle"},k={class:"explainer"};function w(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",T,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 I=v(B,[["render",w],["__scopeId","data-v-9262cc45"],["__file","/tmp/cc-web-panel-sT7rhN/repo/packages/web-panel/src/views/MobileProjects.vue"]]);export{I as default};
@@ -1,7 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./ChatBubbleRenderer-rH_t53ZW.js","./vendor-BvqAck49.js","./index-CzeRvhia.js","./icons-DP3uiYxy.js","./index-Cq93VfoF.css","./ChatBubbleRenderer-gy5SDGw2.css","./OrderTableRenderer-BhlKyGrE.js","./OrderTableRenderer-CfrDjSHT.css","./TimelineRenderer-DuMkErBx.js","./TimelineRenderer-BlTAtkOc.css","./EmailListRenderer-mJViHjiq.js","./EmailListRenderer-DTPZPx_S.css","./GenericCardRenderer-B_a0l9U4.js","./GenericCardRenderer-o85VDYQS.css"])))=>i.map(i=>d[i]);
2
- import{E as ue,r as R,b as w,I as y,P as u,J as O,U as v,c,S as C,V as E,_ as M,F as B,Z as se,a0 as le,R as x,K as m,Q as b,W as A,o as J}from"./vendor-BvqAck49.js";import{u as U}from"./usePersonalDataHub-Dp04zAB3.js";import{_ as F,e as L,d as P}from"./index-CzeRvhia.js";import{a9 as q,af as z,M as Q,aH as G,u as H,aG as K,ap as W,ab as Y,e as de,d as fe,k as pe,ah as me,az as _e,R as ge}from"./icons-DP3uiYxy.js";const I=Object.freeze({q:"",category:null,adapter:null,subtype:null,since:null,until:null}),N=50,Z=300,X=ue("pdhBrowser",()=>{const r=R({...I}),t=R([]),n=R(null),e=R(!1),o=R(!1),l=R(null),a=R(null),s=R(!1),i=R({byCategory:{},byAdapter:{},bySubtype:{},total:0});let d=0,_=null;const T=w(()=>t.value.length>0),j=w(()=>n.value!=null);function h(S={}){const p={},f=r.value;return f.q&&f.q.trim()&&(p.q=f.q.trim()),f.category&&(p.category=f.category),f.adapter&&(p.adapter=f.adapter),f.subtype&&(p.subtype=f.subtype),Number.isFinite(f.since)&&(p.since=f.since),Number.isFinite(f.until)&&(p.until=f.until),{...p,...S}}async function g(){const S=++d;e.value=!0,l.value=null;const p=U();try{const[f,D]=await Promise.all([p.searchEvents(h({limit:N})),p.facetCounts({...r.value.q&&r.value.q.trim()?{q:r.value.q.trim()}:{},...Number.isFinite(r.value.since)?{since:r.value.since}:{},...Number.isFinite(r.value.until)?{until:r.value.until}:{}})]);if(S!==d)return;t.value=f.rows||[],n.value=f.nextCursor||null,a.value=f.mode||"like",s.value=!!f.shortQuery,i.value={byCategory:D.byCategory||{},byAdapter:D.byAdapter||{},bySubtype:D.bySubtype||{},total:D.total||0}}catch(f){if(S!==d)return;l.value=f&&f.message?f.message:String(f),t.value=[],n.value=null}finally{S===d&&(e.value=!1)}}async function k(){if(!n.value||o.value)return;o.value=!0,l.value=null;const S=U();try{const p=await S.searchEvents(h({cursor:n.value,limit:N}));t.value=t.value.concat(p.rows||[]),n.value=p.nextCursor||null,a.value=p.mode||a.value}catch(p){l.value=p&&p.message?p.message:String(p)}finally{o.value=!1}}function ae(S,p){if(!(S in I))throw new Error(`pdhBrowser.setFilter: unknown key "${S}"`);r.value={...r.value,[S]:p},_&&clearTimeout(_),_=setTimeout(()=>{_=null,g()},Z)}function ie(S){return r.value={...I,...S},_&&(clearTimeout(_),_=null),g()}function ce(){r.value={...I},t.value=[],n.value=null,l.value=null,i.value={byCategory:{},byAdapter:{},bySubtype:{},total:0}}return{filters:r,results:t,cursor:n,isLoading:e,isAppending:o,error:l,mode:a,shortQuery:s,facets:i,hasResults:T,canLoadMore:j,search:g,loadMore:k,setFilter:ae,setFilters:ie,reset:ce,PAGE_SIZE:N,SEARCH_DEBOUNCE_MS:Z}}),ye=Object.freeze(["chat","social","email","shopping","travel","system","ai-chat","other"]),ve=Object.freeze({chat:"社交聊天",social:"内容平台",email:"邮件",shopping:"支付订单",travel:"出行",system:"系统数据","ai-chat":"AI 对话",other:"其他"});function V(r){return ve[r]||r||"未知"}const be=Object.freeze([["wechat","chat"],["messaging-","chat"],["social-","social"],["email-","email"],["shopping-","shopping"],["alipay-","shopping"],["travel-","travel"],["system-data","system"],["browser-","system"],["vscode","system"],["win-recent","system"],["git-activity","system"],["shell-history","system"],["local-files","system"],["ai-chat-","ai-chat"]]);function $(r){if(typeof r!="string"||r.length===0)return"other";for(const[t,n]of be)if(t.endsWith("-")||t==="system-data"){if(r.startsWith(t))return n}else if(r===t)return n;return"other"}const he={__name:"CategorySidebar",props:{selected:{type:String,default:null},facets:{type:Object,default:()=>({byCategory:{},total:0})}},emits:["select"],setup(r,{expose:t}){t();const n=r,e=w(()=>n.facets.total||0),o={chat:Y,social:W,email:K,shopping:H,travel:G,system:Q,"ai-chat":z,other:q};function l(i){return o[i]||q}function a(i){return i?{backgroundColor:"#fff",color:"#1677ff"}:{backgroundColor:"#f0f0f0",color:"#666"}}const s={props:n,total:e,ICONS:o,iconFor:l,badgeStyle:a,computed:w,get AppstoreOutlined(){return q},get MessageOutlined(){return Y},get PlayCircleOutlined(){return W},get MailOutlined(){return K},get ShoppingOutlined(){return H},get CarOutlined(){return G},get MobileOutlined(){return Q},get RobotOutlined(){return z},get CATEGORIES(){return ye},get categoryLabel(){return V}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}},Se={class:"pdh-sidebar"},Oe=["onClick"],we={class:"label"};function Ce(r,t,n,e,o,l){const a=y("a-badge");return u(),O("div",Se,[t[2]||(t[2]=v("div",{class:"sidebar-title"},"数据类型",-1)),v("div",{class:M(["cat-item",{active:n.selected===null}]),onClick:t[0]||(t[0]=s=>r.$emit("select",null))},[c(e.AppstoreOutlined,{class:"icon"}),t[1]||(t[1]=v("span",{class:"label"},"全部",-1)),e.total>0?(u(),C(a,{key:0,count:e.total,"number-style":e.badgeStyle(n.selected===null),"overflow-count":9999},null,8,["count","number-style"])):E("v-if",!0)],2),(u(!0),O(B,null,se(e.CATEGORIES,s=>(u(),O("div",{key:s,class:M(["cat-item",{active:n.selected===s,dim:!n.facets.byCategory[s]}]),onClick:i=>r.$emit("select",s)},[(u(),C(le(e.iconFor(s)),{class:"icon"})),v("span",we,x(e.categoryLabel(s)),1),n.facets.byCategory[s]?(u(),C(a,{key:0,count:n.facets.byCategory[s],"number-style":e.badgeStyle(n.selected===s),"overflow-count":9999},null,8,["count","number-style"])):E("v-if",!0)],10,Oe))),128))])}const ke=F(he,[["render",Ce],["__scopeId","data-v-6b62a22e"],["__file","/tmp/cc-web-panel-sT7rhN/repo/packages/web-panel/src/components/pdh/CategorySidebar.vue"]]),Ee={__name:"SearchFilterBar",props:{filters:{type:Object,required:!0},facets:{type:Object,default:()=>({byAdapter:{}})},isLoading:{type:Boolean,default:!1},mode:{type:String,default:null},shortQuery:{type:Boolean,default:!1}},emits:["set-filter","reset"],setup(r,{expose:t,emit:n}){t();const e=r,o=n,l=w(()=>e.filters.category?`在「${e.filters.category}」类目内搜索…`:"搜索关键词(如:支付宝、罗技、Kotlin)…"),a=w(()=>Object.entries(e.facets.byAdapter||{}).sort((g,k)=>k[1]-g[1]).map(([g,k])=>({value:g,label:`${g} (${k})`}))),s=w(()=>!e.filters.since&&!e.filters.until?null:[e.filters.since?new Date(e.filters.since):null,e.filters.until?new Date(e.filters.until):null]),i=w(()=>!!(e.filters.q||e.filters.adapter||e.filters.subtype||e.filters.since||e.filters.until));function d(h){o("set-filter","q",h||"")}function _(h){o("set-filter","q",h||"")}function T(h){if(!h||h.length===0){o("set-filter","since",null),o("set-filter","until",null);return}const[g,k]=h;o("set-filter","since",g?+g:null),o("set-filter","until",k?+k:null)}const j={props:e,emit:o,placeholderText:l,adapterOptions:a,dateRangeValue:s,hasActiveFilters:i,onQInput:d,onSearch:_,onDateChange:T,computed:w,get SearchOutlined(){return pe},get CloseCircleOutlined(){return fe},get InfoCircleOutlined(){return de}};return Object.defineProperty(j,"__isScriptSetup",{enumerable:!1,value:!0}),j}},Re={class:"pdh-filter-bar"},xe={key:1,class:"hint"},Te={key:2,class:"hint"};function je(r,t,n,e,o,l){const a=y("a-input-search"),s=y("a-select"),i=y("a-range-picker"),d=y("a-button");return u(),O("div",Re,[c(a,{value:n.filters.q,placeholder:e.placeholderText,"enter-button":"搜索","allow-clear":"",loading:n.isLoading,style:{flex:"1","max-width":"480px"},"onUpdate:value":e.onQInput,onSearch:e.onSearch},{prefix:m(()=>[c(e.SearchOutlined)]),_:1},8,["value","placeholder","loading"]),c(s,{value:n.filters.adapter,placeholder:"所有 adapter","allow-clear":"",options:e.adapterOptions,style:{width:"200px"},"onUpdate:value":t[0]||(t[0]=_=>r.$emit("set-filter","adapter",_||null))},null,8,["value","options"]),c(i,{value:e.dateRangeValue,placeholder:["开始日期","结束日期"],style:{width:"280px"},"onUpdate:value":e.onDateChange},null,8,["value"]),e.hasActiveFilters?(u(),C(d,{key:0,type:"link",danger:"",onClick:t[1]||(t[1]=_=>r.$emit("reset"))},{icon:m(()=>[c(e.CloseCircleOutlined)]),default:m(()=>[t[2]||(t[2]=b(" 清空筛选 ",-1))]),_:1})):E("v-if",!0),n.shortQuery?(u(),O("span",xe,[c(e.InfoCircleOutlined),t[3]||(t[3]=b(" 关键词需至少 3 字 (FTS5 trigram 限制) ",-1))])):n.mode==="like"?(u(),O("span",Te,[c(e.InfoCircleOutlined),t[4]||(t[4]=b(" 当前为 LIKE 兜底模式 ",-1))])):E("v-if",!0)])}const Ae=F(Ee,[["render",je],["__scopeId","data-v-d7cce6e9"],["__file","/tmp/cc-web-panel-sT7rhN/repo/packages/web-panel/src/components/pdh/SearchFilterBar.vue"]]),Le={__name:"RendererDispatcher",props:{event:{type:Object,required:!0}},setup(r,{expose:t}){t();const n=A(()=>L(()=>import("./ChatBubbleRenderer-rH_t53ZW.js"),__vite__mapDeps([0,1,2,3,4,5]),import.meta.url)),e=A(()=>L(()=>import("./OrderTableRenderer-BhlKyGrE.js"),__vite__mapDeps([6,1,2,3,4,7]),import.meta.url)),o=A(()=>L(()=>import("./TimelineRenderer-DuMkErBx.js"),__vite__mapDeps([8,1,2,3,4,9]),import.meta.url)),l=A(()=>L(()=>import("./EmailListRenderer-mJViHjiq.js"),__vite__mapDeps([10,1,2,3,4,11]),import.meta.url)),a=A(()=>L(()=>import("./GenericCardRenderer-B_a0l9U4.js"),__vite__mapDeps([12,1,2,3,4,13]),import.meta.url));function s(d){const _=d&&d.source&&d.source.adapter;switch($(_)){case"chat":case"ai-chat":return n;case"shopping":return e;case"travel":return o;case"email":return l;default:return a}}const i={ChatBubbleRenderer:n,OrderTableRenderer:e,TimelineRenderer:o,EmailListRenderer:l,GenericCardRenderer:a,rendererFor:s,defineAsyncComponent:A,get getCategory(){return $}};return Object.defineProperty(i,"__isScriptSetup",{enumerable:!1,value:!0}),i}};function Fe(r,t,n,e,o,l){return u(),C(le(e.rendererFor(n.event)),{event:n.event},null,8,["event"])}const De=F(Le,[["render",Fe],["__file","/tmp/cc-web-panel-sT7rhN/repo/packages/web-panel/src/components/pdh/renderers/RendererDispatcher.vue"]]);function ee(r){return JSON.stringify(r,null,2)}function te(r){return r.map(t=>JSON.stringify(t)).join(`
3
- `)+`
4
- `}function ne(r){const n=["id","subtype","occurredAt","occurredAtIso","actor","place","adapter","summary","contentJson","extraJson"].join(","),e=r.map(o=>{const l=Number.isFinite(o.occurredAt)?o.occurredAt:null,a=l?new Date(l).toISOString():"",s=o.source&&o.source.adapter||"",i=o.content&&(o.content.text||o.content.title||o.content.subject)||"";return[o.id||"",o.subtype||"",l!=null?String(l):"",a,o.actor||"",o.place||"",s,i,o.content?JSON.stringify(o.content):"",o.extra?JSON.stringify(o.extra):""].map(Ie).join(",")});return[n,...e].join(`
5
- `)+`
6
- `}function Ie(r){const t=String(r??"");return t.includes(",")||t.includes('"')||t.includes(`
7
- `)||t.includes("\r")?'"'+t.replace(/"/g,'""')+'"':t}function re(r,t,n="application/octet-stream"){if(typeof window>"u"||typeof document>"u")return t;const e=new Blob([r],{type:n}),o=URL.createObjectURL(e),l=document.createElement("a");return l.href=o,l.download=t,document.body.appendChild(l),l.click(),document.body.removeChild(l),setTimeout(()=>URL.revokeObjectURL(o),1e3),t}function oe(r,t=null){const n=new Date,e=n.getFullYear(),o=String(n.getMonth()+1).padStart(2,"0"),l=String(n.getDate()).padStart(2,"0"),a=r==="ndjson"?"ndjson":r,s=t?`-${t}`:"";return`pdh-events-${e}-${o}-${l}${s}.${a}`}const Pe={__name:"ExportDropdown",props:{events:{type:Array,required:!0},category:{type:String,default:null}},setup(r,{expose:t}){t();const n=r,e=w(()=>n.events.length>0),o={json:"application/json;charset=utf-8",ndjson:"application/x-ndjson;charset=utf-8",csv:"text/csv;charset=utf-8"};function l(i){switch(i){case"json":return ee(n.events);case"ndjson":return te(n.events);case"csv":return ne(n.events);default:throw new Error(`unknown format: ${i}`)}}function a({key:i}){try{const d=l(i),_=oe(i,n.category);re(d,_,o[i]),P.success(`已导出 ${n.events.length} 条到 ${_}`)}catch(d){P.error(`导出失败: ${d.message||d}`)}}const s={props:n,hasResults:e,MIME:o,serialize:l,onClick:a,computed:w,get DownloadOutlined(){return _e},get DownOutlined(){return me},get message(){return P},get eventsToJson(){return ee},get eventsToNdjson(){return te},get eventsToCsv(){return ne},get downloadAs(){return re},get suggestFilename(){return oe}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}};function qe(r,t,n,e,o,l){const a=y("a-button"),s=y("a-menu-item"),i=y("a-menu"),d=y("a-dropdown");return u(),C(d,{disabled:!e.hasResults},{overlay:m(()=>[c(i,{onClick:e.onClick},{default:m(()=>[c(s,{key:"json"},{default:m(()=>[...t[0]||(t[0]=[b("JSON (.json)",-1)])]),_:1}),c(s,{key:"ndjson"},{default:m(()=>[...t[1]||(t[1]=[b("NDJSON (.ndjson)",-1)])]),_:1}),c(s,{key:"csv"},{default:m(()=>[...t[2]||(t[2]=[b("CSV (.csv)",-1)])]),_:1})]),_:1})]),default:m(()=>[c(a,{disabled:!e.hasResults},{icon:m(()=>[c(e.DownloadOutlined)]),default:m(()=>[b(" 导出 ("+x(n.events.length)+") ",1),c(e.DownOutlined)]),_:1},8,["disabled"])]),_:1},8,["disabled"])}const Ne=F(Pe,[["render",qe],["__file","/tmp/cc-web-panel-sT7rhN/repo/packages/web-panel/src/components/pdh/ExportDropdown.vue"]]),Be={__name:"PdhVaultBrowser",setup(r,{expose:t}){t();const n=X(),e=w(()=>n.filters.q?`没有匹配 "${n.filters.q}" 的事件 — 试试更短的关键词或换个类目`:n.filters.category?`「${V(n.filters.category)}」类目下还没有数据 — 去采集页同步对应 adapter`:"Vault 里还没有数据 — 去「个人数据中台」页面同步任意 adapter");function o(s){n.filters.category=s,n.search()}function l(s,i){n.setFilter(s,i)}J(()=>{!n.hasResults&&!n.isLoading&&n.search()});const a={store:n,emptyHint:e,onCategorySelect:o,onSetFilter:l,onMounted:J,computed:w,get ReloadOutlined(){return ge},get usePdhBrowserStore(){return X},get categoryLabel(){return V},CategorySidebar:ke,SearchFilterBar:Ae,RendererDispatcher:De,ExportDropdown:Ne};return Object.defineProperty(a,"__isScriptSetup",{enumerable:!1,value:!0}),a}},Ve={class:"pdh-browser-page"},Me={class:"page-header"},Je={class:"main-pane"},Ue={class:"results-summary"},ze={key:0},Qe={key:0},Ge={key:1},He={class:"loaded-of"},Ke={class:"results-list"},We={key:2,class:"load-more"};function Ye(r,t,n,e,o,l){const a=y("a-tag"),s=y("a-button"),i=y("a-space"),d=y("a-col"),_=y("a-spin"),T=y("a-alert"),j=y("a-empty"),h=y("a-row");return u(),O("div",Ve,[v("div",Me,[t[6]||(t[6]=v("div",null,[v("h2",{class:"page-title"},"数据浏览器"),v("p",{class:"page-sub"}," Vault 里所有已采集的数据,按类目浏览 / 全文检索 / 时间窗口筛选。 完全离线,不外传。 ")],-1)),c(i,null,{default:m(()=>[e.store.mode==="fts5"?(u(),C(a,{key:0,color:"green"},{default:m(()=>[...t[3]||(t[3]=[b("FTS5 trigram",-1)])]),_:1})):e.store.mode==="like"?(u(),C(a,{key:1,color:"orange"},{default:m(()=>[...t[4]||(t[4]=[b("LIKE 兜底",-1)])]),_:1})):E("v-if",!0),c(e.ExportDropdown,{events:e.store.results,category:e.store.filters.category},null,8,["events","category"]),c(s,{onClick:t[0]||(t[0]=g=>e.store.search()),loading:e.store.isLoading},{icon:m(()=>[c(e.ReloadOutlined)]),default:m(()=>[t[5]||(t[5]=b(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),c(h,{gutter:16,class:"browser-layout"},{default:m(()=>[c(d,{xs:24,sm:24,md:6,lg:5,xl:4},{default:m(()=>[c(e.CategorySidebar,{selected:e.store.filters.category,facets:e.store.facets,onSelect:e.onCategorySelect},null,8,["selected","facets"])]),_:1}),c(d,{xs:24,sm:24,md:18,lg:19,xl:20},{default:m(()=>[v("div",Je,[c(e.SearchFilterBar,{filters:e.store.filters,facets:e.store.facets,"is-loading":e.store.isLoading,mode:e.store.mode,"short-query":e.store.shortQuery,onSetFilter:e.onSetFilter,onReset:t[1]||(t[1]=g=>{e.store.reset(),e.store.search()})},null,8,["filters","facets","is-loading","mode","short-query"]),v("div",Ue,[e.store.isLoading&&e.store.results.length===0?(u(),O("span",ze,[c(_,{size:"small"}),t[7]||(t[7]=b(" 载入中… ",-1))])):(u(),O(B,{key:1},[v("strong",null,x(e.store.facets.total),1),t[11]||(t[11]=b(" 条事件 ",-1)),e.store.filters.category?(u(),O("span",Qe,[t[8]||(t[8]=b(" / 当前类目 ",-1)),v("strong",null,x(e.categoryLabel(e.store.filters.category)),1),v("strong",null,x(e.store.facets.byCategory[e.store.filters.category]||0),1)])):E("v-if",!0),e.store.filters.q?(u(),O("span",Ge,[t[9]||(t[9]=b(' / 关键词 "',-1)),v("em",null,x(e.store.filters.q),1),t[10]||(t[10]=b('"',-1))])):E("v-if",!0),v("span",He," / 已显示 "+x(e.store.results.length),1)],64))]),e.store.error?(u(),C(T,{key:0,type:"error","show-icon":"",message:e.store.error,closable:"",style:{margin:"12px 0"}},null,8,["message"])):E("v-if",!0),!e.store.isLoading&&e.store.results.length===0&&!e.store.error?(u(),C(j,{key:1,description:e.emptyHint,style:{"margin-top":"40px"}},null,8,["description"])):E("v-if",!0),v("div",Ke,[(u(!0),O(B,null,se(e.store.results,(g,k)=>(u(),C(e.RendererDispatcher,{key:`r-${k}-${g.id}`,event:g},null,8,["event"]))),128))]),e.store.canLoadMore?(u(),O("div",We,[c(s,{loading:e.store.isAppending,onClick:t[2]||(t[2]=g=>e.store.loadMore()),block:""},{default:m(()=>[...t[12]||(t[12]=[b(" 加载下一页 (50 条) ",-1)])]),_:1},8,["loading"])])):E("v-if",!0)])]),_:1})]),_:1})])}const tt=F(Be,[["render",Ye],["__scopeId","data-v-0f7c02cd"],["__file","/tmp/cc-web-panel-sT7rhN/repo/packages/web-panel/src/views/PdhVaultBrowser.vue"]]);export{tt as default};
@@ -1 +0,0 @@
1
- import{I as i,J as A,U as I,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-BvqAck49.js";import{_ as we,b as re,u as ie,d}from"./index-CzeRvhia.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-DP3uiYxy.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),U=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 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:()=>V(o)}}async function V(o){v.value=o,P.value=!0,k.value=!0,U.value=[];try{const f=await w("project.listFiles",{projectId:o.id,limit:200},`project list-files ${o.id} --json`,8e3);U.value=Array.isArray(f?.files)?f.files:[]}catch{U.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:""}),h=u(!1),m=u(!1),R=u({path:""}),n=u(!1),c=u(null),N=u(""),Y=u(!1);function ue(){j.value={path:"",content:""},b.value=!0}function ce(){R.value={path:""},h.value=!0}async function q(){if(v.value){k.value=!0;try{const o=await w("project.listFiles",{projectId:v.value.id,limit:200},`project list-files ${v.value.id} --json`,8e3);U.value=Array.isArray(o?.files)?o.files:[]}catch(o){d.error("刷新文件失败: "+(o.message||o))}finally{k.value=!1}}}async function fe(){if(!j.value.path.trim()){d.warning("请输入文件路径");return}if(v.value){D.value=!0;try{const o=await w("project.createFile",{projectId:v.value.id,filePath:j.value.path.trim(),content:j.value.content||""},`project create-file ${v.value.id} "${j.value.path.trim()}" --json`,8e3);o?.id?(d.success(`已创建文件 '${o.file_name}'`),b.value=!1,await q(),await C()):d.error("创建文件失败")}catch(o){d.error(o.message||String(o))}finally{D.value=!1}}}async function pe(){if(!R.value.path.trim()){d.warning("请输入文件夹路径");return}if(v.value){m.value=!0;try{const o=await w("project.createFolder",{projectId:v.value.id,folderPath:R.value.path.trim()},`project create-folder ${v.value.id} "${R.value.path.trim()}" --json`,8e3);o?.id?(d.success(`已创建文件夹 '${o.file_name}'`),h.value=!1,await q(),await C()):d.error("创建文件夹失败")}catch(o){d.error(o.message||String(o))}finally{m.value=!1}}}async function ve(o){try{(await w("project.deleteFile",{fileId:o.id},`project delete-file ${o.id} --json`,8e3))?.deleted?(d.success(`已删除 '${o.file_name}'`),await q(),await C()):d.error("删除失败")}catch(f){d.error(f.message||String(f))}}async function me(o){if(o.is_folder){d.info("文件夹无内容可编辑");return}try{const f=await w("project.getFile",{fileId:o.id},`project get-file ${o.id} --json`,8e3);c.value=o,N.value=f?.content||"",n.value=!0}catch(f){d.error("读取文件失败: "+(f.message||f))}}async function _e(){if(c.value){Y.value=!0;try{(await w("project.writeFile",{fileId:c.value.id,content:N.value},`project write-file ${c.value.id} --json`,8e3))?.id?(d.success("已保存"),n.value=!1,await q()):d.error("保存失败")}catch(o){d.error(o.message||String(o))}finally{Y.value=!1}}}oe(()=>{C()});const le={t:te,ws:e,isEmbedded:W,callProjectTopic:w,loading:B,projects:y,statusFilter:O,nameFilter:S,detailOpen:P,detail:v,files:U,filesLoading:k,createOpen:E,creating:L,newProject:F,columns:z,countByStatus:M,filteredProjects:J,statusColor:g,syncColor:K,formatTime:Q,loadAll:C,onRowClick:G,openDetail:V,onDelete:H,onShowCreate:X,onCreate:T,createFileOpen:b,creatingFile:D,newFile:j,createFolderOpen:h,creatingFolder:m,newFolder:R,editFileOpen:n,editingFile:c,editFileContent:N,savingFile:Y,openCreateFile:ue,openCreateFolder:ce,refreshFiles:q,onCreateFile:fe,onCreateFolder:pe,onDeleteFile:ve,openEditFile:me,onSaveFile:_e,ref:u,computed:ee,onMounted:oe,get ReloadOutlined(){return Se},get PlusOutlined(){return Oe},get FolderOutlined(){return xe},get FileTextOutlined(){return Ce},get CheckCircleOutlined(){return je},get CheckSquareOutlined(){return be},get FileAddOutlined(){return Fe},get FolderAddOutlined(){return ke},get message(){return d},get useI18n(){return re},get useWsStore(){return ie},get useShellMode(){return de}};return Object.defineProperty(le,"__isScriptSetup",{enumerable:!1,value:!0}),le}},ze={style:{display:"flex","align-items":"center","justify-content":"space-between","margin-bottom":"24px"}},he={class:"page-title"},Ae={class:"page-sub"},Ie={class:"filter-bar",style:{"margin-bottom":"12px",display:"flex",gap:"12px","align-items":"center"}},Ue={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"),U=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"),K=i("a-descriptions"),Q=i("a-divider"),C=i("a-empty"),G=i("a-list-item"),V=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"),h=i("a-modal"),m=i("a-select-option"),R=i("a-select");return p(),A("div",null,[I("div",ze,[I("div",null,[I("h2",he,s(e.t("projects.title")),1),I("p",Ae,[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(U,{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 "),I("div",Ie,[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(),A("code",Ue,s(c.id.slice(0,8))+"…",1)):n.key==="name"?(p(),A(ne,{key:1},[I("strong",null,s(c.name),1),c.description?(p(),A("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(),A(ne,{key:5},[r(s(e.formatTime(c.updated_at)),1)],64)):n.key==="actions"?(p(),x(O,{key:6,onClick:l[2]||(l[2]=ge(()=>{},["stop"]))},{default:a(()=>[t(y,{size:"small",onClick:N=>e.openDetail(c)},{default:a(()=>[...l[26]||(l[26]=[r("详情",-1)])]),_:1},8,["onClick"]),t(M,{title:`删除项目 '${c.name}' ?`,"ok-text":"删除","ok-type":"danger","cancel-text":"取消",onConfirm:N=>e.onDelete(c)},{default:a(()=>[t(y,{size:"small",danger:""},{default:a(()=>[...l[27]||(l[27]=[r("删除",-1)])]),_:1})]),_:1},8,["title","onConfirm"])]),_:2},1024)):_("v-if",!0)]),_:1},8,["data-source","loading"])):_("v-if",!0),_(" Detail drawer "),t(X,{open:e.detailOpen,"onUpdate:open":l[3]||(l[3]=n=>e.detailOpen=n),title:e.detail?.name||"项目详情",width:"640",placement:"right"},{default:a(()=>[e.detail?(p(),x(K,{key:0,column:1,bordered:"",size:"small"},{default:a(()=>[t(g,{label:"ID"},{default:a(()=>[I("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(),A("code",Re,s(e.detail.root_path),1)):(p(),A("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(V,{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(),A("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(()=>[I("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(h,{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(h,{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(h,{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(h,{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-sT7rhN/repo/packages/web-panel/src/views/Projects.vue"]]);export{We as default};
@@ -1 +0,0 @@
1
- import{O as r}from"./index-CzeRvhia.js";const o=((n,a,e)=>{r(n,`[ant-design-vue: ${a}] ${e}`)});export{o as d};
@@ -1 +0,0 @@
1
- import{C as o}from"./Col-CqXc8_ft.js";import{U as t}from"./index-CzeRvhia.js";import"./vendor-BvqAck49.js";import"./index-WDQkyh-E.js";import"./icons-DP3uiYxy.js";const s=t(o);export{s as default};
@@ -1 +0,0 @@
1
- import{A as o}from"./Row-DAio6Dx2.js";import{U as t}from"./index-CzeRvhia.js";import"./vendor-BvqAck49.js";import"./responsiveObserve-B0Cn1i64.js";import"./useFlexGapSupport-y8cUyKiP.js";import"./styleChecker-aYEwS4Pw.js";import"./index-WDQkyh-E.js";import"./icons-DP3uiYxy.js";const l=t(o);export{l as default};