chainlesschain 0.162.47 → 0.162.48

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 (161) hide show
  1. package/package.json +2 -2
  2. package/src/assets/web-panel/assets/{AIOps-BBjFOl4N.js → AIOps-BeMOUkMq.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-B7A6lHz3.js → ActionButton-DrRegmIt.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-DZgNxdvw.js → Analytics-BM7hvUn8.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-CFbPWVnh.js → AppLayout-BfLLYSz_.js} +5 -5
  6. package/src/assets/web-panel/assets/{Audit-Ao9RxevG.js → Audit-BpiPR-rs.js} +1 -1
  7. package/src/assets/web-panel/assets/{Backup-B1AGqahI.js → Backup-BLq4IRI9.js} +1 -1
  8. package/src/assets/web-panel/assets/{BaseInput-M01bA2JM.js → BaseInput-Bv89IFrM.js} +1 -1
  9. package/src/assets/web-panel/assets/{Chat-CC0Gmd9k.js → Chat-BUM9MdnH.js} +6 -6
  10. package/src/assets/web-panel/assets/ChatBubbleRenderer-rH_t53ZW.js +1 -0
  11. package/src/assets/web-panel/assets/{Checkbox-CpEqAg5P.js → Checkbox-82jih_zU.js} +1 -1
  12. package/src/assets/web-panel/assets/{Codegen-9c1H2P_L.js → Codegen-ygmM1mNL.js} +1 -1
  13. package/src/assets/web-panel/assets/{Col-sH2Obo8q.js → Col-CqXc8_ft.js} +1 -1
  14. package/src/assets/web-panel/assets/{Community-DyzjH37r.js → Community-CqPPfyR3.js} +1 -1
  15. package/src/assets/web-panel/assets/{Compact-DsNatLOG.js → Compact-LR8Z206-.js} +1 -1
  16. package/src/assets/web-panel/assets/{Compliance-B3ws7qwL.js → Compliance-D4alm_Gx.js} +1 -1
  17. package/src/assets/web-panel/assets/{Cowork-odGfUMsv.js → Cowork-D-DLVanT.js} +2 -2
  18. package/src/assets/web-panel/assets/{Cron-bxO6NLDR.js → Cron-UDtmjvd4.js} +2 -2
  19. package/src/assets/web-panel/assets/{Crosschain-xHCPQpE9.js → Crosschain-iqbVDPNE.js} +1 -1
  20. package/src/assets/web-panel/assets/{DID-3l7HvzNC.js → DID-DzdUfzc9.js} +2 -2
  21. package/src/assets/web-panel/assets/{Dashboard-BNzT5YBj.js → Dashboard-DvKp1skY.js} +2 -2
  22. package/src/assets/web-panel/assets/{Dropdown-DZynMYpG.js → Dropdown-S6ORlfef.js} +1 -1
  23. package/src/assets/web-panel/assets/{EmailListRenderer-6HZ2XA9g.js → EmailListRenderer-mJViHjiq.js} +1 -1
  24. package/src/assets/web-panel/assets/{FamilyGuardDashboard-DqzqNzRP.js → FamilyGuardDashboard-A4Lu5m_e.js} +1 -1
  25. package/src/assets/web-panel/assets/{Federation-CI7lf1MF.js → Federation-Bv-6737r.js} +1 -1
  26. package/src/assets/web-panel/assets/{FormItemContext-D2m3YZ-k.js → FormItemContext-DNcZoiWu.js} +1 -1
  27. package/src/assets/web-panel/assets/{GenericCardRenderer-Bwcc-9EB.js → GenericCardRenderer-B_a0l9U4.js} +1 -1
  28. package/src/assets/web-panel/assets/{Git-C7qN3bA1.js → Git-BbVAsh_N.js} +2 -2
  29. package/src/assets/web-panel/assets/{Governance-JfuugS1c.js → Governance-ChxUMZEU.js} +1 -1
  30. package/src/assets/web-panel/assets/{Inference-BNsHm2IH.js → Inference-Buu_bAQ-.js} +1 -1
  31. package/src/assets/web-panel/assets/{KnowledgeGraph-CTH_FiL1.js → KnowledgeGraph-BMmMjxEu.js} +1 -1
  32. package/src/assets/web-panel/assets/{Logs-CxcfBcmS.js → Logs-BeGHcPEC.js} +2 -2
  33. package/src/assets/web-panel/assets/{Marketplace-B9PU3qlx.js → Marketplace-CP2Qg_xJ.js} +1 -1
  34. package/src/assets/web-panel/assets/{McpTools-BlvQpnvj.js → McpTools-C42B4JYb.js} +5 -5
  35. package/src/assets/web-panel/assets/{Memory-Diiig9gp.js → Memory-D5VeitFY.js} +2 -2
  36. package/src/assets/web-panel/assets/{MobileBridge-CGfUn4xi.js → MobileBridge-BouoJ2FQ.js} +2 -2
  37. package/src/assets/web-panel/assets/MobileProjects-mAJsyk7U.js +1 -0
  38. package/src/assets/web-panel/assets/{Mtc-CT_1x1Gr.js → Mtc-Chn6ES5y.js} +6 -6
  39. package/src/assets/web-panel/assets/{MtcAudit-DPAjU1Qn.js → MtcAudit-D0_Q6GEn.js} +2 -2
  40. package/src/assets/web-panel/assets/{Multisig-nks2HW0C.js → Multisig-BWaCi_wo.js} +3 -3
  41. package/src/assets/web-panel/assets/{NLProgramming-BWd74a91.js → NLProgramming-CoSEiroa.js} +1 -1
  42. package/src/assets/web-panel/assets/{Notes-B342yG3u.js → Notes-CiqCbDw3.js} +3 -3
  43. package/src/assets/web-panel/assets/{NotificationSettings-C9kjn20B.js → NotificationSettings-BXmzKL9F.js} +1 -1
  44. package/src/assets/web-panel/assets/{OrderTableRenderer-DKQ3FPUN.js → OrderTableRenderer-BhlKyGrE.js} +1 -1
  45. package/src/assets/web-panel/assets/{Organization-Ch-qkiyP.js → Organization-CAVgSxyI.js} +4 -4
  46. package/src/assets/web-panel/assets/{Overflow-DeV865TY.js → Overflow-BIVUo8YB.js} +1 -1
  47. package/src/assets/web-panel/assets/{P2P-9pzyAAE1.js → P2P-DX-Ov-eJ.js} +2 -2
  48. package/src/assets/web-panel/assets/{PdhVaultBrowser-oGgQiWpR.js → PdhVaultBrowser-6clRu-J6.js} +3 -3
  49. package/src/assets/web-panel/assets/{Permissions-MPDfvUva.js → Permissions-CANl-V55.js} +4 -4
  50. package/src/assets/web-panel/assets/{PersonalDataHub-Es8GFY4_.js → PersonalDataHub-BE90gjUO.js} +2 -2
  51. package/src/assets/web-panel/assets/{Pipeline-R10lJHtN.js → Pipeline-Ck8lV8Pn.js} +1 -1
  52. package/src/assets/web-panel/assets/{Privacy-8YMg8xrV.js → Privacy-BBYUDK4T.js} +1 -1
  53. package/src/assets/web-panel/assets/{ProjectInit-B-L3DMBv.js → ProjectInit-DcbOrnbt.js} +2 -2
  54. package/src/assets/web-panel/assets/{ProjectSettings-pR4l7GCe.js → ProjectSettings-DZ6-whxP.js} +2 -2
  55. package/src/assets/web-panel/assets/Projects-DO25SEFT.js +1 -0
  56. package/src/assets/web-panel/assets/{Providers-C_E-G6Bh.js → Providers-VWoO_Y9u.js} +1 -1
  57. package/src/assets/web-panel/assets/{QuickAsk-CM-FSYbK.js → QuickAsk-RJfSXWYg.js} +1 -1
  58. package/src/assets/web-panel/assets/{Recommend-DcwFptAP.js → Recommend-Y7MWWkXa.js} +1 -1
  59. package/src/assets/web-panel/assets/{Reputation-DJKj97w-.js → Reputation-nG8nut3l.js} +1 -1
  60. package/src/assets/web-panel/assets/{Row-BfI2mGUm.js → Row-DAio6Dx2.js} +1 -1
  61. package/src/assets/web-panel/assets/{RssFeed-D6tzthT0.js → RssFeed-DwY72Lc7.js} +2 -2
  62. package/src/assets/web-panel/assets/{Search-CkxIxA5y.js → Search-qGG6AUWY.js} +1 -1
  63. package/src/assets/web-panel/assets/{Security-BeTfFgoX.js → Security-Djsmom8n.js} +4 -4
  64. package/src/assets/web-panel/assets/{Services-BahX89X1.js → Services-DTEgHkUO.js} +2 -2
  65. package/src/assets/web-panel/assets/{Skeleton-55na3k97.js → Skeleton-R5xY0J9Y.js} +1 -1
  66. package/src/assets/web-panel/assets/{Skills-DZ-dxsiR.js → Skills-CFaRLO3o.js} +1 -1
  67. package/src/assets/web-panel/assets/{Sla-BUTClrI0.js → Sla-B5bzoY1I.js} +1 -1
  68. package/src/assets/web-panel/assets/{SpeechSettings-C0c2AmSU.js → SpeechSettings-B_al6SiQ.js} +1 -1
  69. package/src/assets/web-panel/assets/{SyncSettings-Vr5zzdPz.js → SyncSettings-DkUU63oJ.js} +2 -2
  70. package/src/assets/web-panel/assets/Tasks-C2y4XdrQ.js +1 -0
  71. package/src/assets/web-panel/assets/{Templates-DnaU_7nb.js → Templates-CcYJxTNB.js} +1 -1
  72. package/src/assets/web-panel/assets/{Tenant-1dw4SFBA.js → Tenant-B0_sIpl2.js} +1 -1
  73. package/src/assets/web-panel/assets/{Terminal-Pe1vBvOm.js → Terminal-B_waZb0O.js} +2 -2
  74. package/src/assets/web-panel/assets/{TimelineRenderer-dDxMvAvM.js → TimelineRenderer-DuMkErBx.js} +1 -1
  75. package/src/assets/web-panel/assets/{Tokens-CPJMLjkE.js → Tokens-BXjPA6rV.js} +1 -1
  76. package/src/assets/web-panel/assets/{Trigger-B1IWp6HK.js → Trigger-BMAAx3Uu.js} +1 -1
  77. package/src/assets/web-panel/assets/{Trust-iswzFvfA.js → Trust-BPeNXpsi.js} +1 -1
  78. package/src/assets/web-panel/assets/{UkeySign-CuMmDUvU.js → UkeySign-A0qabV14.js} +1 -1
  79. package/src/assets/web-panel/assets/{VideoEditing-BguHSBQ5.js → VideoEditing-BMLfYykd.js} +1 -1
  80. package/src/assets/web-panel/assets/{Wallet-CW4PFXSw.js → Wallet-BfDI3zjs.js} +4 -4
  81. package/src/assets/web-panel/assets/{WebAuthn-YOO0lqjJ.js → WebAuthn-BCnZEScW.js} +3 -3
  82. package/src/assets/web-panel/assets/{WorkflowEditor-A_z3yLuG.js → WorkflowEditor-DvtS5Asf.js} +1 -1
  83. package/src/assets/web-panel/assets/{chat-BSHj9uiJ.js → chat-CDJZtBM7.js} +1 -1
  84. package/src/assets/web-panel/assets/{colors-D7gA-kvN.js → colors-fbH1Saco.js} +1 -1
  85. package/src/assets/web-panel/assets/{compact-item-ChDt0wUv.js → compact-item-CuZFa9l8.js} +1 -1
  86. package/src/assets/web-panel/assets/{createContext-5UAhDsNU.js → createContext-CQuPOqqD.js} +1 -1
  87. package/src/assets/web-panel/assets/devWarning-mhGhHpNs.js +1 -0
  88. package/src/assets/web-panel/assets/{hasIn-7ysmGHSf.js → hasIn-CDZlDrhJ.js} +1 -1
  89. package/src/assets/web-panel/assets/{index-BoCy4bxa.js → index--SCX46Az.js} +1 -1
  90. package/src/assets/web-panel/assets/{index-NtFFgW-x.js → index-14gri6Vh.js} +1 -1
  91. package/src/assets/web-panel/assets/{index-CGVsJplV.js → index-BJCXJCUA.js} +1 -1
  92. package/src/assets/web-panel/assets/{index-Dq4fd0cB.js → index-BKaue5Pv.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-D9R6sJiP.js → index-BNEG9-EK.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-WM_jYoK8.js → index-BSy0noke.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-trVj-RG1.js → index-BdORz0iZ.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-B6OX-6N1.js → index-BhZkMMey.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-ZOmjAajS.js → index-BivMeInw.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DslmMjVo.js → index-Bt1j0mjJ.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-C62SpQws.js → index-Bz5_6E63.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-BzPxVTI2.js → index-BzIDfObk.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-BLoQ2FkI.js → index-C6epsHef.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-Dj3IHF24.js → index-CAzMdnkI.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DttrXREN.js → index-CD9ml9ZJ.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-D-pJNNc5.js → index-CNmJrCxV.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-CHdEHlNY.js → index-COSyGm80.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-BcPEgfGF.js → index-CQ5FVEji.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BTzZlYgQ.js → index-CdiNFWPp.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-pk9WOpeN.js → index-CkhudJH0.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Db4hf2WV.js → index-CmeO_DfK.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-HUiKkQOf.js → index-CnfR7qmj.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-C93TfkpQ.js → index-Cr_shi_7.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-DSRnnGez.js → index-CzeRvhia.js} +3 -3
  113. package/src/assets/web-panel/assets/{index--UCy6rsJ.js → index-D365qmj8.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-COwKdUAS.js → index-DGAK9Dj4.js} +1 -1
  115. package/src/assets/web-panel/assets/index-DGBjZXvW.js +1 -0
  116. package/src/assets/web-panel/assets/{index-B_xBUmAE.js → index-DNN-xBWV.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-_8xZf-zU.js → index-Deqod8La.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-QPBJl4wk.js → index-DhFyStIG.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-s_MPIulF.js → index-DjgZRX0_.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BhsGGFa4.js → index-Dkuecn17.js} +1 -1
  121. package/src/assets/web-panel/assets/index-DujMkFuc.js +1 -0
  122. package/src/assets/web-panel/assets/{index-DcKVERvm.js → index-DvBgQoaw.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-Cl10KB1R.js → index-DwAiu9LT.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-C4nXq9eB.js → index-WDQkyh-E.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-CylU_ot3.js → index-kGzPbvry.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DfjMbFZA.js → index-oe9ZPRtQ.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-BGlolJwU.js → index-ycBlRXAf.js} +1 -1
  128. package/src/assets/web-panel/assets/{initDefaultProps-BcWdcWH2.js → initDefaultProps-DHRWNV-y.js} +1 -1
  129. package/src/assets/web-panel/assets/{motion-D-GC86LC.js → motion-MJ2jhdVO.js} +1 -1
  130. package/src/assets/web-panel/assets/{move-7N01T4vz.js → move-Bly0QFE5.js} +1 -1
  131. package/src/assets/web-panel/assets/{omit-B8_G8lAi.js → omit-DkoMB0pZ.js} +1 -1
  132. package/src/assets/web-panel/assets/{pickAttrs-BeEwgLq8.js → pickAttrs-9M-gsXIc.js} +1 -1
  133. package/src/assets/web-panel/assets/{placementArrow-CiQwkkN_.js → placementArrow-Bnht1xci.js} +1 -1
  134. package/src/assets/web-panel/assets/{responsiveObserve-CtfIP2YM.js → responsiveObserve-B0Cn1i64.js} +1 -1
  135. package/src/assets/web-panel/assets/{slide-DnA-Z3fK.js → slide-BdI4DDyM.js} +1 -1
  136. package/src/assets/web-panel/assets/{statusUtils-Ckaf7hg9.js → statusUtils-DdBktcMD.js} +1 -1
  137. package/src/assets/web-panel/assets/{styleChecker-CE7d6-LQ.js → styleChecker-aYEwS4Pw.js} +1 -1
  138. package/src/assets/web-panel/assets/{useFlexGapSupport-BBC2EqTi.js → useFlexGapSupport-y8cUyKiP.js} +1 -1
  139. package/src/assets/web-panel/assets/{useFs-BWncdesy.js → useFs-Bk1SrPFp.js} +1 -1
  140. package/src/assets/web-panel/assets/{usePersonalDataHub-BVJgKdiT.js → usePersonalDataHub-Dp04zAB3.js} +1 -1
  141. package/src/assets/web-panel/assets/{vnode-CdZoGwk8.js → vnode-B52a38TC.js} +1 -1
  142. package/src/assets/web-panel/assets/{zoom-8BsyiHWV.js → zoom-DFwyL43U.js} +1 -1
  143. package/src/assets/web-panel/index.html +1 -1
  144. package/src/commands/agent.js +62 -0
  145. package/src/lib/agent-worktree.js +78 -0
  146. package/src/lib/ide-context.js +168 -0
  147. package/src/lib/memory-injection.js +2 -0
  148. package/src/lib/safe-mode.js +31 -0
  149. package/src/lib/settings-hooks.cjs +5 -0
  150. package/src/repl/agent-repl.js +72 -17
  151. package/src/repl/ide-status.js +76 -0
  152. package/src/runtime/agent-core.js +21 -0
  153. package/src/runtime/headless-runner.js +11 -2
  154. package/src/runtime/headless-stream.js +15 -4
  155. package/src/assets/web-panel/assets/ChatBubbleRenderer-DKe4yjqq.js +0 -1
  156. package/src/assets/web-panel/assets/MobileProjects-CFvH6A9E.js +0 -1
  157. package/src/assets/web-panel/assets/Projects-5vaXw-7d.js +0 -1
  158. package/src/assets/web-panel/assets/Tasks-BrouZA03.js +0 -1
  159. package/src/assets/web-panel/assets/devWarning-NW6VMT5L.js +0 -1
  160. package/src/assets/web-panel/assets/index-A6oY6RQQ.js +0 -1
  161. package/src/assets/web-panel/assets/index-Cn2g4vqt.js +0 -1
