chainlesschain 0.162.152 → 0.162.154

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 (167) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/src/assets/web-panel/assets/{AIOps-CVLVJS-Q.js → AIOps-CIpoXyVI.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-CJ2_GJsI.js → ActionButton-Ch_QXIPk.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-CZsmlTF8.js → Analytics-CvaBYShv.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-DREvMZ62.js → AppLayout-B6Q6olcr.js} +5 -5
  7. package/src/assets/web-panel/assets/{Audit-B4NR42w_.js → Audit-Bng8eHCW.js} +1 -1
  8. package/src/assets/web-panel/assets/{Backup-CJFmf3In.js → Backup-DvBs8-lm.js} +1 -1
  9. package/src/assets/web-panel/assets/{BaseInput-Bh8_iUZY.js → BaseInput-DKwajm0g.js} +1 -1
  10. package/src/assets/web-panel/assets/{Chat-DEwKjIxV.js → Chat-BoGpZ3uO.js} +5 -5
  11. package/src/assets/web-panel/assets/ChatBubbleRenderer-mDQl_PXO.js +1 -0
  12. package/src/assets/web-panel/assets/{Checkbox-DYWCqYI9.js → Checkbox-BMJEmxFQ.js} +1 -1
  13. package/src/assets/web-panel/assets/{Codegen-BlXrfZAJ.js → Codegen-Bsoag5CV.js} +1 -1
  14. package/src/assets/web-panel/assets/{Col-DLPM22eX.js → Col-CDjH9-sp.js} +1 -1
  15. package/src/assets/web-panel/assets/{Community-PFyzqijs.js → Community-Cg2QHPQ6.js} +1 -1
  16. package/src/assets/web-panel/assets/{Compact-7DIfY5Wp.js → Compact-BU2BaqP-.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compliance-DF4CinPU.js → Compliance-D6ZYMCqZ.js} +1 -1
  18. package/src/assets/web-panel/assets/{Cowork-B1J80Vcj.js → Cowork-DaZ8VW-I.js} +2 -2
  19. package/src/assets/web-panel/assets/{Cron-B7sx2OXX.js → Cron-DQY1RH9v.js} +2 -2
  20. package/src/assets/web-panel/assets/{Crosschain-omLkxmu-.js → Crosschain-BVR28vk9.js} +1 -1
  21. package/src/assets/web-panel/assets/{DID-B_7r7b5F.js → DID-N44KvTP-.js} +2 -2
  22. package/src/assets/web-panel/assets/{Dashboard-Cp7k3GZg.js → Dashboard-Bjhlx6wS.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dropdown-BCKO89Y8.js → Dropdown-CpLYxpy1.js} +1 -1
  24. package/src/assets/web-panel/assets/{EmailListRenderer-CNgTSsFZ.js → EmailListRenderer-srEITSPI.js} +1 -1
  25. package/src/assets/web-panel/assets/{FamilyGuardDashboard-DobM83JP.js → FamilyGuardDashboard-juOC_fX2.js} +1 -1
  26. package/src/assets/web-panel/assets/{Federation-XVAYQIeu.js → Federation-nRaQtaXW.js} +1 -1
  27. package/src/assets/web-panel/assets/{FormItemContext-DV5ka1KQ.js → FormItemContext-DflhTj09.js} +1 -1
  28. package/src/assets/web-panel/assets/{GenericCardRenderer-Dg5q-KpC.js → GenericCardRenderer-DulI_3NI.js} +1 -1
  29. package/src/assets/web-panel/assets/{Git-Dsn3Xhxf.js → Git-BxOPefXn.js} +2 -2
  30. package/src/assets/web-panel/assets/{Governance-D06S4Qow.js → Governance-C6G_Wnwi.js} +1 -1
  31. package/src/assets/web-panel/assets/{Inference-nAvwxUXy.js → Inference-BnFYa2BF.js} +1 -1
  32. package/src/assets/web-panel/assets/{KnowledgeGraph-CtqRP_rF.js → KnowledgeGraph-TqQLEabm.js} +1 -1
  33. package/src/assets/web-panel/assets/{Logs-J5aGAyfY.js → Logs-BH4AVh7s.js} +2 -2
  34. package/src/assets/web-panel/assets/{Marketplace-CaeY23Kj.js → Marketplace-DoWLTaEE.js} +1 -1
  35. package/src/assets/web-panel/assets/{McpTools-C2HHnwnE.js → McpTools-D6yC7OG_.js} +5 -5
  36. package/src/assets/web-panel/assets/{Memory-CWBrdKlR.js → Memory-DLCeHj21.js} +2 -2
  37. package/src/assets/web-panel/assets/{MobileBridge-CBLQ8uCY.js → MobileBridge-BZBE0GRl.js} +1 -1
  38. package/src/assets/web-panel/assets/{MobileProjects-Q_Cy_W4_.js → MobileProjects-DJA15G1J.js} +1 -1
  39. package/src/assets/web-panel/assets/{Mtc-BXur-euo.js → Mtc-CyTKJDHn.js} +4 -4
  40. package/src/assets/web-panel/assets/{MtcAudit-CpQSlOQC.js → MtcAudit-DZKjgEVc.js} +4 -4
  41. package/src/assets/web-panel/assets/{Multisig-DlFwdEOA.js → Multisig-2rMPNhSO.js} +3 -3
  42. package/src/assets/web-panel/assets/{NLProgramming-DSh7fevc.js → NLProgramming-VeMk4Fx-.js} +1 -1
  43. package/src/assets/web-panel/assets/{Notes-Bv4NOVxg.js → Notes-jr2GHMhh.js} +3 -3
  44. package/src/assets/web-panel/assets/{NotificationSettings-CzHNnIfa.js → NotificationSettings-WN9VZyFb.js} +1 -1
  45. package/src/assets/web-panel/assets/{OrderTableRenderer-D7pHfKK4.js → OrderTableRenderer-CjNO-e9T.js} +1 -1
  46. package/src/assets/web-panel/assets/{Organization-COzV01ed.js → Organization-DdjVHuzT.js} +4 -4
  47. package/src/assets/web-panel/assets/{Overflow-CYRZJb2_.js → Overflow-l8vBsGGq.js} +1 -1
  48. package/src/assets/web-panel/assets/{P2P-DFm49FE0.js → P2P-CVQDHHwq.js} +2 -2
  49. package/src/assets/web-panel/assets/{PdhVaultBrowser-Ctr-6k5B.js → PdhVaultBrowser-CTsNh8qE.js} +3 -3
  50. package/src/assets/web-panel/assets/{Permissions-DXVrhFyv.js → Permissions-DLW87uyK.js} +4 -4
  51. package/src/assets/web-panel/assets/{PersonalDataHub-BO5utpLK.js → PersonalDataHub-N8OvASTx.js} +2 -2
  52. package/src/assets/web-panel/assets/{Pipeline-C9irYCg7.js → Pipeline-BPZmdlz2.js} +1 -1
  53. package/src/assets/web-panel/assets/{Privacy-r13hrvoF.js → Privacy-MFZw_GNh.js} +1 -1
  54. package/src/assets/web-panel/assets/{ProjectInit-PRKNPZZC.js → ProjectInit-zW0pEsfU.js} +2 -2
  55. package/src/assets/web-panel/assets/{ProjectSettings-QvxM1ZDO.js → ProjectSettings-CppVHr_o.js} +2 -2
  56. package/src/assets/web-panel/assets/{Projects-DfgmsN3j.js → Projects-BTglkJO2.js} +1 -1
  57. package/src/assets/web-panel/assets/{Providers-DxbrccZ7.js → Providers-CPHZ6JKT.js} +1 -1
  58. package/src/assets/web-panel/assets/{QrScannerModal-BMHVRxBX.js → QrScannerModal-DO4klNZ2.js} +1 -1
  59. package/src/assets/web-panel/assets/{QuickAsk-Co3_ndAH.js → QuickAsk-B37TTqUa.js} +1 -1
  60. package/src/assets/web-panel/assets/{Recommend-Cv3UWR6s.js → Recommend-n7KIfK7y.js} +1 -1
  61. package/src/assets/web-panel/assets/{RemoteSession-CSDsO2zA.js → RemoteSession-SjVoS9mm.js} +2 -2
  62. package/src/assets/web-panel/assets/{Reputation-Bdj59vzM.js → Reputation-Dt6RTeHi.js} +1 -1
  63. package/src/assets/web-panel/assets/{Row-CejfUjmo.js → Row-Dty6jz5V.js} +1 -1
  64. package/src/assets/web-panel/assets/{RssFeed-C83yKkvU.js → RssFeed-DDLhqw5j.js} +3 -3
  65. package/src/assets/web-panel/assets/{Search-Ck4l_VI3.js → Search-DrYbXi-W.js} +1 -1
  66. package/src/assets/web-panel/assets/{Security-DGIIEx6K.js → Security-Fc9Z6fbB.js} +3 -3
  67. package/src/assets/web-panel/assets/{Services-Cj2aNAy3.js → Services-BAhPgjSM.js} +2 -2
  68. package/src/assets/web-panel/assets/{Skeleton-Dlyy8akb.js → Skeleton-8JF7EPfE.js} +1 -1
  69. package/src/assets/web-panel/assets/{Skills-C4aDa9Zh.js → Skills-DL39dY0t.js} +1 -1
  70. package/src/assets/web-panel/assets/{Sla-tHd_Bauo.js → Sla-CSvjcATc.js} +1 -1
  71. package/src/assets/web-panel/assets/{SpeechSettings-DI7R0Qgd.js → SpeechSettings-Demx7Gnx.js} +1 -1
  72. package/src/assets/web-panel/assets/{SyncSettings-OOxiPdsE.js → SyncSettings-CKLnRWJr.js} +2 -2
  73. package/src/assets/web-panel/assets/Tasks-mhITRxjv.js +1 -0
  74. package/src/assets/web-panel/assets/{Templates-Bm7eSMWH.js → Templates-AjQI5rxD.js} +1 -1
  75. package/src/assets/web-panel/assets/{Tenant-B8F8eFvD.js → Tenant-dbtEh1yR.js} +1 -1
  76. package/src/assets/web-panel/assets/{Terminal-2oWhR7QF.js → Terminal-DX-9jjfk.js} +2 -2
  77. package/src/assets/web-panel/assets/{TimelineRenderer-GLnecmpd.js → TimelineRenderer-C11EDZRt.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tokens-CtpFyati.js → Tokens-GiA9fiZn.js} +1 -1
  79. package/src/assets/web-panel/assets/{Trigger-DGkXZzbN.js → Trigger-BPcnclJn.js} +1 -1
  80. package/src/assets/web-panel/assets/{Trust-ClYZMkXN.js → Trust-C-DVY8nq.js} +1 -1
  81. package/src/assets/web-panel/assets/{UkeySign-C1AuEW5-.js → UkeySign-DxodSwME.js} +1 -1
  82. package/src/assets/web-panel/assets/{VideoEditing-DHa9ekSK.js → VideoEditing-D_WV0O8O.js} +1 -1
  83. package/src/assets/web-panel/assets/{Wallet-CyQv8ZAN.js → Wallet-DSeNlVSU.js} +4 -4
  84. package/src/assets/web-panel/assets/{WebAuthn-DPxEEb5Y.js → WebAuthn-Bwuuvpz1.js} +5 -5
  85. package/src/assets/web-panel/assets/{WorkflowEditor-C-fCM8Si.js → WorkflowEditor-8M96EU1N.js} +1 -1
  86. package/src/assets/web-panel/assets/{chat-BMu1Pk8B.js → chat-D5S6SmLm.js} +1 -1
  87. package/src/assets/web-panel/assets/{colors-DYPOXyWQ.js → colors-5fbnGkAP.js} +1 -1
  88. package/src/assets/web-panel/assets/{compact-item-C5r_plPk.js → compact-item-DaSuuMlW.js} +1 -1
  89. package/src/assets/web-panel/assets/{createContext-9fWrWmuJ.js → createContext-BNOHcXAF.js} +1 -1
  90. package/src/assets/web-panel/assets/devWarning-K_woVElh.js +1 -0
  91. package/src/assets/web-panel/assets/{hasIn-CjZM2-qE.js → hasIn-DONwZUra.js} +1 -1
  92. package/src/assets/web-panel/assets/index-3ILvaBpo.js +1 -0
  93. package/src/assets/web-panel/assets/{index-BsHmE__1.js → index-5_fj5gVd.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-DLCoKst9.js → index-B4L3gsNA.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-Du-w2i6G.js → index-BEO5f7Vf.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-CTnaRErh.js → index-BJp4kRjw.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-CGqrVLWe.js → index-BK2N5yVW.js} +3 -3
  98. package/src/assets/web-panel/assets/{index-B56CI20h.js → index-BLzMuz38.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-DNxR1CHs.js → index-B_yDD9Lm.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-BVFtY8Y4.js → index-BcWMZqb4.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-0DVMoDzF.js → index-BcqOK7Lv.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-C3E7xVl1.js → index-BrAJSu-v.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-B_bTdeou.js → index-CAYmc5Nh.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-DjTB4wPn.js → index-CEzd5m5a.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BPucc_ES.js → index-CLXf-8ek.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-Co9kBFxY.js → index-CSfYJqXt.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BW-x3mUK.js → index-CTZeOnzO.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BBVCXmJV.js → index-Cf2OCa8q.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-DJk9cPrs.js → index-ClGqO-2X.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-phHPSXlV.js → index-CmUOjyL6.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-jO4lIpFE.js → index-Cn5LtyIH.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-Bti4lpw5.js → index-CrkCFohi.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-DWwI0Jjd.js → index-CztESwB4.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-CYoS2cwK.js → index-D7gs_3Ck.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-D0rFX-xN.js → index-DHx2lhHW.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CDaA4A0b.js → index-DM3Ug61e.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-Bglw_kmu.js → index-DP2-3A_j.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CyUtBxnC.js → index-DbdQBn4n.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-I3Qdrfcf.js → index-Dd7xwGcD.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-D6zyUpD6.js → index-Dm5A-MN5.js} +1 -1
  121. package/src/assets/web-panel/assets/index-JpB-FoZq.js +1 -0
  122. package/src/assets/web-panel/assets/{index-Cd9_KCPs.js → index-KwV9g_cf.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-HJdfPSMz.js → index-LRIt-AFl.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-Mipa7XgU.js → index-MOgO5Yvx.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-CcDGi9U1.js → index-PsMErAB1.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-B1iUe3Ba.js → index-RkInlwV0.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-oerotzoq.js → index-_6S41ikV.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-ByVDaARk.js → index-uR5KTNZA.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CJJx0kbR.js → index-vYtprlNs.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CvUR6l7C.js → index-xo2f4DZR.js} +1 -1
  131. package/src/assets/web-panel/assets/{initDefaultProps-B7tpABc_.js → initDefaultProps-CxwLynp9.js} +1 -1
  132. package/src/assets/web-panel/assets/{motion-DmvaRoVv.js → motion-XbPvGJbW.js} +1 -1
  133. package/src/assets/web-panel/assets/{move-DF4X29Wf.js → move-D1u5pcgS.js} +1 -1
  134. package/src/assets/web-panel/assets/{mtc-parser-C0cbg4PO.js → mtc-parser-BDxhTBMH.js} +1 -1
  135. package/src/assets/web-panel/assets/{omit-DZzcYy0l.js → omit-EtIFGg5k.js} +1 -1
  136. package/src/assets/web-panel/assets/{pickAttrs-DaZWfzuH.js → pickAttrs-D33sWb0l.js} +1 -1
  137. package/src/assets/web-panel/assets/{placementArrow-CBxOEyvn.js → placementArrow-BwFRzaGo.js} +1 -1
  138. package/src/assets/web-panel/assets/{responsiveObserve-CGl8NIlO.js → responsiveObserve-CBk2WqvQ.js} +1 -1
  139. package/src/assets/web-panel/assets/{slide-Bv330MSZ.js → slide-B52HtrKn.js} +1 -1
  140. package/src/assets/web-panel/assets/{statusUtils-DJVy5oEM.js → statusUtils-D4qxqWnH.js} +1 -1
  141. package/src/assets/web-panel/assets/{styleChecker-BiY1H5ST.js → styleChecker-BxaCFlOL.js} +1 -1
  142. package/src/assets/web-panel/assets/{useFlexGapSupport-D1sN2OlQ.js → useFlexGapSupport-B1lWlqXN.js} +1 -1
  143. package/src/assets/web-panel/assets/{useFs-DxxHawzW.js → useFs-C6VAU1_6.js} +1 -1
  144. package/src/assets/web-panel/assets/{usePersonalDataHub-C1HblLrD.js → usePersonalDataHub-rEG6oXG8.js} +1 -1
  145. package/src/assets/web-panel/assets/{vnode-Dex0jy4T.js → vnode-DOTafkEi.js} +1 -1
  146. package/src/assets/web-panel/assets/{zoom-Bk1MScAD.js → zoom-BuwwN5K2.js} +1 -1
  147. package/src/assets/web-panel/index.html +1 -1
  148. package/src/command-manifest.json +8 -1
  149. package/src/commands/ask.js +1 -1
  150. package/src/commands/complete.js +147 -0
  151. package/src/commands/team.js +34 -0
  152. package/src/data/changelog.json +12 -2
  153. package/src/harness/mcp-client.js +115 -1
  154. package/src/index.js +2 -0
  155. package/src/lib/agent-team/team-runner.js +20 -0
  156. package/src/lib/config-manager.js +14 -1
  157. package/src/lib/sub-agent-context.js +28 -7
  158. package/src/lib/telemetry/span-recorder.js +13 -1
  159. package/src/repl/agent-repl.js +52 -13
  160. package/src/repl/permission-prompt.js +58 -0
  161. package/src/runtime/agent-core.js +236 -1
  162. package/src/runtime/coding-agent-contract-shared.cjs +5 -0
  163. package/src/assets/web-panel/assets/ChatBubbleRenderer-BOqHkxK_.js +0 -1
  164. package/src/assets/web-panel/assets/Tasks-Nro_Ltg5.js +0 -1
  165. package/src/assets/web-panel/assets/devWarning-DmRz5Pet.js +0 -1
  166. package/src/assets/web-panel/assets/index-CrsL7YBW.js +0 -1
  167. package/src/assets/web-panel/assets/index-zW69WSDA.js +0 -1
