chainlesschain 0.162.165 → 0.162.167
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 +3 -1
- package/src/assets/web-panel/assets/{AIOps-DgGZr3PR.js → AIOps-BZJrchIA.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-BAOgBIc_.js → ActionButton-Bhlrylt7.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-Ds4GAvNF.js → Analytics-pHtXVQYs.js} +2 -2
- package/src/assets/web-panel/assets/{AppLayout-CoJvCkoF.js → AppLayout-ORpuri4R.js} +4 -4
- package/src/assets/web-panel/assets/{Artifacts-6EgUaE1T.js → Artifacts-eC77yr1_.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-BYie_i74.js → Audit-B2dZIiqz.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-D5gxOhjd.js → BackgroundAgents-COZiTiwP.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CIsVK2pT.js → Backup-vY_Srl5d.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-ClorP55M.js → BaseInput-Dili5BdM.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-CnhTPGGA.js → Chat-EzKBf0XL.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-Bl1VXgwp.js → ChatBubbleRenderer-D1CtRAyy.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-BRavl7TP.js → Checkbox-Beh6BmuW.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-BXg_ErNT.js → Codegen-C3fA6kBU.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CfDPzFPq.js → Col-CefMqONH.js} +1 -1
- package/src/assets/web-panel/assets/{Community-Cgo0httP.js → Community-CBAxFJtB.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DU5JcEQM.js → Compact--flHc-sM.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-DCH_TVBl.js → Compliance-CPeNLvA6.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-IGb5O2IH.js → Cowork-Bv5yv4BU.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-CPp_Xp9F.js → Cron-C22yMEas.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-Cwrqklzw.js → Crosschain-Dsb2bcpu.js} +1 -1
- package/src/assets/web-panel/assets/{DID-D55sBQwM.js → DID-DAxei4w0.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-CedXhGmP.js → Dashboard-DEUwuVZ8.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-Dm6_v3V4.js → Dropdown-BVp4si2j.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CWjnuE3G.js → EmailListRenderer-CyFkybOG.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-DubTh7y-.js → FamilyGuardDashboard-BWmmsbVx.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-DlSM4uJv.js → Federation-Cxw27A5d.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BYhg0vtG.js → FormItemContext-Q9XthzL1.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-Bkh7qjfK.js → GenericCardRenderer-DS5DIdsW.js} +1 -1
- package/src/assets/web-panel/assets/{Git-DSLWPKvn.js → Git-BOliHfxP.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DIj9O8BB.js → Governance-CD4oxa-W.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-Dhep3e5Y.js → Inference-CMlcivo8.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-Cj8vzxB_.js → KnowledgeGraph-BwhERcC4.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-Ba4SsPja.js → Logs-BjVcZR5P.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-BfRhXdyG.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-CGs9IIbf.js → Marketplace-DQLU3E2w.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-BTPAoX4K.js → McpTools-CeK0XkpB.js} +4 -4
- package/src/assets/web-panel/assets/{Memory-BJ6ISf2c.js → Memory-DLFkgwaz.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-Ca6n3Dcn.js → MobileBridge-Bh6ymXyj.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-lvilHuLt.js → MobileProjects-D950tUIe.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-CMo0acBV.js → Mtc-Bx5x9_2m.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-Hz5wBvFX.js → MtcAudit-a1-Fexsq.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-BK2aKWE6.js → Multisig-eaw0X8X1.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-CExpnYMI.js → NLProgramming-BaNsPV4k.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-B7IFbuBo.js → Notes-C7pevN2X.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-VrGchtb0.js → NotificationSettings-HDqeoP0r.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-CyrNTxkU.js → OrderTableRenderer-DvzVl5T3.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-I0C17GBP.js → Organization-D_xHDlGW.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-CXcWvERe.js → Overflow-B5sRnueL.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-FFSCXrZq.js → P2P-C-IRjOPW.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-1PB-p8Zk.js → PdhVaultBrowser-BqgUPlcU.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-C1YHejsb.js → Permissions-Bm_T1uWw.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-CEMPpgf8.js → PersonalDataHub-DujDllye.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-FoIScdLr.js → Pipeline-DyNPOLIG.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-DDfbEzEj.js → Privacy-CYKTW3iK.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-Dso4kB0O.js → ProjectInit-CGf03uZ0.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-WvDoydDc.js → ProjectSettings-DIec4bTI.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-NJp0kzkd.js → Projects-BY43-bmi.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-BuJXnOLI.js → Providers-RrnUmgPk.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-Bb3lMvGG.js → QrScannerModal-BBWfqd4y.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-Ddxra3fK.js → QuickAsk-BsICSrFp.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-BW-dR9qw.js → Recommend-B8y0b4ys.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-Hnm7-Qkm.js → RemoteSession-0QgdB1Oe.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-DKz6meHE.js → Reputation-DBJGM0YO.js} +1 -1
- package/src/assets/web-panel/assets/{Row-BuAsoNTS.js → Row-DtWQ5otv.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-_do9DMIH.js → RssFeed-2zBxHd5H.js} +3 -3
- package/src/assets/web-panel/assets/{Search-CMlcw7ND.js → Search-BofliSkZ.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DhAkfSpM.js → Security-ockRBBEL.js} +3 -3
- package/src/assets/web-panel/assets/{Services-5zKLhy46.js → Services-QyvG7Vd0.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DCMZ3wfv.js → Skeleton-DwbOndX3.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-DxQgYCC_.js → Skills-cHWa63sZ.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-CJmE4cSN.js → Sla-BHnTEydQ.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-BgpRTPQp.js → SpeechSettings-DE2hrrLb.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-DkogtYbB.js → SyncSettings-CZ9vnbJH.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-DWgoAHvM.js +1 -0
- package/src/assets/web-panel/assets/{Templates-DAZIu5nN.js → Templates-DiR3ad4X.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-BRJMI-su.js → Tenant-NqcW3frV.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-iYeqRQZ0.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-D4z9aSGD.js → TimelineRenderer-C5GOoxFz.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-zgYA4UOI.js → Tokens-82dz0XdU.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DMOgHX4m.js → Trigger-B3JCNrOi.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-CEtoNwcT.js → Trust-BehFYsN_.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-DFx2pQfO.js → UkeySign-BfOxJjVf.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-DLssy-7B.js → VideoEditing-DdITCCPz.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-DQHc6gTl.js → Wallet-B0EhkCmD.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DgKcODkn.js → WebAuthn-DJ4i1f3-.js} +2 -2
- package/src/assets/web-panel/assets/{WorkflowEditor-cPEWfMOf.js → WorkflowEditor-Dr9XTqIT.js} +1 -1
- package/src/assets/web-panel/assets/{chat-Coj7rSO1.js → chat-Dc2nFyOj.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DiyGfr-6.js → colors-Drw9djBR.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-DB63aMXh.js → compact-item-BdLXbU52.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-CENpsYHg.js → createContext-BpQMZiWY.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-CnfpDzMr.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-B9NOmk0K.js → hasIn-CbYwawHf.js} +1 -1
- package/src/assets/web-panel/assets/{index-BvQq6gX2.js → index-B1ANzVc6.js} +1 -1
- package/src/assets/web-panel/assets/{index-mTK_ZHhE.js → index-B3uRI8_y.js} +1 -1
- package/src/assets/web-panel/assets/{index-D_rZCxxI.js → index-B5KboakZ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DAMKhjtT.js → index-B9_u4Qhe.js} +1 -1
- package/src/assets/web-panel/assets/{index-7IMjHwGU.js → index-BAq-4KqY.js} +1 -1
- package/src/assets/web-panel/assets/{index-DqLC0iE4.js → index-BBueKSTR.js} +1 -1
- package/src/assets/web-panel/assets/{index-Kp2AETEw.js → index-BIcEW07n.js} +1 -1
- package/src/assets/web-panel/assets/{index-KDCuTzdx.js → index-BWUoc9-s.js} +1 -1
- package/src/assets/web-panel/assets/{index-nio98wGC.js → index-BZxzdAI0.js} +1 -1
- package/src/assets/web-panel/assets/{index-BxvNtndl.js → index-BiGDrEt4.js} +1 -1
- package/src/assets/web-panel/assets/{index-B45osqnZ.js → index-Blv7c80V.js} +1 -1
- package/src/assets/web-panel/assets/{index-BpmTl8QC.js → index-BmQlot_u.js} +1 -1
- package/src/assets/web-panel/assets/{index-DANoIqXP.js → index-Bo_KwJTF.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dg0v-CXZ.js → index-Bu8Vy-mj.js} +1 -1
- package/src/assets/web-panel/assets/{index-U_snupDl.js → index-C1eo1Qkd.js} +1 -1
- package/src/assets/web-panel/assets/{index-ClEy1v1o.js → index-C3Alz2QD.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bvj07Ab1.js → index-CBwQwtsE.js} +1 -1
- package/src/assets/web-panel/assets/{index-CKNt2vfs.js → index-CJQiSQw7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CXRknr9W.js → index-CKmz3Is-.js} +1 -1
- package/src/assets/web-panel/assets/{index-CRhEJ8JO.js → index-COoIIMbO.js} +1 -1
- package/src/assets/web-panel/assets/index-CYTEB0tb.js +1 -0
- package/src/assets/web-panel/assets/index-CgsEp5bm.js +1 -0
- package/src/assets/web-panel/assets/{index-CxVfbuj9.js → index-CpmlTfpv.js} +1 -1
- package/src/assets/web-panel/assets/{index-CmNCDN5t.js → index-D7Ipfs4F.js} +1 -1
- package/src/assets/web-panel/assets/{index-B0C6zl0y.js → index-DHMeEu-P.js} +1 -1
- package/src/assets/web-panel/assets/{index-DsPDEHOg.js → index-DKQlF7Pw.js} +1 -1
- package/src/assets/web-panel/assets/{index-Yb9EfUnY.js → index-DO7LD_1t.js} +1 -1
- package/src/assets/web-panel/assets/{index-CvTJ-x6b.js → index-DSmZjrFy.js} +1 -1
- package/src/assets/web-panel/assets/{index-C9d8hdgY.js → index-DTeqWdAS.js} +1 -1
- package/src/assets/web-panel/assets/{index-Y_UKQpsV.js → index-DWUN8c01.js} +1 -1
- package/src/assets/web-panel/assets/{index-t6hXF2Cw.js → index-D_lkTnZ0.js} +1 -1
- package/src/assets/web-panel/assets/{index-VDFbduzG.js → index-DyU21xVi.js} +1 -1
- package/src/assets/web-panel/assets/{index-76GMjcbq.js → index-GG_MXjSL.js} +3 -3
- package/src/assets/web-panel/assets/{index-BramLq29.js → index-IG3__pGj.js} +1 -1
- package/src/assets/web-panel/assets/{index-BXzMKVLp.js → index-UX_Mfyfv.js} +1 -1
- package/src/assets/web-panel/assets/{index-CwkK9Kl2.js → index-VIyNlXPX.js} +1 -1
- package/src/assets/web-panel/assets/{index-CAXouogg.js → index-XYe6kBmi.js} +1 -1
- package/src/assets/web-panel/assets/{index-CTuX_MU0.js → index-_vVucYqC.js} +1 -1
- package/src/assets/web-panel/assets/{index-BkoqtJzV.js → index-aHrUfrv1.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-GTwJVIOz.js → initDefaultProps-DybC85E4.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BJQLsPx8.js → motion-BNNuyDg7.js} +1 -1
- package/src/assets/web-panel/assets/{move-DVQM0bdG.js → move-Bm8gSjEN.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-CMXI1I2y.js → mtc-parser-CuHQvzzr.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CAc8MDw9.js → omit-lv4NO7Ng.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-BgqzoyP7.js → pickAttrs-BoSMfjHq.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-B9ebCdRy.js → placementArrow-BOMDSvgz.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-Dy8D0D3n.js → responsiveObserve-C064Ubmu.js} +1 -1
- package/src/assets/web-panel/assets/{slide-Bcrc8J39.js → slide-CeqhbKoG.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-CDW6FOlc.js → statusUtils-CunFoYww.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CWhJrDON.js → styleChecker-Cxz3wPL7.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-C82c33XI.js → useFlexGapSupport-DJsIaU2S.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-A6m--mih.js → useFs-DnAygceJ.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-m-1laJY5.js → usePersonalDataHub-CrEUY7ta.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-CL9oKKRa.js → vnode-Cq3rN2eT.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DrOyaof3.js → zoom-TMzcOx__.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agent.js +75 -0
- package/src/commands/session.js +132 -0
- package/src/data/changelog.json +12 -2
- package/src/harness/jsonl-session-store.js +9 -0
- package/src/harness/session-mirror.js +212 -6
- package/src/lib/async-hook-queue.cjs +288 -0
- package/src/lib/async-hook-supervisor.cjs +52 -0
- package/src/lib/background-session-transport.js +24 -2
- package/src/lib/doctor-checkup.js +184 -4
- package/src/lib/governance-coverage.js +179 -0
- package/src/lib/install-command-policy.js +333 -0
- package/src/lib/jsonl-session-store.js +1 -0
- package/src/lib/lsp/__tests__/lsp-server-registry.test.js +27 -0
- package/src/lib/lsp/lsp-server-registry.js +14 -0
- package/src/lib/packer/smoke-runner.js +85 -15
- package/src/lib/protocol-replay.js +153 -0
- package/src/lib/runtime-checkup.js +33 -0
- package/src/lib/settings-hook-events.cjs +157 -0
- package/src/lib/settings-hooks.cjs +4 -0
- package/src/lib/shell-approval.js +47 -1
- package/src/repl/add-dir.js +59 -1
- package/src/repl/agent-repl.js +85 -3
- package/src/runtime/agent-core.js +35 -0
- package/src/runtime/headless-runner.js +69 -1
- package/src/runtime/headless-stream.js +22 -0
- package/src/runtime/system-prompt.js +39 -12
- package/src/assets/web-panel/assets/MarkdownRenderer-DUjyuVB3.js +0 -1
- package/src/assets/web-panel/assets/Tasks-D5OrwAl9.js +0 -1
- package/src/assets/web-panel/assets/Terminal-CMXLqQKF.js +0 -3
- package/src/assets/web-panel/assets/devWarning-XvRaIiyt.js +0 -1
- package/src/assets/web-panel/assets/index-CbO1zSXV.js +0 -1
- package/src/assets/web-panel/assets/index-aCu2gbUb.js +0 -1
|
@@ -184,6 +184,35 @@ export function listBackgroundShellTasks() {
|
|
|
184
184
|
// spawned detached (its own process group), so signal the group via the
|
|
185
185
|
// negative pid. Windows: `taskkill /T` walks and kills the whole tree.
|
|
186
186
|
// Returns true if a running task was signalled.
|
|
187
|
+
// Release the parent-side handles of a background task's child: the stdout/
|
|
188
|
+
// stderr PIPES (ref'd — on their own they keep the event loop alive) and the
|
|
189
|
+
// process handle. Called once a task is terminal or has been signalled to die,
|
|
190
|
+
// so a still-draining or slowly-dying child can never pin the process past a
|
|
191
|
+
// teardown. In production the agent's own REPL/run loop holds the loop open, so
|
|
192
|
+
// this changes nothing there; in the vitest forks pool nothing else does, and a
|
|
193
|
+
// SIGTERM'd-but-not-yet-dead child was tripping the worker-terminate deadline
|
|
194
|
+
// (the POSIX-only "Timeout terminating forks worker / Worker exited
|
|
195
|
+
// unexpectedly" unit-shard flake). Idempotent + best-effort.
|
|
196
|
+
function _releaseBgChildHandles(task) {
|
|
197
|
+
const child = task?.child;
|
|
198
|
+
if (!child) return;
|
|
199
|
+
try {
|
|
200
|
+
child.stdout?.destroy();
|
|
201
|
+
} catch {
|
|
202
|
+
/* noop */
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
child.stderr?.destroy();
|
|
206
|
+
} catch {
|
|
207
|
+
/* noop */
|
|
208
|
+
}
|
|
209
|
+
try {
|
|
210
|
+
child.unref?.();
|
|
211
|
+
} catch {
|
|
212
|
+
/* noop */
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
187
216
|
function _killTask(task) {
|
|
188
217
|
const child = task?.child;
|
|
189
218
|
if (!child || child.killed || task?.status !== "running") return false;
|
|
@@ -217,6 +246,9 @@ function _killTask(task) {
|
|
|
217
246
|
} else {
|
|
218
247
|
child.kill("SIGTERM");
|
|
219
248
|
}
|
|
249
|
+
// Drop the ref'd pipe/process handles now — the group signal is away, so a
|
|
250
|
+
// slowly-dying child must not pin the loop while it finishes exiting.
|
|
251
|
+
_releaseBgChildHandles(task);
|
|
220
252
|
return true;
|
|
221
253
|
} catch (_err) {
|
|
222
254
|
return false;
|
|
@@ -276,6 +308,7 @@ function _killTaskSync(task) {
|
|
|
276
308
|
} else {
|
|
277
309
|
child.kill("SIGKILL");
|
|
278
310
|
}
|
|
311
|
+
_releaseBgChildHandles(task);
|
|
279
312
|
return true;
|
|
280
313
|
} catch (_err) {
|
|
281
314
|
return false;
|
|
@@ -2692,6 +2725,7 @@ async function executeToolInner(
|
|
|
2692
2725
|
task.status = "error";
|
|
2693
2726
|
task.error = String(err?.message || err).substring(0, 2000);
|
|
2694
2727
|
task.endedAt = new Date().toISOString();
|
|
2728
|
+
_releaseBgChildHandles(task);
|
|
2695
2729
|
});
|
|
2696
2730
|
// 'close' (not 'exit') so stdout/stderr are fully drained before the
|
|
2697
2731
|
// status leaves "running" — otherwise a poll can observe completion
|
|
@@ -2704,6 +2738,7 @@ async function executeToolInner(
|
|
|
2704
2738
|
task.exitCode = code;
|
|
2705
2739
|
task.signal = signal;
|
|
2706
2740
|
task.endedAt = new Date().toISOString();
|
|
2741
|
+
_releaseBgChildHandles(task);
|
|
2707
2742
|
});
|
|
2708
2743
|
} catch (err) {
|
|
2709
2744
|
task.status = "error";
|
|
@@ -707,6 +707,7 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
707
707
|
let sideEffectSeq = 0;
|
|
708
708
|
let currentSideEffectOpId = null;
|
|
709
709
|
let resumeSideEffectContext = null;
|
|
710
|
+
let resumeAsyncHookContext = null;
|
|
710
711
|
const persistSideEffectLedger = () => {
|
|
711
712
|
if (!persist) return;
|
|
712
713
|
try {
|
|
@@ -767,6 +768,34 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
767
768
|
} catch {
|
|
768
769
|
resumeSideEffectContext = null;
|
|
769
770
|
}
|
|
771
|
+
// On resume, recover any async-hook REWAKE (a background check that opted
|
|
772
|
+
// in and FAILED) that the previous run parked but died before draining —
|
|
773
|
+
// surface it to the model instead of silently swallowing the failure. The
|
|
774
|
+
// take also clears the bucket so it isn't replayed on a later resume.
|
|
775
|
+
try {
|
|
776
|
+
const { takePending } = await import("../lib/async-hook-queue.cjs");
|
|
777
|
+
const recovered = takePending(
|
|
778
|
+
{ sessionId, now: deps.now ? deps.now() : Date.now() },
|
|
779
|
+
deps.asyncHookQueuePath || undefined,
|
|
780
|
+
deps.asyncHookQueueFs || undefined,
|
|
781
|
+
);
|
|
782
|
+
if (Array.isArray(recovered) && recovered.length > 0) {
|
|
783
|
+
const lines = recovered.map((r) => {
|
|
784
|
+
const detail = r.error || r.additionalContext || "failed";
|
|
785
|
+
return ` • ${r.command} — ${detail}`;
|
|
786
|
+
});
|
|
787
|
+
resumeAsyncHookContext =
|
|
788
|
+
"Recovery notice — the previous run was interrupted after these " +
|
|
789
|
+
"background (async) hook checks FAILED but before you were told. " +
|
|
790
|
+
"Review each failure and decide whether it still needs action:\n" +
|
|
791
|
+
lines.join("\n");
|
|
792
|
+
writeErr(
|
|
793
|
+
`⚠ Recovered ${recovered.length} failed async-hook check(s) from interrupted run (resume ${resumeId}).\n`,
|
|
794
|
+
);
|
|
795
|
+
}
|
|
796
|
+
} catch {
|
|
797
|
+
resumeAsyncHookContext = null;
|
|
798
|
+
}
|
|
770
799
|
}
|
|
771
800
|
}
|
|
772
801
|
|
|
@@ -856,6 +885,7 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
856
885
|
// rules.md (in buildSystemPrompt) + the cc.md/CLAUDE.md block. Absent flag
|
|
857
886
|
// (undefined) leaves both paths byte-identical.
|
|
858
887
|
const _leanNoProjectMemory = options.projectMemory === false;
|
|
888
|
+
let _loadedInstructions = null;
|
|
859
889
|
const systemContent = composeSystemPrompt(
|
|
860
890
|
buildSystemPrompt(cwd, {
|
|
861
891
|
additionalDirectories,
|
|
@@ -867,6 +897,9 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
867
897
|
outputStyle: outputStyleBody,
|
|
868
898
|
instructionExcludes,
|
|
869
899
|
projectMemory: _leanNoProjectMemory ? false : undefined,
|
|
900
|
+
onInstructionsLoaded: (loaded) => {
|
|
901
|
+
_loadedInstructions = loaded;
|
|
902
|
+
},
|
|
870
903
|
},
|
|
871
904
|
);
|
|
872
905
|
|
|
@@ -896,6 +929,26 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
896
929
|
}
|
|
897
930
|
}
|
|
898
931
|
|
|
932
|
+
// settings.json InstructionsLoaded hooks (observe-only): the project-instruction
|
|
933
|
+
// block was just composed — fire with the EXACT loaded file set so a hook can
|
|
934
|
+
// audit which cc.md/CLAUDE.md/AGENTS.md/rules are authoritative this session.
|
|
935
|
+
// Any emitted context is injected like SessionStart's. Best-effort; no-op when
|
|
936
|
+
// project memory is off (no loaded set) or no hook is registered.
|
|
937
|
+
let instructionsLoadedContext = null;
|
|
938
|
+
if (settingsHooks && _loadedInstructions) {
|
|
939
|
+
try {
|
|
940
|
+
const { runInstructionsLoadedHooks } =
|
|
941
|
+
await import("../lib/settings-hook-events.cjs");
|
|
942
|
+
instructionsLoadedContext = runInstructionsLoadedHooks(settingsHooks, {
|
|
943
|
+
files: _loadedInstructions.files,
|
|
944
|
+
cwd,
|
|
945
|
+
sessionId,
|
|
946
|
+
}).additionalContext;
|
|
947
|
+
} catch (_err) {
|
|
948
|
+
instructionsLoadedContext = null;
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
|
|
899
952
|
// settings.json SessionStart hooks → inject session context (observe-only).
|
|
900
953
|
let sessionStartContext = null;
|
|
901
954
|
if (settingsHooks) {
|
|
@@ -950,12 +1003,18 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
950
1003
|
// No-op on a healthy alternating transcript.
|
|
951
1004
|
const messages = mergeConsecutiveMessages([
|
|
952
1005
|
{ role: "system", content: systemContent },
|
|
1006
|
+
...(instructionsLoadedContext
|
|
1007
|
+
? [{ role: "system", content: instructionsLoadedContext }]
|
|
1008
|
+
: []),
|
|
953
1009
|
...(sessionStartContext
|
|
954
1010
|
? [{ role: "system", content: sessionStartContext }]
|
|
955
1011
|
: []),
|
|
956
1012
|
...(resumeSideEffectContext
|
|
957
1013
|
? [{ role: "system", content: resumeSideEffectContext }]
|
|
958
1014
|
: []),
|
|
1015
|
+
...(resumeAsyncHookContext
|
|
1016
|
+
? [{ role: "system", content: resumeAsyncHookContext }]
|
|
1017
|
+
: []),
|
|
959
1018
|
...history,
|
|
960
1019
|
{ role: "user", content: userMessageContent },
|
|
961
1020
|
]);
|
|
@@ -1160,7 +1219,16 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
1160
1219
|
try {
|
|
1161
1220
|
const { AsyncHookSupervisor } =
|
|
1162
1221
|
await import("../lib/async-hook-supervisor.cjs");
|
|
1163
|
-
_hookSupervisor = new AsyncHookSupervisor({
|
|
1222
|
+
_hookSupervisor = new AsyncHookSupervisor({
|
|
1223
|
+
persistStats: true,
|
|
1224
|
+
// Durably park failed-rewake signals keyed by session so a crash before
|
|
1225
|
+
// the turn loop drains them doesn't lose the failure — recovered on the
|
|
1226
|
+
// next `--resume` (see the resume block above). Only a PERSISTABLE
|
|
1227
|
+
// session can be resumed, so the queue follows `persist`; a one-shot /
|
|
1228
|
+
// --ephemeral run stays byte-unchanged (no session id → no writes).
|
|
1229
|
+
persistQueue: persist,
|
|
1230
|
+
sessionId: persist ? sessionId : null,
|
|
1231
|
+
});
|
|
1164
1232
|
} catch {
|
|
1165
1233
|
_hookSupervisor = null; // async hooks are best-effort
|
|
1166
1234
|
}
|
|
@@ -1078,6 +1078,7 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
1078
1078
|
// cc.md/CLAUDE.md instruction block. Only `=== false` changes anything; when
|
|
1079
1079
|
// the flag is absent (undefined) both paths stay byte-identical.
|
|
1080
1080
|
const _leanNoProjectMemory = options.projectMemory === false;
|
|
1081
|
+
let _loadedInstructions = null;
|
|
1081
1082
|
const systemContent = composeSystemPrompt(
|
|
1082
1083
|
buildSystemPrompt(cwd, {
|
|
1083
1084
|
additionalDirectories,
|
|
@@ -1093,10 +1094,31 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
1093
1094
|
outputStyle: outputStyleBody,
|
|
1094
1095
|
instructionExcludes,
|
|
1095
1096
|
projectMemory: _leanNoProjectMemory ? false : undefined,
|
|
1097
|
+
onInstructionsLoaded: (loaded) => {
|
|
1098
|
+
_loadedInstructions = loaded;
|
|
1099
|
+
},
|
|
1096
1100
|
},
|
|
1097
1101
|
);
|
|
1098
1102
|
const messages = [{ role: "system", content: systemContent }];
|
|
1099
1103
|
|
|
1104
|
+
// settings.json InstructionsLoaded hooks (observe-only): fire once with the
|
|
1105
|
+
// exact loaded instruction file set right after the system prompt is built.
|
|
1106
|
+
// Best-effort; no-op when project memory is off or no hook is registered.
|
|
1107
|
+
if (settingsHooks && _loadedInstructions) {
|
|
1108
|
+
try {
|
|
1109
|
+
const { runInstructionsLoadedHooks } =
|
|
1110
|
+
await import("../lib/settings-hook-events.cjs");
|
|
1111
|
+
const ctx = runInstructionsLoadedHooks(settingsHooks, {
|
|
1112
|
+
files: _loadedInstructions.files,
|
|
1113
|
+
cwd,
|
|
1114
|
+
sessionId,
|
|
1115
|
+
}).additionalContext;
|
|
1116
|
+
if (ctx) messages.push({ role: "system", content: ctx });
|
|
1117
|
+
} catch (_err) {
|
|
1118
|
+
// best-effort
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1100
1122
|
// §3.5.13 flywheel consumption (design module 101): in a PDH session, lead
|
|
1101
1123
|
// with the user's standing feedback preferences learned ACROSS sessions
|
|
1102
1124
|
// (corrections + net sentiment) so the agent honours past corrections from
|
|
@@ -15,7 +15,10 @@
|
|
|
15
15
|
|
|
16
16
|
import fsDefault from "fs";
|
|
17
17
|
import pathDefault from "path";
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
loadProjectInstructions,
|
|
20
|
+
renderProjectInstructionsBlock,
|
|
21
|
+
} from "../lib/project-instructions.js";
|
|
19
22
|
|
|
20
23
|
/**
|
|
21
24
|
* Resolve a CLI prompt value. A leading `@` means "read this file"; anything
|
|
@@ -48,7 +51,12 @@ export function resolvePromptText(value, opts = {}) {
|
|
|
48
51
|
* - an append is added after, separated by a blank line.
|
|
49
52
|
*
|
|
50
53
|
* @param {string} base
|
|
51
|
-
* @param {object} [opts] { systemPrompt, appendSystemPrompt
|
|
54
|
+
* @param {object} [opts] { systemPrompt, appendSystemPrompt, outputStyle,
|
|
55
|
+
* projectMemory, cwd, instructionExcludes, onInstructionsLoaded }.
|
|
56
|
+
* `onInstructionsLoaded(loaded)` — optional observe-only callback invoked with
|
|
57
|
+
* the loaded project-instruction object ({files:[{path,scope,truncated,…}]})
|
|
58
|
+
* right after it is rendered, so a caller can fire an InstructionsLoaded
|
|
59
|
+
* lifecycle hook. Never affects the returned prompt.
|
|
52
60
|
* @returns {string}
|
|
53
61
|
*/
|
|
54
62
|
export function composeSystemPrompt(base, opts = {}) {
|
|
@@ -77,16 +85,35 @@ export function composeSystemPrompt(base, opts = {}) {
|
|
|
77
85
|
else pmMode = process.env.VITEST ? "off" : "full";
|
|
78
86
|
}
|
|
79
87
|
if (pmMode !== "off") {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
// Inlined loadProjectInstructionsBlock (load → render, fail-open to "") so
|
|
89
|
+
// the loaded metadata is available for the optional onInstructionsLoaded
|
|
90
|
+
// callback — the InstructionsLoaded lifecycle hook fires with the EXACT set
|
|
91
|
+
// that was injected (path/scope/truncated), never a re-discovery that could
|
|
92
|
+
// drift from what actually loaded. The prompt output is byte-identical.
|
|
93
|
+
let block = "";
|
|
94
|
+
try {
|
|
95
|
+
const loaded = loadProjectInstructions({
|
|
96
|
+
cwd,
|
|
97
|
+
home: opts.projectMemoryHome,
|
|
98
|
+
deps: opts.projectMemoryDeps,
|
|
99
|
+
// Large-monorepo reduction lever: subtrees whose instruction/rule/@import
|
|
100
|
+
// files never load (config `instructionExcludes`, forwarded by the caller).
|
|
101
|
+
instructionExcludes: opts.instructionExcludes,
|
|
102
|
+
// Lean mode → keep only the entry instruction files.
|
|
103
|
+
entryOnly: pmMode === "lean",
|
|
104
|
+
});
|
|
105
|
+
block = renderProjectInstructionsBlock(loaded);
|
|
106
|
+
if (typeof opts.onInstructionsLoaded === "function") {
|
|
107
|
+
// Observe-only: a callback throw must never affect the composed prompt.
|
|
108
|
+
try {
|
|
109
|
+
opts.onInstructionsLoaded(loaded);
|
|
110
|
+
} catch {
|
|
111
|
+
/* callback is best-effort */
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
} catch {
|
|
115
|
+
block = ""; // fail-open, identical to loadProjectInstructionsBlock
|
|
116
|
+
}
|
|
90
117
|
if (block) result = result ? `${result}\n\n${block}` : block;
|
|
91
118
|
}
|
|
92
119
|
if (appendSystemPrompt) {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{P as c,J as p,b as s}from"./vendor-Bn1JzzAn.js";import{r as a}from"./markdown-Yo_c6Krv.js";import{_ as d}from"./index-76GMjcbq.js";const _={__name:"MarkdownRenderer",props:{content:{type:String,default:""}},setup(t,{expose:o}){o();const e=t,r=s(()=>a(e.content||"")),n={props:e,rendered:r,computed:s,get renderMarkdown(){return a}};return Object.defineProperty(n,"__isScriptSetup",{enumerable:!1,value:!0}),n}},i=["innerHTML"];function u(t,o,e,r,n,m){return c(),p("div",{class:"markdown-content",innerHTML:r.rendered},null,8,i)}const b=d(_,[["render",u],["__scopeId","data-v-0b0b9f63"],["__file","/tmp/cc-web-panel-bNHuzk/repo/packages/web-panel/src/components/MarkdownRenderer.vue"]]);export{b as M};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{E as F,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 b,o as I,x as V,P as i,Q as k,R as r,F as x,Z as O}from"./vendor-Bn1JzzAn.js";import{u as P,_ as E}from"./index-76GMjcbq.js";import{R as U}from"./icons-DG5UD-6K.js";const B=F("tasks",()=>{const y=R([]),l=R(!1);let u=null,t=null,d=null;const N=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){T(),s(),u=setInterval(s,e),S()}function T(){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:N,pending:v,completed:w,lastNotification:f,fetchTasks:s,stopTask:m,startPolling:h,stopPolling:T,formatDuration:A,getStatusColor:o}}),L={__name:"Tasks",setup(y,{expose:l}){l();const u=B(),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 N(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)),V(()=>u.stopPolling());const w={store:u,columns:t,getDuration:d,formatTime:N,truncate:v,onMounted:I,onUnmounted:V,get ReloadOutlined(){return U},get useTasksStore(){return B}};return Object.defineProperty(w,"__isScriptSetup",{enumerable:!1,value:!0}),w}},j={class:"page-header"},H={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"},X={key:2,class:"muted-text"};function Y(y,l,u,t,d,N){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"),T=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",H,r(t.store.lastNotification.error),1)):t.store.lastNotification.result?(i(),c("span",J,r(t.truncate(String(t.store.lastNotification.result),120)),1)):b("v-if",!0)]),_:1},8,["type"])):b("v-if",!0),n(T,{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(x,null,O(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})):b("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(x,{key:2},[k(r(t.getDuration(e)),1)],64)):o.key==="createdAt"?(i(),c(x,{key:3},[k(r(t.formatTime(e.createdAt)),1)],64)):o.key==="result"?(i(),c(x,{key:4},[e.error?(i(),c("span",q,r(t.truncate(e.error,60)),1)):e.result?(i(),c("span",G,r(t.truncate(String(e.result),60)),1)):(i(),c("span",X,"-"))],64)):o.key==="action"?(i(),c(x,{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"])):b("v-if",!0)],64)):b("v-if",!0)]),_:1},8,["data-source","loading"])]),_:1})])}const st=E(L,[["render",Y],["__scopeId","data-v-da5ff6a2"],["__file","/tmp/cc-web-panel-bNHuzk/repo/packages/web-panel/src/views/Tasks.vue"]]);export{st as default};
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./xterm-BZcWGsqw.js","./markdown-CsiA8-E5.js","./markdown-Dfs9RUU9.css","./addon-fit-CK6X9sAG.js","./xterm-DFuMZ0ql.css"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{u as fe,_ as me,d as V,e as U}from"./index-76GMjcbq.js";import{I as z,J as x,U as _,Q as D,S as K,K as T,V as R,c as A,F as Q,Z as Y,R as E,o as Z,f as G,w as $,n as q,b as ee,r as S,P as y,_ as ve,a2 as we,a3 as he,a4 as _e}from"./vendor-Bn1JzzAn.js";import{R as ye,b as pe,at as ge}from"./icons-DG5UD-6K.js";const k=new Map,C=new Map,N=new Set,F=new Set;let te=!1;function xe(c){te||(te=!0,c.onMessage(o=>{if(!(!o||typeof o.type!="string")){if(o.type==="terminal.stdout"){const{sessionId:s,data:e,seq:i}=o.payload||{};if(!s)return;let w;try{const d=atob(e||""),f=new Uint8Array(d.length);for(let n=0;n<d.length;n++)f[n]=d.charCodeAt(n);w=new TextDecoder("utf-8").decode(f)}catch{w=""}const u={sessionId:s,data:w,seq:i};k.get(s)?.forEach(d=>d(u)),N.forEach(d=>d(u))}else if(o.type==="terminal.exit"){const{sessionId:s,exitCode:e,signal:i}=o.payload||{};if(!s)return;const w={sessionId:s,exitCode:e,signal:i};C.get(s)?.forEach(u=>u(w)),F.forEach(u=>u(w))}}}))}function ne(c){const o=new TextEncoder().encode(c);let s="";for(let e=0;e<o.length;e++)s+=String.fromCharCode(o[e]);return btoa(s)}function ae(c){const o=atob(c||""),s=new Uint8Array(o.length);for(let e=0;e<o.length;e++)s[e]=o.charCodeAt(e);return new TextDecoder("utf-8").decode(s)}function oe(){const c=fe();xe(c);async function o(n={}){const a=await c.sendRaw({type:"terminal.create",payload:{shell:n.shell,cwd:n.cwd,env:n.env,cols:n.cols,rows:n.rows}});if(a.ok===!1)throw new Error(a.error||"terminal_create_failed");return a.result??a}async function s(){const n=await c.sendRaw({type:"terminal.list",payload:{}});if(n.ok===!1)throw new Error(n.error||"terminal_list_failed");const a=n.result??n;return Array.isArray(a.sessions)?a.sessions:[]}async function e(n,a){const r=await c.sendRaw({type:"terminal.stdin",payload:{sessionId:n,data:ne(String(a))}});if(r.ok===!1)throw new Error(r.error||"terminal_stdin_failed");return r.result??r}async function i(n,a,r){const h=await c.sendRaw({type:"terminal.resize",payload:{sessionId:n,cols:a,rows:r}});if(h.ok===!1)throw new Error(h.error||"terminal_resize_failed");return h.result??h}async function w(n){const a=await c.sendRaw({type:"terminal.close",payload:{sessionId:n}});if(a.ok===!1)throw new Error(a.error||"terminal_close_failed");return a.result??a}async function u(n,a=0){const r=await c.sendRaw({type:"terminal.history",payload:{sessionId:n,fromSeq:a}});if(r.ok===!1)throw new Error(r.error||"terminal_history_failed");const h=r.result??r;return{truncated:!!h.truncated,chunks:(h.chunks||[]).map(L=>({seq:L.seq,data:ae(L.data)}))}}function d(n,a){return n?(k.has(n)||k.set(n,new Set),k.get(n).add(a),()=>{k.get(n)?.delete(a),k.get(n)?.size===0&&k.delete(n)}):(N.add(a),()=>N.delete(a))}function f(n,a){return n?(C.has(n)||C.set(n,new Set),C.get(n).add(a),()=>{C.get(n)?.delete(a),C.get(n)?.size===0&&C.delete(n)}):(F.add(a),()=>F.delete(a))}return{create:o,list:s,stdin:e,resize:i,close:w,history:u,onStdout:d,onExit:f,_internal:{stdoutSubs:k,exitSubs:C,toBase64Utf8:ne,fromBase64Utf8:ae}}}const Se={__name:"Terminal",setup(c,{expose:o}){o();const s=oe(),e=S([]),i=S(null),w=S("pwsh"),u=S(!1),d=S(!1),f=S(""),n=S(""),a=S([]),r=[{value:"pwsh",label:"PowerShell"},{value:"cmd",label:"CMD"},{value:"bash",label:"Bash"},{value:"wsl",label:"WSL"}],h=ee(()=>e.value.find(t=>t.id===i.value));function L(t){return t?t.slice(0,8):""}let O=null,M=null;async function I(){if(O)return{xtermMod:O,fitAddonMod:M};try{O=await U(()=>import("./xterm-BZcWGsqw.js").then(t=>t.x),__vite__mapDeps([0,1,2]),import.meta.url),M=await U(()=>import("./addon-fit-CK6X9sAG.js").then(t=>t.a),__vite__mapDeps([3,1,2]),import.meta.url),await U(()=>Promise.resolve({}),__vite__mapDeps([4]),import.meta.url)}catch(t){throw n.value="xterm 资源加载失败:"+(t?.message||"未知错误"),t}return{xtermMod:O,fitAddonMod:M}}async function B(t){await q();const{xtermMod:l,fitAddonMod:p}=await I(),b=a.value.find(v=>v?.dataset?.sessionId===t.id);if(!b)return;const m=new l.Terminal({cursorBlink:!0,fontFamily:'Consolas, "Courier New", monospace',fontSize:13,theme:{background:"#1e1e1e",foreground:"#d4d4d4"},convertEol:!1}),P=new p.FitAddon;m.loadAddon(P),m.open(b);try{P.fit()}catch{}t.xterm=m,t.fitAddon=P;const ie=m.onData(v=>{s.stdin(t.id,v).catch(g=>{String(g?.message||"").includes("dangerous_keyword_blocked")?V.warning("该命令被桌面端拦截(高危关键字)"):V.error("stdin 失败: "+(g?.message||g))})}),ce=s.onStdout(t.id,({data:v,seq:g})=>{t.lastSeq=g,m.write(v)}),de=s.onExit(t.id,({exitCode:v,signal:g})=>{t.alive=!1,t.exitCode=v,t.signal=g,m.writeln(`\r
|
|
3
|
-
\x1B[33m[session exited, code=${v}, signal=${g??"-"}]\x1B[0m`)});t.offs=()=>{try{ie.dispose?.()}catch{}ce(),de()};try{const{chunks:v,truncated:g}=await s.history(t.id,0);g&&m.writeln("\x1B[2m[history truncated — earlier output was evicted]\x1B[0m");for(const J of v)m.write(J.data),t.lastSeq=J.seq}catch(v){m.writeln(`\x1B[31m[history fetch failed: ${v?.message||v}]\x1B[0m`)}const H=new ResizeObserver(()=>{try{P.fit(),s.resize(t.id,m.cols,m.rows).catch(()=>{})}catch{}});H.observe(b);const ue=t.offs;t.offs=()=>{try{H.disconnect()}catch{}ue()}}async function re(){u.value=!0,f.value="";try{const t=await s.create({shell:w.value,cols:80,rows:24}),l={id:t.sessionId,shell:t.shell,cwd:"",alive:!0,lastSeq:0,exitCode:null,xterm:null,fitAddon:null,offs:()=>{}};e.value.push(l),i.value=l.id,await B(l)}catch(t){f.value=t?.message||String(t)}finally{u.value=!1}}async function se(t){try{await s.close(t)}catch(l){f.value=l?.message||String(l)}setTimeout(()=>W(t),500)}function W(t){const l=e.value.findIndex(b=>b.id===t);if(l===-1)return;const p=e.value[l];try{p.offs?.()}catch{}try{p.xterm?.dispose?.()}catch{}e.value.splice(l,1),i.value===t&&(i.value=e.value[0]?.id||null)}function le(t){i.value=t,q(()=>{const l=e.value.find(p=>p.id===t);try{l?.fitAddon?.fit()}catch{}})}async function X(){d.value=!0,f.value="";try{const t=await s.list();for(const l of t){const p=e.value.find(m=>m.id===l.id);if(p){p.alive=l.alive,p.lastSeq=l.lastSeq;continue}const b={id:l.id,shell:l.shell,cwd:l.cwd,alive:l.alive,lastSeq:l.lastSeq,exitCode:null,xterm:null,fitAddon:null,offs:()=>{}};e.value.push(b),await B(b)}!i.value&&e.value.length>0&&(i.value=e.value[0].id)}catch(t){f.value=t?.message||String(t)}finally{d.value=!1}}Z(async()=>{await X()}),G(()=>{for(const t of e.value){try{t.offs?.()}catch{}try{t.xterm?.dispose?.()}catch{}}}),$(i,()=>{q(()=>{const t=h.value;try{t?.fitAddon?.fit()}catch{}})});const j={term:s,sessions:e,activeId:i,newShell:w,creating:u,loadingList:d,error:f,warning:n,xtermContainers:a,shellOptions:r,active:h,shortId:L,get xtermMod(){return O},set xtermMod(t){O=t},get fitAddonMod(){return M},set fitAddonMod(t){M=t},loadXterm:I,mountXterm:B,onCreate:re,onClose:se,removeSession:W,activate:le,refreshList:X,ref:S,computed:ee,onMounted:Z,onBeforeUnmount:G,nextTick:q,watch:$,get message(){return V},get PlusOutlined(){return ge},get CloseOutlined(){return pe},get ReloadOutlined(){return ye},get useTerminal(){return oe}};return Object.defineProperty(j,"__isScriptSetup",{enumerable:!1,value:!0}),j}},be={class:"terminal-page"},ke={class:"terminal-header"},Ce={class:"page-sub"},Ae={class:"terminal-body"},Ee={class:"session-tabs"},Oe=["onClick"],Te={class:"session-shell"},Re={class:"session-id"},Me={key:0,class:"session-empty"},ze={class:"xterm-host"},Le=["data-session-id"],Pe={key:0,class:"xterm-placeholder"},De={key:1,class:"terminal-footer"},qe={key:0,class:"footer-exit"};function Be(c,o,s,e,i,w){const u=z("a-tag"),d=z("a-select"),f=z("a-button"),n=z("a-space"),a=z("a-alert");return y(),x("div",be,[_("div",ke,[_("div",null,[o[3]||(o[3]=_("h2",{class:"page-title"},"远程终端",-1)),_("p",Ce,[o[2]||(o[2]=D(" 桌面端托管的 PTY 会话;Android 端可远程操控同一通道 ",-1)),e.warning?(y(),K(u,{key:0,color:"orange",style:{"margin-left":"8px"}},{default:T(()=>[D(E(e.warning),1)]),_:1})):R("v-if",!0)])]),A(n,null,{default:T(()=>[A(d,{value:e.newShell,"onUpdate:value":o[0]||(o[0]=r=>e.newShell=r),style:{width:"130px"},size:"small",options:e.shellOptions},null,8,["value"]),A(f,{type:"primary",size:"small",loading:e.creating,onClick:e.onCreate},{icon:T(()=>[A(e.PlusOutlined)]),default:T(()=>[o[4]||(o[4]=D(" 新会话 ",-1))]),_:1},8,["loading"]),A(f,{size:"small",loading:e.loadingList,onClick:e.refreshList},{icon:T(()=>[A(e.ReloadOutlined)]),default:T(()=>[o[5]||(o[5]=D(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),e.error?(y(),K(a,{key:0,message:e.error,type:"error","show-icon":"",closable:"",style:{"margin-bottom":"12px"},onClose:o[1]||(o[1]=r=>e.error="")},null,8,["message"])):R("v-if",!0),_("div",Ae,[_("div",Ee,[(y(!0),x(Q,null,Y(e.sessions,r=>(y(),x("div",{key:r.id,class:ve(["session-tab",{active:r.id===e.activeId,dead:!r.alive}]),onClick:h=>e.activate(r.id)},[_("span",Te,E(r.shell),1),_("span",Re,E(e.shortId(r.id)),1),A(e.CloseOutlined,{class:"session-close",onClick:we(h=>e.onClose(r.id),["stop"])},null,8,["onClick"])],10,Oe))),128)),e.sessions.length===0?(y(),x("div",Me,' 点击 "新会话" 创建第一个终端 ')):R("v-if",!0)]),_("div",ze,[(y(!0),x(Q,null,Y(e.sessions,r=>he((y(),x("div",{key:r.id,ref_for:!0,ref:"xtermContainers","data-session-id":r.id,class:"xterm-container"},null,8,Le)),[[_e,r.id===e.activeId]])),128)),e.sessions.length===0?(y(),x("div",Pe,[...o[6]||(o[6]=[_("span",null,"无活跃会话",-1)])])):R("v-if",!0)])]),e.active?(y(),x("div",De,[_("span",null,E(e.active.shell)+" · "+E(e.active.cwd||"(默认 cwd)")+" · seq "+E(e.active.lastSeq),1),e.active.alive?R("v-if",!0):(y(),x("span",qe,"已退出 (code="+E(e.active.exitCode??"-")+")",1))])):R("v-if",!0)])}const Fe=me(Se,[["render",Be],["__scopeId","data-v-65366a29"],["__file","/tmp/cc-web-panel-bNHuzk/repo/packages/web-panel/src/views/Terminal.vue"]]);export{Fe as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Q as r}from"./index-76GMjcbq.js";const o=((n,a,e)=>{r(n,`[ant-design-vue: ${a}] ${e}`)});export{o as d};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{C as o}from"./Col-CfDPzFPq.js";import{a0 as t}from"./index-76GMjcbq.js";import"./vendor-Bn1JzzAn.js";import"./index-Bvj07Ab1.js";import"./icons-DG5UD-6K.js";const s=t(o);export{s as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{A as o}from"./Row-BuAsoNTS.js";import{a0 as t}from"./index-76GMjcbq.js";import"./vendor-Bn1JzzAn.js";import"./responsiveObserve-Dy8D0D3n.js";import"./useFlexGapSupport-C82c33XI.js";import"./styleChecker-CWhJrDON.js";import"./index-Bvj07Ab1.js";import"./icons-DG5UD-6K.js";const l=t(o);export{l as default};
|