@@ -0,0 +1,31 @@
1
+ /**
2
+ * `cc agent --safe-mode` — Claude-Code 2.1.169 parity ("--safe-mode flag
3
+ * disables customizations"): one flag flips every customization kill-switch
4
+ * so a misbehaving hook / memory file / persona can be isolated by running
5
+ * the agent bare.
6
+ *
7
+ * Deliberate divergence from Claude Code: settings PERMISSION RULES stay
8
+ * active — deny rules are a safety surface, and "debug my customizations"
9
+ * must never widen what the agent may do.
10
+ */
11
+
12
+ /** env switches applied by --safe-mode (all existing kill-switches). */
13
+ export const SAFE_MODE_SWITCHES = Object.freeze({
14
+ CC_PROJECT_MEMORY: "0", // cc.md / CLAUDE.md / rules auto-load
15
+ CC_SETTINGS_HOOKS: "0", // .claude/settings.json hooks
16
+ CC_MEMORY_INJECT: "0", // session-core startup memory recall
17
+ CC_IDE_CONTEXT: "0", // <ide-context> injection + diagnostics feedback
18
+ CC_STATUSLINE: "0", // custom/built-in status line
19
+ CC_UPDATE_NOTICE: "0", // passive update nudge
20
+ });
21
+
22
+ /**
23
+ * Apply safe mode to an env (default process.env).
24
+ * @returns {string[]} the switch names applied (for the startup notice)
25
+ */
26
+ export function applySafeMode(env = process.env) {
27
+ for (const [k, v] of Object.entries(SAFE_MODE_SWITCHES)) {
28
+ env[k] = v;
29
+ }
30
+ return Object.keys(SAFE_MODE_SWITCHES);
31
+ }
@@ -76,6 +76,11 @@ function readJson(file, onWarn) {
76
76
  function loadHooks({ cwd = process.cwd(), settingsFile, onWarn } = {}) {
77
77
  const merged = {};
78
78
  const files = [];
79
+ // Safe-mode kill switch (`cc agent --safe-mode` sets CC_SETTINGS_HOOKS=0):
80
+ // run with NO settings hooks so a broken hook can be diagnosed.
81
+ if (process.env.CC_SETTINGS_HOOKS === "0") {
82
+ return { hooks: merged, files };
83
+ }
79
84
  for (const file of settingsFiles(cwd, settingsFile)) {
80
85
  const data = readJson(file, onWarn);
81
86
  const block =
@@ -761,6 +761,7 @@ export async function startAgentRepl(options = {}) {
761
761
  "/cowork",
762
762
  "/exit",
763
763
  "/help",
764
+ "/ide",
764
765
  "/mcp",
765
766
  "/model",
766
767
  "/output-style",
@@ -769,6 +770,7 @@ export async function startAgentRepl(options = {}) {
769
770
  "/provider",
770
771
  "/quit",
771
772
  "/reindex",
773
+ "/reload-skills",
772
774
  "/rewind",
773
775
  "/search",
774
776
  "/session",
@@ -953,8 +955,16 @@ export async function startAgentRepl(options = {}) {
953
955
  const { runBangCommand } = await import("../lib/repl-bang-memorize.js");
954
956
  const res = runBangCommand(trimmed, { cwd: process.cwd() });
955
957
  logger.log(chalk.gray(`$ ${res.cmd}`));
956
- if (res.stdout) process.stdout.write(res.stdout.endsWith("\n") ? res.stdout : `${res.stdout}\n`);
957
- if (res.stderr) process.stderr.write(chalk.red(res.stderr.endsWith("\n") ? res.stderr : `${res.stderr}\n`));
958
+ if (res.stdout)
959
+ process.stdout.write(
960
+ res.stdout.endsWith("\n") ? res.stdout : `${res.stdout}\n`,
961
+ );
962
+ if (res.stderr)
963
+ process.stderr.write(
964
+ chalk.red(
965
+ res.stderr.endsWith("\n") ? res.stderr : `${res.stderr}\n`,
966
+ ),
967
+ );
958
968
  if (res.error) logger.error(`shell error: ${res.error.message}`);
959
969
  logger.log(chalk.gray(`(exit ${res.exitCode})`));
960
970
  messages.push(res.contextMessage);
@@ -969,14 +979,17 @@ export async function startAgentRepl(options = {}) {
969
979
  // cc.md (auto-loaded next session) and keep it active in this one.
970
980
  if (trimmed.startsWith("#") && trimmed.slice(1).trim()) {
971
981
  try {
972
- const { appendMemoryNote } = await import("../lib/repl-bang-memorize.js");
982
+ const { appendMemoryNote } =
983
+ await import("../lib/repl-bang-memorize.js");
973
984
  const res = appendMemoryNote(trimmed, { cwd: process.cwd() });
974
985
  messages.push({
975
986
  role: "system",
976
987
  content: `<memory-note source="${res.target}">${res.note}</memory-note>`,
977
988
  });
978
989
  logger.log(
979
- chalk.green(`✔ remembered in ${res.target}${res.created ? " (created)" : ""}`),
990
+ chalk.green(
991
+ `✔ remembered in ${res.target}${res.created ? " (created)" : ""}`,
992
+ ),
980
993
  );
981
994
  } catch (err) {
982
995
  logger.error(`# memorize failed: ${err.message}`);
@@ -1018,6 +1031,9 @@ export async function startAgentRepl(options = {}) {
1018
1031
  logger.log(
1019
1032
  ` ${chalk.cyan("/cd <dir>")} Change working directory mid-session (completion/memory follow)`,
1020
1033
  );
1034
+ logger.log(
1035
+ ` ${chalk.cyan("/reload-skills")} Re-scan skill layers without restarting`,
1036
+ );
1021
1037
  logger.log(
1022
1038
  ` ${chalk.cyan("/compact")} Smart compact (importance-based)`,
1023
1039
  );
@@ -1055,6 +1071,9 @@ export async function startAgentRepl(options = {}) {
1055
1071
  logger.log(
1056
1072
  ` ${chalk.cyan("/sub-agents")} Show active/completed sub-agents`,
1057
1073
  );
1074
+ logger.log(
1075
+ ` ${chalk.cyan("/ide")} IDE bridge status (connected editor, tools, or why not)`,
1076
+ );
1058
1077
  logger.log(chalk.bold("\nCapabilities:"));
1059
1078
  logger.log(" Read, write, and edit files");
1060
1079
  logger.log(" Run shell commands (git, npm, etc.)");
@@ -1278,14 +1297,11 @@ export async function startAgentRepl(options = {}) {
1278
1297
 
1279
1298
  if (trimmed === "/rewind" || trimmed.startsWith("/rewind ")) {
1280
1299
  try {
1281
- const { listUserTurns, rewindToTurn, renderTurnList } = await import(
1282
- "../lib/repl-rewind.js"
1283
- );
1300
+ const { listUserTurns, rewindToTurn, renderTurnList } =
1301
+ await import("../lib/repl-rewind.js");
1284
1302
  const arg = trimmed.slice("/rewind".length).trim();
1285
1303
  if (!arg) {
1286
- logger.log(
1287
- chalk.bold("\nRewind — pick a user turn (newest first):"),
1288
- );
1304
+ logger.log(chalk.bold("\nRewind — pick a user turn (newest first):"));
1289
1305
  logger.log(renderTurnList(listUserTurns(messages)));
1290
1306
  logger.log(
1291
1307
  chalk.gray(
@@ -1320,9 +1336,8 @@ export async function startAgentRepl(options = {}) {
1320
1336
  // window. Reuses the same categorizer + estimator as the archived view.
1321
1337
  try {
1322
1338
  const { categorizeContext } = await import("../commands/context.js");
1323
- const { estimateTokens } = await import(
1324
- "../harness/prompt-compressor.js"
1325
- );
1339
+ const { estimateTokens } =
1340
+ await import("../harness/prompt-compressor.js");
1326
1341
  const { buckets, counts, total } = categorizeContext(
1327
1342
  messages,
1328
1343
  estimateTokens,
@@ -1462,6 +1477,24 @@ export async function startAgentRepl(options = {}) {
1462
1477
  }
1463
1478
 
1464
1479
  // Reindex notes
1480
+ // `/reload-skills` (Claude-Code 2.1.152 parity): re-scan the 6 skill
1481
+ // layers (incl. .claude/skills) without restarting the session.
1482
+ if (trimmed === "/reload-skills") {
1483
+ try {
1484
+ const { reloadSkills } = await import("../runtime/agent-core.js");
1485
+ const n = reloadSkills();
1486
+ logger.log(
1487
+ chalk.green(
1488
+ `✔ skills reloaded — ${n} available (6 layers re-scanned)`,
1489
+ ),
1490
+ );
1491
+ } catch (err) {
1492
+ logger.error(`/reload-skills failed: ${err.message}`);
1493
+ }
1494
+ prompt();
1495
+ return;
1496
+ }
1497
+
1465
1498
  if (trimmed === "/reindex") {
1466
1499
  if (contextEngine) {
1467
1500
  contextEngine.reindexNotes();
@@ -2085,6 +2118,22 @@ export async function startAgentRepl(options = {}) {
2085
2118
  return;
2086
2119
  }
2087
2120
 
2121
+ // `/ide` — IDE bridge connection status (Claude-Code parity): which editor
2122
+ // is connected, its tools, or why discovery came up empty.
2123
+ if (trimmed === "/ide" || trimmed === "/ide ") {
2124
+ let diag = null;
2125
+ try {
2126
+ const { diagnoseIde } = await import("../lib/ide-bridge.js");
2127
+ diag = diagnoseIde({ cwd: process.cwd(), env: process.env });
2128
+ } catch (_err) {
2129
+ // discovery is best-effort — fall back to in-session tools only
2130
+ }
2131
+ const { renderIdeStatus } = await import("./ide-status.js");
2132
+ logger.log(renderIdeStatus(_adhocMcp, diag));
2133
+ prompt();
2134
+ return;
2135
+ }
2136
+
2088
2137
  // User-defined slash-command macros (.claude/commands/*.md), Claude-Code
2089
2138
  // parity. resolveSlashMacro maps a leading /name to a command macro and
2090
2139
  // expands its template; a non-match returns the line unchanged so a literal
@@ -2201,9 +2250,17 @@ export async function startAgentRepl(options = {}) {
2201
2250
  // Ephemeral: persistence stores effectivePrompt, not this snapshot.
2202
2251
  // Best-effort; CC_IDE_CONTEXT=0 disables.
2203
2252
  try {
2204
- const { buildIdePromptContext } = await import("../lib/ide-context.js");
2253
+ const { buildIdePromptContext, expandIdeMentions } =
2254
+ await import("../lib/ide-context.js");
2205
2255
  const ideCtx = await buildIdePromptContext(_adhocMcp);
2206
2256
  if (ideCtx) userContent += `\n\n${ideCtx}`;
2257
+ // Explicit @selection / @diagnostics mentions (Claude-Code parity);
2258
+ // scan the user's original prompt, append the expansion ephemerally.
2259
+ const mentioned = await expandIdeMentions(effectivePrompt, _adhocMcp);
2260
+ for (const w of mentioned.warnings) {
2261
+ logger.info(chalk.yellow(`[@ide] ${w}`));
2262
+ }
2263
+ if (mentioned.block) userContent += `\n\n${mentioned.block}`;
2207
2264
  } catch (_err) {
2208
2265
  // optional polish — never fail the turn over it
2209
2266
  }
@@ -2433,9 +2490,7 @@ export async function startAgentRepl(options = {}) {
2433
2490
  // Esc interrupt: an aborted turn is normal flow, not an error — the
2434
2491
  // partial conversation stays usable and queued lines still drain.
2435
2492
  if (err?.name === "AbortError" || /abort/i.test(err?.message || "")) {
2436
- logger.log(
2437
- chalk.yellow("⎋ turn interrupted — partial progress kept"),
2438
- );
2493
+ logger.log(chalk.yellow("⎋ turn interrupted — partial progress kept"));
2439
2494
  prompt();
2440
2495
  return;
2441
2496
  }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * `/ide` REPL command renderer (Claude-Code parity) — report whether an IDE
3
+ * bridge is connected to THIS agent session, which editor/port/workspace it
4
+ * is, the IDE tools the agent can call, and — when nothing is connected — why
5
+ * discovery came up empty plus how to fix it.
6
+ *
7
+ * Pure and dependency-free: takes the resolved MCP bundle (for the live,
8
+ * in-session connection) and an optional `diagnoseIde()` result (for lockfile
9
+ * details), returns plain text. The REPL does the I/O.
10
+ */
11
+
12
+ const IDE_PREFIX = "mcp__ide__";
13
+
14
+ /** Sorted bare IDE tool names connected in this session (e.g. ["getSelection"]). */
15
+ export function ideToolNames(mcp) {
16
+ const ex = (mcp && mcp.externalToolExecutors) || {};
17
+ return Object.keys(ex)
18
+ .filter((k) => k.startsWith(IDE_PREFIX) && ex[k] && ex[k].kind === "mcp")
19
+ .map((k) => k.slice(IDE_PREFIX.length))
20
+ .sort();
21
+ }
22
+
23
+ /**
24
+ * @param {object|null} mcp resolved bundle from resolveAgentMcp (or null)
25
+ * @param {object|null} diag diagnoseIde() result, or null when unavailable
26
+ * @returns {string}
27
+ */
28
+ export function renderIdeStatus(mcp, diag = null) {
29
+ const tools = ideToolNames(mcp);
30
+ const chosen = diag && diag.chosen ? diag.chosen : null;
31
+ const lines = [];
32
+
33
+ if (tools.length > 0) {
34
+ const where = chosen
35
+ ? `${chosen.ide || "ide"} on 127.0.0.1:${chosen.port} (${chosen.transport})`
36
+ : "an editor extension";
37
+ lines.push(`● IDE bridge connected — ${where}`);
38
+ if (
39
+ chosen &&
40
+ Array.isArray(chosen.workspaceFolders) &&
41
+ chosen.workspaceFolders.length
42
+ ) {
43
+ lines.push(` workspace: ${chosen.workspaceFolders.join(", ")}`);
44
+ }
45
+ lines.push(` tools: ${tools.map((t) => IDE_PREFIX + t).join(", ")}`);
46
+ lines.push(
47
+ " selection/diagnostics auto-share each turn · " +
48
+ "@selection / @diagnostics expand on demand",
49
+ );
50
+ return lines.join("\n");
51
+ }
52
+
53
+ lines.push("○ IDE bridge not connected to this session");
54
+ if (diag) {
55
+ if (diag.reason) lines.push(` ${diag.reason}`);
56
+ if (Array.isArray(diag.locks) && diag.locks.length) {
57
+ lines.push(` ${diag.locks.length} lockfile(s) in ${diag.lockDir}:`);
58
+ for (const l of diag.locks.slice(0, 5)) {
59
+ lines.push(
60
+ ` - ${l.ide || "?"} :${l.port} ${l.transport} ` +
61
+ `(matchScore ${l.matchScore})`,
62
+ );
63
+ }
64
+ }
65
+ lines.push(
66
+ diag.inIdeTerminal
67
+ ? " you're in an IDE terminal — restart the agent so it re-discovers the bridge"
68
+ : " launch `cc` from your IDE's integrated terminal, or pass --ide to force-connect",
69
+ );
70
+ } else {
71
+ lines.push(
72
+ " install the ChainlessChain IDE extension, then launch cc from its terminal",
73
+ );
74
+ }
75
+ return lines.join("\n");
76
+ }
@@ -334,6 +334,16 @@ export function getAgentToolDescriptors(options = {}) {
334
334
 
335
335
  const _defaultSkillLoader = new CLISkillLoader();
336
336
 
337
+ /**
338
+ * Re-scan all skill layers (Claude-Code `/reload-skills` parity): drops the
339
+ * default loader's cache so newly added/edited SKILL.md dirs are picked up
340
+ * without restarting the session. Returns the resolved skill count.
341
+ */
342
+ export function reloadSkills() {
343
+ _defaultSkillLoader.clearCache();
344
+ return _defaultSkillLoader.loadAll().length;
345
+ }
346
+
337
347
  // ─── Cached environment detection ────────────────────────────────────────
338
348
 
339
349
  let _cachedPython = null;
@@ -1399,6 +1409,11 @@ async function executeToolInner(
1399
1409
  cwd: task.cwd,
1400
1410
  shell: true,
1401
1411
  windowsHide: true,
1412
+ // Same CC_SESSION_ID correlation as the foreground path.
1413
+ env: {
1414
+ ...process.env,
1415
+ ...(sessionId ? { CC_SESSION_ID: String(sessionId) } : {}),
1416
+ },
1402
1417
  // POSIX: own process group so check_shell{kill}/teardown can signal
1403
1418
  // the whole tree (shell + its grandchild command). No-op on Windows
1404
1419
  // where the tree is killed via taskkill /T instead.
@@ -1456,6 +1471,12 @@ async function executeToolInner(
1456
1471
  encoding: "utf8",
1457
1472
  timeout: _resolveShellTimeout(args.timeout),
1458
1473
  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.
1476
+ env: {
1477
+ ...process.env,
1478
+ ...(sessionId ? { CC_SESSION_ID: String(sessionId) } : {}),
1479
+ },
1459
1480
  });
1460
1481
  return attachDescriptor(
1461
1482
  {
@@ -552,15 +552,24 @@ export async function runAgentHeadless(options = {}, deps = {}) {
552
552
  // session replays the prompt, not a stale editor snapshot. Best-effort with
553
553
  // a short timeout; CC_IDE_CONTEXT=0 disables.
554
554
  try {
555
- const { buildIdePromptContext, appendTextToContent } =
555
+ const { buildIdePromptContext, appendTextToContent, expandIdeMentions } =
556
556
  await import("../lib/ide-context.js");
557
+ const last = messages[messages.length - 1];
557
558
  const ideCtx = await (deps.buildIdePromptContext || buildIdePromptContext)(
558
559
  mcp,
559
560
  );
560
561
  if (ideCtx) {
561
- const last = messages[messages.length - 1];
562
562
  last.content = appendTextToContent(last.content, ideCtx);
563
563
  }
564
+ // Explicit @selection / @diagnostics mentions in the user's prompt
565
+ // (Claude-Code parity). Scan the ORIGINAL prompt so injected file-ref
566
+ // blocks can't spoof a mention; append the expansion to the in-flight
567
+ // message only (ephemeral, like the ambient block above).
568
+ const mentioned = await expandIdeMentions(prompt, mcp);
569
+ for (const w of mentioned.warnings) writeErr(` @ide: ${w}\n`);
570
+ if (mentioned.block) {
571
+ last.content = appendTextToContent(last.content, mentioned.block);
572
+ }
564
573
  } catch {
565
574
  // IDE context is optional polish — never fail the run over it.
566
575
  }
@@ -105,13 +105,15 @@ export function parseInputEvent(line) {
105
105
  // Vision input (chat-panel image paste): {"type":"user","text":…,
106
106
  // "images":["/abs/file.png", …]} — file paths, resolved at turn build via
107
107
  // the same image-input pipeline as `cc agent --image`.
108
- const rawImages = obj && typeof obj === "object" ? obj.images || msg.images : null;
108
+ const rawImages =
109
+ obj && typeof obj === "object" ? obj.images || msg.images : null;
109
110
  const images = Array.isArray(rawImages)
110
111
  ? rawImages.filter((p) => typeof p === "string" && p.trim()).slice(0, 8)
111
112
  : [];
112
113
  if (typeof content !== "string" || !content.trim()) {
113
114
  // An image-only turn is valid — give the model something to act on.
114
- if (images.length) return { text: "Please look at the attached image(s).", images };
115
+ if (images.length)
116
+ return { text: "Please look at the attached image(s).", images };
115
117
  return null;
116
118
  }
117
119
  return images.length ? { text: content, images } : { text: content };
@@ -729,11 +731,17 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
729
731
  // IDE bridge is connected — the user's selection moves between prompts.
730
732
  // Best-effort; CC_IDE_CONTEXT=0 disables.
731
733
  try {
732
- const { buildIdePromptContext } = await import("../lib/ide-context.js");
734
+ const { buildIdePromptContext, expandIdeMentions } =
735
+ await import("../lib/ide-context.js");
733
736
  const ideCtx = await (
734
737
  deps.buildIdePromptContext || buildIdePromptContext
735
738
  )(mcp);
736
739
  if (ideCtx) userContent += `\n\n${ideCtx}`;
740
+ // Explicit @selection / @diagnostics mentions (Claude-Code parity);
741
+ // scan the original user event text, append the expansion ephemerally.
742
+ const mentioned = await expandIdeMentions(parsed.text, mcp);
743
+ for (const w of mentioned.warnings) writeErr(` @ide: ${w}\n`);
744
+ if (mentioned.block) userContent += `\n\n${mentioned.block}`;
737
745
  } catch {
738
746
  // optional polish — never fail the turn over it
739
747
  }
@@ -746,7 +754,10 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
746
754
  try {
747
755
  const { resolveImages, buildUserContent } =
748
756
  await import("../lib/image-input.js");
749
- turnContent = buildUserContent(userContent, resolveImages(parsed.images));
757
+ turnContent = buildUserContent(
758
+ userContent,
759
+ resolveImages(parsed.images),
760
+ );
750
761
  } catch (err) {
751
762
  emit({
752
763
  type: "result",
@@ -1 +0,0 @@
1
- import{I as v,P as u,J as S,U as s,R as a,S as y,K as C,Q as x,V as w,_ as B,b as n}from"./vendor-BvqAck49.js";import{_ as k}from"./index-DSRnnGez.js";import"./icons-DP3uiYxy.js";const N={__name:"ChatBubbleRenderer",props:{event:{type:Object,required:!0}},setup(c,{expose:d}){d();const t=c,r=n(()=>{const e=t.event.content||{};return e.text||e.body||e.message||e.title||JSON.stringify(e).slice(0,200)}),i=n(()=>{const e=t.event.content||{};return e.from||e.sender||e.senderName||t.event.actor||"(unknown)"}),l=n(()=>{const e=(t.event.actor||"").toLowerCase();return e.includes("self")||e==="me"||e.endsWith("_self")}),o=n(()=>{const e=t.event.source.adapter||"";return e.startsWith("messaging-qq")?"magenta":e==="wechat"?"green":"blue"}),m=n(()=>{if(!t.event.occurredAt)return"";try{const e=new Date(t.event.occurredAt),p=e.getFullYear(),b=String(e.getMonth()+1).padStart(2,"0"),f=String(e.getDate()).padStart(2,"0"),g=String(e.getHours()).padStart(2,"0"),h=String(e.getMinutes()).padStart(2,"0");return`${p}-${b}-${f} ${g}:${h}`}catch{return""}}),_={props:t,messageText:r,actorLabel:i,isMine:l,adapterColor:o,formattedTime:m,computed:n};return Object.defineProperty(_,"__isScriptSetup",{enumerable:!1,value:!0}),_}},T={class:"bubble"},M={class:"meta"},R={class:"actor"},V={class:"time"},q={class:"body"};function D(c,d,t,r,i,l){const o=v("a-tag");return u(),S("div",{class:B(["chat-row",{mine:r.isMine}])},[s("div",T,[s("div",M,[s("span",R,a(r.actorLabel),1),s("span",V,a(r.formattedTime),1)]),s("div",q,a(r.messageText),1),t.event.source.adapter?(u(),y(o,{key:0,class:"src",color:r.adapterColor},{default:C(()=>[x(a(t.event.source.adapter),1)]),_:1},8,["color"])):w("v-if",!0)])],2)}const A=k(N,[["render",D],["__scopeId","data-v-49238629"],["__file","/tmp/cc-web-panel-6n5bBX/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-BvqAck49.js";import{_ as v,b as m}from"./index-DSRnnGez.js";import{a7 as y,M as B}from"./icons-DP3uiYxy.js";const M={__name:"MobileProjects",setup(p,{expose:i}){i();const c=u(),{t:e}=m();function a(){c.push("/projects")}function _(){c.push("/mobile-bridge")}const s={router:c,t:e,goToProjects:a,goToMobileBridge:_,get useRouter(){return u},get useI18n(){return m},get MobileOutlined(){return B},get FolderOutlined(){return y}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}},x={class:"mobile-projects-placeholder"},O={class:"title"},k={class:"subtitle"},w={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",k,t(e.t("mobileProjects.subtitle")),1),l(s,{message:e.t("mobileProjects.v02Banner"),type:"info","show-icon":"",class:"banner"},null,8,["message"]),o("div",w,[o("h3",null,t(e.t("mobileProjects.currentDirection")),1),o("p",null,t(e.t("mobileProjects.currentDirectionBody")),1),o("ul",null,[o("li",null,t(e.t("mobileProjects.stepPhone")),1),o("li",null,t(e.t("mobileProjects.stepTap")),1),o("li",null,t(e.t("mobileProjects.stepPull")),1)]),o("h3",null,t(e.t("mobileProjects.reverseDirection")),1),o("p",null,t(e.t("mobileProjects.reverseDirectionBody")),1)]),l(f,{class:"actions"},{default:r(()=>[l(d,{type:"primary",onClick:e.goToProjects},{default:r(()=>[l(e.FolderOutlined),b(" "+t(e.t("mobileProjects.viewLocalProjects")),1)]),_:1}),l(d,{onClick:e.goToMobileBridge},{default:r(()=>[l(e.MobileOutlined),b(" "+t(e.t("mobileProjects.checkBridge")),1)]),_:1})]),_:1})]),_:1})]),_:1})])}const N=v(M,[["render",T],["__scopeId","data-v-9262cc45"],["__file","/tmp/cc-web-panel-6n5bBX/repo/packages/web-panel/src/views/MobileProjects.vue"]]);export{N 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-BvqAck49.js";import{_ as we,b as re,u as ie,d}from"./index-DSRnnGez.js";import{u as de}from"./useShellMode-CgR0wCYM.js";import{aM as ke,aN as be,aO as Fe,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 T=u(!1),y=u([]),O=u(""),S=u(""),P=u(!1),v=u(null),h=u([]),k=u(!1),E=u(!1),L=u(!1),b=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(){T.value=!0;try{const o=await w("project.list",{limit:500},"project list --limit 500 --json",1e4);y.value=Array.isArray(o?.projects)?o.projects:Array.isArray(o)?o:[]}catch(o){d.error("加载失败: "+(o.message||o)),y.value=[]}finally{T.value=!1}}function X(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 H(){b.value={name:"",description:"",type:"document",rootPath:""},E.value=!0}async function B(){if(!b.value.name.trim()){d.warning("请输入项目名称");return}L.value=!0;try{const o=await w("project.init",{name:b.value.name.trim(),description:b.value.description||null,projectType:b.value.type,rootPath:b.value.rootPath||null},`project init "${b.value.name.trim()}" --type ${b.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 F=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:""},F.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}'`),F.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:T,projects:y,statusFilter:O,nameFilter:S,detailOpen:P,detail:v,files:h,filesLoading:k,createOpen:E,creating:L,newProject:b,columns:z,countByStatus:M,filteredProjects:J,statusColor:g,syncColor:K,formatTime:Q,loadAll:C,onRowClick:X,openDetail:V,onDelete:G,onShowCreate:H,onCreate:B,createFileOpen:F,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 Fe},get FileAddOutlined(){return be},get FolderAddOutlined(){return ke},get message(){return d},get useI18n(){return re},get useWsStore(){return ie},get useShellMode(){return de}};return Object.defineProperty(le,"__isScriptSetup",{enumerable:!1,value:!0}),le}},ze={style:{display:"flex","align-items":"center","justify-content":"space-between","margin-bottom":"24px"}},Ae={class:"page-title"},Ie={class:"page-sub"},Ue={class:"filter-bar",style:{"margin-bottom":"12px",display:"flex",gap:"12px","align-items":"center"}},he={key:0,style:{"font-size":"12px",color:"#888"}},De={key:0,style:{color:"#888","font-size":"12px"}},Re={key:0},Be={key:1,style:{color:"#888"}},Te=["onClick"],Ee={key:0,style:{color:"#888","font-size":"12px"}};function Le(se,l,te,e,W,w){const T=i("router-link"),y=i("a-button"),O=i("a-space"),S=i("a-statistic"),P=i("a-card"),v=i("a-col"),h=i("a-row"),k=i("a-radio-button"),E=i("a-radio-group"),L=i("a-input-search"),b=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"),X=i("a-list-item"),V=i("a-list"),G=i("a-spin"),H=i("a-drawer"),B=i("a-input"),F=i("a-form-item"),D=i("a-textarea"),j=i("a-form"),A=i("a-modal"),m=i("a-select-option"),R=i("a-select");return p(),I("div",null,[U("div",ze,[U("div",null,[U("h2",Ae,s(e.t("projects.title")),1),U("p",Ie,[l[17]||(l[17]=r("桌面 / CLI / 手机 三端共享同一份项目数据,Phase 3d sync 自动同步 (",-1)),t(T,{to:"/project-init"},{default:a(()=>[...l[16]||(l[16]=[r("项目初始化 / 环境设置",-1)])]),_:1}),l[18]||(l[18]=r(")",-1))])]),t(O,null,{default:a(()=>[t(y,{loading:e.loading,onClick:e.loadAll},{icon:a(()=>[t(e.ReloadOutlined)]),default:a(()=>[l[19]||(l[19]=r(" 刷新 ",-1))]),_:1},8,["loading"]),t(y,{type:"primary",onClick:e.onShowCreate},{icon:a(()=>[t(e.PlusOutlined)]),default:a(()=>[l[20]||(l[20]=r(" 新建项目 ",-1))]),_:1})]),_:1})]),_(" Stats "),t(h,{gutter:[16,16],style:{"margin-bottom":"20px"}},{default:a(()=>[t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"总项目",value:e.projects.length,"value-style":{color:"#1677ff",fontSize:"20px"}},{prefix:a(()=>[t(e.FolderOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"活跃",value:e.countByStatus.active,"value-style":{color:"#52c41a",fontSize:"20px"}},{prefix:a(()=>[t(e.CheckCircleOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"草稿",value:e.countByStatus.draft,"value-style":{color:"#8c8c8c",fontSize:"20px"}},{prefix:a(()=>[t(e.FileTextOutlined)]),_:1},8,["value"])]),_:1})]),_:1}),t(v,{xs:12,sm:8,lg:6},{default:a(()=>[t(P,{style:{background:"var(--bg-card)","border-color":"var(--border-color)"}},{default:a(()=>[t(S,{title:"已完成",value:e.countByStatus.completed,"value-style":{color:"#13c2c2",fontSize:"20px"}},{prefix:a(()=>[t(e.CheckSquareOutlined)]),_:1},8,["value"])]),_:1})]),_:1})]),_:1}),_(" Filter "),U("div",Ue,[t(E,{value:e.statusFilter,"onUpdate:value":l[0]||(l[0]=n=>e.statusFilter=n),size:"small","button-style":"solid"},{default:a(()=>[t(k,{value:""},{default:a(()=>[...l[21]||(l[21]=[r("全部",-1)])]),_:1}),t(k,{value:"active"},{default:a(()=>[...l[22]||(l[22]=[r("活跃",-1)])]),_:1}),t(k,{value:"draft"},{default:a(()=>[...l[23]||(l[23]=[r("草稿",-1)])]),_:1}),t(k,{value:"completed"},{default:a(()=>[...l[24]||(l[24]=[r("已完成",-1)])]),_:1}),t(k,{value:"archived"},{default:a(()=>[...l[25]||(l[25]=[r("已归档",-1)])]),_:1})]),_:1},8,["value"]),t(L,{value:e.nameFilter,"onUpdate:value":l[1]||(l[1]=n=>e.nameFilter=n),placeholder:"按名称过滤",style:{"max-width":"260px"},"allow-clear":""},null,8,["value"])]),!e.projects.length&&!e.loading?(p(),x(b,{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(H,{open:e.detailOpen,"onUpdate:open":l[3]||(l[3]=n=>e.detailOpen=n),title:e.detail?.name||"项目详情",width:"640",placement:"right"},{default:a(()=>[e.detail?(p(),x(K,{key:0,column:1,bordered:"",size:"small"},{default:a(()=>[t(g,{label:"ID"},{default:a(()=>[U("code",null,s(e.detail.id),1)]),_:1}),t(g,{label:"名称"},{default:a(()=>[r(s(e.detail.name),1)]),_:1}),t(g,{label:"描述"},{default:a(()=>[r(s(e.detail.description||"-"),1)]),_:1}),t(g,{label:"类型"},{default:a(()=>[t(z,null,{default:a(()=>[r(s(e.detail.project_type),1)]),_:1})]),_:1}),t(g,{label:"状态"},{default:a(()=>[t(z,{color:e.statusColor(e.detail.status)},{default:a(()=>[r(s(e.detail.status),1)]),_:1},8,["color"])]),_:1}),t(g,{label:"同步状态"},{default:a(()=>[t(z,{color:e.syncColor(e.detail.sync_status)},{default:a(()=>[r(s(e.detail.sync_status||"unknown"),1)]),_:1},8,["color"])]),_:1}),t(g,{label:"用户"},{default:a(()=>[r(s(e.detail.user_id),1)]),_:1}),t(g,{label:"根路径"},{default:a(()=>[e.detail.root_path?(p(),I("code",Re,s(e.detail.root_path),1)):(p(),I("span",Be,"(无)"))]),_:1}),t(g,{label:"文件数"},{default:a(()=>[r(s(e.detail.file_count||0),1)]),_:1}),t(g,{label:"创建"},{default:a(()=>[r(s(e.formatTime(e.detail.created_at)),1)]),_:1}),t(g,{label:"更新"},{default:a(()=>[r(s(e.formatTime(e.detail.updated_at)),1)]),_:1})]),_:1})):_("v-if",!0),t(Q,null,{default:a(()=>[...l[28]||(l[28]=[r("文件",-1)])]),_:1}),_(" Sub-phase 7.3 (2026-05-17): 文件 CRUD toolbar "),t(O,{style:{"margin-bottom":"12px"}},{default:a(()=>[t(y,{size:"small",type:"primary",disabled:!e.detail,onClick:e.openCreateFile},{default:a(()=>[t(e.FileAddOutlined),l[29]||(l[29]=r(" 新建文件 ",-1))]),_:1},8,["disabled"]),t(y,{size:"small",disabled:!e.detail,onClick:e.openCreateFolder},{default:a(()=>[t(e.FolderAddOutlined),l[30]||(l[30]=r(" 新建文件夹 ",-1))]),_:1},8,["disabled"])]),_:1}),t(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(X,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,Te)]),_:2},1024)]),_:1},8,["data-source"]))]),_:1},8,["spinning"])]),_:1},8,["open","title"]),_(" Sub-phase 7.3: Create file modal "),t(A,{open:e.createFileOpen,"onUpdate:open":l[6]||(l[6]=n=>e.createFileOpen=n),title:"新建文件","confirm-loading":e.creatingFile,"ok-text":"创建","cancel-text":"取消",onOk:e.onCreateFile},{default:a(()=>[t(j,{layout:"vertical"},{default:a(()=>[t(F,{label:"文件路径(项目内)",required:""},{default:a(()=>[t(B,{value:e.newFile.path,"onUpdate:value":l[4]||(l[4]=n=>e.newFile.path=n),placeholder:"例如 README.md 或 src/main.kt"},null,8,["value"])]),_:1}),t(F,{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(F,{label:"文件夹路径(项目内)",required:""},{default:a(()=>[t(B,{value:e.newFolder.path,"onUpdate:value":l[7]||(l[7]=n=>e.newFolder.path=n),placeholder:"例如 src/utils"},null,8,["value"])]),_:1})]),_:1})]),_:1},8,["open","confirm-loading"]),_(" Sub-phase 7.3: Edit file content modal "),t(A,{open:e.editFileOpen,"onUpdate:open":l[10]||(l[10]=n=>e.editFileOpen=n),title:`编辑 ${e.editingFile?.file_name||""}`,"confirm-loading":e.savingFile,"ok-text":"保存","cancel-text":"取消",onOk:e.onSaveFile,width:"720"},{default:a(()=>[t(D,{value:e.editFileContent,"onUpdate:value":l[9]||(l[9]=n=>e.editFileContent=n),rows:18,"auto-size":{minRows:12,maxRows:24},style:{"font-family":"monospace"}},null,8,["value"])]),_:1},8,["open","title","confirm-loading"]),_(" Create modal "),t(A,{open:e.createOpen,"onUpdate:open":l[15]||(l[15]=n=>e.createOpen=n),title:"新建项目","confirm-loading":e.creating,"ok-text":"创建","cancel-text":"取消",onOk:e.onCreate},{default:a(()=>[t(j,{layout:"vertical"},{default:a(()=>[t(F,{label:"项目名称",required:""},{default:a(()=>[t(B,{value:e.newProject.name,"onUpdate:value":l[11]||(l[11]=n=>e.newProject.name=n),placeholder:"例如:旅行计划-上海"},null,8,["value"])]),_:1}),t(F,{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(F,{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(F,{label:"根路径 (可选)"},{default:a(()=>[t(B,{value:e.newProject.rootPath,"onUpdate:value":l[14]||(l[14]=n=>e.newProject.rootPath=n),placeholder:"留空则仅元数据"},null,8,["value"])]),_:1})]),_:1})]),_:1},8,["open","confirm-loading"])])}const We=we(Pe,[["render",Le],["__scopeId","data-v-019ac5aa"],["__file","/tmp/cc-web-panel-6n5bBX/repo/packages/web-panel/src/views/Projects.vue"]]);export{We as default};
@@ -1 +0,0 @@
1
- import{E as V,b as z,r as D,I as p,J as c,U as _,c as n,K as a,S as T,V as w,o as P,x as B,P as i,Q as g,R as r,F as h,Z as F}from"./vendor-BvqAck49.js";import{u as R,_ as O}from"./index-DSRnnGez.js";import{R as E}from"./icons-DP3uiYxy.js";const I=V("tasks",()=>{const k=D([]),l=D(!1);let u=null,e=null;const b=z(()=>k.value.filter(t=>t.status==="running")),x=z(()=>k.value.filter(t=>t.status==="pending")),y=z(()=>k.value.filter(t=>t.status==="completed"||t.status==="failed"||t.status==="timeout"));async function f(){const t=R();l.value=!0;try{const s=await t.sendRaw({type:"tasks-list"});s&&Array.isArray(s.tasks)&&(k.value=s.tasks)}catch{}finally{l.value=!1}}async function o(t){const s=R();try{await s.sendRaw({type:"tasks-stop",taskId:t})}catch{}finally{await f()}}const d=D(null);function m(t=5e3){v(),f(),u=setInterval(f,t),C()}function v(){u&&(clearInterval(u),u=null),e&&(e(),e=null)}function C(){const t=R();if(e)return;const s=S=>{S.type==="task:notification"&&S.payload?.task&&(d.value=S.payload.task,f(),setTimeout(()=>{d.value=null},8e3))};e=t.onRuntimeEvent(s)}function N(t){return!t||t<0?"-":t<1e3?`${t}ms`:t<6e4?`${(t/1e3).toFixed(1)}s`:`${(t/6e4).toFixed(1)}m`}function A(t){switch(t){case"running":return"processing";case"pending":return"default";case"completed":return"success";case"failed":return"error";case"timeout":return"warning";default:return"default"}}return{tasks:k,loading:l,running:b,pending:x,completed:y,lastNotification:d,fetchTasks:f,stopTask:o,startPolling:m,stopPolling:v,formatDuration:N,getStatusColor:A}}),U={__name:"Tasks",setup(k,{expose:l}){l();const u=I(),e=[{title:"状态",key:"status",width:90},{title:"描述",key:"description",ellipsis:!0},{title:"类型",dataIndex:"type",width:100},{title:"耗时",key:"duration",width:90},{title:"创建时间",key:"createdAt",width:180},{title:"结果",key:"result",ellipsis:!0},{title:"操作",key:"action",width:80}];function b(o){return o.status==="running"&&o.startedAt?u.formatDuration(Date.now()-o.startedAt):o.completedAt&&o.startedAt?u.formatDuration(o.completedAt-o.startedAt):"-"}function x(o){return o?new Date(o).toLocaleString():"-"}function y(o,d){return o?o.length>d?`${o.slice(0,d)}...`:o:""}P(()=>u.startPolling(5e3)),B(()=>u.stopPolling());const f={store:u,columns:e,getDuration:b,formatTime:x,truncate:y,onMounted:P,onUnmounted:B,get ReloadOutlined(){return E},get useTasksStore(){return I}};return Object.defineProperty(f,"__isScriptSetup",{enumerable:!1,value:!0}),f}},L={class:"page-header"},j={key:0,class:"error-text"},J={key:1},K={class:"task-header"},M={class:"task-desc"},Q={class:"task-id"},W={class:"task-meta"},X=["title"],Z={key:0,class:"error-text"},q={key:1,class:"success-text"},G={key:2,class:"muted-text"};function H(k,l,u,e,b,x){const y=p("a-button"),f=p("a-space"),o=p("a-alert"),d=p("a-statistic"),m=p("a-card"),v=p("a-col"),C=p("a-row"),N=p("a-tag"),A=p("a-table");return i(),c("div",null,[_("div",L,[l[3]||(l[3]=_("div",null,[_("h2",{class:"page-title"},"后台任务"),_("p",{class:"page-sub"},"查看后台任务队列、实时通知和任务执行结果。")],-1)),n(f,null,{default:a(()=>[n(y,{ghost:"",loading:e.store.loading,onClick:l[0]||(l[0]=t=>e.store.fetchTasks())},{icon:a(()=>[n(e.ReloadOutlined)]),default:a(()=>[l[2]||(l[2]=g(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),e.store.lastNotification?(i(),T(o,{key:0,type:e.store.lastNotification.status==="completed"?"success":"error","show-icon":"",closable:"",class:"banner",onClose:l[1]||(l[1]=t=>e.store.lastNotification=null)},{message:a(()=>[g(" 任务"+r(e.store.lastNotification.status==="completed"?"完成":"结束")+": "+r(e.store.lastNotification.description||e.store.lastNotification.id.slice(0,16)),1)]),description:a(()=>[e.store.lastNotification.error?(i(),c("span",j,r(e.store.lastNotification.error),1)):e.store.lastNotification.result?(i(),c("span",J,r(e.truncate(String(e.store.lastNotification.result),120)),1)):w("v-if",!0)]),_:1},8,["type"])):w("v-if",!0),n(C,{gutter:[16,16],class:"stats-row"},{default:a(()=>[n(v,{xs:12,sm:6},{default:a(()=>[n(m,{class:"stat-card",size:"small"},{default:a(()=>[n(d,{title:"全部任务",value:e.store.tasks.length},null,8,["value"])]),_:1})]),_:1}),n(v,{xs:12,sm:6},{default:a(()=>[n(m,{class:"stat-card",size:"small"},{default:a(()=>[n(d,{title:"运行中",value:e.store.running.length},null,8,["value"])]),_:1})]),_:1}),n(v,{xs:12,sm:6},{default:a(()=>[n(m,{class:"stat-card",size:"small"},{default:a(()=>[n(d,{title:"等待中",value:e.store.pending.length},null,8,["value"])]),_:1})]),_:1}),n(v,{xs:12,sm:6},{default:a(()=>[n(m,{class:"stat-card",size:"small"},{default:a(()=>[n(d,{title:"已完成",value:e.store.completed.length},null,8,["value"])]),_:1})]),_:1})]),_:1}),e.store.running.length>0?(i(),T(m,{key:1,title:"运行中的任务",class:"panel-card",size:"small"},{default:a(()=>[(i(!0),c(h,null,F(e.store.running,t=>(i(),c("div",{key:t.id,class:"task-item running"},[_("div",K,[n(N,{color:e.store.getStatusColor(t.status)},{default:a(()=>[g(r(t.status.toUpperCase()),1)]),_:2},1032,["color"]),_("span",M,r(t.description),1),_("span",Q,r(t.id.slice(0,16)),1)]),_("div",W,[_("span",null,"类型: "+r(t.type||"-"),1),_("span",null,"已运行: "+r(e.store.formatDuration(Date.now()-t.startedAt)),1),n(y,{size:"small",danger:"",onClick:s=>e.store.stopTask(t.id)},{default:a(()=>[...l[4]||(l[4]=[g("停止",-1)])]),_:1},8,["onClick"])])]))),128))]),_:1})):w("v-if",!0),n(m,{class:"panel-card"},{default:a(()=>[n(A,{columns:e.columns,"data-source":e.store.tasks,pagination:{pageSize:15,size:"small"},loading:e.store.loading,"row-key":"id",size:"small"},{bodyCell:a(({column:t,record:s})=>[t.key==="status"?(i(),T(N,{key:0,color:e.store.getStatusColor(s.status)},{default:a(()=>[g(r(s.status),1)]),_:2},1032,["color"])):t.key==="description"?(i(),c("span",{key:1,title:s.command},r(s.description),9,X)):t.key==="duration"?(i(),c(h,{key:2},[g(r(e.getDuration(s)),1)],64)):t.key==="createdAt"?(i(),c(h,{key:3},[g(r(e.formatTime(s.createdAt)),1)],64)):t.key==="result"?(i(),c(h,{key:4},[s.error?(i(),c("span",Z,r(e.truncate(s.error,60)),1)):s.result?(i(),c("span",q,r(e.truncate(String(s.result),60)),1)):(i(),c("span",G,"-"))],64)):t.key==="action"?(i(),c(h,{key:5},[s.status==="running"?(i(),T(y,{key:0,size:"small",danger:"",onClick:S=>e.store.stopTask(s.id)},{default:a(()=>[...l[5]||(l[5]=[g(" 停止 ",-1)])]),_:1},8,["onClick"])):w("v-if",!0)],64)):w("v-if",!0)]),_:1},8,["data-source","loading"])]),_:1})])}const et=O(U,[["render",H],["__scopeId","data-v-da5ff6a2"],["__file","/tmp/cc-web-panel-6n5bBX/repo/packages/web-panel/src/views/Tasks.vue"]]);export{et as default};
@@ -1 +0,0 @@
1
- import{O as r}from"./index-DSRnnGez.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-BfI2mGUm.js";import{U as t}from"./index-DSRnnGez.js";import"./vendor-BvqAck49.js";import"./responsiveObserve-CtfIP2YM.js";import"./useFlexGapSupport-BBC2EqTi.js";import"./styleChecker-CE7d6-LQ.js";import"./index-C4nXq9eB.js";import"./icons-DP3uiYxy.js";const l=t(o);export{l as default};
@@ -1 +0,0 @@
1
- import{C as o}from"./Col-sH2Obo8q.js";import{U as t}from"./index-DSRnnGez.js";import"./vendor-BvqAck49.js";import"./index-C4nXq9eB.js";import"./icons-DP3uiYxy.js";const s=t(o);export{s as default};