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.
Files changed (163) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/assets/{AIOps-CPmKv82o.js → AIOps-Dsw5p7A7.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-BNDYY7Qd.js → ActionButton-sk89dGuT.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-BgCMCOsk.js → Analytics-kd8hzeK3.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-Dv4oJcqS.js → AppLayout-CxlLp7J8.js} +5 -5
  6. package/src/assets/web-panel/assets/{Audit-5iV3yrGa.js → Audit-CQnGmRxA.js} +1 -1
  7. package/src/assets/web-panel/assets/{Backup-CHDhnbzF.js → Backup-BioBFWVV.js} +1 -1
  8. package/src/assets/web-panel/assets/{BaseInput-B6reFkra.js → BaseInput-DiYG1n7T.js} +1 -1
  9. package/src/assets/web-panel/assets/{Chat-DwS5YyE2.js → Chat-BBuQf6VM.js} +6 -6
  10. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CqXa87Hw.js → ChatBubbleRenderer-BwgFmlRu.js} +1 -1
  11. package/src/assets/web-panel/assets/{Checkbox-yiW0M4RE.js → Checkbox-B-9WwFTA.js} +1 -1
  12. package/src/assets/web-panel/assets/{Codegen-DoiVuD_g.js → Codegen-DCkpThQa.js} +1 -1
  13. package/src/assets/web-panel/assets/{Col-BVASLexk.js → Col-BowFdito.js} +1 -1
  14. package/src/assets/web-panel/assets/{Community-D6KQ7JoU.js → Community-BWGa92rE.js} +1 -1
  15. package/src/assets/web-panel/assets/{Compact-Bl9Uhb6v.js → Compact-CqJYYK0v.js} +1 -1
  16. package/src/assets/web-panel/assets/{Compliance-MM31-dba.js → Compliance-DiFqpJrM.js} +1 -1
  17. package/src/assets/web-panel/assets/{Cowork-PjU_1ieD.js → Cowork-qZNWcSQ9.js} +2 -2
  18. package/src/assets/web-panel/assets/{Cron-DorNtPZL.js → Cron-BK70XYci.js} +2 -2
  19. package/src/assets/web-panel/assets/{Crosschain-Bm5ts2Kw.js → Crosschain-DoM9N2kO.js} +1 -1
  20. package/src/assets/web-panel/assets/{DID-7Y3jlFdY.js → DID-B1F1RhQr.js} +2 -2
  21. package/src/assets/web-panel/assets/{Dashboard-1oE532bG.js → Dashboard-CmDxx07G.js} +2 -2
  22. package/src/assets/web-panel/assets/{Dropdown-hJlOPs0s.js → Dropdown-5GRByJY9.js} +1 -1
  23. package/src/assets/web-panel/assets/{EmailListRenderer-BEqJxKaO.js → EmailListRenderer-CyNgNjLG.js} +1 -1
  24. package/src/assets/web-panel/assets/{FamilyGuardDashboard-BvCGwB6X.js → FamilyGuardDashboard-Jwg-Wuye.js} +1 -1
  25. package/src/assets/web-panel/assets/{Federation-CsXI72e5.js → Federation-BQvoY2_5.js} +1 -1
  26. package/src/assets/web-panel/assets/{FormItemContext-Dh9SMul-.js → FormItemContext-DKy8Zatd.js} +1 -1
  27. package/src/assets/web-panel/assets/{GenericCardRenderer-9edWzrtG.js → GenericCardRenderer-n7VGwZNh.js} +1 -1
  28. package/src/assets/web-panel/assets/{Git-ZYhNL8Xk.js → Git-CFCUe_so.js} +2 -2
  29. package/src/assets/web-panel/assets/{Governance-BwAdp8QA.js → Governance-DuZbRElA.js} +1 -1
  30. package/src/assets/web-panel/assets/{Inference-5C-M1XsH.js → Inference-DSEsBonV.js} +1 -1
  31. package/src/assets/web-panel/assets/{KnowledgeGraph-zFAi-zCi.js → KnowledgeGraph-DQoaeSnN.js} +1 -1
  32. package/src/assets/web-panel/assets/{Logs-BZsEdbgE.js → Logs-u7UMHPnz.js} +2 -2
  33. package/src/assets/web-panel/assets/{Marketplace-BP6gErRK.js → Marketplace--gDqWnX8.js} +1 -1
  34. package/src/assets/web-panel/assets/{McpTools-CXVzoLrd.js → McpTools-btiDEQ_G.js} +5 -5
  35. package/src/assets/web-panel/assets/{Memory-BIpChb4-.js → Memory-CYrqC903.js} +2 -2
  36. package/src/assets/web-panel/assets/{MobileBridge-B4O7wDT8.js → MobileBridge-CktV5fRJ.js} +2 -2
  37. package/src/assets/web-panel/assets/MobileProjects-CTVZQD7g.js +1 -0
  38. package/src/assets/web-panel/assets/{Mtc-BTmEyTM5.js → Mtc-CRq5Ir7q.js} +6 -6
  39. package/src/assets/web-panel/assets/{MtcAudit-CsbG9LlV.js → MtcAudit-HvY-N0XZ.js} +2 -2
  40. package/src/assets/web-panel/assets/{Multisig-CL8yoGon.js → Multisig-CWmUSW7g.js} +3 -3
  41. package/src/assets/web-panel/assets/{NLProgramming-C2cIlIp_.js → NLProgramming-BUwhn6xG.js} +1 -1
  42. package/src/assets/web-panel/assets/{Notes-7aBk_n_M.js → Notes-BI8NqNSW.js} +4 -4
  43. package/src/assets/web-panel/assets/{NotificationSettings-BuhQk4rJ.js → NotificationSettings-DVa8gbo1.js} +1 -1
  44. package/src/assets/web-panel/assets/{OrderTableRenderer-mqMFZu0x.js → OrderTableRenderer-XNEr64wi.js} +1 -1
  45. package/src/assets/web-panel/assets/{Organization-CAdq-170.js → Organization-a0imltNQ.js} +4 -4
  46. package/src/assets/web-panel/assets/{Overflow--Xn0E787.js → Overflow-DJ2P1mNg.js} +1 -1
  47. package/src/assets/web-panel/assets/{P2P-DYt3YAXI.js → P2P-pRJPEJ7a.js} +2 -2
  48. package/src/assets/web-panel/assets/{PdhVaultBrowser-Bgb_v8WN.js → PdhVaultBrowser-eJa8vkF5.js} +5 -5
  49. package/src/assets/web-panel/assets/{Permissions-DoFlmoaW.js → Permissions-fxa21qzR.js} +4 -4
  50. package/src/assets/web-panel/assets/{PersonalDataHub-C-FJB3a0.js → PersonalDataHub-C3JggyPn.js} +2 -2
  51. package/src/assets/web-panel/assets/{Pipeline-3bL2RzzL.js → Pipeline-iR9fwke0.js} +1 -1
  52. package/src/assets/web-panel/assets/{Privacy-c4igYUCF.js → Privacy-oBf4gwv0.js} +1 -1
  53. package/src/assets/web-panel/assets/{ProjectInit-C0QS1UPR.js → ProjectInit-DZU2PVgs.js} +2 -2
  54. package/src/assets/web-panel/assets/{ProjectSettings-CkYC0xkE.js → ProjectSettings-amcXcSet.js} +2 -2
  55. package/src/assets/web-panel/assets/{Projects-Di17SYft.js → Projects-QoksY3-i.js} +1 -1
  56. package/src/assets/web-panel/assets/{Providers-41NySsLt.js → Providers-uquz_5KZ.js} +1 -1
  57. package/src/assets/web-panel/assets/{QuickAsk-DHq9pD7z.js → QuickAsk-Wxx-iIH9.js} +1 -1
  58. package/src/assets/web-panel/assets/{Recommend-CLjgFPLv.js → Recommend-CD8OJGJF.js} +1 -1
  59. package/src/assets/web-panel/assets/{Reputation-EIrgErm3.js → Reputation-BuJMHfco.js} +1 -1
  60. package/src/assets/web-panel/assets/{Row-GAvKzKH7.js → Row-DvfqASM7.js} +1 -1
  61. package/src/assets/web-panel/assets/{RssFeed-CYCNsVmD.js → RssFeed-TGSmYgmV.js} +3 -3
  62. package/src/assets/web-panel/assets/{Search-DWOE32k8.js → Search-ndSDi33l.js} +1 -1
  63. package/src/assets/web-panel/assets/{Security-Dgh8Jevn.js → Security-CL1FLyzy.js} +4 -4
  64. package/src/assets/web-panel/assets/{Services-BxdgP67N.js → Services--AeNKFrY.js} +2 -2
  65. package/src/assets/web-panel/assets/{Skeleton-D-xT4ZkA.js → Skeleton-CMllAeqY.js} +1 -1
  66. package/src/assets/web-panel/assets/{Skills-BKN4lfSa.js → Skills-DD29bVTm.js} +1 -1
  67. package/src/assets/web-panel/assets/{Sla--N1TudpS.js → Sla-DU_Mdrad.js} +1 -1
  68. package/src/assets/web-panel/assets/{SpeechSettings-B0vfJpEh.js → SpeechSettings-Cu0ncgI_.js} +1 -1
  69. package/src/assets/web-panel/assets/{SyncSettings-BuBAbPAh.js → SyncSettings-Bfk00Eb9.js} +2 -2
  70. package/src/assets/web-panel/assets/Tasks-C-2V1COO.js +1 -0
  71. package/src/assets/web-panel/assets/{Templates-DI2giLgc.js → Templates-CWO4Aw1l.js} +1 -1
  72. package/src/assets/web-panel/assets/{Tenant-BiTWvm0g.js → Tenant-BnDkNC6u.js} +1 -1
  73. package/src/assets/web-panel/assets/Terminal-VR0JLDdw.js +3 -0
  74. package/src/assets/web-panel/assets/{TimelineRenderer-BmgzKdAp.js → TimelineRenderer-DMjbfev0.js} +1 -1
  75. package/src/assets/web-panel/assets/{Tokens-Nvupdm6p.js → Tokens-j1ZGEgBP.js} +1 -1
  76. package/src/assets/web-panel/assets/{Trigger-DRfR77WJ.js → Trigger-BKVNLlOB.js} +1 -1
  77. package/src/assets/web-panel/assets/{Trust-De0Jal_6.js → Trust-Bbfv8AJr.js} +1 -1
  78. package/src/assets/web-panel/assets/{UkeySign-Dzo4-VAM.js → UkeySign-C0_Gllsu.js} +1 -1
  79. package/src/assets/web-panel/assets/{VideoEditing-hg2ytiJB.js → VideoEditing-CE__3Owf.js} +1 -1
  80. package/src/assets/web-panel/assets/{Wallet--bU5-gRh.js → Wallet-Cjzavume.js} +4 -4
  81. package/src/assets/web-panel/assets/{WebAuthn-DZptt-PV.js → WebAuthn-KbjxueWc.js} +4 -4
  82. package/src/assets/web-panel/assets/{WorkflowEditor-Dy9223bY.js → WorkflowEditor-Bz7UuLhK.js} +1 -1
  83. package/src/assets/web-panel/assets/{chat-DaxGeI9w.js → chat-BrSAQ_Gd.js} +1 -1
  84. package/src/assets/web-panel/assets/{colors-Cu2VEci3.js → colors-Bn8oqI93.js} +1 -1
  85. package/src/assets/web-panel/assets/{compact-item-CGolhyJq.js → compact-item-jxrLqj8Q.js} +1 -1
  86. package/src/assets/web-panel/assets/{createContext-DY7EFhkD.js → createContext-B0uxIvgB.js} +1 -1
  87. package/src/assets/web-panel/assets/devWarning-rqonNzey.js +1 -0
  88. package/src/assets/web-panel/assets/{hasIn-Bpc-NoFN.js → hasIn-BFsfry47.js} +1 -1
  89. package/src/assets/web-panel/assets/{index-BQ2z6Ky5.js → index-9iuxVwRC.js} +1 -1
  90. package/src/assets/web-panel/assets/{index-eF9RV_4c.js → index-B9ZDJUc0.js} +1 -1
  91. package/src/assets/web-panel/assets/index-BI1fCgPX.js +1 -0
  92. package/src/assets/web-panel/assets/{index-VBRPxZeE.js → index-BPpGWBAU.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-BlHq81Ow.js → index-BQZsB8nt.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-BjfxHEmX.js → index-BQvlv_iE.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-8h9y5S6X.js → index-BRkK0yoO.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-lfP8sdzB.js → index-BY4oOQaA.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-Bz83ngs0.js → index-Bd-zsWvY.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-BP9P6chP.js → index-BiXyJmcf.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-D63ObMdQ.js → index-Bk_Tv7Ey.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-D0GN5tdM.js → index-BzZfG8Ft.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DNX81oSR.js → index-C6AmzUjG.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-BTvwiqJE.js → index-C7q_gApa.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-C2RpsAiO.js → index-CAIdm73g.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-Bn5gM9Oy.js → index-CCVF9irI.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DexYD87j.js → index-CR3QNisI.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DfKmAEtE.js → index-CZ8gyTGc.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BRAgl2J_.js → index-CireH7ze.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DpRSzAFl.js → index-CovEs7is.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-C-Hkl_2G.js → index-Crqzhccj.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-DldaToUA.js → index-D08W2YxD.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DAov-rJR.js → index-D1WrY_4z.js} +1 -1
  112. package/src/assets/web-panel/assets/index-D8iCZ8gl.js +1 -0
  113. package/src/assets/web-panel/assets/{index-oJQgRCrR.js → index-DMPQqeLb.js} +3 -3
  114. package/src/assets/web-panel/assets/{index-Ciw5-X1B.js → index-DOJYoYG7.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CJFYF8F9.js → index-DSDgBgrL.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-1D4sfByw.js → index-DcHQBw3b.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-CLNqZF55.js → index-DdjhDnIk.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CGqeHu_F.js → index-DeHd8uSh.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DZ4Vm8dQ.js → index-DjxJSCB8.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CFAnEzRW.js → index-DmD-qtjF.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-C0_zeYnx.js → index-DteDdzDQ.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CBSk_VrT.js → index-E6sYKDbw.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CaKXhpEu.js → index-LLFwwG0R.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DxXkr-NS.js → index-_fgTMPd1.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-RumxOD0S.js → index-pMVcl-a3.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-rkm7dHwG.js → index-vma7bVdQ.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-DElatOQ0.js → index-xRD9Fctn.js} +1 -1
  128. package/src/assets/web-panel/assets/{initDefaultProps-CkJZfCo8.js → initDefaultProps-AKS5cCeZ.js} +1 -1
  129. package/src/assets/web-panel/assets/{motion-BerbusV1.js → motion-SDjWiFhF.js} +1 -1
  130. package/src/assets/web-panel/assets/{move-DyRzKPD4.js → move-LEZnOtYR.js} +1 -1
  131. package/src/assets/web-panel/assets/{omit-CCdrTUAs.js → omit-DhLBVNzX.js} +1 -1
  132. package/src/assets/web-panel/assets/{pickAttrs-mVDeZx2m.js → pickAttrs-DdVSELea.js} +1 -1
  133. package/src/assets/web-panel/assets/{placementArrow-Bb_-Fs_o.js → placementArrow-BaEGCCq9.js} +1 -1
  134. package/src/assets/web-panel/assets/{responsiveObserve-C6TMj1R_.js → responsiveObserve-DV6XM19W.js} +1 -1
  135. package/src/assets/web-panel/assets/{slide-CdCNsy1J.js → slide-BOUnaBay.js} +1 -1
  136. package/src/assets/web-panel/assets/{statusUtils-Ccxd1rFd.js → statusUtils-BAaMQ0VA.js} +1 -1
  137. package/src/assets/web-panel/assets/{styleChecker-3IL-yw1V.js → styleChecker-CsoP0nmm.js} +1 -1
  138. package/src/assets/web-panel/assets/{useFlexGapSupport-CH8DjUHl.js → useFlexGapSupport-t20RbINy.js} +1 -1
  139. package/src/assets/web-panel/assets/{useFs-Cn9nE2sp.js → useFs-DH_Emn7A.js} +1 -1
  140. package/src/assets/web-panel/assets/{usePersonalDataHub-BPyT0HO7.js → usePersonalDataHub-CeYW427U.js} +1 -1
  141. package/src/assets/web-panel/assets/{vnode-Mfm7vy07.js → vnode-CX5gGmGb.js} +1 -1
  142. package/src/assets/web-panel/assets/{zoom-CTpAiAE9.js → zoom-CofyY9oD.js} +1 -1
  143. package/src/assets/web-panel/index.html +1 -1
  144. package/src/commands/agent.js +38 -4
  145. package/src/commands/init.js +31 -0
  146. package/src/commands/mcp.js +57 -0
  147. package/src/commands/memory.js +62 -0
  148. package/src/commands/session.js +70 -0
  149. package/src/lib/agent-core.js +1 -0
  150. package/src/lib/init-ai-refine.js +66 -0
  151. package/src/lib/json-schema-output.js +181 -0
  152. package/src/lib/mcp-serve.js +259 -0
  153. package/src/lib/project-instructions.js +89 -0
  154. package/src/lib/repl-completer.js +9 -3
  155. package/src/lib/repl-rewind.js +107 -0
  156. package/src/repl/agent-repl.js +145 -1
  157. package/src/runtime/headless-stream.js +60 -0
  158. package/src/assets/web-panel/assets/MobileProjects-7VPMoHus.js +0 -1
  159. package/src/assets/web-panel/assets/Tasks-4XugjJ87.js +0 -1
  160. package/src/assets/web-panel/assets/Terminal-vV6AWGDi.js +0 -3
  161. package/src/assets/web-panel/assets/devWarning-DV2BNd59.js +0 -1
  162. package/src/assets/web-panel/assets/index-BZqtTmyG.js +0 -1
  163. package/src/assets/web-panel/assets/index-DUpwdJt9.js +0 -1
@@ -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
- rl.on("line", async (input) => {
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};