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.
- package/README.md +1 -1
- package/package.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-CVLVJS-Q.js → AIOps-CIpoXyVI.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CJ2_GJsI.js → ActionButton-Ch_QXIPk.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-CZsmlTF8.js → Analytics-CvaBYShv.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DREvMZ62.js → AppLayout-B6Q6olcr.js} +5 -5
- package/src/assets/web-panel/assets/{Audit-B4NR42w_.js → Audit-Bng8eHCW.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CJFmf3In.js → Backup-DvBs8-lm.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-Bh8_iUZY.js → BaseInput-DKwajm0g.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-DEwKjIxV.js → Chat-BoGpZ3uO.js} +5 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-mDQl_PXO.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-DYWCqYI9.js → Checkbox-BMJEmxFQ.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-BlXrfZAJ.js → Codegen-Bsoag5CV.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DLPM22eX.js → Col-CDjH9-sp.js} +1 -1
- package/src/assets/web-panel/assets/{Community-PFyzqijs.js → Community-Cg2QHPQ6.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-7DIfY5Wp.js → Compact-BU2BaqP-.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-DF4CinPU.js → Compliance-D6ZYMCqZ.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-B1J80Vcj.js → Cowork-DaZ8VW-I.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-B7sx2OXX.js → Cron-DQY1RH9v.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-omLkxmu-.js → Crosschain-BVR28vk9.js} +1 -1
- package/src/assets/web-panel/assets/{DID-B_7r7b5F.js → DID-N44KvTP-.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-Cp7k3GZg.js → Dashboard-Bjhlx6wS.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BCKO89Y8.js → Dropdown-CpLYxpy1.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CNgTSsFZ.js → EmailListRenderer-srEITSPI.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-DobM83JP.js → FamilyGuardDashboard-juOC_fX2.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-XVAYQIeu.js → Federation-nRaQtaXW.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DV5ka1KQ.js → FormItemContext-DflhTj09.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-Dg5q-KpC.js → GenericCardRenderer-DulI_3NI.js} +1 -1
- package/src/assets/web-panel/assets/{Git-Dsn3Xhxf.js → Git-BxOPefXn.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-D06S4Qow.js → Governance-C6G_Wnwi.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-nAvwxUXy.js → Inference-BnFYa2BF.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-CtqRP_rF.js → KnowledgeGraph-TqQLEabm.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-J5aGAyfY.js → Logs-BH4AVh7s.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-CaeY23Kj.js → Marketplace-DoWLTaEE.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-C2HHnwnE.js → McpTools-D6yC7OG_.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-CWBrdKlR.js → Memory-DLCeHj21.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-CBLQ8uCY.js → MobileBridge-BZBE0GRl.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-Q_Cy_W4_.js → MobileProjects-DJA15G1J.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-BXur-euo.js → Mtc-CyTKJDHn.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-CpQSlOQC.js → MtcAudit-DZKjgEVc.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-DlFwdEOA.js → Multisig-2rMPNhSO.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-DSh7fevc.js → NLProgramming-VeMk4Fx-.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-Bv4NOVxg.js → Notes-jr2GHMhh.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-CzHNnIfa.js → NotificationSettings-WN9VZyFb.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-D7pHfKK4.js → OrderTableRenderer-CjNO-e9T.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-COzV01ed.js → Organization-DdjVHuzT.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-CYRZJb2_.js → Overflow-l8vBsGGq.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-DFm49FE0.js → P2P-CVQDHHwq.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-Ctr-6k5B.js → PdhVaultBrowser-CTsNh8qE.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-DXVrhFyv.js → Permissions-DLW87uyK.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-BO5utpLK.js → PersonalDataHub-N8OvASTx.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-C9irYCg7.js → Pipeline-BPZmdlz2.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-r13hrvoF.js → Privacy-MFZw_GNh.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-PRKNPZZC.js → ProjectInit-zW0pEsfU.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-QvxM1ZDO.js → ProjectSettings-CppVHr_o.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-DfgmsN3j.js → Projects-BTglkJO2.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-DxbrccZ7.js → Providers-CPHZ6JKT.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-BMHVRxBX.js → QrScannerModal-DO4klNZ2.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-Co3_ndAH.js → QuickAsk-B37TTqUa.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Cv3UWR6s.js → Recommend-n7KIfK7y.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-CSDsO2zA.js → RemoteSession-SjVoS9mm.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-Bdj59vzM.js → Reputation-Dt6RTeHi.js} +1 -1
- package/src/assets/web-panel/assets/{Row-CejfUjmo.js → Row-Dty6jz5V.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-C83yKkvU.js → RssFeed-DDLhqw5j.js} +3 -3
- package/src/assets/web-panel/assets/{Search-Ck4l_VI3.js → Search-DrYbXi-W.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DGIIEx6K.js → Security-Fc9Z6fbB.js} +3 -3
- package/src/assets/web-panel/assets/{Services-Cj2aNAy3.js → Services-BAhPgjSM.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-Dlyy8akb.js → Skeleton-8JF7EPfE.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-C4aDa9Zh.js → Skills-DL39dY0t.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-tHd_Bauo.js → Sla-CSvjcATc.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DI7R0Qgd.js → SpeechSettings-Demx7Gnx.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-OOxiPdsE.js → SyncSettings-CKLnRWJr.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-mhITRxjv.js +1 -0
- package/src/assets/web-panel/assets/{Templates-Bm7eSMWH.js → Templates-AjQI5rxD.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-B8F8eFvD.js → Tenant-dbtEh1yR.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-2oWhR7QF.js → Terminal-DX-9jjfk.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-GLnecmpd.js → TimelineRenderer-C11EDZRt.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-CtpFyati.js → Tokens-GiA9fiZn.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DGkXZzbN.js → Trigger-BPcnclJn.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-ClYZMkXN.js → Trust-C-DVY8nq.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-C1AuEW5-.js → UkeySign-DxodSwME.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-DHa9ekSK.js → VideoEditing-D_WV0O8O.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-CyQv8ZAN.js → Wallet-DSeNlVSU.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DPxEEb5Y.js → WebAuthn-Bwuuvpz1.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-C-fCM8Si.js → WorkflowEditor-8M96EU1N.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BMu1Pk8B.js → chat-D5S6SmLm.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DYPOXyWQ.js → colors-5fbnGkAP.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-C5r_plPk.js → compact-item-DaSuuMlW.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-9fWrWmuJ.js → createContext-BNOHcXAF.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-K_woVElh.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CjZM2-qE.js → hasIn-DONwZUra.js} +1 -1
- package/src/assets/web-panel/assets/index-3ILvaBpo.js +1 -0
- package/src/assets/web-panel/assets/{index-BsHmE__1.js → index-5_fj5gVd.js} +1 -1
- package/src/assets/web-panel/assets/{index-DLCoKst9.js → index-B4L3gsNA.js} +1 -1
- package/src/assets/web-panel/assets/{index-Du-w2i6G.js → index-BEO5f7Vf.js} +1 -1
- package/src/assets/web-panel/assets/{index-CTnaRErh.js → index-BJp4kRjw.js} +1 -1
- package/src/assets/web-panel/assets/{index-CGqrVLWe.js → index-BK2N5yVW.js} +3 -3
- package/src/assets/web-panel/assets/{index-B56CI20h.js → index-BLzMuz38.js} +1 -1
- package/src/assets/web-panel/assets/{index-DNxR1CHs.js → index-B_yDD9Lm.js} +1 -1
- package/src/assets/web-panel/assets/{index-BVFtY8Y4.js → index-BcWMZqb4.js} +1 -1
- package/src/assets/web-panel/assets/{index-0DVMoDzF.js → index-BcqOK7Lv.js} +1 -1
- package/src/assets/web-panel/assets/{index-C3E7xVl1.js → index-BrAJSu-v.js} +1 -1
- package/src/assets/web-panel/assets/{index-B_bTdeou.js → index-CAYmc5Nh.js} +1 -1
- package/src/assets/web-panel/assets/{index-DjTB4wPn.js → index-CEzd5m5a.js} +1 -1
- package/src/assets/web-panel/assets/{index-BPucc_ES.js → index-CLXf-8ek.js} +1 -1
- package/src/assets/web-panel/assets/{index-Co9kBFxY.js → index-CSfYJqXt.js} +1 -1
- package/src/assets/web-panel/assets/{index-BW-x3mUK.js → index-CTZeOnzO.js} +1 -1
- package/src/assets/web-panel/assets/{index-BBVCXmJV.js → index-Cf2OCa8q.js} +1 -1
- package/src/assets/web-panel/assets/{index-DJk9cPrs.js → index-ClGqO-2X.js} +1 -1
- package/src/assets/web-panel/assets/{index-phHPSXlV.js → index-CmUOjyL6.js} +1 -1
- package/src/assets/web-panel/assets/{index-jO4lIpFE.js → index-Cn5LtyIH.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bti4lpw5.js → index-CrkCFohi.js} +1 -1
- package/src/assets/web-panel/assets/{index-DWwI0Jjd.js → index-CztESwB4.js} +1 -1
- package/src/assets/web-panel/assets/{index-CYoS2cwK.js → index-D7gs_3Ck.js} +1 -1
- package/src/assets/web-panel/assets/{index-D0rFX-xN.js → index-DHx2lhHW.js} +1 -1
- package/src/assets/web-panel/assets/{index-CDaA4A0b.js → index-DM3Ug61e.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bglw_kmu.js → index-DP2-3A_j.js} +1 -1
- package/src/assets/web-panel/assets/{index-CyUtBxnC.js → index-DbdQBn4n.js} +1 -1
- package/src/assets/web-panel/assets/{index-I3Qdrfcf.js → index-Dd7xwGcD.js} +1 -1
- package/src/assets/web-panel/assets/{index-D6zyUpD6.js → index-Dm5A-MN5.js} +1 -1
- package/src/assets/web-panel/assets/index-JpB-FoZq.js +1 -0
- package/src/assets/web-panel/assets/{index-Cd9_KCPs.js → index-KwV9g_cf.js} +1 -1
- package/src/assets/web-panel/assets/{index-HJdfPSMz.js → index-LRIt-AFl.js} +1 -1
- package/src/assets/web-panel/assets/{index-Mipa7XgU.js → index-MOgO5Yvx.js} +1 -1
- package/src/assets/web-panel/assets/{index-CcDGi9U1.js → index-PsMErAB1.js} +1 -1
- package/src/assets/web-panel/assets/{index-B1iUe3Ba.js → index-RkInlwV0.js} +1 -1
- package/src/assets/web-panel/assets/{index-oerotzoq.js → index-_6S41ikV.js} +1 -1
- package/src/assets/web-panel/assets/{index-ByVDaARk.js → index-uR5KTNZA.js} +1 -1
- package/src/assets/web-panel/assets/{index-CJJx0kbR.js → index-vYtprlNs.js} +1 -1
- package/src/assets/web-panel/assets/{index-CvUR6l7C.js → index-xo2f4DZR.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-B7tpABc_.js → initDefaultProps-CxwLynp9.js} +1 -1
- package/src/assets/web-panel/assets/{motion-DmvaRoVv.js → motion-XbPvGJbW.js} +1 -1
- package/src/assets/web-panel/assets/{move-DF4X29Wf.js → move-D1u5pcgS.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-C0cbg4PO.js → mtc-parser-BDxhTBMH.js} +1 -1
- package/src/assets/web-panel/assets/{omit-DZzcYy0l.js → omit-EtIFGg5k.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DaZWfzuH.js → pickAttrs-D33sWb0l.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-CBxOEyvn.js → placementArrow-BwFRzaGo.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CGl8NIlO.js → responsiveObserve-CBk2WqvQ.js} +1 -1
- package/src/assets/web-panel/assets/{slide-Bv330MSZ.js → slide-B52HtrKn.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-DJVy5oEM.js → statusUtils-D4qxqWnH.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-BiY1H5ST.js → styleChecker-BxaCFlOL.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-D1sN2OlQ.js → useFlexGapSupport-B1lWlqXN.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DxxHawzW.js → useFs-C6VAU1_6.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-C1HblLrD.js → usePersonalDataHub-rEG6oXG8.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-Dex0jy4T.js → vnode-DOTafkEi.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-Bk1MScAD.js → zoom-BuwwN5K2.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-manifest.json +8 -1
- package/src/commands/ask.js +1 -1
- package/src/commands/complete.js +147 -0
- package/src/commands/team.js +34 -0
- package/src/data/changelog.json +12 -2
- package/src/harness/mcp-client.js +115 -1
- package/src/index.js +2 -0
- package/src/lib/agent-team/team-runner.js +20 -0
- package/src/lib/config-manager.js +14 -1
- package/src/lib/sub-agent-context.js +28 -7
- package/src/lib/telemetry/span-recorder.js +13 -1
- package/src/repl/agent-repl.js +52 -13
- package/src/repl/permission-prompt.js +58 -0
- package/src/runtime/agent-core.js +236 -1
- package/src/runtime/coding-agent-contract-shared.cjs +5 -0
- package/src/assets/web-panel/assets/ChatBubbleRenderer-BOqHkxK_.js +0 -1
- package/src/assets/web-panel/assets/Tasks-Nro_Ltg5.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DmRz5Pet.js +0 -1
- package/src/assets/web-panel/assets/index-CrsL7YBW.js +0 -1
- package/src/assets/web-panel/assets/index-zW69WSDA.js +0 -1
package/src/repl/agent-repl.js
CHANGED
|
@@ -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 {
|
|
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
|
|
563
|
-
|
|
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
|
|
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
|
-
|
|
571
|
-
|
|
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
|
|
629
|
-
|
|
630
|
-
.
|
|
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};
|