chainlesschain 0.162.40 → 0.162.42
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-CPmKv82o.js → AIOps-Dsw5p7A7.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-BNDYY7Qd.js → ActionButton-sk89dGuT.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-BgCMCOsk.js → Analytics-kd8hzeK3.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-Dv4oJcqS.js → AppLayout-CxlLp7J8.js} +5 -5
- package/src/assets/web-panel/assets/{Audit-5iV3yrGa.js → Audit-CQnGmRxA.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-CHDhnbzF.js → Backup-BioBFWVV.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-B6reFkra.js → BaseInput-DiYG1n7T.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-DwS5YyE2.js → Chat-BBuQf6VM.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-CqXa87Hw.js → ChatBubbleRenderer-BwgFmlRu.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-yiW0M4RE.js → Checkbox-B-9WwFTA.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DoiVuD_g.js → Codegen-DCkpThQa.js} +1 -1
- package/src/assets/web-panel/assets/{Col-BVASLexk.js → Col-BowFdito.js} +1 -1
- package/src/assets/web-panel/assets/{Community-D6KQ7JoU.js → Community-BWGa92rE.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-Bl9Uhb6v.js → Compact-CqJYYK0v.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-MM31-dba.js → Compliance-DiFqpJrM.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-PjU_1ieD.js → Cowork-qZNWcSQ9.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-DorNtPZL.js → Cron-BK70XYci.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-Bm5ts2Kw.js → Crosschain-DoM9N2kO.js} +1 -1
- package/src/assets/web-panel/assets/{DID-7Y3jlFdY.js → DID-B1F1RhQr.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-1oE532bG.js → Dashboard-CmDxx07G.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-hJlOPs0s.js → Dropdown-5GRByJY9.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-BEqJxKaO.js → EmailListRenderer-CyNgNjLG.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-BvCGwB6X.js → FamilyGuardDashboard-Jwg-Wuye.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-CsXI72e5.js → Federation-BQvoY2_5.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-Dh9SMul-.js → FormItemContext-DKy8Zatd.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-9edWzrtG.js → GenericCardRenderer-n7VGwZNh.js} +1 -1
- package/src/assets/web-panel/assets/{Git-ZYhNL8Xk.js → Git-CFCUe_so.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-BwAdp8QA.js → Governance-DuZbRElA.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-5C-M1XsH.js → Inference-DSEsBonV.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-zFAi-zCi.js → KnowledgeGraph-DQoaeSnN.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BZsEdbgE.js → Logs-u7UMHPnz.js} +2 -2
- package/src/assets/web-panel/assets/{Marketplace-BP6gErRK.js → Marketplace--gDqWnX8.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-CXVzoLrd.js → McpTools-btiDEQ_G.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-BIpChb4-.js → Memory-CYrqC903.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-B4O7wDT8.js → MobileBridge-CktV5fRJ.js} +2 -2
- package/src/assets/web-panel/assets/MobileProjects-CTVZQD7g.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-BTmEyTM5.js → Mtc-CRq5Ir7q.js} +6 -6
- package/src/assets/web-panel/assets/{MtcAudit-CsbG9LlV.js → MtcAudit-HvY-N0XZ.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-CL8yoGon.js → Multisig-CWmUSW7g.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-C2cIlIp_.js → NLProgramming-BUwhn6xG.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-7aBk_n_M.js → Notes-BI8NqNSW.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-BuhQk4rJ.js → NotificationSettings-DVa8gbo1.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-mqMFZu0x.js → OrderTableRenderer-XNEr64wi.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-CAdq-170.js → Organization-a0imltNQ.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow--Xn0E787.js → Overflow-DJ2P1mNg.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-DYt3YAXI.js → P2P-pRJPEJ7a.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-Bgb_v8WN.js → PdhVaultBrowser-eJa8vkF5.js} +5 -5
- package/src/assets/web-panel/assets/{Permissions-DoFlmoaW.js → Permissions-fxa21qzR.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-C-FJB3a0.js → PersonalDataHub-C3JggyPn.js} +2 -2
- package/src/assets/web-panel/assets/{Pipeline-3bL2RzzL.js → Pipeline-iR9fwke0.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-c4igYUCF.js → Privacy-oBf4gwv0.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-C0QS1UPR.js → ProjectInit-DZU2PVgs.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-CkYC0xkE.js → ProjectSettings-amcXcSet.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-Di17SYft.js → Projects-QoksY3-i.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-41NySsLt.js → Providers-uquz_5KZ.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DHq9pD7z.js → QuickAsk-Wxx-iIH9.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CLjgFPLv.js → Recommend-CD8OJGJF.js} +1 -1
- package/src/assets/web-panel/assets/{Reputation-EIrgErm3.js → Reputation-BuJMHfco.js} +1 -1
- package/src/assets/web-panel/assets/{Row-GAvKzKH7.js → Row-DvfqASM7.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-CYCNsVmD.js → RssFeed-TGSmYgmV.js} +3 -3
- package/src/assets/web-panel/assets/{Search-DWOE32k8.js → Search-ndSDi33l.js} +1 -1
- package/src/assets/web-panel/assets/{Security-Dgh8Jevn.js → Security-CL1FLyzy.js} +4 -4
- package/src/assets/web-panel/assets/{Services-BxdgP67N.js → Services--AeNKFrY.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-D-xT4ZkA.js → Skeleton-CMllAeqY.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-BKN4lfSa.js → Skills-DD29bVTm.js} +1 -1
- package/src/assets/web-panel/assets/{Sla--N1TudpS.js → Sla-DU_Mdrad.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-B0vfJpEh.js → SpeechSettings-Cu0ncgI_.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-BuBAbPAh.js → SyncSettings-Bfk00Eb9.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-C-2V1COO.js +1 -0
- package/src/assets/web-panel/assets/{Templates-DI2giLgc.js → Templates-CWO4Aw1l.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-BiTWvm0g.js → Tenant-BnDkNC6u.js} +1 -1
- package/src/assets/web-panel/assets/Terminal-VR0JLDdw.js +3 -0
- package/src/assets/web-panel/assets/{TimelineRenderer-BmgzKdAp.js → TimelineRenderer-DMjbfev0.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-Nvupdm6p.js → Tokens-j1ZGEgBP.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DRfR77WJ.js → Trigger-BKVNLlOB.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-De0Jal_6.js → Trust-Bbfv8AJr.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-Dzo4-VAM.js → UkeySign-C0_Gllsu.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-hg2ytiJB.js → VideoEditing-CE__3Owf.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet--bU5-gRh.js → Wallet-Cjzavume.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DZptt-PV.js → WebAuthn-KbjxueWc.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-Dy9223bY.js → WorkflowEditor-Bz7UuLhK.js} +1 -1
- package/src/assets/web-panel/assets/{chat-DaxGeI9w.js → chat-BrSAQ_Gd.js} +1 -1
- package/src/assets/web-panel/assets/{colors-Cu2VEci3.js → colors-Bn8oqI93.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-CGolhyJq.js → compact-item-jxrLqj8Q.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DY7EFhkD.js → createContext-B0uxIvgB.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-rqonNzey.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-Bpc-NoFN.js → hasIn-BFsfry47.js} +1 -1
- package/src/assets/web-panel/assets/{index-BQ2z6Ky5.js → index-9iuxVwRC.js} +1 -1
- package/src/assets/web-panel/assets/{index-eF9RV_4c.js → index-B9ZDJUc0.js} +1 -1
- package/src/assets/web-panel/assets/index-BI1fCgPX.js +1 -0
- package/src/assets/web-panel/assets/{index-VBRPxZeE.js → index-BPpGWBAU.js} +1 -1
- package/src/assets/web-panel/assets/{index-BlHq81Ow.js → index-BQZsB8nt.js} +1 -1
- package/src/assets/web-panel/assets/{index-BjfxHEmX.js → index-BQvlv_iE.js} +1 -1
- package/src/assets/web-panel/assets/{index-8h9y5S6X.js → index-BRkK0yoO.js} +1 -1
- package/src/assets/web-panel/assets/{index-lfP8sdzB.js → index-BY4oOQaA.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bz83ngs0.js → index-Bd-zsWvY.js} +1 -1
- package/src/assets/web-panel/assets/{index-BP9P6chP.js → index-BiXyJmcf.js} +1 -1
- package/src/assets/web-panel/assets/{index-D63ObMdQ.js → index-Bk_Tv7Ey.js} +1 -1
- package/src/assets/web-panel/assets/{index-D0GN5tdM.js → index-BzZfG8Ft.js} +1 -1
- package/src/assets/web-panel/assets/{index-DNX81oSR.js → index-C6AmzUjG.js} +1 -1
- package/src/assets/web-panel/assets/{index-BTvwiqJE.js → index-C7q_gApa.js} +1 -1
- package/src/assets/web-panel/assets/{index-C2RpsAiO.js → index-CAIdm73g.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bn5gM9Oy.js → index-CCVF9irI.js} +1 -1
- package/src/assets/web-panel/assets/{index-DexYD87j.js → index-CR3QNisI.js} +1 -1
- package/src/assets/web-panel/assets/{index-DfKmAEtE.js → index-CZ8gyTGc.js} +1 -1
- package/src/assets/web-panel/assets/{index-BRAgl2J_.js → index-CireH7ze.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpRSzAFl.js → index-CovEs7is.js} +1 -1
- package/src/assets/web-panel/assets/{index-C-Hkl_2G.js → index-Crqzhccj.js} +1 -1
- package/src/assets/web-panel/assets/{index-DldaToUA.js → index-D08W2YxD.js} +1 -1
- package/src/assets/web-panel/assets/{index-DAov-rJR.js → index-D1WrY_4z.js} +1 -1
- package/src/assets/web-panel/assets/index-D8iCZ8gl.js +1 -0
- package/src/assets/web-panel/assets/{index-oJQgRCrR.js → index-DMPQqeLb.js} +3 -3
- package/src/assets/web-panel/assets/{index-Ciw5-X1B.js → index-DOJYoYG7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CJFYF8F9.js → index-DSDgBgrL.js} +1 -1
- package/src/assets/web-panel/assets/{index-1D4sfByw.js → index-DcHQBw3b.js} +1 -1
- package/src/assets/web-panel/assets/{index-CLNqZF55.js → index-DdjhDnIk.js} +1 -1
- package/src/assets/web-panel/assets/{index-CGqeHu_F.js → index-DeHd8uSh.js} +1 -1
- package/src/assets/web-panel/assets/{index-DZ4Vm8dQ.js → index-DjxJSCB8.js} +1 -1
- package/src/assets/web-panel/assets/{index-CFAnEzRW.js → index-DmD-qtjF.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0_zeYnx.js → index-DteDdzDQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-CBSk_VrT.js → index-E6sYKDbw.js} +1 -1
- package/src/assets/web-panel/assets/{index-CaKXhpEu.js → index-LLFwwG0R.js} +1 -1
- package/src/assets/web-panel/assets/{index-DxXkr-NS.js → index-_fgTMPd1.js} +1 -1
- package/src/assets/web-panel/assets/{index-RumxOD0S.js → index-pMVcl-a3.js} +1 -1
- package/src/assets/web-panel/assets/{index-rkm7dHwG.js → index-vma7bVdQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DElatOQ0.js → index-xRD9Fctn.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CkJZfCo8.js → initDefaultProps-AKS5cCeZ.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BerbusV1.js → motion-SDjWiFhF.js} +1 -1
- package/src/assets/web-panel/assets/{move-DyRzKPD4.js → move-LEZnOtYR.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CCdrTUAs.js → omit-DhLBVNzX.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-mVDeZx2m.js → pickAttrs-DdVSELea.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-Bb_-Fs_o.js → placementArrow-BaEGCCq9.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-C6TMj1R_.js → responsiveObserve-DV6XM19W.js} +1 -1
- package/src/assets/web-panel/assets/{slide-CdCNsy1J.js → slide-BOUnaBay.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-Ccxd1rFd.js → statusUtils-BAaMQ0VA.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-3IL-yw1V.js → styleChecker-CsoP0nmm.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-CH8DjUHl.js → useFlexGapSupport-t20RbINy.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-Cn9nE2sp.js → useFs-DH_Emn7A.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-BPyT0HO7.js → usePersonalDataHub-CeYW427U.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-Mfm7vy07.js → vnode-CX5gGmGb.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-CTpAiAE9.js → zoom-CofyY9oD.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agent.js +38 -4
- package/src/commands/init.js +31 -0
- package/src/commands/mcp.js +57 -0
- package/src/commands/memory.js +62 -0
- package/src/commands/session.js +70 -0
- package/src/lib/agent-core.js +1 -0
- package/src/lib/init-ai-refine.js +66 -0
- package/src/lib/json-schema-output.js +181 -0
- package/src/lib/mcp-serve.js +259 -0
- package/src/lib/project-instructions.js +89 -0
- package/src/lib/repl-completer.js +9 -3
- package/src/lib/repl-rewind.js +107 -0
- package/src/repl/agent-repl.js +145 -1
- package/src/runtime/headless-stream.js +60 -0
- package/src/assets/web-panel/assets/MobileProjects-7VPMoHus.js +0 -1
- package/src/assets/web-panel/assets/Tasks-4XugjJ87.js +0 -1
- package/src/assets/web-panel/assets/Terminal-vV6AWGDi.js +0 -3
- package/src/assets/web-panel/assets/devWarning-DV2BNd59.js +0 -1
- package/src/assets/web-panel/assets/index-BZqtTmyG.js +0 -1
- package/src/assets/web-panel/assets/index-DUpwdJt9.js +0 -1
package/src/repl/agent-repl.js
CHANGED
|
@@ -718,6 +718,18 @@ export async function startAgentRepl(options = {}) {
|
|
|
718
718
|
} catch (_err) {
|
|
719
719
|
// Non-critical
|
|
720
720
|
}
|
|
721
|
+
// Resume recap (offline, extractive — no LLM): a quick "where were we"
|
|
722
|
+
// so the user doesn't have to scroll the old transcript.
|
|
723
|
+
try {
|
|
724
|
+
const { buildResumeRecap } = await import("../lib/repl-rewind.js");
|
|
725
|
+
const recap = buildResumeRecap(messages);
|
|
726
|
+
if (recap) {
|
|
727
|
+
logger.log(chalk.bold("Recap:"));
|
|
728
|
+
for (const line of recap) logger.log(chalk.gray(` ${line}`));
|
|
729
|
+
}
|
|
730
|
+
} catch (_err) {
|
|
731
|
+
/* non-critical */
|
|
732
|
+
}
|
|
721
733
|
}
|
|
722
734
|
|
|
723
735
|
const getPrompt = () => {
|
|
@@ -754,6 +766,7 @@ export async function startAgentRepl(options = {}) {
|
|
|
754
766
|
"/provider",
|
|
755
767
|
"/quit",
|
|
756
768
|
"/reindex",
|
|
769
|
+
"/rewind",
|
|
757
770
|
"/search",
|
|
758
771
|
"/session",
|
|
759
772
|
"/stats",
|
|
@@ -787,6 +800,53 @@ export async function startAgentRepl(options = {}) {
|
|
|
787
800
|
completer: atCompleter,
|
|
788
801
|
});
|
|
789
802
|
|
|
803
|
+
// Esc interrupt (Claude-Code parity): pressing Esc while a turn is in
|
|
804
|
+
// flight aborts the in-flight agentLoop through its existing AbortSignal
|
|
805
|
+
// seam (throwIfAborted at each iteration); partial conversation is kept.
|
|
806
|
+
// Idle Esc presses (no active turn) are ignored, and escape-prefixed key
|
|
807
|
+
// sequences (arrows etc.) never reach here as bare "escape".
|
|
808
|
+
let _turnAbort = null;
|
|
809
|
+
let _lastIdleEscAt = 0;
|
|
810
|
+
if (process.stdin.isTTY) {
|
|
811
|
+
process.stdin.on("keypress", (_str, key) => {
|
|
812
|
+
if (!key || key.name !== "escape" || key.meta) return;
|
|
813
|
+
if (_turnAbort) {
|
|
814
|
+
process.stdout.write(chalk.yellow("\n⎋ interrupting…\n"));
|
|
815
|
+
try {
|
|
816
|
+
_turnAbort.abort();
|
|
817
|
+
} catch {
|
|
818
|
+
/* already aborted */
|
|
819
|
+
}
|
|
820
|
+
_turnAbort = null;
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
// Double-Esc while idle → rewind picker shortcut (Claude-Code parity);
|
|
824
|
+
// the actual rewind is `/rewind <n>` so stdin stays readline-owned.
|
|
825
|
+
const nowTs = Date.now();
|
|
826
|
+
if (nowTs - _lastIdleEscAt < 600) {
|
|
827
|
+
_lastIdleEscAt = 0;
|
|
828
|
+
import("../lib/repl-rewind.js")
|
|
829
|
+
.then(({ listUserTurns, renderTurnList }) => {
|
|
830
|
+
process.stdout.write(
|
|
831
|
+
chalk.bold("\nRewind — pick a user turn (newest first):\n"),
|
|
832
|
+
);
|
|
833
|
+
process.stdout.write(
|
|
834
|
+
`${renderTurnList(listUserTurns(messages))}\n`,
|
|
835
|
+
);
|
|
836
|
+
process.stdout.write(
|
|
837
|
+
chalk.gray(
|
|
838
|
+
"Run /rewind <n> to rewind the conversation (files: cc checkpoint restore).\n",
|
|
839
|
+
),
|
|
840
|
+
);
|
|
841
|
+
prompt();
|
|
842
|
+
})
|
|
843
|
+
.catch(() => {});
|
|
844
|
+
} else {
|
|
845
|
+
_lastIdleEscAt = nowTs;
|
|
846
|
+
}
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
|
|
790
850
|
logger.log(chalk.bold("\nChainlessChain Agent"));
|
|
791
851
|
logger.log(
|
|
792
852
|
chalk.gray(`Model: ${model} Provider: ${provider} CWD: ${process.cwd()}`),
|
|
@@ -871,7 +931,12 @@ export async function startAgentRepl(options = {}) {
|
|
|
871
931
|
|
|
872
932
|
prompt();
|
|
873
933
|
|
|
874
|
-
|
|
934
|
+
// Steering (Claude-Code parity): typing while a turn is running QUEUES the
|
|
935
|
+
// line instead of racing a second concurrent turn; the queue drains FIFO
|
|
936
|
+
// when the current turn finishes.
|
|
937
|
+
let _processingLine = false;
|
|
938
|
+
const _pendingLines = [];
|
|
939
|
+
const handleLine = async (input) => {
|
|
875
940
|
const trimmed = input.trim();
|
|
876
941
|
if (!trimmed) {
|
|
877
942
|
prompt();
|
|
@@ -944,6 +1009,9 @@ export async function startAgentRepl(options = {}) {
|
|
|
944
1009
|
logger.log(
|
|
945
1010
|
` ${chalk.cyan("/context")} Live context-window usage by role`,
|
|
946
1011
|
);
|
|
1012
|
+
logger.log(
|
|
1013
|
+
` ${chalk.cyan("/rewind")} Rewind conversation to an earlier turn (double-Esc lists)`,
|
|
1014
|
+
);
|
|
947
1015
|
logger.log(
|
|
948
1016
|
` ${chalk.cyan("/compact")} Smart compact (importance-based)`,
|
|
949
1017
|
);
|
|
@@ -1182,6 +1250,44 @@ export async function startAgentRepl(options = {}) {
|
|
|
1182
1250
|
return;
|
|
1183
1251
|
}
|
|
1184
1252
|
|
|
1253
|
+
if (trimmed === "/rewind" || trimmed.startsWith("/rewind ")) {
|
|
1254
|
+
try {
|
|
1255
|
+
const { listUserTurns, rewindToTurn, renderTurnList } = await import(
|
|
1256
|
+
"../lib/repl-rewind.js"
|
|
1257
|
+
);
|
|
1258
|
+
const arg = trimmed.slice("/rewind".length).trim();
|
|
1259
|
+
if (!arg) {
|
|
1260
|
+
logger.log(
|
|
1261
|
+
chalk.bold("\nRewind — pick a user turn (newest first):"),
|
|
1262
|
+
);
|
|
1263
|
+
logger.log(renderTurnList(listUserTurns(messages)));
|
|
1264
|
+
logger.log(
|
|
1265
|
+
chalk.gray(
|
|
1266
|
+
"Usage: /rewind <n> (conversation only — restore files with `cc checkpoint restore`)",
|
|
1267
|
+
),
|
|
1268
|
+
);
|
|
1269
|
+
} else {
|
|
1270
|
+
const res = rewindToTurn(messages, arg);
|
|
1271
|
+
if (!res) {
|
|
1272
|
+
logger.error(`No such turn: ${arg} — run /rewind to list.`);
|
|
1273
|
+
} else {
|
|
1274
|
+
logger.log(
|
|
1275
|
+
chalk.yellow(
|
|
1276
|
+
`⎌ rewound — dropped ${res.removed} message(s); edit and resend below`,
|
|
1277
|
+
),
|
|
1278
|
+
);
|
|
1279
|
+
prompt();
|
|
1280
|
+
if (res.text) rl.write(res.text);
|
|
1281
|
+
return;
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
} catch (err) {
|
|
1285
|
+
logger.error(`/rewind failed: ${err.message}`);
|
|
1286
|
+
}
|
|
1287
|
+
prompt();
|
|
1288
|
+
return;
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1185
1291
|
if (trimmed === "/context") {
|
|
1186
1292
|
// Live-session twin of `cc context` (Claude-Code /context parity):
|
|
1187
1293
|
// bucket the CURRENT in-memory conversation by role against the model
|
|
@@ -2142,7 +2248,9 @@ export async function startAgentRepl(options = {}) {
|
|
|
2142
2248
|
} catch (_e) {
|
|
2143
2249
|
/* goal binding is best-effort — fall back to defaultPrepareCall */
|
|
2144
2250
|
}
|
|
2251
|
+
_turnAbort = new AbortController();
|
|
2145
2252
|
const { content: response, usageEvents } = await agentLoop(messages, {
|
|
2253
|
+
signal: _turnAbort.signal,
|
|
2146
2254
|
provider,
|
|
2147
2255
|
model: activeModel,
|
|
2148
2256
|
thinking,
|
|
@@ -2169,6 +2277,7 @@ export async function startAgentRepl(options = {}) {
|
|
|
2169
2277
|
externalToolDescriptors: _adhocMcp?.externalToolDescriptors,
|
|
2170
2278
|
chatFn: _fallbackChatFn,
|
|
2171
2279
|
});
|
|
2280
|
+
_turnAbort = null;
|
|
2172
2281
|
|
|
2173
2282
|
if (sessionId && usageEvents?.length) {
|
|
2174
2283
|
for (const ue of usageEvents) {
|
|
@@ -2294,6 +2403,16 @@ export async function startAgentRepl(options = {}) {
|
|
|
2294
2403
|
}
|
|
2295
2404
|
}
|
|
2296
2405
|
} catch (err) {
|
|
2406
|
+
_turnAbort = null;
|
|
2407
|
+
// Esc interrupt: an aborted turn is normal flow, not an error — the
|
|
2408
|
+
// partial conversation stays usable and queued lines still drain.
|
|
2409
|
+
if (err?.name === "AbortError" || /abort/i.test(err?.message || "")) {
|
|
2410
|
+
logger.log(
|
|
2411
|
+
chalk.yellow("⎋ turn interrupted — partial progress kept"),
|
|
2412
|
+
);
|
|
2413
|
+
prompt();
|
|
2414
|
+
return;
|
|
2415
|
+
}
|
|
2297
2416
|
logger.error(`Error: ${err.message}`);
|
|
2298
2417
|
|
|
2299
2418
|
// Record error for context injection
|
|
@@ -2317,6 +2436,31 @@ export async function startAgentRepl(options = {}) {
|
|
|
2317
2436
|
}
|
|
2318
2437
|
|
|
2319
2438
|
prompt();
|
|
2439
|
+
};
|
|
2440
|
+
|
|
2441
|
+
rl.on("line", async (input) => {
|
|
2442
|
+
if (_processingLine) {
|
|
2443
|
+
if (input.trim()) {
|
|
2444
|
+
_pendingLines.push(input);
|
|
2445
|
+
logger.log(
|
|
2446
|
+
chalk.gray(
|
|
2447
|
+
`⏸ queued (${_pendingLines.length}) — runs after the current turn`,
|
|
2448
|
+
),
|
|
2449
|
+
);
|
|
2450
|
+
}
|
|
2451
|
+
return;
|
|
2452
|
+
}
|
|
2453
|
+
_processingLine = true;
|
|
2454
|
+
try {
|
|
2455
|
+
await handleLine(input);
|
|
2456
|
+
while (_pendingLines.length) {
|
|
2457
|
+
const next = _pendingLines.shift();
|
|
2458
|
+
logger.log(chalk.cyan(`▶ running queued input: ${next}`));
|
|
2459
|
+
await handleLine(next);
|
|
2460
|
+
}
|
|
2461
|
+
} finally {
|
|
2462
|
+
_processingLine = false;
|
|
2463
|
+
}
|
|
2320
2464
|
});
|
|
2321
2465
|
|
|
2322
2466
|
rl.on("close", async () => {
|
|
@@ -30,6 +30,13 @@ import {
|
|
|
30
30
|
resolvePermissionMode,
|
|
31
31
|
resolveEnabledTools,
|
|
32
32
|
} from "./headless-runner.js";
|
|
33
|
+
import {
|
|
34
|
+
startSession as jsonlStartSession,
|
|
35
|
+
appendUserMessage as jsonlAppendUserMessage,
|
|
36
|
+
appendAssistantMessage as jsonlAppendAssistantMessage,
|
|
37
|
+
rebuildMessages as jsonlRebuildMessages,
|
|
38
|
+
sessionExists as jsonlSessionExists,
|
|
39
|
+
} from "../harness/jsonl-session-store.js";
|
|
33
40
|
import { withQuietStdout } from "./quiet-stdout.js";
|
|
34
41
|
|
|
35
42
|
/**
|
|
@@ -212,6 +219,21 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
212
219
|
const sessionId =
|
|
213
220
|
options.sessionId || `headless-stream-${Date.now()}-${process.pid}`;
|
|
214
221
|
|
|
222
|
+
// Session persistence + resume (chat-panel "session resume" / --resume):
|
|
223
|
+
// an EXPLICIT session id (--session / --resume) opts into JSONL persistence —
|
|
224
|
+
// prior history is rebuilt into the conversation and every new turn is
|
|
225
|
+
// appended, so a later run with the same id picks up where this one left
|
|
226
|
+
// off. Anonymous runs (no id) stay persistence-free, exactly as before.
|
|
227
|
+
const store = {
|
|
228
|
+
sessionExists: deps.sessionExists || jsonlSessionExists,
|
|
229
|
+
startSession: deps.startSession || jsonlStartSession,
|
|
230
|
+
appendUserMessage: deps.appendUserMessage || jsonlAppendUserMessage,
|
|
231
|
+
appendAssistantMessage:
|
|
232
|
+
deps.appendAssistantMessage || jsonlAppendAssistantMessage,
|
|
233
|
+
rebuildMessages: deps.rebuildMessages || jsonlRebuildMessages,
|
|
234
|
+
};
|
|
235
|
+
const persist = Boolean(options.sessionId);
|
|
236
|
+
|
|
215
237
|
let approvalGate = null;
|
|
216
238
|
try {
|
|
217
239
|
approvalGate = await getApprovalGate();
|
|
@@ -258,6 +280,29 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
258
280
|
}
|
|
259
281
|
}
|
|
260
282
|
|
|
283
|
+
// Resume: replay the persisted conversation (fresh system prompt always
|
|
284
|
+
// leads; persisted system turns are dropped, mirroring runAgentHeadless).
|
|
285
|
+
let resumedMessages = 0;
|
|
286
|
+
if (persist) {
|
|
287
|
+
try {
|
|
288
|
+
if (store.sessionExists(sessionId)) {
|
|
289
|
+
const history = (store.rebuildMessages(sessionId) || []).filter(
|
|
290
|
+
(m) => m && m.role !== "system",
|
|
291
|
+
);
|
|
292
|
+
messages.push(...history);
|
|
293
|
+
resumedMessages = history.length;
|
|
294
|
+
} else {
|
|
295
|
+
store.startSession(sessionId, {
|
|
296
|
+
title: "stream session",
|
|
297
|
+
provider,
|
|
298
|
+
model,
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
} catch {
|
|
302
|
+
// persistence is best-effort — never fail the stream over it
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
261
306
|
emit({
|
|
262
307
|
type: "system",
|
|
263
308
|
subtype: "init",
|
|
@@ -268,6 +313,7 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
268
313
|
tools: enabledToolNames,
|
|
269
314
|
input_format: "stream-json",
|
|
270
315
|
additional_directories: additionalDirectories,
|
|
316
|
+
resumed_messages: resumedMessages,
|
|
271
317
|
});
|
|
272
318
|
|
|
273
319
|
// Goal binding (cc goal, Phase 1) — resolved once and injected on every turn.
|
|
@@ -466,6 +512,13 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
466
512
|
}
|
|
467
513
|
|
|
468
514
|
messages.push({ role: "user", content: userContent });
|
|
515
|
+
if (persist) {
|
|
516
|
+
try {
|
|
517
|
+
store.appendUserMessage(sessionId, userContent);
|
|
518
|
+
} catch {
|
|
519
|
+
/* best-effort */
|
|
520
|
+
}
|
|
521
|
+
}
|
|
469
522
|
turns += 1;
|
|
470
523
|
|
|
471
524
|
let outcome;
|
|
@@ -489,6 +542,13 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
|
|
|
489
542
|
|
|
490
543
|
// Grow the conversation so the next turn has context.
|
|
491
544
|
messages.push({ role: "assistant", content: outcome.finalText });
|
|
545
|
+
if (persist) {
|
|
546
|
+
try {
|
|
547
|
+
store.appendAssistantMessage(sessionId, outcome.finalText);
|
|
548
|
+
} catch {
|
|
549
|
+
/* best-effort */
|
|
550
|
+
}
|
|
551
|
+
}
|
|
492
552
|
|
|
493
553
|
const exhausted =
|
|
494
554
|
outcome.endReason === "budget-exhausted" ||
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{I as n,J as g,c as l,K as r,N as u,P as h,U as o,R as t,Q as b}from"./vendor-BvqAck49.js";import{_ as v,b as m}from"./index-oJQgRCrR.js";import{a7 as y,M as B}from"./icons-DP3uiYxy.js";const M={__name:"MobileProjects",setup(p,{expose:i}){i();const c=u(),{t:e}=m();function a(){c.push("/projects")}function _(){c.push("/mobile-bridge")}const s={router:c,t:e,goToProjects:a,goToMobileBridge:_,get useRouter(){return u},get useI18n(){return m},get MobileOutlined(){return B},get FolderOutlined(){return y}};return Object.defineProperty(s,"__isScriptSetup",{enumerable:!1,value:!0}),s}},x={class:"mobile-projects-placeholder"},O={class:"title"},T={class:"subtitle"},k={class:"explainer"};function w(p,i,c,e,a,_){const s=n("a-alert"),d=n("a-button"),f=n("a-space"),P=n("a-empty"),j=n("a-card");return h(),g("div",x,[l(j,null,{default:r(()=>[l(P,{description:!1},{image:r(()=>[l(e.MobileOutlined,{style:{fontSize:"64px",color:"#bfbfbf"}})]),default:r(()=>[o("h2",O,t(e.t("mobileProjects.title")),1),o("p",T,t(e.t("mobileProjects.subtitle")),1),l(s,{message:e.t("mobileProjects.v02Banner"),type:"info","show-icon":"",class:"banner"},null,8,["message"]),o("div",k,[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(M,[["render",w],["__scopeId","data-v-9262cc45"],["__file","/tmp/cc-web-panel-RrTzBJ/repo/packages/web-panel/src/views/MobileProjects.vue"]]);export{N as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{E as V,b as z,r as D,I as p,J as c,U as _,c as n,K as a,S,V as w,o as P,x as B,P as i,Q as g,R as r,F as h,Z as F}from"./vendor-BvqAck49.js";import{u as R,_ as O}from"./index-oJQgRCrR.js";import{R as E}from"./icons-DP3uiYxy.js";const I=V("tasks",()=>{const k=D([]),l=D(!1);let u=null,e=null;const x=z(()=>k.value.filter(t=>t.status==="running")),b=z(()=>k.value.filter(t=>t.status==="pending")),y=z(()=>k.value.filter(t=>t.status==="completed"||t.status==="failed"||t.status==="timeout"));async function f(){const t=R();l.value=!0;try{const s=await t.sendRaw({type:"tasks-list"});s&&Array.isArray(s.tasks)&&(k.value=s.tasks)}catch{}finally{l.value=!1}}async function o(t){const s=R();try{await s.sendRaw({type:"tasks-stop",taskId:t})}catch{}finally{await f()}}const d=D(null);function m(t=5e3){v(),f(),u=setInterval(f,t),C()}function v(){u&&(clearInterval(u),u=null),e&&(e(),e=null)}function C(){const t=R();if(e)return;const s=T=>{T.type==="task:notification"&&T.payload?.task&&(d.value=T.payload.task,f(),setTimeout(()=>{d.value=null},8e3))};e=t.onRuntimeEvent(s)}function N(t){return!t||t<0?"-":t<1e3?`${t}ms`:t<6e4?`${(t/1e3).toFixed(1)}s`:`${(t/6e4).toFixed(1)}m`}function A(t){switch(t){case"running":return"processing";case"pending":return"default";case"completed":return"success";case"failed":return"error";case"timeout":return"warning";default:return"default"}}return{tasks:k,loading:l,running:x,pending:b,completed:y,lastNotification:d,fetchTasks:f,stopTask:o,startPolling:m,stopPolling:v,formatDuration:N,getStatusColor:A}}),U={__name:"Tasks",setup(k,{expose:l}){l();const u=I(),e=[{title:"状态",key:"status",width:90},{title:"描述",key:"description",ellipsis:!0},{title:"类型",dataIndex:"type",width:100},{title:"耗时",key:"duration",width:90},{title:"创建时间",key:"createdAt",width:180},{title:"结果",key:"result",ellipsis:!0},{title:"操作",key:"action",width:80}];function x(o){return o.status==="running"&&o.startedAt?u.formatDuration(Date.now()-o.startedAt):o.completedAt&&o.startedAt?u.formatDuration(o.completedAt-o.startedAt):"-"}function b(o){return o?new Date(o).toLocaleString():"-"}function y(o,d){return o?o.length>d?`${o.slice(0,d)}...`:o:""}P(()=>u.startPolling(5e3)),B(()=>u.stopPolling());const f={store:u,columns:e,getDuration:x,formatTime:b,truncate:y,onMounted:P,onUnmounted:B,get ReloadOutlined(){return E},get useTasksStore(){return I}};return Object.defineProperty(f,"__isScriptSetup",{enumerable:!1,value:!0}),f}},J={class:"page-header"},L={key:0,class:"error-text"},j={key:1},K={class:"task-header"},M={class:"task-desc"},Q={class:"task-id"},W={class:"task-meta"},Z=["title"],q={key:0,class:"error-text"},G={key:1,class:"success-text"},H={key:2,class:"muted-text"};function X(k,l,u,e,x,b){const y=p("a-button"),f=p("a-space"),o=p("a-alert"),d=p("a-statistic"),m=p("a-card"),v=p("a-col"),C=p("a-row"),N=p("a-tag"),A=p("a-table");return i(),c("div",null,[_("div",J,[l[3]||(l[3]=_("div",null,[_("h2",{class:"page-title"},"后台任务"),_("p",{class:"page-sub"},"查看后台任务队列、实时通知和任务执行结果。")],-1)),n(f,null,{default:a(()=>[n(y,{ghost:"",loading:e.store.loading,onClick:l[0]||(l[0]=t=>e.store.fetchTasks())},{icon:a(()=>[n(e.ReloadOutlined)]),default:a(()=>[l[2]||(l[2]=g(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),e.store.lastNotification?(i(),S(o,{key:0,type:e.store.lastNotification.status==="completed"?"success":"error","show-icon":"",closable:"",class:"banner",onClose:l[1]||(l[1]=t=>e.store.lastNotification=null)},{message:a(()=>[g(" 任务"+r(e.store.lastNotification.status==="completed"?"完成":"结束")+": "+r(e.store.lastNotification.description||e.store.lastNotification.id.slice(0,16)),1)]),description:a(()=>[e.store.lastNotification.error?(i(),c("span",L,r(e.store.lastNotification.error),1)):e.store.lastNotification.result?(i(),c("span",j,r(e.truncate(String(e.store.lastNotification.result),120)),1)):w("v-if",!0)]),_:1},8,["type"])):w("v-if",!0),n(C,{gutter:[16,16],class:"stats-row"},{default:a(()=>[n(v,{xs:12,sm:6},{default:a(()=>[n(m,{class:"stat-card",size:"small"},{default:a(()=>[n(d,{title:"全部任务",value:e.store.tasks.length},null,8,["value"])]),_:1})]),_:1}),n(v,{xs:12,sm:6},{default:a(()=>[n(m,{class:"stat-card",size:"small"},{default:a(()=>[n(d,{title:"运行中",value:e.store.running.length},null,8,["value"])]),_:1})]),_:1}),n(v,{xs:12,sm:6},{default:a(()=>[n(m,{class:"stat-card",size:"small"},{default:a(()=>[n(d,{title:"等待中",value:e.store.pending.length},null,8,["value"])]),_:1})]),_:1}),n(v,{xs:12,sm:6},{default:a(()=>[n(m,{class:"stat-card",size:"small"},{default:a(()=>[n(d,{title:"已完成",value:e.store.completed.length},null,8,["value"])]),_:1})]),_:1})]),_:1}),e.store.running.length>0?(i(),S(m,{key:1,title:"运行中的任务",class:"panel-card",size:"small"},{default:a(()=>[(i(!0),c(h,null,F(e.store.running,t=>(i(),c("div",{key:t.id,class:"task-item running"},[_("div",K,[n(N,{color:e.store.getStatusColor(t.status)},{default:a(()=>[g(r(t.status.toUpperCase()),1)]),_:2},1032,["color"]),_("span",M,r(t.description),1),_("span",Q,r(t.id.slice(0,16)),1)]),_("div",W,[_("span",null,"类型: "+r(t.type||"-"),1),_("span",null,"已运行: "+r(e.store.formatDuration(Date.now()-t.startedAt)),1),n(y,{size:"small",danger:"",onClick:s=>e.store.stopTask(t.id)},{default:a(()=>[...l[4]||(l[4]=[g("停止",-1)])]),_:1},8,["onClick"])])]))),128))]),_:1})):w("v-if",!0),n(m,{class:"panel-card"},{default:a(()=>[n(A,{columns:e.columns,"data-source":e.store.tasks,pagination:{pageSize:15,size:"small"},loading:e.store.loading,"row-key":"id",size:"small"},{bodyCell:a(({column:t,record:s})=>[t.key==="status"?(i(),S(N,{key:0,color:e.store.getStatusColor(s.status)},{default:a(()=>[g(r(s.status),1)]),_:2},1032,["color"])):t.key==="description"?(i(),c("span",{key:1,title:s.command},r(s.description),9,Z)):t.key==="duration"?(i(),c(h,{key:2},[g(r(e.getDuration(s)),1)],64)):t.key==="createdAt"?(i(),c(h,{key:3},[g(r(e.formatTime(s.createdAt)),1)],64)):t.key==="result"?(i(),c(h,{key:4},[s.error?(i(),c("span",q,r(e.truncate(s.error,60)),1)):s.result?(i(),c("span",G,r(e.truncate(String(s.result),60)),1)):(i(),c("span",H,"-"))],64)):t.key==="action"?(i(),c(h,{key:5},[s.status==="running"?(i(),S(y,{key:0,size:"small",danger:"",onClick:T=>e.store.stopTask(s.id)},{default:a(()=>[...l[5]||(l[5]=[g(" 停止 ",-1)])]),_:1},8,["onClick"])):w("v-if",!0)],64)):w("v-if",!0)]),_:1},8,["data-source","loading"])]),_:1})])}const et=O(U,[["render",X],["__scopeId","data-v-da5ff6a2"],["__file","/tmp/cc-web-panel-RrTzBJ/repo/packages/web-panel/src/views/Tasks.vue"]]);export{et 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-oJQgRCrR.js";import{I as z,J as x,U as _,Q as B,S as Q,K as T,V as R,c as A,F as Y,Z,R as E,o as G,f as H,w as $,n as D,b as ee,r as S,P as y,_ as ve,a2 as we,a3 as he,a4 as _e}from"./vendor-BvqAck49.js";import{R as ye,b as pe,as as ge}from"./icons-DP3uiYxy.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 q(t){await D();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 K of v)m.write(K.data),t.lastSeq=K.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 q(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,D(()=>{const l=e.value.find(p=>p.id===t);try{l?.fitAddon?.fit()}catch{}})}async function J(){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 q(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 J()}),H(()=>{for(const t of e.value){try{t.offs?.()}catch{}try{t.xterm?.dispose?.()}catch{}}}),$(i,()=>{D(()=>{const t=h.value;try{t?.fitAddon?.fit()}catch{}})});const X={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:q,onCreate:re,onClose:se,removeSession:W,activate:le,refreshList:J,ref:S,computed:ee,onMounted:G,onBeforeUnmount:H,nextTick:D,watch:$,get message(){return V},get PlusOutlined(){return ge},get CloseOutlined(){return pe},get ReloadOutlined(){return ye},get useTerminal(){return oe}};return Object.defineProperty(X,"__isScriptSetup",{enumerable:!1,value:!0}),X}},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"},Be={key:1,class:"terminal-footer"},De={key:0,class:"footer-exit"};function qe(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]=B(" 桌面端托管的 PTY 会话;Android 端可远程操控同一通道 ",-1)),e.warning?(y(),Q(u,{key:0,color:"orange",style:{"margin-left":"8px"}},{default:T(()=>[B(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]=B(" 新会话 ",-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]=B(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),e.error?(y(),Q(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(Y,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(Y,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",Be,[_("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",De,"已退出 (code="+E(e.active.exitCode??"-")+")",1))])):R("v-if",!0)])}const Fe=me(Se,[["render",qe],["__scopeId","data-v-65366a29"],["__file","/tmp/cc-web-panel-RrTzBJ/repo/packages/web-panel/src/views/Terminal.vue"]]);export{Fe as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{O as r}from"./index-oJQgRCrR.js";const o=((n,a,e)=>{r(n,`[ant-design-vue: ${a}] ${e}`)});export{o as d};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{A as o}from"./Row-GAvKzKH7.js";import{U as t}from"./index-oJQgRCrR.js";import"./vendor-BvqAck49.js";import"./responsiveObserve-C6TMj1R_.js";import"./useFlexGapSupport-CH8DjUHl.js";import"./styleChecker-3IL-yw1V.js";import"./index-DexYD87j.js";import"./icons-DP3uiYxy.js";const l=t(o);export{l as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{C as o}from"./Col-BVASLexk.js";import{U as t}from"./index-oJQgRCrR.js";import"./vendor-BvqAck49.js";import"./index-DexYD87j.js";import"./icons-DP3uiYxy.js";const s=t(o);export{s as default};
|