@@ -105,7 +105,11 @@ import { parseThinkCommand, parseEffortCommand } from "./think-command.js";
105
105
  import { parseBtwCommand, buildAsideBlock, applyAside } from "./btw-command.js";
106
106
  import { shouldStreamLive } from "./stream-decision.js";
107
107
  import { emptyTurnNotice } from "./empty-turn-notice.js";
108
- import { buildPermissionPrompt } from "./permission-prompt.js";
108
+ import {
109
+ buildPermissionPrompt,
110
+ resolveAskIdleTimeoutMs,
111
+ questionWithIdleTimeout,
112
+ } from "./permission-prompt.js";
109
113
  import {
110
114
  parsePermissionTier,
111
115
  describeTier,
@@ -425,11 +429,17 @@ export async function startAgentRepl(options = {}) {
425
429
  // CC_AUTO_PIN env ("1"/"0") > config `context.autoPin` (true/false/object) >
426
430
  // default on. See resolveAutoPinOption.
427
431
  let _autoPinCfgValue;
432
+ // Idle timeout for interactive permission prompts (0 = wait forever).
433
+ // CC_PERMISSION_ASK_TIMEOUT_MS env > config permissions.askTimeoutMs > off.
434
+ let _askIdleTimeoutMs = resolveAskIdleTimeoutMs();
428
435
  try {
429
436
  const { loadConfig } = await import("../lib/config-manager.js");
430
437
  const _cfg = loadConfig();
431
438
  _visionModel = _cfg?.llm?.visionModel || undefined;
432
439
  _autoPinCfgValue = _cfg?.context?.autoPin;
440
+ _askIdleTimeoutMs = resolveAskIdleTimeoutMs({
441
+ config: _cfg?.permissions?.askTimeoutMs,
442
+ });
433
443
  const raw = _cfg?.llm?.streamStallTimeoutMs;
434
444
  const t = Number(raw);
435
445
  // Accept 0 (explicit disable) — only ignore absent/invalid values.
@@ -559,17 +569,24 @@ export async function startAgentRepl(options = {}) {
559
569
  });
560
570
  const q = (p) => new Promise((res) => rlConfirm.question(p, res));
561
571
  const cmd = args?.command ? ` ${args.command}` : "";
562
- const ans = (
563
- await q(
572
+ const res = await questionWithIdleTimeout(
573
+ q,
574
+ chalk.yellow(
575
+ `\n[ApprovalGate] ${riskLevel || "medium"} risk command:${cmd}\n` +
576
+ ` Proceed? [y]es once / [a]lways allow / [N]o: `,
577
+ ),
578
+ _askIdleTimeoutMs,
579
+ );
580
+ rlConfirm.close();
581
+ if (res.timedOut) {
582
+ process.stdout.write(
564
583
  chalk.yellow(
565
- `\n[ApprovalGate] ${riskLevel || "medium"} risk command:${cmd}\n` +
566
- ` Proceed? [y]es once / [a]lways allow / [N]o: `,
584
+ `\n no response in ${_askIdleTimeoutMs}ms auto-denied\n`,
567
585
  ),
568
- )
569
- )
570
- .trim()
571
- .toLowerCase();
572
- rlConfirm.close();
586
+ );
587
+ return false;
588
+ }
589
+ const ans = res.answer.trim().toLowerCase();
573
590
  if (ans === "a" || ans === "always") {
574
591
  const saved = await _persistAlwaysAllow(tool || "run_shell", args);
575
592
  if (saved) {
@@ -625,10 +642,21 @@ export async function startAgentRepl(options = {}) {
625
642
  // (settings/hook ask) or a `reason` (destructive-git / sensitive-file
626
643
  // guards) — avoids the literal "null" the old template printed.
627
644
  const header = buildPermissionPrompt({ tool, args, rule, reason });
628
- const ans = (await q(chalk.yellow(`\n${header}\n Proceed? (y/N) `)))
629
- .trim()
630
- .toLowerCase();
645
+ const res = await questionWithIdleTimeout(
646
+ q,
647
+ chalk.yellow(`\n${header}\n Proceed? (y/N) `),
648
+ _askIdleTimeoutMs,
649
+ );
631
650
  rl.close();
651
+ if (res.timedOut) {
652
+ process.stdout.write(
653
+ chalk.yellow(
654
+ `\n ⏱ no response in ${_askIdleTimeoutMs}ms — auto-denied\n`,
655
+ ),
656
+ );
657
+ return false;
658
+ }
659
+ const ans = res.answer.trim().toLowerCase();
632
660
  return ans === "y" || ans === "yes";
633
661
  };
634
662
  } catch (_err) {
@@ -2383,6 +2411,17 @@ export async function startAgentRepl(options = {}) {
2383
2411
  const expanded = target.replace(/^~(?=$|[\\/])/, os.homedir());
2384
2412
  process.chdir(path.resolve(process.cwd(), expanded));
2385
2413
  logger.log(chalk.green(`cwd → ${process.cwd()}`));
2414
+ // MCP roots derive from cwd — tell connected servers to re-query
2415
+ // roots/list (Claude-Code 2.1.203 change-notification parity).
2416
+ for (const c of [_adhocMcp?.mcpClient, _bundleMcpClient]) {
2417
+ if (c && typeof c.notifyRootsListChanged === "function") {
2418
+ try {
2419
+ c.notifyRootsListChanged();
2420
+ } catch {
2421
+ /* best-effort */
2422
+ }
2423
+ }
2424
+ }
2386
2425
  } catch (err) {
2387
2426
  logger.error(`/cd failed: ${err.message}`);
2388
2427
  }
@@ -24,3 +24,61 @@ export function buildPermissionPrompt({ tool, args, rule, reason } = {}) {
24
24
  if (reason) return `[Permission] ${reason}`;
25
25
  return `[Permission] confirm ${tool}:${detail}`;
26
26
  }
27
+
28
+ /**
29
+ * Resolve the idle timeout (ms) for interactive permission prompts.
30
+ *
31
+ * An unanswered prompt blocks the whole agent turn forever (e.g. the user
32
+ * walked away mid-run). With a timeout configured, the prompt auto-denies
33
+ * after `ms` of silence — deny is the only safe unattended answer.
34
+ *
35
+ * Precedence: CC_PERMISSION_ASK_TIMEOUT_MS env > config
36
+ * `permissions.askTimeoutMs` > default 0 (disabled — waits forever, the
37
+ * historical behavior). Non-finite / non-positive values disable it.
38
+ *
39
+ * @param {{env?: string, config?: unknown}} [opts] - injectable for tests
40
+ * @returns {number} timeout in ms, 0 = disabled
41
+ */
42
+ export function resolveAskIdleTimeoutMs({ env, config } = {}) {
43
+ const envRaw =
44
+ env !== undefined ? env : process.env.CC_PERMISSION_ASK_TIMEOUT_MS;
45
+ const candidate =
46
+ envRaw !== undefined && envRaw !== null && envRaw !== ""
47
+ ? Number(envRaw)
48
+ : typeof config === "number" || typeof config === "string"
49
+ ? Number(config)
50
+ : NaN; // booleans/objects are not a timeout — disabled
51
+ return Number.isFinite(candidate) && candidate > 0 ? candidate : 0;
52
+ }
53
+
54
+ /**
55
+ * Race an interactive question against an idle timeout.
56
+ *
57
+ * `ask` is the readline-question-as-promise (never rejects). On timeout the
58
+ * caller must still close its readline interface; the stranded question
59
+ * callback becomes a no-op once the interface is closed.
60
+ *
61
+ * @param {(prompt: string) => Promise<string>} ask
62
+ * @param {string} prompt
63
+ * @param {number} timeoutMs - 0/negative = no timeout (plain await)
64
+ * @returns {Promise<{answer: string|null, timedOut: boolean}>}
65
+ */
66
+ export async function questionWithIdleTimeout(ask, prompt, timeoutMs) {
67
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
68
+ return { answer: await ask(prompt), timedOut: false };
69
+ }
70
+ let timer = null;
71
+ try {
72
+ return await Promise.race([
73
+ ask(prompt).then((answer) => ({ answer, timedOut: false })),
74
+ new Promise((res) => {
75
+ timer = setTimeout(
76
+ () => res({ answer: null, timedOut: true }),
77
+ timeoutMs,
78
+ );
79
+ }),
80
+ ]);
81
+ } finally {
82
+ if (timer) clearTimeout(timer);
83
+ }
84
+ }
@@ -1443,6 +1443,8 @@ export async function executeTool(name, args, context = {}) {
1443
1443
  subAgentBudget: context.subAgentBudget || null,
1444
1444
  interactiveApproval: context.interactiveApproval || false,
1445
1445
  settingsHooks: context.settingsHooks || null,
1446
+ signal: context.signal || null,
1447
+ backgroundSubAgents: context.backgroundSubAgents || null,
1446
1448
  });
1447
1449
  } catch (err) {
1448
1450
  if (hookDb) {
@@ -1541,7 +1543,10 @@ export async function executeTool(name, args, context = {}) {
1541
1543
  name === "spawn_sub_agent" &&
1542
1544
  context.settingsHooks &&
1543
1545
  toolResult &&
1544
- typeof toolResult === "object"
1546
+ typeof toolResult === "object" &&
1547
+ // Background spawns return a "running" handle here — their SubagentStop
1548
+ // fires later, when the RESULT is drained into the conversation.
1549
+ !(toolResult.background === true && toolResult.status === "running")
1545
1550
  ) {
1546
1551
  try {
1547
1552
  const outcome = runObserveHooks(
@@ -2056,6 +2061,8 @@ async function executeToolInner(
2056
2061
  subAgentBudget = null,
2057
2062
  interactiveApproval = false,
2058
2063
  settingsHooks = null,
2064
+ signal = null,
2065
+ backgroundSubAgents = null,
2059
2066
  },
2060
2067
  ) {
2061
2068
  const localToolDescriptor =
@@ -2777,6 +2784,8 @@ async function executeToolInner(
2777
2784
  subAgentDepth,
2778
2785
  subAgentBudget,
2779
2786
  settingsHooks,
2787
+ signal,
2788
+ backgroundSubAgents,
2780
2789
  }),
2781
2790
  );
2782
2791
  }
@@ -3703,6 +3712,46 @@ export function safeStringifyToolResult(value) {
3703
3712
  * @param {object} ctx - { skillLoader, cwd, parentMessages, interaction, sessionId }
3704
3713
  * @returns {Promise<object>}
3705
3714
  */
3715
+ /**
3716
+ * Remove and return every SETTLED background sub-agent entry from the run's
3717
+ * map. Called by agentLoop before each LLM call (deliver fresh results) and
3718
+ * after the end-of-run wait (deliver stragglers).
3719
+ */
3720
+ function _takeSettledBackgroundSubAgents(map) {
3721
+ const done = [];
3722
+ for (const [id, entry] of map) {
3723
+ if (entry.settled) {
3724
+ done.push(entry);
3725
+ map.delete(id);
3726
+ }
3727
+ }
3728
+ return done;
3729
+ }
3730
+
3731
+ /**
3732
+ * Render a settled background sub-agent's outcome as the user-role message
3733
+ * injected into the parent conversation (the only channel that reaches the
3734
+ * model between turns — there is no open tool_call to attach a result to).
3735
+ */
3736
+ function _backgroundSubAgentResultText(entry) {
3737
+ const o = entry.outcome || {};
3738
+ const status = o.error ? "FAILED" : "completed";
3739
+ const summary =
3740
+ (o.result && o.result.summary) || o.error || "(no output from sub-agent)";
3741
+ const tools =
3742
+ o.result && Array.isArray(o.result.toolsUsed) && o.result.toolsUsed.length
3743
+ ? `\nTools used: ${o.result.toolsUsed.join(", ")}`
3744
+ : "";
3745
+ const feedback = entry.hookFeedback
3746
+ ? `\nHook feedback: ${entry.hookFeedback}`
3747
+ : "";
3748
+ return (
3749
+ `[Background sub-agent "${entry.role}" (${entry.id}) ${status}]\n` +
3750
+ `Task: ${entry.task}\n` +
3751
+ `Result:\n${summary}${tools}${feedback}`
3752
+ );
3753
+ }
3754
+
3706
3755
  async function _executeSpawnSubAgent(args, ctx) {
3707
3756
  // Nesting cap: refuse before any context/registry work.
3708
3757
  const currentDepth = ctx.subAgentDepth || 0;
@@ -3897,6 +3946,88 @@ async function _executeSpawnSubAgent(args, ctx) {
3897
3946
  }
3898
3947
  }
3899
3948
 
3949
+ // ── Background mode (Claude-Code 2.1.198 parity) ────────────────────────
3950
+ // Return a running handle immediately; the parent loop keeps working and
3951
+ // drains the result into the conversation when it settles (agentLoop also
3952
+ // refuses to finish while any background sub-agent is still running). Only
3953
+ // available when the calling loop provided the per-run map — a bare
3954
+ // executeTool() without it falls through to the blocking path.
3955
+ if (args.background === true && ctx.backgroundSubAgents instanceof Map) {
3956
+ // Cancel with the parent: forward the loop's abort signal so killing the
3957
+ // run doesn't orphan a detached child mid-LLM-call.
3958
+ subCtx._signal = subCtx._signal || ctx.signal || null;
3959
+ if (registry) {
3960
+ try {
3961
+ registry.register(subCtx);
3962
+ } catch (_err) {
3963
+ // Registry not available — non-critical
3964
+ }
3965
+ }
3966
+ emit("sub-agent.started", {
3967
+ task: subCtx.task,
3968
+ background: true,
3969
+ allowedTools: allowedTools || null,
3970
+ maxIterations: subCtx.maxIterations,
3971
+ createdAt: subCtx.createdAt,
3972
+ });
3973
+ const entry = {
3974
+ id: subCtx.id,
3975
+ role: subCtx.role,
3976
+ task: subCtx.task,
3977
+ settled: false,
3978
+ outcome: null,
3979
+ hookFeedback: null,
3980
+ promise: null,
3981
+ };
3982
+ // Settle-capture wrapper: the stored promise NEVER rejects, so an
3983
+ // unconsumed handle can't surface as an unhandled rejection.
3984
+ entry.promise = subCtx
3985
+ .run(task)
3986
+ .then(
3987
+ (result) => ({ result, error: null }),
3988
+ (err) => {
3989
+ subCtx.forceComplete(err.message);
3990
+ return { result: subCtx.result, error: err.message };
3991
+ },
3992
+ )
3993
+ .then((outcome) => {
3994
+ entry.settled = true;
3995
+ entry.outcome = outcome;
3996
+ if (registry) {
3997
+ try {
3998
+ registry.complete(subCtx.id, outcome.result);
3999
+ } catch (_err) {
4000
+ // Non-critical
4001
+ }
4002
+ }
4003
+ emit(outcome.error ? "sub-agent.failed" : "sub-agent.completed", {
4004
+ status: subCtx.status,
4005
+ background: true,
4006
+ ...(outcome.error
4007
+ ? { error: outcome.error }
4008
+ : {
4009
+ summary: outcome.result?.summary,
4010
+ toolsUsed: outcome.result?.toolsUsed,
4011
+ iterationCount: outcome.result?.iterationCount,
4012
+ tokenCount: outcome.result?.tokenCount,
4013
+ artifactCount: outcome.result?.artifacts?.length || 0,
4014
+ }),
4015
+ completedAt: subCtx.completedAt,
4016
+ });
4017
+ return outcome;
4018
+ });
4019
+ ctx.backgroundSubAgents.set(subCtx.id, entry);
4020
+ return {
4021
+ success: true,
4022
+ background: true,
4023
+ status: "running",
4024
+ subAgentId: subCtx.id,
4025
+ role: subCtx.role,
4026
+ parentSessionId,
4027
+ note: "Sub-agent is running in the background. Its result will be delivered to you automatically in a later turn — continue with other work; the run will not finish before the result arrives.",
4028
+ };
4029
+ }
4030
+
3900
4031
  try {
3901
4032
  // Notify registry if available
3902
4033
  if (registry) {
@@ -5385,7 +5516,17 @@ export async function* agentLoop(messages, options) {
5385
5516
  spawned: 0,
5386
5517
  max: MAX_SUB_AGENTS_PER_RUN,
5387
5518
  },
5519
+ // Abort signal — forwarded to background sub-agents so cancelling the
5520
+ // parent run also cancels children still running detached.
5521
+ signal,
5522
+ // Background sub-agents spawned THIS loop (spawn_sub_agent background:true).
5523
+ // id → { id, role, task, promise, settled, outcome }. Results are drained
5524
+ // into `messages` before each LLM call; the loop refuses to finish while
5525
+ // any are still running (it waits, injects, and gives the model one more
5526
+ // turn) so a background result can never be silently lost.
5527
+ backgroundSubAgents: new Map(),
5388
5528
  };
5529
+ const backgroundSubAgents = toolContext.backgroundSubAgents;
5389
5530
 
5390
5531
  throwIfAborted(signal);
5391
5532
 
@@ -5490,6 +5631,18 @@ export async function* agentLoop(messages, options) {
5490
5631
  const runId =
5491
5632
  options.runId ||
5492
5633
  `run-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
5634
+ // Workflow-tracing attributes (Claude-Code 2.1.202): stamp the run id (and
5635
+ // an optional caller-provided workflow name) onto EVERY span this run emits,
5636
+ // so a collector can group one run's model/tool spans into one workflow.
5637
+ if (recorder && typeof recorder.setDefaultAttribute === "function") {
5638
+ recorder.setDefaultAttribute("workflow.run_id", runId);
5639
+ if (options.workflowName) {
5640
+ recorder.setDefaultAttribute(
5641
+ "workflow.name",
5642
+ String(options.workflowName),
5643
+ );
5644
+ }
5645
+ }
5493
5646
  yield {
5494
5647
  type: "run-started",
5495
5648
  runId,
@@ -5657,6 +5810,52 @@ export async function* agentLoop(messages, options) {
5657
5810
  }
5658
5811
  }
5659
5812
 
5813
+ // Deliver background sub-agent results that settled since the last turn:
5814
+ // inject them as user-role context so THIS LLM call sees them. (There is
5815
+ // no open tool_call to attach a late result to — the spawn call already
5816
+ // returned its "running" handle.)
5817
+ if (backgroundSubAgents.size > 0) {
5818
+ for (const entry of _takeSettledBackgroundSubAgents(
5819
+ backgroundSubAgents,
5820
+ )) {
5821
+ // SubagentStop fires at RESULT time for background spawns (the
5822
+ // spawn-time handle skips it); a block reason rides along as feedback.
5823
+ if (options.settingsHooks) {
5824
+ try {
5825
+ const outcome = runObserveHooks(
5826
+ options.settingsHooks,
5827
+ "SubagentStop",
5828
+ {
5829
+ stop_hook_active: false,
5830
+ session_id: options.sessionId || null,
5831
+ subagent_response: JSON.stringify(
5832
+ entry.outcome?.result || { error: entry.outcome?.error },
5833
+ ).substring(0, 2000),
5834
+ },
5835
+ { cwd: toolContext.cwd },
5836
+ );
5837
+ if (outcome.decision === "block" && outcome.reason) {
5838
+ entry.hookFeedback = outcome.reason;
5839
+ }
5840
+ } catch (_err) {
5841
+ // SubagentStop hooks are best-effort
5842
+ }
5843
+ }
5844
+ messages.push({
5845
+ role: "user",
5846
+ content: _backgroundSubAgentResultText(entry),
5847
+ });
5848
+ yield {
5849
+ type: "background-sub-agent-result",
5850
+ runId,
5851
+ subAgentId: entry.id,
5852
+ role: entry.role,
5853
+ error: entry.outcome?.error || null,
5854
+ summary: entry.outcome?.result?.summary || null,
5855
+ };
5856
+ }
5857
+ }
5858
+
5660
5859
  // Turn-scoped context injection (open-agents prepareCall parity).
5661
5860
  // prepareCall runs fresh each iteration and returns an ephemeral
5662
5861
  // system-message supplement that is NOT persisted to messages history.
@@ -5736,6 +5935,42 @@ export async function* agentLoop(messages, options) {
5736
5935
  const toolCalls = msg.tool_calls;
5737
5936
 
5738
5937
  if (!toolCalls || toolCalls.length === 0) {
5938
+ // A final answer while background sub-agents are still outstanding is
5939
+ // premature — their results must not be silently lost. Wait for ALL of
5940
+ // them, inject the results, and give the model one more turn to fold
5941
+ // them into its real final answer. The iteration budget is the backstop
5942
+ // if it keeps spawning more.
5943
+ if (backgroundSubAgents.size > 0) {
5944
+ yield {
5945
+ type: "waiting-background-sub-agents",
5946
+ runId,
5947
+ count: backgroundSubAgents.size,
5948
+ };
5949
+ await Promise.all(
5950
+ [...backgroundSubAgents.values()].map((e) => e.promise),
5951
+ );
5952
+ throwIfAborted(signal);
5953
+ messages.push({ role: "assistant", content: msg.content || "" });
5954
+ for (const entry of _takeSettledBackgroundSubAgents(
5955
+ backgroundSubAgents,
5956
+ )) {
5957
+ messages.push({
5958
+ role: "user",
5959
+ content:
5960
+ _backgroundSubAgentResultText(entry) +
5961
+ "\n\nAll background sub-agents have finished. Incorporate their results and give your final answer.",
5962
+ });
5963
+ yield {
5964
+ type: "background-sub-agent-result",
5965
+ runId,
5966
+ subAgentId: entry.id,
5967
+ role: entry.role,
5968
+ error: entry.outcome?.error || null,
5969
+ summary: entry.outcome?.result?.summary || null,
5970
+ };
5971
+ }
5972
+ continue;
5973
+ }
5739
5974
  // Surface the final answer's extended-thinking reasoning (Anthropic, when
5740
5975
  // --think is on) so non-streaming consumers (the REPL) can show it. The
5741
5976
  // streaming path forwards reasoning live via onThinking instead.
@@ -588,6 +588,11 @@ const CODING_AGENT_TOOL_CONTRACTS = Object.freeze([
588
588
  description:
589
589
  "Optional declarative profile (from sub-agent-profiles). When set, seeds systemPrompt / tool allowlist / iteration cap. Explicit `tools` overrides the profile allowlist.",
590
590
  },
591
+ background: {
592
+ type: "boolean",
593
+ description:
594
+ "Run the sub-agent in the BACKGROUND: the call returns immediately with a running handle and you continue working; the sub-agent's result is delivered to you automatically in a later turn (the run waits for stragglers before finishing). Use for independent subtasks you don't need before your next step.",
595
+ },
591
596
  },
592
597
  required: ["task"],
593
598
  },
@@ -1 +0,0 @@
1
- import{I as v,P as u,J as y,U as n,R as a,S,K as C,Q as x,V as w,_ as B,b as s}from"./vendor-BMxUs6UX.js";import{_ as k}from"./index-CGqrVLWe.js";import"./icons-BsDmGpcT.js";const N={__name:"ChatBubbleRenderer",props:{event:{type:Object,required:!0}},setup(c,{expose:d}){d();const t=c,r=s(()=>{const e=t.event.content||{};return e.text||e.body||e.message||e.title||JSON.stringify(e).slice(0,200)}),i=s(()=>{const e=t.event.content||{};return e.from||e.sender||e.senderName||t.event.actor||"(unknown)"}),l=s(()=>{const e=(t.event.actor||"").toLowerCase();return e.includes("self")||e==="me"||e.endsWith("_self")}),o=s(()=>{const e=t.event.source.adapter||"";return e.startsWith("messaging-qq")?"magenta":e==="wechat"?"green":"blue"}),m=s(()=>{if(!t.event.occurredAt)return"";try{const e=new Date(t.event.occurredAt),p=e.getFullYear(),f=String(e.getMonth()+1).padStart(2,"0"),g=String(e.getDate()).padStart(2,"0"),b=String(e.getHours()).padStart(2,"0"),h=String(e.getMinutes()).padStart(2,"0");return`${p}-${f}-${g} ${b}:${h}`}catch{return""}}),_={props:t,messageText:r,actorLabel:i,isMine:l,adapterColor:o,formattedTime:m,computed:s};return Object.defineProperty(_,"__isScriptSetup",{enumerable:!1,value:!0}),_}},T={class:"bubble"},q={class:"meta"},M={class:"actor"},O={class:"time"},R={class:"body"};function V(c,d,t,r,i,l){const o=v("a-tag");return u(),y("div",{class:B(["chat-row",{mine:r.isMine}])},[n("div",T,[n("div",q,[n("span",M,a(r.actorLabel),1),n("span",O,a(r.formattedTime),1)]),n("div",R,a(r.messageText),1),t.event.source.adapter?(u(),S(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",V],["__scopeId","data-v-49238629"],["__file","/tmp/cc-web-panel-7Oqy5c/repo/packages/web-panel/src/components/pdh/renderers/ChatBubbleRenderer.vue"]]);export{A as default};
@@ -1 +0,0 @@
1
- import{E as B,b as D,r as R,I as p,J as c,U as _,c as n,K as a,S as C,V as x,o as I,x as O,P as i,Q as k,R as r,F as T,Z as F}from"./vendor-BMxUs6UX.js";import{u as P,_ as E}from"./index-CGqrVLWe.js";import{R as U}from"./icons-BsDmGpcT.js";const V=B("tasks",()=>{const y=R([]),l=R(!1);let u=null,t=null,d=null;const b=D(()=>y.value.filter(e=>e.status==="running")),v=D(()=>y.value.filter(e=>e.status==="pending")),w=D(()=>y.value.filter(e=>e.status==="completed"||e.status==="failed"||e.status==="timeout"));async function s(){const e=P();l.value=!0;try{const g=await e.sendRaw({type:"tasks-list"});g&&Array.isArray(g.tasks)&&(y.value=g.tasks)}catch{}finally{l.value=!1}}async function m(e){const g=P();try{await g.sendRaw({type:"tasks-stop",taskId:e})}catch{}finally{await s()}}const f=R(null);function h(e=5e3){N(),s(),u=setInterval(s,e),S()}function N(){u&&(clearInterval(u),u=null),t&&(t(),t=null),d&&(clearTimeout(d),d=null)}function S(){const e=P();if(t)return;const g=z=>{z.type==="task:notification"&&z.payload?.task&&(f.value=z.payload.task,s(),d&&clearTimeout(d),d=setTimeout(()=>{f.value=null,d=null},8e3))};t=e.onRuntimeEvent(g)}function A(e){return!e||e<0?"-":e<1e3?`${e}ms`:e<6e4?`${(e/1e3).toFixed(1)}s`:`${(e/6e4).toFixed(1)}m`}function o(e){switch(e){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:y,loading:l,running:b,pending:v,completed:w,lastNotification:f,fetchTasks:s,stopTask:m,startPolling:h,stopPolling:N,formatDuration:A,getStatusColor:o}}),L={__name:"Tasks",setup(y,{expose:l}){l();const u=V(),t=[{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 d(s){return s.status==="running"&&s.startedAt?u.formatDuration(Date.now()-s.startedAt):s.completedAt&&s.startedAt?u.formatDuration(s.completedAt-s.startedAt):"-"}function b(s){return s?new Date(s).toLocaleString():"-"}function v(s,m){return s?s.length>m?`${s.slice(0,m)}...`:s:""}I(()=>u.startPolling(5e3)),O(()=>u.stopPolling());const w={store:u,columns:t,getDuration:d,formatTime:b,truncate:v,onMounted:I,onUnmounted:O,get ReloadOutlined(){return U},get useTasksStore(){return V}};return Object.defineProperty(w,"__isScriptSetup",{enumerable:!1,value:!0}),w}},j={class:"page-header"},q={key:0,class:"error-text"},J={key:1},K={class:"task-header"},M={class:"task-desc"},Q={class:"task-id"},W={class:"task-meta"},Z=["title"],G={key:0,class:"error-text"},H={key:1,class:"success-text"},X={key:2,class:"muted-text"};function Y(y,l,u,t,d,b){const v=p("a-button"),w=p("a-space"),s=p("a-alert"),m=p("a-statistic"),f=p("a-card"),h=p("a-col"),N=p("a-row"),S=p("a-tag"),A=p("a-table");return i(),c("div",null,[_("div",j,[l[3]||(l[3]=_("div",null,[_("h2",{class:"page-title"},"后台任务"),_("p",{class:"page-sub"},"查看后台任务队列、实时通知和任务执行结果。")],-1)),n(w,null,{default:a(()=>[n(v,{ghost:"",loading:t.store.loading,onClick:l[0]||(l[0]=o=>t.store.fetchTasks())},{icon:a(()=>[n(t.ReloadOutlined)]),default:a(()=>[l[2]||(l[2]=k(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),t.store.lastNotification?(i(),C(s,{key:0,type:t.store.lastNotification.status==="completed"?"success":"error","show-icon":"",closable:"",class:"banner",onClose:l[1]||(l[1]=o=>t.store.lastNotification=null)},{message:a(()=>[k(" 任务"+r(t.store.lastNotification.status==="completed"?"完成":"结束")+": "+r(t.store.lastNotification.description||t.store.lastNotification.id.slice(0,16)),1)]),description:a(()=>[t.store.lastNotification.error?(i(),c("span",q,r(t.store.lastNotification.error),1)):t.store.lastNotification.result?(i(),c("span",J,r(t.truncate(String(t.store.lastNotification.result),120)),1)):x("v-if",!0)]),_:1},8,["type"])):x("v-if",!0),n(N,{gutter:[16,16],class:"stats-row"},{default:a(()=>[n(h,{xs:12,sm:6},{default:a(()=>[n(f,{class:"stat-card",size:"small"},{default:a(()=>[n(m,{title:"全部任务",value:t.store.tasks.length},null,8,["value"])]),_:1})]),_:1}),n(h,{xs:12,sm:6},{default:a(()=>[n(f,{class:"stat-card",size:"small"},{default:a(()=>[n(m,{title:"运行中",value:t.store.running.length},null,8,["value"])]),_:1})]),_:1}),n(h,{xs:12,sm:6},{default:a(()=>[n(f,{class:"stat-card",size:"small"},{default:a(()=>[n(m,{title:"等待中",value:t.store.pending.length},null,8,["value"])]),_:1})]),_:1}),n(h,{xs:12,sm:6},{default:a(()=>[n(f,{class:"stat-card",size:"small"},{default:a(()=>[n(m,{title:"已完成",value:t.store.completed.length},null,8,["value"])]),_:1})]),_:1})]),_:1}),t.store.running.length>0?(i(),C(f,{key:1,title:"运行中的任务",class:"panel-card",size:"small"},{default:a(()=>[(i(!0),c(T,null,F(t.store.running,o=>(i(),c("div",{key:o.id,class:"task-item running"},[_("div",K,[n(S,{color:t.store.getStatusColor(o.status)},{default:a(()=>[k(r(o.status.toUpperCase()),1)]),_:2},1032,["color"]),_("span",M,r(o.description),1),_("span",Q,r(o.id.slice(0,16)),1)]),_("div",W,[_("span",null,"类型: "+r(o.type||"-"),1),_("span",null,"已运行: "+r(t.store.formatDuration(Date.now()-o.startedAt)),1),n(v,{size:"small",danger:"",onClick:e=>t.store.stopTask(o.id)},{default:a(()=>[...l[4]||(l[4]=[k("停止",-1)])]),_:1},8,["onClick"])])]))),128))]),_:1})):x("v-if",!0),n(f,{class:"panel-card"},{default:a(()=>[n(A,{columns:t.columns,"data-source":t.store.tasks,pagination:{pageSize:15,size:"small"},loading:t.store.loading,"row-key":"id",size:"small"},{bodyCell:a(({column:o,record:e})=>[o.key==="status"?(i(),C(S,{key:0,color:t.store.getStatusColor(e.status)},{default:a(()=>[k(r(e.status),1)]),_:2},1032,["color"])):o.key==="description"?(i(),c("span",{key:1,title:e.command},r(e.description),9,Z)):o.key==="duration"?(i(),c(T,{key:2},[k(r(t.getDuration(e)),1)],64)):o.key==="createdAt"?(i(),c(T,{key:3},[k(r(t.formatTime(e.createdAt)),1)],64)):o.key==="result"?(i(),c(T,{key:4},[e.error?(i(),c("span",G,r(t.truncate(e.error,60)),1)):e.result?(i(),c("span",H,r(t.truncate(String(e.result),60)),1)):(i(),c("span",X,"-"))],64)):o.key==="action"?(i(),c(T,{key:5},[e.status==="running"?(i(),C(v,{key:0,size:"small",danger:"",onClick:g=>t.store.stopTask(e.id)},{default:a(()=>[...l[5]||(l[5]=[k(" 停止 ",-1)])]),_:1},8,["onClick"])):x("v-if",!0)],64)):x("v-if",!0)]),_:1},8,["data-source","loading"])]),_:1})])}const st=E(L,[["render",Y],["__scopeId","data-v-da5ff6a2"],["__file","/tmp/cc-web-panel-7Oqy5c/repo/packages/web-panel/src/views/Tasks.vue"]]);export{st as default};
@@ -1 +0,0 @@
1
- import{Q as r}from"./index-CGqrVLWe.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-CejfUjmo.js";import{a0 as t}from"./index-CGqrVLWe.js";import"./vendor-BMxUs6UX.js";import"./responsiveObserve-CGl8NIlO.js";import"./useFlexGapSupport-D1sN2OlQ.js";import"./styleChecker-BiY1H5ST.js";import"./index-phHPSXlV.js";import"./icons-BsDmGpcT.js";const l=t(o);export{l as default};
@@ -1 +0,0 @@
1
- import{C as o}from"./Col-DLPM22eX.js";import{a0 as t}from"./index-CGqrVLWe.js";import"./vendor-BMxUs6UX.js";import"./index-phHPSXlV.js";import"./icons-BsDmGpcT.js";const s=t(o);export{s as default};