chainlesschain 0.162.166 → 0.162.168
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/assets/{AIOps-LbDx7jL6.js → AIOps-CDzzuWZV.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DnurtK34.js → ActionButton-Dy-8MmQi.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DXSsV1am.js → Analytics-BtJ_VWkx.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-dqRpzNuD.js → AppLayout-DkjiI4VS.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-BwdmYepK.js → Artifacts-h8PyDO86.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-oSX0kOUG.js → Audit-DiDV0C6l.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-C2KxJahT.js → BackgroundAgents-DTw_aOaf.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-B4TkxWkC.js → Backup-CihFuUO9.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CX5-KxeU.js → BaseInput-CqP2QNoR.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-O_HzD-PL.js → Chat-tm-ygX-p.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-Br8saHQA.js → ChatBubbleRenderer-BVKEhj_y.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-ChepDpC1.js → Checkbox-BFMyRN3Q.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-D9z8kc7q.js → Codegen-B1gTeoAS.js} +1 -1
- package/src/assets/web-panel/assets/{Col-B-H5eoNw.js → Col-1GP8MvKL.js} +1 -1
- package/src/assets/web-panel/assets/{Community-Ccyp_Kk5.js → Community-BLY938F6.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BNvBznp_.js → Compact-DVt_p36I.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-D1FjRd8n.js → Compliance-DxqEBXVG.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CV9B9u-8.js → Cowork-CyWrM-T8.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-BowJ4VIx.js → Cron-Domu6aI9.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BJc6jzRF.js → Crosschain-C8LKpjHJ.js} +1 -1
- package/src/assets/web-panel/assets/{DID-BEp8NV6D.js → DID-XBy15RZ5.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-Dls0B3YB.js → Dashboard-DDAyPD-V.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DQ7zXVtD.js → Dropdown-BHV0MZ13.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-B9q79tOl.js → EmailListRenderer-DmFGW4PX.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-CD8Ie-88.js → FamilyGuardDashboard-CqYdbKvd.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-5o7XU5Vf.js → Federation-YP5-Puv5.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DeKbMvOs.js → FormItemContext-BOmcIcTe.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-CZiQvz_z.js → GenericCardRenderer-CvTZdoc4.js} +1 -1
- package/src/assets/web-panel/assets/{Git-CTvFxVV8.js → Git-Q2oxua0L.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DwzFIjHt.js → Governance-D-WpyWEU.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-CJBk59c-.js → Inference-NUtsYHQo.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-DfsaXN2z.js → KnowledgeGraph-BHQLa8fr.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-DVRYf18S.js → Logs-6WsR5Q1G.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-DuWoDwMx.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-BuIwyE4t.js → Marketplace-CigohRRW.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-D3U0o78E.js → McpTools-jcp6jVLf.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-QYVmyb3b.js → Memory-B00NU1ph.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-BFgrj6eZ.js → MobileBridge-Cs_p3PzU.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-BFs2WljZ.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-BZQu8TcH.js → Mtc-CSEflwzw.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-BnFfEkLo.js → MtcAudit-dxSiEZ96.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-iUnNS9Cm.js → Multisig-CDAFEAyq.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-DNNz1y9Y.js → NLProgramming-HoFpZNiB.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-CZezNYRU.js → Notes-tAoQvVcE.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-DBvrplIR.js → NotificationSettings-Czo2M9F4.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-CTDtee49.js → OrderTableRenderer-CM1kNTp6.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-CCOUJX1R.js → Organization-Cudr0VOC.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-DcZghdk0.js → Overflow-BSXeDKiN.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-jmddWX9q.js → P2P-Cqv_g-F9.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-wfjMcczl.js → PdhVaultBrowser-7rjprPh8.js} +4 -4
- package/src/assets/web-panel/assets/{Permissions-DU1GJjca.js → Permissions-97pIDQKE.js} +3 -3
- package/src/assets/web-panel/assets/{PersonalDataHub-BzTMzDF9.js → PersonalDataHub-bparK9eQ.js} +3 -3
- package/src/assets/web-panel/assets/{Pipeline-DPmjlpVc.js → Pipeline-CJgerM09.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-B6HRLpfK.js → Privacy-JqFS3PN7.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-Cyy86AsN.js → ProjectInit-DMITd-2c.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-Bl_WQxJ5.js → ProjectSettings-1UkdJ8Ii.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-Co9yKThA.js → Projects-CYZqegqw.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-DLa4NlIs.js → Providers-ChfXz3U0.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-BvzM7q5f.js → QrScannerModal-Rzkka-mf.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-BN8yyyUj.js → QuickAsk-DEz9HaON.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-QsVN4w0i.js → Recommend-EFGP8AVu.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-tkDXw-TY.js → RemoteSession-6um0lGGy.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-DAifkGsy.js → Reputation-CA1BXTup.js} +1 -1
- package/src/assets/web-panel/assets/{Row-D7dZEyak.js → Row-stTnDJ9y.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-DB5sImTA.js → RssFeed-B10qCCoG.js} +2 -2
- package/src/assets/web-panel/assets/{Search-3py3TO9V.js → Search-DSJroZ6p.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DhNUfT_k.js → Security-BpXkwiMW.js} +4 -4
- package/src/assets/web-panel/assets/{Services-DjJAA_5D.js → Services-BPQxjwK6.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-u95JjK3n.js → Skeleton-CfbKAMul.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-DPo3L0Tz.js → Skills-CttYTfX0.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DWhkAZV1.js → Sla-ByluHich.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-PUegMtqV.js → SpeechSettings-BdZXKsfV.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-BMNYrnrU.js → SyncSettings-xCR7iDzy.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-CYm_oTJC.js → Tasks-qTko_INn.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-Dw9Er5DN.js → Templates-CkIzhgDJ.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-7P3QIBSo.js → Tenant-BIaCaaK8.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-B2Qq38XP.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-DbCd1bDH.js → TimelineRenderer-D5eQDnEF.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-EQofpA0t.js → Tokens-DmeJ8NMQ.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-ChNLLypd.js → Trigger-C5sgb3C7.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-dlVGUKs5.js → Trust-H2vOb3Rb.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-BXyBUhNF.js → UkeySign-NmPtHK2u.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BE8-68ge.js → VideoEditing-DHv-Ti7K.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-7ZIJOwNg.js → Wallet-BYZ3-PRP.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DgNd2Amr.js → WebAuthn-BaSlP7om.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-Z-Un-9l5.js → WorkflowEditor-CZ7IHuIi.js} +1 -1
- package/src/assets/web-panel/assets/{chat-CtVDEkUc.js → chat-Dd9kY8gn.js} +1 -1
- package/src/assets/web-panel/assets/{colors-PXtJ2f1B.js → colors-yhzo6QSV.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-oN96nuBi.js → compact-item-C1JneVdM.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-okCJXQXa.js → createContext-C_waVCg2.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DaDlyVDY.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-pcHm--4o.js → hasIn-CkVg0Xnh.js} +1 -1
- package/src/assets/web-panel/assets/{index-BeAWCGEK.js → index-1VYhIr6D.js} +1 -1
- package/src/assets/web-panel/assets/{index-DC0bqrqV.js → index-BTMiVIBI.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQYes2mk.js → index-BYOyb5X2.js} +1 -1
- package/src/assets/web-panel/assets/{index-vW0lwj0Y.js → index-BjDnI7oM.js} +1 -1
- package/src/assets/web-panel/assets/{index-BUUJ2WfG.js → index-BlJNvg-2.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0rfJBU3.js → index-BlzbSUK9.js} +1 -1
- package/src/assets/web-panel/assets/{index-Rk0X8lVz.js → index-BrN2hAeE.js} +1 -1
- package/src/assets/web-panel/assets/{index-BDR2mi1p.js → index-BsSsurcn.js} +1 -1
- package/src/assets/web-panel/assets/index-BtsLExcc.js +1 -0
- package/src/assets/web-panel/assets/{index-jAY55MSx.js → index-Bwuu3Bf3.js} +1 -1
- package/src/assets/web-panel/assets/{index-_SaFHNsG.js → index-Bx3A6X4J.js} +1 -1
- package/src/assets/web-panel/assets/{index-T3QE8LuV.js → index-C-Sscgnv.js} +1 -1
- package/src/assets/web-panel/assets/index-C3qDvvIb.js +1 -0
- package/src/assets/web-panel/assets/{index-BUTyx-Lk.js → index-C4HNdMCt.js} +1 -1
- package/src/assets/web-panel/assets/{index-nMqLdwao.js → index-CBwmwTNa.js} +1 -1
- package/src/assets/web-panel/assets/{index-BuME9k4Y.js → index-CErewFeT.js} +1 -1
- package/src/assets/web-panel/assets/{index-BHJIfdCV.js → index-CGtoL5mR.js} +1 -1
- package/src/assets/web-panel/assets/{index-D0bfypsF.js → index-CUDjGt_V.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bl6N7ZyX.js → index-C_qqYZT7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CXhezK4d.js → index-C_riAa6d.js} +1 -1
- package/src/assets/web-panel/assets/{index-BnhHxZul.js → index-CfEMjbhu.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cs1fGk1Z.js → index-ClQhh6v3.js} +1 -1
- package/src/assets/web-panel/assets/{index-BjVIZfdA.js → index-CmiLmG0i.js} +1 -1
- package/src/assets/web-panel/assets/{index-CWUJlCvK.js → index-D1xIbAxQ.js} +3 -3
- package/src/assets/web-panel/assets/{index-DfL10EcN.js → index-D6UXDH2D.js} +1 -1
- package/src/assets/web-panel/assets/{index-C4ravjdv.js → index-D7kQ_4uL.js} +1 -1
- package/src/assets/web-panel/assets/{index-DtsyPnF5.js → index-DPkqQ2Pr.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQ1ZzJjN.js → index-DUA96wEj.js} +1 -1
- package/src/assets/web-panel/assets/{index-5aO2V0V4.js → index-DXHk9Vof.js} +1 -1
- package/src/assets/web-panel/assets/{index-CopGaCI_.js → index-DapftLUr.js} +1 -1
- package/src/assets/web-panel/assets/{index-D1efSh1X.js → index-Dez7TUgG.js} +1 -1
- package/src/assets/web-panel/assets/{index-DBcKBb1E.js → index-DhZgULsY.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bht9n8Sm.js → index-Diquc7-l.js} +1 -1
- package/src/assets/web-panel/assets/{index-CAQktO-6.js → index-DuGtLiTW.js} +1 -1
- package/src/assets/web-panel/assets/{index-CK0H3pQW.js → index-U_nLXGIx.js} +1 -1
- package/src/assets/web-panel/assets/{index-BZKk4Lnm.js → index-_M8El5iz.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cc_MkksW.js → index-_VmzCYFn.js} +1 -1
- package/src/assets/web-panel/assets/{index-mB1UV7wA.js → index-_rZxgFtc.js} +1 -1
- package/src/assets/web-panel/assets/{index-BEtzqJw3.js → index-ewb0-LoH.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CG1jyiI7.js → initDefaultProps-DNN6qtGa.js} +1 -1
- package/src/assets/web-panel/assets/{motion-C8BYa98D.js → motion-BcM9exeo.js} +1 -1
- package/src/assets/web-panel/assets/{move-D1hqwitW.js → move-DsKJ-YvA.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-C2lol8rp.js → mtc-parser-glgGkxaK.js} +1 -1
- package/src/assets/web-panel/assets/{omit-Ct6Zghfi.js → omit-BwHCU50S.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CSYbYfdc.js → pickAttrs-BVp-bLt7.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-WCk8di0z.js → placementArrow-CZNe0r-w.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CEC8CZ-3.js → responsiveObserve-DUafj9pU.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BsXyd7Lq.js → slide-H4NqXQxu.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-tDKldiUT.js → statusUtils-UjMzzGZ5.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-BIS2unhx.js → styleChecker-qO5aCjyk.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-yFTVMDUv.js → useFlexGapSupport-ChecYwC8.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-CZYbJwkO.js → useFs-BR0QvwO3.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-sbEHRLAM.js → usePersonalDataHub-DitK2Qgz.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-BVjeSEQK.js → vnode-dxSb40dY.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-BZKVvEZ6.js → zoom-ekJk8YB2.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 +8 -2
- package/src/harness/jsonl-session-store.js +9 -0
- package/src/harness/session-mirror.js +212 -6
- package/src/harness/worktree-isolator.js +10 -2
- package/src/lib/agent-core.js +1 -0
- package/src/lib/async-hook-queue.cjs +288 -0
- package/src/lib/async-hook-supervisor.cjs +52 -0
- package/src/lib/background-phase-reporter.js +116 -0
- package/src/lib/doctor-checkup.js +184 -4
- package/src/lib/hook-runner.cjs +248 -36
- package/src/lib/install-command-policy.js +343 -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/code-intelligence.js +5 -1
- package/src/lib/lsp/lsp-server-registry.js +14 -0
- package/src/lib/lsp/workspace-roots.js +115 -0
- package/src/lib/runtime-checkup.js +33 -0
- package/src/lib/settings-hook-events.cjs +173 -3
- package/src/lib/settings-hooks.cjs +4 -0
- package/src/lib/shell-approval.js +47 -1
- package/src/lib/sub-agent-context.js +13 -0
- package/src/repl/add-dir.js +59 -1
- package/src/repl/agent-repl.js +85 -3
- package/src/runtime/agent-core.js +411 -82
- package/src/runtime/headless-runner.js +111 -9
- package/src/runtime/headless-stream.js +39 -0
- package/src/runtime/system-prompt.js +39 -12
- package/src/workers/background-agent-worker.js +8 -0
- package/src/assets/web-panel/assets/MarkdownRenderer-BL_WsWZM.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-Bp5QB-46.js +0 -1
- package/src/assets/web-panel/assets/Terminal-ClPrfWW7.js +0 -3
- package/src/assets/web-panel/assets/devWarning-BzV6dk1B.js +0 -1
- package/src/assets/web-panel/assets/index-BFrAwXHp.js +0 -1
- package/src/assets/web-panel/assets/index-DJQFP47u.js +0 -1
|
@@ -75,6 +75,7 @@ import {
|
|
|
75
75
|
exitCodeForEndReason,
|
|
76
76
|
} from "../lib/exit-codes.cjs";
|
|
77
77
|
import { isolationLevel } from "../lib/agent-sandbox.js";
|
|
78
|
+
import { createBackgroundPhaseReporter } from "../lib/background-phase-reporter.js";
|
|
78
79
|
import { withQuietStdout } from "./quiet-stdout.js";
|
|
79
80
|
import { CostBudget } from "../lib/cost-budget.js";
|
|
80
81
|
import {
|
|
@@ -707,6 +708,7 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
707
708
|
let sideEffectSeq = 0;
|
|
708
709
|
let currentSideEffectOpId = null;
|
|
709
710
|
let resumeSideEffectContext = null;
|
|
711
|
+
let resumeAsyncHookContext = null;
|
|
710
712
|
const persistSideEffectLedger = () => {
|
|
711
713
|
if (!persist) return;
|
|
712
714
|
try {
|
|
@@ -767,6 +769,34 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
767
769
|
} catch {
|
|
768
770
|
resumeSideEffectContext = null;
|
|
769
771
|
}
|
|
772
|
+
// On resume, recover any async-hook REWAKE (a background check that opted
|
|
773
|
+
// in and FAILED) that the previous run parked but died before draining —
|
|
774
|
+
// surface it to the model instead of silently swallowing the failure. The
|
|
775
|
+
// take also clears the bucket so it isn't replayed on a later resume.
|
|
776
|
+
try {
|
|
777
|
+
const { takePending } = await import("../lib/async-hook-queue.cjs");
|
|
778
|
+
const recovered = takePending(
|
|
779
|
+
{ sessionId, now: deps.now ? deps.now() : Date.now() },
|
|
780
|
+
deps.asyncHookQueuePath || undefined,
|
|
781
|
+
deps.asyncHookQueueFs || undefined,
|
|
782
|
+
);
|
|
783
|
+
if (Array.isArray(recovered) && recovered.length > 0) {
|
|
784
|
+
const lines = recovered.map((r) => {
|
|
785
|
+
const detail = r.error || r.additionalContext || "failed";
|
|
786
|
+
return ` • ${r.command} — ${detail}`;
|
|
787
|
+
});
|
|
788
|
+
resumeAsyncHookContext =
|
|
789
|
+
"Recovery notice — the previous run was interrupted after these " +
|
|
790
|
+
"background (async) hook checks FAILED but before you were told. " +
|
|
791
|
+
"Review each failure and decide whether it still needs action:\n" +
|
|
792
|
+
lines.join("\n");
|
|
793
|
+
writeErr(
|
|
794
|
+
`⚠ Recovered ${recovered.length} failed async-hook check(s) from interrupted run (resume ${resumeId}).\n`,
|
|
795
|
+
);
|
|
796
|
+
}
|
|
797
|
+
} catch {
|
|
798
|
+
resumeAsyncHookContext = null;
|
|
799
|
+
}
|
|
770
800
|
}
|
|
771
801
|
}
|
|
772
802
|
|
|
@@ -856,6 +886,7 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
856
886
|
// rules.md (in buildSystemPrompt) + the cc.md/CLAUDE.md block. Absent flag
|
|
857
887
|
// (undefined) leaves both paths byte-identical.
|
|
858
888
|
const _leanNoProjectMemory = options.projectMemory === false;
|
|
889
|
+
let _loadedInstructions = null;
|
|
859
890
|
const systemContent = composeSystemPrompt(
|
|
860
891
|
buildSystemPrompt(cwd, {
|
|
861
892
|
additionalDirectories,
|
|
@@ -867,6 +898,9 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
867
898
|
outputStyle: outputStyleBody,
|
|
868
899
|
instructionExcludes,
|
|
869
900
|
projectMemory: _leanNoProjectMemory ? false : undefined,
|
|
901
|
+
onInstructionsLoaded: (loaded) => {
|
|
902
|
+
_loadedInstructions = loaded;
|
|
903
|
+
},
|
|
870
904
|
},
|
|
871
905
|
);
|
|
872
906
|
|
|
@@ -896,6 +930,26 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
896
930
|
}
|
|
897
931
|
}
|
|
898
932
|
|
|
933
|
+
// settings.json InstructionsLoaded hooks (observe-only): the project-instruction
|
|
934
|
+
// block was just composed — fire with the EXACT loaded file set so a hook can
|
|
935
|
+
// audit which cc.md/CLAUDE.md/AGENTS.md/rules are authoritative this session.
|
|
936
|
+
// Any emitted context is injected like SessionStart's. Best-effort; no-op when
|
|
937
|
+
// project memory is off (no loaded set) or no hook is registered.
|
|
938
|
+
let instructionsLoadedContext = null;
|
|
939
|
+
if (settingsHooks && _loadedInstructions) {
|
|
940
|
+
try {
|
|
941
|
+
const { runInstructionsLoadedHooks } =
|
|
942
|
+
await import("../lib/settings-hook-events.cjs");
|
|
943
|
+
instructionsLoadedContext = runInstructionsLoadedHooks(settingsHooks, {
|
|
944
|
+
files: _loadedInstructions.files,
|
|
945
|
+
cwd,
|
|
946
|
+
sessionId,
|
|
947
|
+
}).additionalContext;
|
|
948
|
+
} catch (_err) {
|
|
949
|
+
instructionsLoadedContext = null;
|
|
950
|
+
}
|
|
951
|
+
}
|
|
952
|
+
|
|
899
953
|
// settings.json SessionStart hooks → inject session context (observe-only).
|
|
900
954
|
let sessionStartContext = null;
|
|
901
955
|
if (settingsHooks) {
|
|
@@ -950,12 +1004,18 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
950
1004
|
// No-op on a healthy alternating transcript.
|
|
951
1005
|
const messages = mergeConsecutiveMessages([
|
|
952
1006
|
{ role: "system", content: systemContent },
|
|
1007
|
+
...(instructionsLoadedContext
|
|
1008
|
+
? [{ role: "system", content: instructionsLoadedContext }]
|
|
1009
|
+
: []),
|
|
953
1010
|
...(sessionStartContext
|
|
954
1011
|
? [{ role: "system", content: sessionStartContext }]
|
|
955
1012
|
: []),
|
|
956
1013
|
...(resumeSideEffectContext
|
|
957
1014
|
? [{ role: "system", content: resumeSideEffectContext }]
|
|
958
1015
|
: []),
|
|
1016
|
+
...(resumeAsyncHookContext
|
|
1017
|
+
? [{ role: "system", content: resumeAsyncHookContext }]
|
|
1018
|
+
: []),
|
|
959
1019
|
...history,
|
|
960
1020
|
{ role: "user", content: userMessageContent },
|
|
961
1021
|
]);
|
|
@@ -1049,6 +1109,25 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
1049
1109
|
}
|
|
1050
1110
|
}
|
|
1051
1111
|
|
|
1112
|
+
// Seed MCP roots for --add-dir (Claude-Code roots/list_changed parity): a
|
|
1113
|
+
// headless session started with extra workspace roots must advertise the FULL
|
|
1114
|
+
// root list to connected MCP servers, exactly like the REPL /add-dir path —
|
|
1115
|
+
// otherwise a server's roots/list only ever sees the cwd. Only meaningful when
|
|
1116
|
+
// extra roots exist (setRoots fires only when the list actually changes); no
|
|
1117
|
+
// --add-dir → workspaceRootDirs = [cwd] and this is a no-op. Best-effort.
|
|
1118
|
+
if (mcp?.mcpClient && additionalDirectories.length > 0) {
|
|
1119
|
+
try {
|
|
1120
|
+
const { notifyMcpRootsChanged, workspaceRootDirs } =
|
|
1121
|
+
await import("../repl/add-dir.js");
|
|
1122
|
+
notifyMcpRootsChanged(
|
|
1123
|
+
[mcp.mcpClient],
|
|
1124
|
+
workspaceRootDirs(options.cwd || process.cwd(), additionalDirectories),
|
|
1125
|
+
);
|
|
1126
|
+
} catch {
|
|
1127
|
+
// best-effort — root advertisement never blocks a run
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1052
1131
|
// IDE live context (Claude-Code parity): when an IDE bridge is connected,
|
|
1053
1132
|
// share the editor's selection/active file/open tabs with this turn. Appended
|
|
1054
1133
|
// to the in-flight user message only — AFTER persistence — so a resumed
|
|
@@ -1077,6 +1156,16 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
1077
1156
|
// IDE context is optional polish — never fail the run over it.
|
|
1078
1157
|
}
|
|
1079
1158
|
|
|
1159
|
+
// Background phase reporter (P0 state-machine producer): when this run IS a
|
|
1160
|
+
// background agent's turn child (CC_BACKGROUND_AGENT_ID set by the worker),
|
|
1161
|
+
// the human-blocking confirmers below surface their pending window as
|
|
1162
|
+
// `phase: "waiting_permission"` + `pendingApprovals` in the shared state
|
|
1163
|
+
// file so the dashboard's "Needs input" group is real, not inferred. For
|
|
1164
|
+
// every non-background run this is a disabled no-op (wrapConfirmer returns
|
|
1165
|
+
// the same function object).
|
|
1166
|
+
const _bgPhase =
|
|
1167
|
+
deps.backgroundPhaseReporter || createBackgroundPhaseReporter();
|
|
1168
|
+
|
|
1080
1169
|
// --permission-prompt-tool: route every CONFIRM-tier approval to an MCP tool
|
|
1081
1170
|
// (loaded via --mcp-config) instead of headless fail-closed. Overrides the
|
|
1082
1171
|
// permission-mode confirmer on the gate for this session.
|
|
@@ -1097,13 +1186,15 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
1097
1186
|
}
|
|
1098
1187
|
if (approvalGate && typeof approvalGate.setConfirmer === "function") {
|
|
1099
1188
|
approvalGate.setConfirmer(
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1189
|
+
_bgPhase.wrapConfirmer(
|
|
1190
|
+
makePermissionPromptConfirmer({
|
|
1191
|
+
mcpClient: mcp.mcpClient,
|
|
1192
|
+
server: ppt.server,
|
|
1193
|
+
tool: ppt.tool,
|
|
1194
|
+
writeErr,
|
|
1195
|
+
isText,
|
|
1196
|
+
}),
|
|
1197
|
+
),
|
|
1107
1198
|
);
|
|
1108
1199
|
}
|
|
1109
1200
|
}
|
|
@@ -1127,7 +1218,9 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
1127
1218
|
isText,
|
|
1128
1219
|
});
|
|
1129
1220
|
if (approvalGate && typeof approvalGate.setConfirmer === "function") {
|
|
1130
|
-
approvalGate.setConfirmer(
|
|
1221
|
+
approvalGate.setConfirmer(
|
|
1222
|
+
_bgPhase.wrapConfirmer(_remoteApproval.confirmer),
|
|
1223
|
+
);
|
|
1131
1224
|
}
|
|
1132
1225
|
} catch (err) {
|
|
1133
1226
|
// Remote approval could not come up → keep headless fail-closed rather
|
|
@@ -1160,7 +1253,16 @@ export async function runAgentHeadless(options = {}, deps = {}) {
|
|
|
1160
1253
|
try {
|
|
1161
1254
|
const { AsyncHookSupervisor } =
|
|
1162
1255
|
await import("../lib/async-hook-supervisor.cjs");
|
|
1163
|
-
_hookSupervisor = new AsyncHookSupervisor({
|
|
1256
|
+
_hookSupervisor = new AsyncHookSupervisor({
|
|
1257
|
+
persistStats: true,
|
|
1258
|
+
// Durably park failed-rewake signals keyed by session so a crash before
|
|
1259
|
+
// the turn loop drains them doesn't lose the failure — recovered on the
|
|
1260
|
+
// next `--resume` (see the resume block above). Only a PERSISTABLE
|
|
1261
|
+
// session can be resumed, so the queue follows `persist`; a one-shot /
|
|
1262
|
+
// --ephemeral run stays byte-unchanged (no session id → no writes).
|
|
1263
|
+
persistQueue: persist,
|
|
1264
|
+
sessionId: persist ? sessionId : null,
|
|
1265
|
+
});
|
|
1164
1266
|
} catch {
|
|
1165
1267
|
_hookSupervisor = null; // async hooks are best-effort
|
|
1166
1268
|
}
|
|
@@ -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
|
|
@@ -1280,6 +1302,23 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
1280
1302
|
}
|
|
1281
1303
|
}
|
|
1282
1304
|
|
|
1305
|
+
// Seed MCP roots for --add-dir (roots/list_changed parity): advertise the full
|
|
1306
|
+
// workspace-root list to connected MCP servers when the stream session started
|
|
1307
|
+
// with extra roots. No --add-dir → workspaceRootDirs = [cwd] → no-op. Mirrors
|
|
1308
|
+
// the single-prompt runner + the REPL /add-dir path. Best-effort.
|
|
1309
|
+
if (mcp?.mcpClient && additionalDirectories.length > 0) {
|
|
1310
|
+
try {
|
|
1311
|
+
const { notifyMcpRootsChanged, workspaceRootDirs } =
|
|
1312
|
+
await import("../repl/add-dir.js");
|
|
1313
|
+
notifyMcpRootsChanged(
|
|
1314
|
+
[mcp.mcpClient],
|
|
1315
|
+
workspaceRootDirs(options.cwd || process.cwd(), additionalDirectories),
|
|
1316
|
+
);
|
|
1317
|
+
} catch {
|
|
1318
|
+
// best-effort — root advertisement never blocks a run
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1283
1322
|
// --permission-prompt-tool: defer CONFIRM-tier approvals to an MCP tool
|
|
1284
1323
|
// (loaded via --mcp-config) instead of headless fail-closed.
|
|
1285
1324
|
if (options.permissionPromptTool) {
|
|
@@ -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) {
|
|
@@ -124,6 +124,10 @@ function startTurn(argv, promptText) {
|
|
|
124
124
|
status: "running",
|
|
125
125
|
phase,
|
|
126
126
|
turnCount,
|
|
127
|
+
// A fresh turn has nothing pending; also clears a stale count left behind
|
|
128
|
+
// if the previous turn's child was hard-killed mid-approval (the child's
|
|
129
|
+
// phase reporter clears on settle, but SIGKILL never settles).
|
|
130
|
+
pendingApprovals: 0,
|
|
127
131
|
agentPid: child.pid,
|
|
128
132
|
// Identity anchor for the supervisor's orphan reclaim (Gap 2): pairs
|
|
129
133
|
// with agentPid the way startedAt pairs with the worker pid, so a
|
|
@@ -166,6 +170,10 @@ function maybeContinue() {
|
|
|
166
170
|
phase = "idle";
|
|
167
171
|
mergeState({
|
|
168
172
|
phase,
|
|
173
|
+
// Between turns nothing can be pending — the approval-owning child has
|
|
174
|
+
// exited. Honest zero keeps a killed-mid-approval count from parking
|
|
175
|
+
// the session in "Needs input" forever.
|
|
176
|
+
pendingApprovals: 0,
|
|
169
177
|
agentPid: null,
|
|
170
178
|
agentStartedAt: null,
|
|
171
179
|
heartbeatAt: Date.now(),
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{P as s,J as p,b as a}from"./vendor-Bn1JzzAn.js";import{r as c}from"./markdown-Yo_c6Krv.js";import{_ as d}from"./index-CWUJlCvK.js";const _={__name:"MarkdownRenderer",props:{content:{type:String,default:""}},setup(t,{expose:o}){o();const e=t,r=a(()=>c(e.content||"")),n={props:e,rendered:r,computed:a,get renderMarkdown(){return c}};return Object.defineProperty(n,"__isScriptSetup",{enumerable:!1,value:!0}),n}},i=["innerHTML"];function m(t,o,e,r,n,u){return s(),p("div",{class:"markdown-content",innerHTML:r.rendered},null,8,i)}const w=d(_,[["render",m],["__scopeId","data-v-0b0b9f63"],["__file","/tmp/cc-web-panel-dapzcY/repo/packages/web-panel/src/components/MarkdownRenderer.vue"]]);export{w as M};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{I as c,J as g,c as l,K as r,N as u,P as h,U as o,R as t,Q as b}from"./vendor-Bn1JzzAn.js";import{_ as v,b as m}from"./index-CWUJlCvK.js";import{a8 as y,M}from"./icons-DG5UD-6K.js";const B={__name:"MobileProjects",setup(p,{expose:i}){i();const n=u(),{t:e}=m();function a(){n.push("/projects")}function _(){n.push("/mobile-bridge")}const s={router:n,t:e,goToProjects:a,goToMobileBridge:_,get useRouter(){return u},get useI18n(){return m},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,n,e,a,_){const s=c("a-alert"),d=c("a-button"),f=c("a-space"),P=c("a-empty"),j=c("a-card");return h(),g("div",x,[l(j,null,{default:r(()=>[l(P,{description:!1},{image:r(()=>[l(e.MobileOutlined,{style:{fontSize:"64px",color:"#bfbfbf"}})]),default:r(()=>[o("h2",O,t(e.t("mobileProjects.title")),1),o("p",k,t(e.t("mobileProjects.subtitle")),1),l(s,{message:e.t("mobileProjects.v02Banner"),type:"info","show-icon":"",class:"banner"},null,8,["message"]),o("div",w,[o("h3",null,t(e.t("mobileProjects.currentDirection")),1),o("p",null,t(e.t("mobileProjects.currentDirectionBody")),1),o("ul",null,[o("li",null,t(e.t("mobileProjects.stepPhone")),1),o("li",null,t(e.t("mobileProjects.stepTap")),1),o("li",null,t(e.t("mobileProjects.stepPull")),1)]),o("h3",null,t(e.t("mobileProjects.reverseDirection")),1),o("p",null,t(e.t("mobileProjects.reverseDirectionBody")),1)]),l(f,{class:"actions"},{default:r(()=>[l(d,{type:"primary",onClick:e.goToProjects},{default:r(()=>[l(e.FolderOutlined),b(" "+t(e.t("mobileProjects.viewLocalProjects")),1)]),_:1}),l(d,{onClick:e.goToMobileBridge},{default:r(()=>[l(e.MobileOutlined),b(" "+t(e.t("mobileProjects.checkBridge")),1)]),_:1})]),_:1})]),_:1})]),_:1})])}const N=v(B,[["render",T],["__scopeId","data-v-9262cc45"],["__file","/tmp/cc-web-panel-dapzcY/repo/packages/web-panel/src/views/MobileProjects.vue"]]);export{N 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-CWUJlCvK.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,R as E,o as G,f as H,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 j=new ResizeObserver(()=>{try{P.fit(),s.resize(t.id,m.cols,m.rows).catch(()=>{})}catch{}});j.observe(b);const ue=t.offs;t.offs=()=>{try{j.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}}G(async()=>{await X()}),H(()=>{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 Y={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:G,onBeforeUnmount:H,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(Y,"__isScriptSetup",{enumerable:!1,value:!0}),Y}},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,Z(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,Z(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-dapzcY/repo/packages/web-panel/src/views/Terminal.vue"]]);export{Fe as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Q as r}from"./index-CWUJlCvK.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-B-H5eoNw.js";import{a0 as t}from"./index-CWUJlCvK.js";import"./vendor-Bn1JzzAn.js";import"./index-DBcKBb1E.js";import"./icons-DG5UD-6K.js";const s=t(o);export{s as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{A as o}from"./Row-D7dZEyak.js";import{a0 as t}from"./index-CWUJlCvK.js";import"./vendor-Bn1JzzAn.js";import"./responsiveObserve-CEC8CZ-3.js";import"./useFlexGapSupport-yFTVMDUv.js";import"./styleChecker-BIS2unhx.js";import"./index-DBcKBb1E.js";import"./icons-DG5UD-6K.js";const l=t(o);export{l as default};
|