chainlesschain 0.162.94 → 0.162.95
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/package.json +1 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-CiEoV_Hg.js → AIOps-DLvvkb9x.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DrrjQMuK.js → ActionButton-BxhQTwqd.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-ChlhPe9a.js → Analytics-C4oUXzhG.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-CIkI7d5o.js → AppLayout-CjzKJdv3.js} +5 -5
- package/src/assets/web-panel/assets/{Audit-_sY9bNSN.js → Audit-B-MrugUs.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DvzaThN8.js → Backup-ecIfEpIZ.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-DDZW_DU8.js → BaseInput-BUcSfWnx.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-DqErkog2.js → Chat-DIc1n_Lk.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-BcnNHS-r.js → ChatBubbleRenderer-BGzg7oVA.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-NWDuyRK6.js → Checkbox-BQ3Ueff-.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-B_jnSC8a.js → Codegen-CvSGLnqE.js} +1 -1
- package/src/assets/web-panel/assets/{Col-B-uyUy0z.js → Col-Br9IXZcE.js} +1 -1
- package/src/assets/web-panel/assets/{Community-Dmf1MpG7.js → Community-tPuLOf0r.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-fGI68M5y.js → Compact-vMWH73BE.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-PV9qT-iV.js → Compliance-Ct9z699x.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-BM6BvCgv.js → Cowork-Bxs1kL1y.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-BsSWwFFo.js → Cron-QEpr2k4U.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-DUdPVYvS.js → Crosschain-u4xbUw6O.js} +1 -1
- package/src/assets/web-panel/assets/{DID-PPLLhrJs.js → DID-DXTEvyrW.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-Cn_Xjj80.js → Dashboard-C4pZgzkg.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DkTXjy5D.js → Dropdown-LRuqREGe.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-BnA27cjB.js → EmailListRenderer-D7XI1yBM.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-jqrv5VCp.js → FamilyGuardDashboard-3y_SuAMQ.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-DESwXwtR.js → Federation-DbjbJJCW.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-C9gbyY1r.js → FormItemContext-WPpMZcUw.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-CkZB9crH.js → GenericCardRenderer-nNT9Tn4E.js} +1 -1
- package/src/assets/web-panel/assets/{Git-B6niu0W9.js → Git-DqDaVzwV.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BrF28dEi.js → Governance-BquBZpcg.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CZDnV8SN.js → Inference-RcPPYijs.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-eqZ0hP0l.js → KnowledgeGraph-ByXfZV13.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BlHS7DoS.js → Logs-CHT3DUcq.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-NOp9G83e.js → Marketplace-Bi0HJ9pN.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-B6wMx173.js → McpTools-QCBxPRRc.js} +4 -4
- package/src/assets/web-panel/assets/{Memory-BKVeTAeT.js → Memory-D4RlxGXn.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-Da2y6iYW.js → MobileBridge-CU_PV7e-.js} +2 -2
- package/src/assets/web-panel/assets/MobileProjects-c1CMFD8z.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-B7Hy5rAT.js → Mtc-BezDB1-s.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-BgBoX0XI.js → MtcAudit-CgLpiHpE.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-Db7bwi5J.js → Multisig-vx6bz-bA.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-f9ca2vst.js → NLProgramming-CGOagg3-.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-meVqoOMz.js → Notes-BcuDGYRS.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-BfEhBXNo.js → NotificationSettings-ZAGCDUpc.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-e25Q6ALJ.js → OrderTableRenderer-B5onE0eX.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-BpgOG9lj.js → Organization-y_y20-5Y.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-fI3L05Rq.js → Overflow-BEICS31D.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-wD0wpJJY.js → P2P-D_WRMzh4.js} +2 -2
- package/src/assets/web-panel/assets/PdhVaultBrowser-C8f5NbbI.js +7 -0
- package/src/assets/web-panel/assets/{Permissions-BJH7W2iv.js → Permissions-3aqCc_4f.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-CqQ3XpMz.js → PersonalDataHub-DT3R9g9Y.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-CHyXCU1i.js → Pipeline-MiMWIhw0.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-CJtfNlc7.js → Privacy-C3JsLuDa.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-CKOaHFGR.js → ProjectInit-EhHVi1ff.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-QD8wp_EM.js → ProjectSettings-D_dNEA37.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-Dj33CO-H.js → Projects-CXydUXp8.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-BPESqCEg.js → Providers-CPEhi2iZ.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-C5AzvvRo.js → QuickAsk-BFQpMleX.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-cGpF3tsA.js → Recommend-DzbovRC8.js} +1 -1
- package/src/assets/web-panel/assets/{Reputation-Duaxvbt9.js → Reputation-DoBeV3TD.js} +1 -1
- package/src/assets/web-panel/assets/{Row-xsUwB5Ay.js → Row-DthhwX_B.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-DmUUsqaF.js → RssFeed-Dsf5U0lP.js} +3 -3
- package/src/assets/web-panel/assets/{Search-Do9YuDbX.js → Search-CJPB8kKl.js} +1 -1
- package/src/assets/web-panel/assets/{Security-06BgEn-d.js → Security-DI9MfpdD.js} +3 -3
- package/src/assets/web-panel/assets/{Services-DyaCes7r.js → Services-BdG0TFGf.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-Cj_VbkFG.js → Skeleton-DSYazY_B.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-DCOWMJOR.js → Skills-BD309VTT.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-C44_86bu.js → Sla-CaUlw4_6.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-BXhBJSMB.js → SpeechSettings-CZAPkR7H.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-BpHsaNWg.js → SyncSettings-CFRSowN3.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-Di8EOluc.js +1 -0
- package/src/assets/web-panel/assets/{Templates-aEWbCOdo.js → Templates-B5FTziwi.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-DkOLw1Yz.js → Tenant-Dj3XYfBg.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-5Z4paIoh.js → Terminal-CznH_rJT.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-CYhublOm.js → TimelineRenderer-DTHzaXPt.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-h57dBT4T.js → Tokens-Bo56nuML.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-abE21FpD.js → Trigger-pyVUVBwb.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-urB3VZip.js → Trust-Cp7jMkKN.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-D6uXV9pp.js → UkeySign-aPcZCdpz.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-C9MxXAzw.js → VideoEditing-DAv5j--w.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-DTn5rW4u.js → Wallet-DRhK7IDR.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-BNYEqeqr.js → WebAuthn-B2yQJuq8.js} +2 -2
- package/src/assets/web-panel/assets/{WorkflowEditor-CsRoOJPT.js → WorkflowEditor-D98DhR54.js} +1 -1
- package/src/assets/web-panel/assets/{chat-B5GoUHDS.js → chat-BXrRNi8C.js} +1 -1
- package/src/assets/web-panel/assets/{colors-BF_Rqaab.js → colors-jQ94T_qn.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BNPfqT4P.js → compact-item-KqUJLlF2.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-C3qLKXX-.js → createContext-DxM3zuQW.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-Bo1r5_zX.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-BLpAeFXB.js → hasIn-BGm946KV.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dn95Blhx.js → index-1P0sXNhG.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cqb8TXEp.js → index-B-2HpfWo.js} +1 -1
- package/src/assets/web-panel/assets/{index-BqjU6Jp9.js → index-B4b7KjRq.js} +1 -1
- package/src/assets/web-panel/assets/{index-D-PNuV4r.js → index-BAPk6ntc.js} +1 -1
- package/src/assets/web-panel/assets/index-BCU6dVQ-.js +1 -0
- package/src/assets/web-panel/assets/{index-DGVf-eOG.js → index-BGjCjsf1.js} +1 -1
- package/src/assets/web-panel/assets/{index-7Tt41tHa.js → index-BMp41Q1Y.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dj6rUk3f.js → index-BXMZLfd8.js} +1 -1
- package/src/assets/web-panel/assets/{index-2-7AD4Fq.js → index-BaU_fSK7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CgIrRLBP.js → index-BbS0cBU9.js} +1 -1
- package/src/assets/web-panel/assets/{index-BIpGZeh2.js → index-BnEZfi5D.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cv1WRH-j.js → index-C5NQai7O.js} +1 -1
- package/src/assets/web-panel/assets/{index-BJsVUj80.js → index-C7Z2m28C.js} +1 -1
- package/src/assets/web-panel/assets/{index-DMKbLaTg.js → index-C7sBLech.js} +1 -1
- package/src/assets/web-panel/assets/{index-CaROOJ5Z.js → index-CbQvgx2e.js} +1 -1
- package/src/assets/web-panel/assets/{index-CMRdeB2r.js → index-Ce-YoL4x.js} +1 -1
- package/src/assets/web-panel/assets/{index-CmBMP52w.js → index-CfE3jxrT.js} +1 -1
- package/src/assets/web-panel/assets/{index-o1doEeT3.js → index-CghRL1dh.js} +1 -1
- package/src/assets/web-panel/assets/{index-vXHPZOmO.js → index-CreXAr5Y.js} +1 -1
- package/src/assets/web-panel/assets/{index-CIjPwa7h.js → index-Crw76vIF.js} +1 -1
- package/src/assets/web-panel/assets/{index-BxWEK9FS.js → index-Cz_SFSix.js} +1 -1
- package/src/assets/web-panel/assets/{index-DudglWTC.js → index-D1VWL6Lc.js} +1 -1
- package/src/assets/web-panel/assets/{index-CBFekqcY.js → index-DOYcemym.js} +1 -1
- package/src/assets/web-panel/assets/{index-C8B3rHnr.js → index-DRzsaWQy.js} +1 -1
- package/src/assets/web-panel/assets/{index-ixN0R0We.js → index-DSzb9VOG.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dz7o1Zt6.js → index-DTUs9t5F.js} +1 -1
- package/src/assets/web-panel/assets/{index-DmrPbYXh.js → index-DWcd5zDG.js} +3 -3
- package/src/assets/web-panel/assets/{index-C6yRwT6e.js → index-DZMzj4ay.js} +1 -1
- package/src/assets/web-panel/assets/{index-BryugSCS.js → index-DZpVYD4j.js} +1 -1
- package/src/assets/web-panel/assets/{index-DH95hKUN.js → index-DboUBf6R.js} +1 -1
- package/src/assets/web-panel/assets/{index-BlEDjdTc.js → index-Dgzw6eKr.js} +1 -1
- package/src/assets/web-panel/assets/{index-BOoTjHGU.js → index-Dib0FsTT.js} +1 -1
- package/src/assets/web-panel/assets/{index-DYWExa2Z.js → index-FSYz5aww.js} +1 -1
- package/src/assets/web-panel/assets/{index-C2wJowV1.js → index-LWTZAud0.js} +1 -1
- package/src/assets/web-panel/assets/index-N_oOFphx.js +1 -0
- package/src/assets/web-panel/assets/{index-Cxd2RsZR.js → index-T4UJiTi3.js} +1 -1
- package/src/assets/web-panel/assets/{index-KUdyAwqr.js → index-aOLXuHpG.js} +1 -1
- package/src/assets/web-panel/assets/{index-DMKiwMJa.js → index-mZNLT2SP.js} +1 -1
- package/src/assets/web-panel/assets/{index-81hgV6U6.js → index-yavsyHif.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-Dhfx-jOJ.js → initDefaultProps-BDoZJI7g.js} +1 -1
- package/src/assets/web-panel/assets/{motion-DzZPc4Mq.js → motion-sceLjgp-.js} +1 -1
- package/src/assets/web-panel/assets/{move-D6R8EIjz.js → move-CTWQpFa7.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CPniUUR1.js → omit-dr-NCrHZ.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DbzxHNNa.js → pickAttrs-DK-GX_Z2.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-B_MxmwXz.js → placementArrow-BIPf--18.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-Em-jKJ7U.js → responsiveObserve-BzrWT5tV.js} +1 -1
- package/src/assets/web-panel/assets/{slide-B2RV1mQl.js → slide-D5XhxlET.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-C9Ps6HQe.js → statusUtils-6DI-k-9E.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-DCoehh1S.js → styleChecker-DMw-eyn9.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DZOaLVto.js → useFlexGapSupport-D4oVdliM.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-Dk_JA91R.js → useFs-D3PPZnvy.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-CJR6Dqtz.js → usePersonalDataHub-Gh5ba4KP.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-BaFNaDQL.js → vnode-CVEM1u4x.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-CxA9IYpM.js → zoom-ClT_-9RZ.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/pdh.js +162 -0
- package/src/harness/mcp-client.js +19 -2
- package/src/index.js +2 -0
- package/src/lib/claude-code-bridge.js +14 -2
- package/src/lib/file-checkpoint.js +30 -4
- package/src/lib/session-tail.js +6 -1
- package/src/repl/agent-repl.js +13 -6
- package/src/runtime/headless-runner.js +39 -5
- package/src/runtime/headless-stream.js +92 -1
- package/src/assets/web-panel/assets/MobileProjects-CTFPhn4A.js +0 -1
- package/src/assets/web-panel/assets/PdhVaultBrowser-BWV9J4VZ.js +0 -7
- package/src/assets/web-panel/assets/Tasks-C83eyBn8.js +0 -1
- package/src/assets/web-panel/assets/devWarning-D5Rwbl_Y.js +0 -1
- package/src/assets/web-panel/assets/index-7ls1Z3dH.js +0 -1
- package/src/assets/web-panel/assets/index-DoldiBPq.js +0 -1
|
@@ -43,6 +43,33 @@ function ensureDir(dir) {
|
|
|
43
43
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Write a file atomically: write to a unique temp sibling, then rename over the
|
|
48
|
+
* target. rename() is atomic within a filesystem, so a crash mid-write leaves
|
|
49
|
+
* the previous file (or nothing) intact — never a half-written manifest/blob.
|
|
50
|
+
* Without this, a checkpoint manifest truncated by a crash makes the whole
|
|
51
|
+
* checkpoint unrecoverable (getCheckpoint's JSON.parse fails → null) while its
|
|
52
|
+
* blobs are orphaned on disk. The temp lives in the SAME dir as the target so
|
|
53
|
+
* the rename stays on one filesystem; on failure the temp is best-effort
|
|
54
|
+
* removed. Temp names end in `.tmp` (never `.json`), so a leftover from a hard
|
|
55
|
+
* crash is ignored by listCheckpoints.
|
|
56
|
+
*/
|
|
57
|
+
function atomicWriteFileSync(filePath, data) {
|
|
58
|
+
const rand = Math.random().toString(36).slice(2, 8);
|
|
59
|
+
const tmp = `${filePath}.${process.pid}.${rand}.tmp`;
|
|
60
|
+
try {
|
|
61
|
+
fs.writeFileSync(tmp, data);
|
|
62
|
+
fs.renameSync(tmp, filePath);
|
|
63
|
+
} catch (err) {
|
|
64
|
+
try {
|
|
65
|
+
if (fs.existsSync(tmp)) fs.unlinkSync(tmp);
|
|
66
|
+
} catch {
|
|
67
|
+
/* best-effort temp cleanup */
|
|
68
|
+
}
|
|
69
|
+
throw err;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
46
73
|
function sha256(buf) {
|
|
47
74
|
return createHash("sha256").update(buf).digest("hex");
|
|
48
75
|
}
|
|
@@ -127,7 +154,7 @@ export function createCheckpoint(paths, opts = {}) {
|
|
|
127
154
|
const buf = fs.readFileSync(abs);
|
|
128
155
|
const hash = sha256(buf);
|
|
129
156
|
const blobPath = path.join(blobDir, hash);
|
|
130
|
-
if (!fs.existsSync(blobPath))
|
|
157
|
+
if (!fs.existsSync(blobPath)) atomicWriteFileSync(blobPath, buf);
|
|
131
158
|
files.push({
|
|
132
159
|
rel: path.relative(cwd, abs) || path.basename(abs),
|
|
133
160
|
abs,
|
|
@@ -145,10 +172,9 @@ export function createCheckpoint(paths, opts = {}) {
|
|
|
145
172
|
files,
|
|
146
173
|
};
|
|
147
174
|
ensureDir(root);
|
|
148
|
-
|
|
175
|
+
atomicWriteFileSync(
|
|
149
176
|
path.join(root, `${id}.json`),
|
|
150
177
|
JSON.stringify(manifest, null, 2),
|
|
151
|
-
"utf-8",
|
|
152
178
|
);
|
|
153
179
|
return manifest;
|
|
154
180
|
}
|
|
@@ -275,7 +301,7 @@ export function restoreCheckpoint(id, opts = {}) {
|
|
|
275
301
|
|
|
276
302
|
for (const w of toWrite) {
|
|
277
303
|
ensureDir(path.dirname(w.abs));
|
|
278
|
-
|
|
304
|
+
atomicWriteFileSync(w.abs, w.blob);
|
|
279
305
|
restored.push(w.rel);
|
|
280
306
|
}
|
|
281
307
|
|
package/src/lib/session-tail.js
CHANGED
|
@@ -89,6 +89,10 @@ export async function* followSession(sessionId, options = {}) {
|
|
|
89
89
|
? fromOffset
|
|
90
90
|
: initialOffset(sessionId, { fromStart });
|
|
91
91
|
let buffer = "";
|
|
92
|
+
// Streaming decoder persisted across polls: when the file grows by a partial
|
|
93
|
+
// multi-byte UTF-8 character between reads (the rest arrives next poll), the
|
|
94
|
+
// held bytes are reassembled instead of corrupted into U+FFFD.
|
|
95
|
+
let decoder = new TextDecoder("utf-8");
|
|
92
96
|
|
|
93
97
|
// eslint-disable-next-line no-constant-condition
|
|
94
98
|
while (true) {
|
|
@@ -100,6 +104,7 @@ export async function* followSession(sessionId, options = {}) {
|
|
|
100
104
|
// File was truncated / rotated — restart from beginning
|
|
101
105
|
offset = 0;
|
|
102
106
|
buffer = "";
|
|
107
|
+
decoder = new TextDecoder("utf-8"); // drop any held partial-char bytes
|
|
103
108
|
}
|
|
104
109
|
if (stat.size > offset) {
|
|
105
110
|
const fd = await fsp.open(filePath, "r");
|
|
@@ -108,7 +113,7 @@ export async function* followSession(sessionId, options = {}) {
|
|
|
108
113
|
const buf = Buffer.alloc(length);
|
|
109
114
|
await fd.read(buf, 0, length, offset);
|
|
110
115
|
offset = stat.size;
|
|
111
|
-
buffer +=
|
|
116
|
+
buffer += decoder.decode(buf, { stream: true });
|
|
112
117
|
} finally {
|
|
113
118
|
await fd.close();
|
|
114
119
|
}
|
package/src/repl/agent-repl.js
CHANGED
|
@@ -1946,6 +1946,11 @@ export async function startAgentRepl(options = {}) {
|
|
|
1946
1946
|
messages.length = 1; // keep system prompt
|
|
1947
1947
|
messages.push(...rebuilt.filter((m) => m.role !== "system"));
|
|
1948
1948
|
sessionId = resumeId;
|
|
1949
|
+
// The prior session's checkpoint marks (turn-index → checkpoint id)
|
|
1950
|
+
// no longer map to this swapped-in history; keeping them would make
|
|
1951
|
+
// a later /rewind restore files from the WRONG session's snapshot.
|
|
1952
|
+
// Same reset /clear does on a context swap.
|
|
1953
|
+
_checkpointMarks.length = 0;
|
|
1949
1954
|
logger.info(
|
|
1950
1955
|
`Resumed JSONL session ${sessionId} (${rebuilt.length} messages)`,
|
|
1951
1956
|
);
|
|
@@ -1959,6 +1964,8 @@ export async function startAgentRepl(options = {}) {
|
|
|
1959
1964
|
messages.length = 1; // keep system prompt
|
|
1960
1965
|
messages.push(...parsed.filter((m) => m.role !== "system"));
|
|
1961
1966
|
sessionId = existing.id;
|
|
1967
|
+
// Drop the prior session's checkpoint marks (see JSONL branch).
|
|
1968
|
+
_checkpointMarks.length = 0;
|
|
1962
1969
|
logger.info(
|
|
1963
1970
|
`Resumed session ${sessionId} (${parsed.length} messages)`,
|
|
1964
1971
|
);
|
|
@@ -2660,7 +2667,7 @@ export async function startAgentRepl(options = {}) {
|
|
|
2660
2667
|
|
|
2661
2668
|
// `/sessions` — list recent RESUMABLE conversations (read-only; the ids
|
|
2662
2669
|
// work with `cc agent --resume <id>`). `/session` shows the current one.
|
|
2663
|
-
if (trimmed === "/sessions" || trimmed
|
|
2670
|
+
if (trimmed === "/sessions" || trimmed.startsWith("/sessions ")) {
|
|
2664
2671
|
try {
|
|
2665
2672
|
const { listRecentSessions } = await import("../lib/recent-session.js");
|
|
2666
2673
|
const { renderRecentSessions } = await import("./recent-sessions.js");
|
|
@@ -2676,7 +2683,7 @@ export async function startAgentRepl(options = {}) {
|
|
|
2676
2683
|
// `/memory` — project-memory files auto-loaded into the system prompt
|
|
2677
2684
|
// (cc.md hierarchy + imports + path-scoped rules). Distinct from `#` (add
|
|
2678
2685
|
// a note) and `cc memory recall` (scoped store).
|
|
2679
|
-
if (trimmed === "/memory" || trimmed
|
|
2686
|
+
if (trimmed === "/memory" || trimmed.startsWith("/memory ")) {
|
|
2680
2687
|
try {
|
|
2681
2688
|
const { loadProjectInstructions } =
|
|
2682
2689
|
await import("../lib/project-instructions.js");
|
|
@@ -2695,7 +2702,7 @@ export async function startAgentRepl(options = {}) {
|
|
|
2695
2702
|
}
|
|
2696
2703
|
|
|
2697
2704
|
// `/mcp` — overview of connected MCP servers' resources + prompts.
|
|
2698
|
-
if (trimmed === "/mcp" || trimmed
|
|
2705
|
+
if (trimmed === "/mcp" || trimmed.startsWith("/mcp ")) {
|
|
2699
2706
|
const mcpClient = _adhocMcp?.mcpClient || _bundleMcpClient;
|
|
2700
2707
|
logger.log(renderMcpSurface(mcpClient));
|
|
2701
2708
|
prompt();
|
|
@@ -2753,7 +2760,7 @@ export async function startAgentRepl(options = {}) {
|
|
|
2753
2760
|
|
|
2754
2761
|
// `/doctor` — consolidated session-health readout (Claude-Code parity):
|
|
2755
2762
|
// provider/key/IDE/MCP/permissions/hooks in one pass-or-warn view.
|
|
2756
|
-
if (trimmed === "/doctor" || trimmed
|
|
2763
|
+
if (trimmed === "/doctor" || trimmed.startsWith("/doctor ")) {
|
|
2757
2764
|
let config = {};
|
|
2758
2765
|
try {
|
|
2759
2766
|
config = (await import("../lib/config-manager.js")).loadConfig() || {};
|
|
@@ -2860,7 +2867,7 @@ export async function startAgentRepl(options = {}) {
|
|
|
2860
2867
|
|
|
2861
2868
|
// `/cost` — running token spend + estimated $ for this session (Claude-Code
|
|
2862
2869
|
// parity). In-memory accumulation, so it works without session persistence.
|
|
2863
|
-
if (trimmed === "/cost" || trimmed
|
|
2870
|
+
if (trimmed === "/cost" || trimmed.startsWith("/cost ")) {
|
|
2864
2871
|
let overrides;
|
|
2865
2872
|
let visionModel;
|
|
2866
2873
|
try {
|
|
@@ -2937,7 +2944,7 @@ export async function startAgentRepl(options = {}) {
|
|
|
2937
2944
|
|
|
2938
2945
|
// `/ide` — IDE bridge connection status (Claude-Code parity): which editor
|
|
2939
2946
|
// is connected, its tools, or why discovery came up empty.
|
|
2940
|
-
if (trimmed === "/ide" || trimmed
|
|
2947
|
+
if (trimmed === "/ide" || trimmed.startsWith("/ide ")) {
|
|
2941
2948
|
let diag = null;
|
|
2942
2949
|
try {
|
|
2943
2950
|
const { diagnoseIde } = await import("../lib/ide-bridge.js");
|
|
@@ -414,6 +414,40 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
414
414
|
writeErr("No previous session to continue; starting a new one.\n");
|
|
415
415
|
}
|
|
416
416
|
|
|
417
|
+
// Machine-readable modes (`--output-format json` / `stream-json`) must ALWAYS
|
|
418
|
+
// end with a terminal result envelope — a consumer parsing stdout otherwise
|
|
419
|
+
// gets nothing and can't tell success from failure. Several setup-phase error
|
|
420
|
+
// paths below early-return BEFORE the main loop's try/catch envelope (and
|
|
421
|
+
// before `system/init`), so route them through this so stdout is never empty.
|
|
422
|
+
// No-op in text mode (those paths already writeErr a human message).
|
|
423
|
+
const emitHeadlessError = (resultMsg) => {
|
|
424
|
+
if (isStream) {
|
|
425
|
+
writeOut(
|
|
426
|
+
JSON.stringify({
|
|
427
|
+
type: "result",
|
|
428
|
+
subtype: "error",
|
|
429
|
+
is_error: true,
|
|
430
|
+
error: resultMsg,
|
|
431
|
+
}) + "\n",
|
|
432
|
+
);
|
|
433
|
+
} else if (isJson) {
|
|
434
|
+
writeOut(
|
|
435
|
+
JSON.stringify(
|
|
436
|
+
buildResultEnvelope({
|
|
437
|
+
subtype: "error",
|
|
438
|
+
isError: true,
|
|
439
|
+
result: resultMsg,
|
|
440
|
+
sessionId,
|
|
441
|
+
toolCalls: [],
|
|
442
|
+
usage: {},
|
|
443
|
+
numTurns: 0,
|
|
444
|
+
durationMs: 0,
|
|
445
|
+
}),
|
|
446
|
+
) + "\n",
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
|
|
417
451
|
// Load prior conversation when resuming an existing session. The fresh
|
|
418
452
|
// system prompt always leads; we drop any persisted system turns so it is
|
|
419
453
|
// never duplicated.
|
|
@@ -489,11 +523,9 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
489
523
|
writeErr(
|
|
490
524
|
`[hook] prompt blocked${ups.reason ? ": " + ups.reason : ""}\n`,
|
|
491
525
|
);
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
isError: true,
|
|
496
|
-
};
|
|
526
|
+
const reason = ups.reason || "blocked by UserPromptSubmit hook";
|
|
527
|
+
emitHeadlessError(reason);
|
|
528
|
+
return { exitCode: 2, result: reason, isError: true };
|
|
497
529
|
}
|
|
498
530
|
if (ups.additionalContext) {
|
|
499
531
|
userContent += `\n\n[hook context]\n${ups.additionalContext}`;
|
|
@@ -593,6 +625,7 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
593
625
|
}
|
|
594
626
|
} catch (err) {
|
|
595
627
|
writeErr(`Error: ${err.message}\n`);
|
|
628
|
+
emitHeadlessError(err.message);
|
|
596
629
|
return { exitCode: 1, result: err.message, isError: true };
|
|
597
630
|
}
|
|
598
631
|
}
|
|
@@ -635,6 +668,7 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
635
668
|
} catch (err) {
|
|
636
669
|
writeErr(`Error: ${err.message}\n`);
|
|
637
670
|
if (mcp?.mcpClient) await mcp.mcpClient.disconnectAll().catch(() => {});
|
|
671
|
+
emitHeadlessError(err.message);
|
|
638
672
|
return { exitCode: 1, result: err.message, isError: true };
|
|
639
673
|
}
|
|
640
674
|
if (approvalGate && typeof approvalGate.setConfirmer === "function") {
|
|
@@ -102,6 +102,18 @@ export function parseInputEvent(line) {
|
|
|
102
102
|
if (!obj.id) return null;
|
|
103
103
|
return { approval: { id: String(obj.id), approve: obj.approve === true } };
|
|
104
104
|
}
|
|
105
|
+
// Answer to an ask_user_question (panel QuickPick for interactive questions):
|
|
106
|
+
// {"type":"answer","id":"q-1","answer":<string|string[]|null>}
|
|
107
|
+
// A null/absent answer cancels (handler → user_timeout, model proceeds).
|
|
108
|
+
if (obj && typeof obj === "object" && obj.type === "answer") {
|
|
109
|
+
if (!obj.id) return null;
|
|
110
|
+
return {
|
|
111
|
+
answer: {
|
|
112
|
+
id: String(obj.id),
|
|
113
|
+
value: obj.answer === undefined ? null : obj.answer,
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
}
|
|
105
117
|
const msg = obj && typeof obj === "object" ? obj.message || obj : {};
|
|
106
118
|
let content = msg.content ?? obj.text ?? obj.prompt;
|
|
107
119
|
if (Array.isArray(content)) {
|
|
@@ -147,14 +159,24 @@ export function parseInputEvent(line) {
|
|
|
147
159
|
*/
|
|
148
160
|
export async function* readJsonLines(input) {
|
|
149
161
|
let buf = "";
|
|
162
|
+
// Reuse ONE streaming decoder across chunks so a multi-byte UTF-8 character
|
|
163
|
+
// (e.g. a 3-byte Chinese char) split across two Buffer chunks is reassembled
|
|
164
|
+
// rather than corrupted. process.stdin yields Buffers with no setEncoding, so
|
|
165
|
+
// a per-chunk `chunk.toString("utf-8")` would turn a split character into
|
|
166
|
+
// U+FFFD replacement chars.
|
|
167
|
+
const decoder = new TextDecoder();
|
|
150
168
|
for await (const chunk of input) {
|
|
151
|
-
buf +=
|
|
169
|
+
buf +=
|
|
170
|
+
typeof chunk === "string"
|
|
171
|
+
? chunk
|
|
172
|
+
: decoder.decode(chunk, { stream: true });
|
|
152
173
|
let idx;
|
|
153
174
|
while ((idx = buf.indexOf("\n")) >= 0) {
|
|
154
175
|
yield buf.slice(0, idx);
|
|
155
176
|
buf = buf.slice(idx + 1);
|
|
156
177
|
}
|
|
157
178
|
}
|
|
179
|
+
buf += decoder.decode(); // flush any bytes held from a final partial char
|
|
158
180
|
if (buf.trim()) yield buf;
|
|
159
181
|
}
|
|
160
182
|
|
|
@@ -404,6 +426,60 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
404
426
|
approvalGate = null;
|
|
405
427
|
}
|
|
406
428
|
|
|
429
|
+
// ── Interactive questions (ask_user_question round-trip; chat-panel UX) ────
|
|
430
|
+
// Same structured pattern as approvals: when the consumer opts in (the IDE
|
|
431
|
+
// panel sets CC_INTERACTIVE_QUESTIONS=1 in the child env), the model's
|
|
432
|
+
// `ask_user_question` tool emits `question_request`, BLOCKS until a
|
|
433
|
+
// {"type":"answer",id,answer} arrives on stdin, and times out gracefully
|
|
434
|
+
// (CC_QUESTION_TIMEOUT_MS, default 180s) — the handler maps the timeout to
|
|
435
|
+
// user_timeout so the model proceeds, never a hard failure. Off by default
|
|
436
|
+
// (env unset / pipes) → agent-core gets no askUser → user_not_reachable, the
|
|
437
|
+
// existing graceful "proceed autonomously" path. Backward-safe: an env var
|
|
438
|
+
// (not a flag) means an old `cc` simply ignores it.
|
|
439
|
+
const interactiveQuestions =
|
|
440
|
+
options.interactiveQuestions === true ||
|
|
441
|
+
process.env.CC_INTERACTIVE_QUESTIONS === "1";
|
|
442
|
+
const pendingQuestions = new Map();
|
|
443
|
+
let questionSeq = 0;
|
|
444
|
+
const questionTimeoutMs =
|
|
445
|
+
Number(process.env.CC_QUESTION_TIMEOUT_MS) > 0
|
|
446
|
+
? Number(process.env.CC_QUESTION_TIMEOUT_MS)
|
|
447
|
+
: 180000;
|
|
448
|
+
const settleQuestion = (id, answer, via) => {
|
|
449
|
+
const p = pendingQuestions.get(id);
|
|
450
|
+
if (!p) return;
|
|
451
|
+
pendingQuestions.delete(id);
|
|
452
|
+
clearTimeout(p.timer);
|
|
453
|
+
emit({ type: "question_resolved", id, via, session_id: sessionId });
|
|
454
|
+
p.resolve(answer);
|
|
455
|
+
};
|
|
456
|
+
const failQuestion = (id, via) => {
|
|
457
|
+
const p = pendingQuestions.get(id);
|
|
458
|
+
if (!p) return;
|
|
459
|
+
pendingQuestions.delete(id);
|
|
460
|
+
clearTimeout(p.timer);
|
|
461
|
+
emit({ type: "question_resolved", id, via, session_id: sessionId });
|
|
462
|
+
const e = new Error(`ask_user_question ${via}`);
|
|
463
|
+
e.code = "USER_TIMEOUT"; // handler → user_timeout (model proceeds, not a failure)
|
|
464
|
+
p.reject(e);
|
|
465
|
+
};
|
|
466
|
+
const interactionAskUser = ({ question, options: qOptions, multiSelect, timeoutMs } = {}) =>
|
|
467
|
+
new Promise((resolve, reject) => {
|
|
468
|
+
const id = `q-${++questionSeq}`;
|
|
469
|
+
const ms = Number(timeoutMs) > 0 ? Number(timeoutMs) : questionTimeoutMs;
|
|
470
|
+
const timer = setTimeout(() => failQuestion(id, "timeout"), ms);
|
|
471
|
+
timer.unref?.();
|
|
472
|
+
pendingQuestions.set(id, { resolve, reject, timer });
|
|
473
|
+
emit({
|
|
474
|
+
type: "question_request",
|
|
475
|
+
id,
|
|
476
|
+
session_id: sessionId,
|
|
477
|
+
question: typeof question === "string" ? question : "",
|
|
478
|
+
options: Array.isArray(qOptions) ? qOptions : null,
|
|
479
|
+
multiSelect: multiSelect === true,
|
|
480
|
+
});
|
|
481
|
+
});
|
|
482
|
+
|
|
407
483
|
// --output-style (or settings.json `outputStyle`) persona, appended.
|
|
408
484
|
let outputStyleBody = null;
|
|
409
485
|
try {
|
|
@@ -591,6 +667,10 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
591
667
|
// edit reviews via openDiff) route to the structured approval round-trip
|
|
592
668
|
// instead of failing closed. Absent in CI/pipes → unchanged fail-closed.
|
|
593
669
|
permissionConfirm: interactive ? interactiveConfirm : undefined,
|
|
670
|
+
// ask_user_question round-trip (opt-in via CC_INTERACTIVE_QUESTIONS): give
|
|
671
|
+
// the tool handler an askUser that emits question_request + blocks on stdin.
|
|
672
|
+
// Absent → agent-core returns user_not_reachable (graceful proceed).
|
|
673
|
+
interaction: interactiveQuestions ? { askUser: interactionAskUser } : undefined,
|
|
594
674
|
prepareCall: goalPrepareCallFn,
|
|
595
675
|
// --mcp-config wiring (tool defs + dispatch map + live client).
|
|
596
676
|
mcpClient: mcp?.mcpClient || null,
|
|
@@ -684,6 +764,13 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
684
764
|
);
|
|
685
765
|
continue;
|
|
686
766
|
}
|
|
767
|
+
if (parsed.answer) {
|
|
768
|
+
// Answers settle a BLOCKED ask_user_question — never queued. A null
|
|
769
|
+
// value (user cancelled the QuickPick) → user_timeout (model proceeds).
|
|
770
|
+
if (parsed.answer.value == null) failQuestion(parsed.answer.id, "cancelled");
|
|
771
|
+
else settleQuestion(parsed.answer.id, parsed.answer.value, "user-answer");
|
|
772
|
+
continue;
|
|
773
|
+
}
|
|
687
774
|
queue.push(parsed);
|
|
688
775
|
if (wakeQueue) wakeQueue();
|
|
689
776
|
}
|
|
@@ -696,6 +783,10 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
696
783
|
for (const id of [...pendingApprovals.keys()]) {
|
|
697
784
|
settleApproval(id, false, "stdin-closed");
|
|
698
785
|
}
|
|
786
|
+
// stdin closed while a question was pending → user_timeout (model proceeds).
|
|
787
|
+
for (const id of [...pendingQuestions.keys()]) {
|
|
788
|
+
failQuestion(id, "stdin-closed");
|
|
789
|
+
}
|
|
699
790
|
if (wakeQueue) wakeQueue();
|
|
700
791
|
})();
|
|
701
792
|
const nextEvent = async () => {
|
|
@@ -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 m}from"./vendor-BvqAck49.js";import{_ as v,b}from"./index-DmrPbYXh.js";import{a7 as y,M}from"./icons-DP3uiYxy.js";const B={__name:"MobileProjects",setup(p,{expose:i}){i();const c=u(),{t:e}=b();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 b},get MobileOutlined(){return M},get FolderOutlined(){return y}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}},x={class:"mobile-projects-placeholder"},O={class:"title"},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),m(" "+t(e.t("mobileProjects.viewLocalProjects")),1)]),_:1}),l(d,{onClick:e.goToMobileBridge},{default:r(()=>[l(e.MobileOutlined),m(" "+t(e.t("mobileProjects.checkBridge")),1)]),_:1})]),_:1})]),_:1})]),_:1})])}const I=v(B,[["render",T],["__scopeId","data-v-9262cc45"],["__file","/tmp/cc-web-panel-94r5Fm/repo/packages/web-panel/src/views/MobileProjects.vue"]]);export{I as default};
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./ChatBubbleRenderer-BcnNHS-r.js","./vendor-BvqAck49.js","./index-DmrPbYXh.js","./icons-DP3uiYxy.js","./index-Cq93VfoF.css","./ChatBubbleRenderer-gy5SDGw2.css","./OrderTableRenderer-e25Q6ALJ.js","./OrderTableRenderer-CfrDjSHT.css","./TimelineRenderer-CYhublOm.js","./TimelineRenderer-BlTAtkOc.css","./EmailListRenderer-BnA27cjB.js","./EmailListRenderer-DTPZPx_S.css","./GenericCardRenderer-CkZB9crH.js","./GenericCardRenderer-o85VDYQS.css"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{E as ue,r as R,b as w,I as y,P as u,J as O,U as v,c,S as C,V as E,_ as M,F as V,Z as se,a0 as le,R as x,K as m,Q as b,W as A,o as J}from"./vendor-BvqAck49.js";import{u as U}from"./usePersonalDataHub-CJR6Dqtz.js";import{_ as D,e as L,d as P}from"./index-DmrPbYXh.js";import{a9 as q,af as z,M as Q,aH as G,u as H,aG as K,ap as W,ab as Y,e as de,d as fe,k as pe,ah as me,az as _e,R as ge}from"./icons-DP3uiYxy.js";const I=Object.freeze({q:"",category:null,adapter:null,subtype:null,since:null,until:null}),B=50,Z=300,X=ue("pdhBrowser",()=>{const r=R({...I}),t=R([]),n=R(null),e=R(!1),o=R(!1),l=R(null),a=R(null),s=R(!1),i=R({byCategory:{},byAdapter:{},bySubtype:{},total:0});let d=0,_=null;const F=w(()=>t.value.length>0),j=w(()=>n.value!=null);function h(S={}){const p={},f=r.value;return f.q&&f.q.trim()&&(p.q=f.q.trim()),f.category&&(p.category=f.category),f.adapter&&(p.adapter=f.adapter),f.subtype&&(p.subtype=f.subtype),Number.isFinite(f.since)&&(p.since=f.since),Number.isFinite(f.until)&&(p.until=f.until),{...p,...S}}async function g(){const S=++d;e.value=!0,l.value=null;const p=U();try{const[f,T]=await Promise.all([p.searchEvents(h({limit:B})),p.facetCounts({...r.value.q&&r.value.q.trim()?{q:r.value.q.trim()}:{},...Number.isFinite(r.value.since)?{since:r.value.since}:{},...Number.isFinite(r.value.until)?{until:r.value.until}:{}})]);if(S!==d)return;t.value=f.rows||[],n.value=f.nextCursor||null,a.value=f.mode||"like",s.value=!!f.shortQuery,i.value={byCategory:T.byCategory||{},byAdapter:T.byAdapter||{},bySubtype:T.bySubtype||{},total:T.total||0}}catch(f){if(S!==d)return;l.value=f&&f.message?f.message:String(f),t.value=[],n.value=null}finally{S===d&&(e.value=!1)}}async function k(){if(!n.value||o.value)return;o.value=!0,l.value=null;const S=U();try{const p=await S.searchEvents(h({cursor:n.value,limit:B}));t.value=t.value.concat(p.rows||[]),n.value=p.nextCursor||null,a.value=p.mode||a.value}catch(p){l.value=p&&p.message?p.message:String(p)}finally{o.value=!1}}function ae(S,p){if(!(S in I))throw new Error(`pdhBrowser.setFilter: unknown key "${S}"`);r.value={...r.value,[S]:p},_&&clearTimeout(_),_=setTimeout(()=>{_=null,g()},Z)}function ie(S){return r.value={...I,...S},_&&(clearTimeout(_),_=null),g()}function ce(){r.value={...I},t.value=[],n.value=null,l.value=null,i.value={byCategory:{},byAdapter:{},bySubtype:{},total:0}}return{filters:r,results:t,cursor:n,isLoading:e,isAppending:o,error:l,mode:a,shortQuery:s,facets:i,hasResults:F,canLoadMore:j,search:g,loadMore:k,setFilter:ae,setFilters:ie,reset:ce,PAGE_SIZE:B,SEARCH_DEBOUNCE_MS:Z}}),ye=Object.freeze(["chat","social","email","shopping","travel","system","ai-chat","other"]),ve=Object.freeze({chat:"社交聊天",social:"内容平台",email:"邮件",shopping:"支付订单",travel:"出行",system:"系统数据","ai-chat":"AI 对话",other:"其他"});function N(r){return ve[r]||r||"未知"}const be=Object.freeze([["wechat","chat"],["messaging-","chat"],["social-","social"],["email-","email"],["shopping-","shopping"],["alipay-","shopping"],["travel-","travel"],["system-data","system"],["browser-","system"],["vscode","system"],["win-recent","system"],["git-activity","system"],["shell-history","system"],["local-files","system"],["ai-chat-","ai-chat"]]);function $(r){if(typeof r!="string"||r.length===0)return"other";for(const[t,n]of be)if(t.endsWith("-")||t==="system-data"){if(r.startsWith(t))return n}else if(r===t)return n;return"other"}const he={__name:"CategorySidebar",props:{selected:{type:String,default:null},facets:{type:Object,default:()=>({byCategory:{},total:0})}},emits:["select"],setup(r,{expose:t}){t();const n=r,e=w(()=>n.facets.total||0),o={chat:Y,social:W,email:K,shopping:H,travel:G,system:Q,"ai-chat":z,other:q};function l(i){return o[i]||q}function a(i){return i?{backgroundColor:"#fff",color:"#1677ff"}:{backgroundColor:"#f0f0f0",color:"#666"}}const s={props:n,total:e,ICONS:o,iconFor:l,badgeStyle:a,computed:w,get AppstoreOutlined(){return q},get MessageOutlined(){return Y},get PlayCircleOutlined(){return W},get MailOutlined(){return K},get ShoppingOutlined(){return H},get CarOutlined(){return G},get MobileOutlined(){return Q},get RobotOutlined(){return z},get CATEGORIES(){return ye},get categoryLabel(){return N}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}},Se={class:"pdh-sidebar"},Oe=["onClick"],we={class:"label"};function Ce(r,t,n,e,o,l){const a=y("a-badge");return u(),O("div",Se,[t[2]||(t[2]=v("div",{class:"sidebar-title"},"数据类型",-1)),v("div",{class:M(["cat-item",{active:n.selected===null}]),onClick:t[0]||(t[0]=s=>r.$emit("select",null))},[c(e.AppstoreOutlined,{class:"icon"}),t[1]||(t[1]=v("span",{class:"label"},"全部",-1)),e.total>0?(u(),C(a,{key:0,count:e.total,"number-style":e.badgeStyle(n.selected===null),"overflow-count":9999},null,8,["count","number-style"])):E("v-if",!0)],2),(u(!0),O(V,null,se(e.CATEGORIES,s=>(u(),O("div",{key:s,class:M(["cat-item",{active:n.selected===s,dim:!n.facets.byCategory[s]}]),onClick:i=>r.$emit("select",s)},[(u(),C(le(e.iconFor(s)),{class:"icon"})),v("span",we,x(e.categoryLabel(s)),1),n.facets.byCategory[s]?(u(),C(a,{key:0,count:n.facets.byCategory[s],"number-style":e.badgeStyle(n.selected===s),"overflow-count":9999},null,8,["count","number-style"])):E("v-if",!0)],10,Oe))),128))])}const ke=D(he,[["render",Ce],["__scopeId","data-v-6b62a22e"],["__file","/tmp/cc-web-panel-94r5Fm/repo/packages/web-panel/src/components/pdh/CategorySidebar.vue"]]),Ee={__name:"SearchFilterBar",props:{filters:{type:Object,required:!0},facets:{type:Object,default:()=>({byAdapter:{}})},isLoading:{type:Boolean,default:!1},mode:{type:String,default:null},shortQuery:{type:Boolean,default:!1}},emits:["set-filter","reset"],setup(r,{expose:t,emit:n}){t();const e=r,o=n,l=w(()=>e.filters.category?`在「${e.filters.category}」类目内搜索…`:"搜索关键词(如:支付宝、罗技、Kotlin)…"),a=w(()=>Object.entries(e.facets.byAdapter||{}).sort((g,k)=>k[1]-g[1]).map(([g,k])=>({value:g,label:`${g} (${k})`}))),s=w(()=>!e.filters.since&&!e.filters.until?null:[e.filters.since?new Date(e.filters.since):null,e.filters.until?new Date(e.filters.until):null]),i=w(()=>!!(e.filters.q||e.filters.adapter||e.filters.subtype||e.filters.since||e.filters.until));function d(h){o("set-filter","q",h||"")}function _(h){o("set-filter","q",h||"")}function F(h){if(!h||h.length===0){o("set-filter","since",null),o("set-filter","until",null);return}const[g,k]=h;o("set-filter","since",g?+g:null),o("set-filter","until",k?+k:null)}const j={props:e,emit:o,placeholderText:l,adapterOptions:a,dateRangeValue:s,hasActiveFilters:i,onQInput:d,onSearch:_,onDateChange:F,computed:w,get SearchOutlined(){return pe},get CloseCircleOutlined(){return fe},get InfoCircleOutlined(){return de}};return Object.defineProperty(j,"__isScriptSetup",{enumerable:!1,value:!0}),j}},Re={class:"pdh-filter-bar"},xe={key:1,class:"hint"},Fe={key:2,class:"hint"};function je(r,t,n,e,o,l){const a=y("a-input-search"),s=y("a-select"),i=y("a-range-picker"),d=y("a-button");return u(),O("div",Re,[c(a,{value:n.filters.q,placeholder:e.placeholderText,"enter-button":"搜索","allow-clear":"",loading:n.isLoading,style:{flex:"1","max-width":"480px"},"onUpdate:value":e.onQInput,onSearch:e.onSearch},{prefix:m(()=>[c(e.SearchOutlined)]),_:1},8,["value","placeholder","loading"]),c(s,{value:n.filters.adapter,placeholder:"所有 adapter","allow-clear":"",options:e.adapterOptions,style:{width:"200px"},"onUpdate:value":t[0]||(t[0]=_=>r.$emit("set-filter","adapter",_||null))},null,8,["value","options"]),c(i,{value:e.dateRangeValue,placeholder:["开始日期","结束日期"],style:{width:"280px"},"onUpdate:value":e.onDateChange},null,8,["value"]),e.hasActiveFilters?(u(),C(d,{key:0,type:"link",danger:"",onClick:t[1]||(t[1]=_=>r.$emit("reset"))},{icon:m(()=>[c(e.CloseCircleOutlined)]),default:m(()=>[t[2]||(t[2]=b(" 清空筛选 ",-1))]),_:1})):E("v-if",!0),n.shortQuery?(u(),O("span",xe,[c(e.InfoCircleOutlined),t[3]||(t[3]=b(" 关键词需至少 3 字 (FTS5 trigram 限制) ",-1))])):n.mode==="like"?(u(),O("span",Fe,[c(e.InfoCircleOutlined),t[4]||(t[4]=b(" 当前为 LIKE 兜底模式 ",-1))])):E("v-if",!0)])}const Ae=D(Ee,[["render",je],["__scopeId","data-v-d7cce6e9"],["__file","/tmp/cc-web-panel-94r5Fm/repo/packages/web-panel/src/components/pdh/SearchFilterBar.vue"]]),Le={__name:"RendererDispatcher",props:{event:{type:Object,required:!0}},setup(r,{expose:t}){t();const n=A(()=>L(()=>import("./ChatBubbleRenderer-BcnNHS-r.js"),__vite__mapDeps([0,1,2,3,4,5]),import.meta.url)),e=A(()=>L(()=>import("./OrderTableRenderer-e25Q6ALJ.js"),__vite__mapDeps([6,1,2,3,4,7]),import.meta.url)),o=A(()=>L(()=>import("./TimelineRenderer-CYhublOm.js"),__vite__mapDeps([8,1,2,3,4,9]),import.meta.url)),l=A(()=>L(()=>import("./EmailListRenderer-BnA27cjB.js"),__vite__mapDeps([10,1,2,3,4,11]),import.meta.url)),a=A(()=>L(()=>import("./GenericCardRenderer-CkZB9crH.js"),__vite__mapDeps([12,1,2,3,4,13]),import.meta.url));function s(d){const _=d&&d.source&&d.source.adapter;switch($(_)){case"chat":case"ai-chat":return n;case"shopping":return e;case"travel":return o;case"email":return l;default:return a}}const i={ChatBubbleRenderer:n,OrderTableRenderer:e,TimelineRenderer:o,EmailListRenderer:l,GenericCardRenderer:a,rendererFor:s,defineAsyncComponent:A,get getCategory(){return $}};return Object.defineProperty(i,"__isScriptSetup",{enumerable:!1,value:!0}),i}};function De(r,t,n,e,o,l){return u(),C(le(e.rendererFor(n.event)),{event:n.event},null,8,["event"])}const Te=D(Le,[["render",De],["__file","/tmp/cc-web-panel-94r5Fm/repo/packages/web-panel/src/components/pdh/renderers/RendererDispatcher.vue"]]);function ee(r){return JSON.stringify(r,null,2)}function te(r){return r.map(t=>JSON.stringify(t)).join(`
|
|
3
|
-
`)+`
|
|
4
|
-
`}function ne(r){const n=["id","subtype","occurredAt","occurredAtIso","actor","place","adapter","summary","contentJson","extraJson"].join(","),e=r.map(o=>{const l=Number.isFinite(o.occurredAt)?o.occurredAt:null,a=l?new Date(l).toISOString():"",s=o.source&&o.source.adapter||"",i=o.content&&(o.content.text||o.content.title||o.content.subject)||"";return[o.id||"",o.subtype||"",l!=null?String(l):"",a,o.actor||"",o.place||"",s,i,o.content?JSON.stringify(o.content):"",o.extra?JSON.stringify(o.extra):""].map(Ie).join(",")});return[n,...e].join(`
|
|
5
|
-
`)+`
|
|
6
|
-
`}function Ie(r){const t=String(r??"");return t.includes(",")||t.includes('"')||t.includes(`
|
|
7
|
-
`)||t.includes("\r")?'"'+t.replace(/"/g,'""')+'"':t}function re(r,t,n="application/octet-stream"){if(typeof window>"u"||typeof document>"u")return t;const e=new Blob([r],{type:n}),o=URL.createObjectURL(e),l=document.createElement("a");return l.href=o,l.download=t,document.body.appendChild(l),l.click(),document.body.removeChild(l),setTimeout(()=>URL.revokeObjectURL(o),1e3),t}function oe(r,t=null){const n=new Date,e=n.getFullYear(),o=String(n.getMonth()+1).padStart(2,"0"),l=String(n.getDate()).padStart(2,"0"),a=r==="ndjson"?"ndjson":r,s=t?`-${t}`:"";return`pdh-events-${e}-${o}-${l}${s}.${a}`}const Pe={__name:"ExportDropdown",props:{events:{type:Array,required:!0},category:{type:String,default:null}},setup(r,{expose:t}){t();const n=r,e=w(()=>n.events.length>0),o={json:"application/json;charset=utf-8",ndjson:"application/x-ndjson;charset=utf-8",csv:"text/csv;charset=utf-8"};function l(i){switch(i){case"json":return ee(n.events);case"ndjson":return te(n.events);case"csv":return ne(n.events);default:throw new Error(`unknown format: ${i}`)}}function a({key:i}){try{const d=l(i),_=oe(i,n.category);re(d,_,o[i]),P.success(`已导出 ${n.events.length} 条到 ${_}`)}catch(d){P.error(`导出失败: ${d.message||d}`)}}const s={props:n,hasResults:e,MIME:o,serialize:l,onClick:a,computed:w,get DownloadOutlined(){return _e},get DownOutlined(){return me},get message(){return P},get eventsToJson(){return ee},get eventsToNdjson(){return te},get eventsToCsv(){return ne},get downloadAs(){return re},get suggestFilename(){return oe}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}};function qe(r,t,n,e,o,l){const a=y("a-button"),s=y("a-menu-item"),i=y("a-menu"),d=y("a-dropdown");return u(),C(d,{disabled:!e.hasResults},{overlay:m(()=>[c(i,{onClick:e.onClick},{default:m(()=>[c(s,{key:"json"},{default:m(()=>[...t[0]||(t[0]=[b("JSON (.json)",-1)])]),_:1}),c(s,{key:"ndjson"},{default:m(()=>[...t[1]||(t[1]=[b("NDJSON (.ndjson)",-1)])]),_:1}),c(s,{key:"csv"},{default:m(()=>[...t[2]||(t[2]=[b("CSV (.csv)",-1)])]),_:1})]),_:1})]),default:m(()=>[c(a,{disabled:!e.hasResults},{icon:m(()=>[c(e.DownloadOutlined)]),default:m(()=>[b(" 导出 ("+x(n.events.length)+") ",1),c(e.DownOutlined)]),_:1},8,["disabled"])]),_:1},8,["disabled"])}const Be=D(Pe,[["render",qe],["__file","/tmp/cc-web-panel-94r5Fm/repo/packages/web-panel/src/components/pdh/ExportDropdown.vue"]]),Ve={__name:"PdhVaultBrowser",setup(r,{expose:t}){t();const n=X(),e=w(()=>n.filters.q?`没有匹配 "${n.filters.q}" 的事件 — 试试更短的关键词或换个类目`:n.filters.category?`「${N(n.filters.category)}」类目下还没有数据 — 去采集页同步对应 adapter`:"Vault 里还没有数据 — 去「个人数据中台」页面同步任意 adapter");function o(s){n.filters.category=s,n.search()}function l(s,i){n.setFilter(s,i)}J(()=>{!n.hasResults&&!n.isLoading&&n.search()});const a={store:n,emptyHint:e,onCategorySelect:o,onSetFilter:l,onMounted:J,computed:w,get ReloadOutlined(){return ge},get usePdhBrowserStore(){return X},get categoryLabel(){return N},CategorySidebar:ke,SearchFilterBar:Ae,RendererDispatcher:Te,ExportDropdown:Be};return Object.defineProperty(a,"__isScriptSetup",{enumerable:!1,value:!0}),a}},Ne={class:"pdh-browser-page"},Me={class:"page-header"},Je={class:"main-pane"},Ue={class:"results-summary"},ze={key:0},Qe={key:0},Ge={key:1},He={class:"loaded-of"},Ke={class:"results-list"},We={key:2,class:"load-more"};function Ye(r,t,n,e,o,l){const a=y("a-tag"),s=y("a-button"),i=y("a-space"),d=y("a-col"),_=y("a-spin"),F=y("a-alert"),j=y("a-empty"),h=y("a-row");return u(),O("div",Ne,[v("div",Me,[t[6]||(t[6]=v("div",null,[v("h2",{class:"page-title"},"数据浏览器"),v("p",{class:"page-sub"}," Vault 里所有已采集的数据,按类目浏览 / 全文检索 / 时间窗口筛选。 完全离线,不外传。 ")],-1)),c(i,null,{default:m(()=>[e.store.mode==="fts5"?(u(),C(a,{key:0,color:"green"},{default:m(()=>[...t[3]||(t[3]=[b("FTS5 trigram",-1)])]),_:1})):e.store.mode==="like"?(u(),C(a,{key:1,color:"orange"},{default:m(()=>[...t[4]||(t[4]=[b("LIKE 兜底",-1)])]),_:1})):E("v-if",!0),c(e.ExportDropdown,{events:e.store.results,category:e.store.filters.category},null,8,["events","category"]),c(s,{onClick:t[0]||(t[0]=g=>e.store.search()),loading:e.store.isLoading},{icon:m(()=>[c(e.ReloadOutlined)]),default:m(()=>[t[5]||(t[5]=b(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),c(h,{gutter:16,class:"browser-layout"},{default:m(()=>[c(d,{xs:24,sm:24,md:6,lg:5,xl:4},{default:m(()=>[c(e.CategorySidebar,{selected:e.store.filters.category,facets:e.store.facets,onSelect:e.onCategorySelect},null,8,["selected","facets"])]),_:1}),c(d,{xs:24,sm:24,md:18,lg:19,xl:20},{default:m(()=>[v("div",Je,[c(e.SearchFilterBar,{filters:e.store.filters,facets:e.store.facets,"is-loading":e.store.isLoading,mode:e.store.mode,"short-query":e.store.shortQuery,onSetFilter:e.onSetFilter,onReset:t[1]||(t[1]=g=>{e.store.reset(),e.store.search()})},null,8,["filters","facets","is-loading","mode","short-query"]),v("div",Ue,[e.store.isLoading&&e.store.results.length===0?(u(),O("span",ze,[c(_,{size:"small"}),t[7]||(t[7]=b(" 载入中… ",-1))])):(u(),O(V,{key:1},[v("strong",null,x(e.store.facets.total),1),t[11]||(t[11]=b(" 条事件 ",-1)),e.store.filters.category?(u(),O("span",Qe,[t[8]||(t[8]=b(" / 当前类目 ",-1)),v("strong",null,x(e.categoryLabel(e.store.filters.category)),1),v("strong",null,x(e.store.facets.byCategory[e.store.filters.category]||0),1)])):E("v-if",!0),e.store.filters.q?(u(),O("span",Ge,[t[9]||(t[9]=b(' / 关键词 "',-1)),v("em",null,x(e.store.filters.q),1),t[10]||(t[10]=b('"',-1))])):E("v-if",!0),v("span",He," / 已显示 "+x(e.store.results.length),1)],64))]),e.store.error?(u(),C(F,{key:0,type:"error","show-icon":"",message:e.store.error,closable:"",style:{margin:"12px 0"}},null,8,["message"])):E("v-if",!0),!e.store.isLoading&&e.store.results.length===0&&!e.store.error?(u(),C(j,{key:1,description:e.emptyHint,style:{"margin-top":"40px"}},null,8,["description"])):E("v-if",!0),v("div",Ke,[(u(!0),O(V,null,se(e.store.results,(g,k)=>(u(),C(e.RendererDispatcher,{key:`r-${k}-${g.id}`,event:g},null,8,["event"]))),128))]),e.store.canLoadMore?(u(),O("div",We,[c(s,{loading:e.store.isAppending,onClick:t[2]||(t[2]=g=>e.store.loadMore()),block:""},{default:m(()=>[...t[12]||(t[12]=[b(" 加载下一页 (50 条) ",-1)])]),_:1},8,["loading"])])):E("v-if",!0)])]),_:1})]),_:1})])}const tt=D(Ve,[["render",Ye],["__scopeId","data-v-0f7c02cd"],["__file","/tmp/cc-web-panel-94r5Fm/repo/packages/web-panel/src/views/PdhVaultBrowser.vue"]]);export{tt 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 F,P as i,Q as g,R as r,F as h,Z as B}from"./vendor-BvqAck49.js";import{u as R,_ as O}from"./index-DmrPbYXh.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 x=z(()=>k.value.filter(t=>t.status==="running")),b=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:x,pending:b,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 x(o){return o.status==="running"&&o.startedAt?u.formatDuration(Date.now()-o.startedAt):o.completedAt&&o.startedAt?u.formatDuration(o.completedAt-o.startedAt):"-"}function b(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)),F(()=>u.stopPolling());const f={store:u,columns:e,getDuration:x,formatTime:b,truncate:y,onMounted:P,onUnmounted:F,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"},Z=["title"],q={key:0,class:"error-text"},G={key:1,class:"success-text"},H={key:2,class:"muted-text"};function X(k,l,u,e,x,b){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,B(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,Z)):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",q,r(e.truncate(s.error,60)),1)):s.result?(i(),c("span",G,r(e.truncate(String(s.result),60)),1)):(i(),c("span",H,"-"))],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",X],["__scopeId","data-v-da5ff6a2"],["__file","/tmp/cc-web-panel-94r5Fm/repo/packages/web-panel/src/views/Tasks.vue"]]);export{et as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{O as r}from"./index-DmrPbYXh.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-xsUwB5Ay.js";import{U as t}from"./index-DmrPbYXh.js";import"./vendor-BvqAck49.js";import"./responsiveObserve-Em-jKJ7U.js";import"./useFlexGapSupport-DZOaLVto.js";import"./styleChecker-DCoehh1S.js";import"./index-Dj6rUk3f.js";import"./icons-DP3uiYxy.js";const l=t(o);export{l as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{C as o}from"./Col-B-uyUy0z.js";import{U as t}from"./index-DmrPbYXh.js";import"./vendor-BvqAck49.js";import"./index-Dj6rUk3f.js";import"./icons-DP3uiYxy.js";const s=t(o);export{s as default};
|