chainlesschain 0.162.42 → 0.162.44

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 (150) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/assets/{AIOps-Dsw5p7A7.js → AIOps-DKzTpK-Y.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-sk89dGuT.js → ActionButton-CMAlqdwe.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-kd8hzeK3.js → Analytics-QMe2cbkc.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-CxlLp7J8.js → AppLayout-DWSbQ4Li.js} +5 -5
  6. package/src/assets/web-panel/assets/{Audit-CQnGmRxA.js → Audit-B2m5_PZ1.js} +1 -1
  7. package/src/assets/web-panel/assets/{Backup-BioBFWVV.js → Backup-CfTZgrj4.js} +1 -1
  8. package/src/assets/web-panel/assets/{BaseInput-DiYG1n7T.js → BaseInput-DQMQQpXM.js} +1 -1
  9. package/src/assets/web-panel/assets/{Chat-BBuQf6VM.js → Chat-XSNjF8Mp.js} +6 -6
  10. package/src/assets/web-panel/assets/{ChatBubbleRenderer-BwgFmlRu.js → ChatBubbleRenderer-BjWwWSBW.js} +1 -1
  11. package/src/assets/web-panel/assets/{Checkbox-B-9WwFTA.js → Checkbox-DcHFXGYe.js} +1 -1
  12. package/src/assets/web-panel/assets/{Codegen-DCkpThQa.js → Codegen-CbGi3e7e.js} +1 -1
  13. package/src/assets/web-panel/assets/{Col-BowFdito.js → Col-uRz8SHXE.js} +1 -1
  14. package/src/assets/web-panel/assets/{Community-BWGa92rE.js → Community-CneB2EQd.js} +1 -1
  15. package/src/assets/web-panel/assets/{Compact-CqJYYK0v.js → Compact-C9t4kI4u.js} +1 -1
  16. package/src/assets/web-panel/assets/{Compliance-DiFqpJrM.js → Compliance-BSgNNAgN.js} +1 -1
  17. package/src/assets/web-panel/assets/{Cowork-qZNWcSQ9.js → Cowork-BOJD_XKQ.js} +4 -4
  18. package/src/assets/web-panel/assets/{Cron-BK70XYci.js → Cron-DBZVqJWg.js} +2 -2
  19. package/src/assets/web-panel/assets/{Crosschain-DoM9N2kO.js → Crosschain-BPBndx_n.js} +1 -1
  20. package/src/assets/web-panel/assets/{DID-B1F1RhQr.js → DID-BFeOnAbj.js} +2 -2
  21. package/src/assets/web-panel/assets/{Dashboard-CmDxx07G.js → Dashboard-DR_krdui.js} +2 -2
  22. package/src/assets/web-panel/assets/{Dropdown-5GRByJY9.js → Dropdown-DBFIX9zX.js} +1 -1
  23. package/src/assets/web-panel/assets/{EmailListRenderer-CyNgNjLG.js → EmailListRenderer-j7nUo0EN.js} +1 -1
  24. package/src/assets/web-panel/assets/{FamilyGuardDashboard-Jwg-Wuye.js → FamilyGuardDashboard-BNrIZkRp.js} +1 -1
  25. package/src/assets/web-panel/assets/{Federation-BQvoY2_5.js → Federation-D1cPCDKh.js} +1 -1
  26. package/src/assets/web-panel/assets/{FormItemContext-DKy8Zatd.js → FormItemContext-C24JXiJZ.js} +1 -1
  27. package/src/assets/web-panel/assets/{GenericCardRenderer-n7VGwZNh.js → GenericCardRenderer-g-EsfuMZ.js} +1 -1
  28. package/src/assets/web-panel/assets/{Git-CFCUe_so.js → Git-BVEJZ29p.js} +2 -2
  29. package/src/assets/web-panel/assets/{Governance-DuZbRElA.js → Governance-B-fAe2v1.js} +1 -1
  30. package/src/assets/web-panel/assets/{Inference-DSEsBonV.js → Inference-DBYa0ztr.js} +1 -1
  31. package/src/assets/web-panel/assets/{KnowledgeGraph-DQoaeSnN.js → KnowledgeGraph-B0S0at2T.js} +1 -1
  32. package/src/assets/web-panel/assets/{Logs-u7UMHPnz.js → Logs-BUHn58RG.js} +2 -2
  33. package/src/assets/web-panel/assets/{Marketplace--gDqWnX8.js → Marketplace-DSYpWtgR.js} +1 -1
  34. package/src/assets/web-panel/assets/{McpTools-btiDEQ_G.js → McpTools-Cm_GD-uS.js} +5 -5
  35. package/src/assets/web-panel/assets/{Memory-CYrqC903.js → Memory-CB9uRtzi.js} +2 -2
  36. package/src/assets/web-panel/assets/{MobileBridge-CktV5fRJ.js → MobileBridge-vgX_FQ74.js} +2 -2
  37. package/src/assets/web-panel/assets/{MobileProjects-CTVZQD7g.js → MobileProjects-DCMhJceG.js} +1 -1
  38. package/src/assets/web-panel/assets/{Mtc-CRq5Ir7q.js → Mtc-Atr0Zh0n.js} +2 -2
  39. package/src/assets/web-panel/assets/{MtcAudit-HvY-N0XZ.js → MtcAudit-DxQjtoAG.js} +2 -2
  40. package/src/assets/web-panel/assets/{Multisig-CWmUSW7g.js → Multisig-DBc1IRY-.js} +3 -3
  41. package/src/assets/web-panel/assets/{NLProgramming-BUwhn6xG.js → NLProgramming-C55Qg6EX.js} +1 -1
  42. package/src/assets/web-panel/assets/{Notes-BI8NqNSW.js → Notes-CVRXn9dM.js} +3 -3
  43. package/src/assets/web-panel/assets/{NotificationSettings-DVa8gbo1.js → NotificationSettings-B8_Y2rYz.js} +1 -1
  44. package/src/assets/web-panel/assets/{OrderTableRenderer-XNEr64wi.js → OrderTableRenderer-BvbjrcIW.js} +1 -1
  45. package/src/assets/web-panel/assets/{Organization-a0imltNQ.js → Organization-fmONrEpS.js} +4 -4
  46. package/src/assets/web-panel/assets/{Overflow-DJ2P1mNg.js → Overflow-DtS9U-lj.js} +1 -1
  47. package/src/assets/web-panel/assets/{P2P-pRJPEJ7a.js → P2P-BCp9IFsu.js} +2 -2
  48. package/src/assets/web-panel/assets/{PdhVaultBrowser-eJa8vkF5.js → PdhVaultBrowser-FB03lQ_0.js} +5 -5
  49. package/src/assets/web-panel/assets/{Permissions-fxa21qzR.js → Permissions-BD3VCCBY.js} +4 -4
  50. package/src/assets/web-panel/assets/{PersonalDataHub-C3JggyPn.js → PersonalDataHub-I_dIzQfI.js} +2 -2
  51. package/src/assets/web-panel/assets/{Pipeline-iR9fwke0.js → Pipeline-BfqiuVgI.js} +1 -1
  52. package/src/assets/web-panel/assets/{Privacy-oBf4gwv0.js → Privacy-Dnm-Lxv0.js} +1 -1
  53. package/src/assets/web-panel/assets/{ProjectInit-DZU2PVgs.js → ProjectInit-D12saZXQ.js} +2 -2
  54. package/src/assets/web-panel/assets/{ProjectSettings-amcXcSet.js → ProjectSettings-BHk78dtG.js} +2 -2
  55. package/src/assets/web-panel/assets/{Projects-QoksY3-i.js → Projects-BQgMcz56.js} +1 -1
  56. package/src/assets/web-panel/assets/{Providers-uquz_5KZ.js → Providers-Bs7dxjKE.js} +1 -1
  57. package/src/assets/web-panel/assets/{QuickAsk-Wxx-iIH9.js → QuickAsk-CqhoJCPD.js} +1 -1
  58. package/src/assets/web-panel/assets/{Recommend-CD8OJGJF.js → Recommend-D-l-eJFr.js} +1 -1
  59. package/src/assets/web-panel/assets/{Reputation-BuJMHfco.js → Reputation-CPrlP2Ux.js} +1 -1
  60. package/src/assets/web-panel/assets/{Row-DvfqASM7.js → Row-C3Q9Dshq.js} +1 -1
  61. package/src/assets/web-panel/assets/{RssFeed-TGSmYgmV.js → RssFeed-DlLlpbtD.js} +3 -3
  62. package/src/assets/web-panel/assets/{Search-ndSDi33l.js → Search-EIs5mUs2.js} +1 -1
  63. package/src/assets/web-panel/assets/{Security-CL1FLyzy.js → Security-NJbvreOk.js} +3 -3
  64. package/src/assets/web-panel/assets/{Services--AeNKFrY.js → Services-B-GS4dFT.js} +2 -2
  65. package/src/assets/web-panel/assets/{Skeleton-CMllAeqY.js → Skeleton-Bycye0oO.js} +1 -1
  66. package/src/assets/web-panel/assets/{Skills-DD29bVTm.js → Skills-D9gOTB8D.js} +1 -1
  67. package/src/assets/web-panel/assets/{Sla-DU_Mdrad.js → Sla-hR2sLl6u.js} +1 -1
  68. package/src/assets/web-panel/assets/{SpeechSettings-Cu0ncgI_.js → SpeechSettings-xNkqwlx_.js} +1 -1
  69. package/src/assets/web-panel/assets/{SyncSettings-Bfk00Eb9.js → SyncSettings-C53VuHwk.js} +2 -2
  70. package/src/assets/web-panel/assets/{Tasks-C-2V1COO.js → Tasks-XIDFrKjD.js} +1 -1
  71. package/src/assets/web-panel/assets/{Templates-CWO4Aw1l.js → Templates-JA8aUZm3.js} +1 -1
  72. package/src/assets/web-panel/assets/{Tenant-BnDkNC6u.js → Tenant-DjGO2SFi.js} +1 -1
  73. package/src/assets/web-panel/assets/Terminal-D_8L6tYA.js +3 -0
  74. package/src/assets/web-panel/assets/{TimelineRenderer-DMjbfev0.js → TimelineRenderer-Cfalxtc_.js} +1 -1
  75. package/src/assets/web-panel/assets/{Tokens-j1ZGEgBP.js → Tokens-lvG8zW-n.js} +1 -1
  76. package/src/assets/web-panel/assets/{Trigger-BKVNLlOB.js → Trigger-G3EmMFkS.js} +1 -1
  77. package/src/assets/web-panel/assets/{Trust-Bbfv8AJr.js → Trust-BDXSbpLN.js} +1 -1
  78. package/src/assets/web-panel/assets/{UkeySign-C0_Gllsu.js → UkeySign-9GtCtwS7.js} +1 -1
  79. package/src/assets/web-panel/assets/{VideoEditing-CE__3Owf.js → VideoEditing-DorUOflW.js} +1 -1
  80. package/src/assets/web-panel/assets/{Wallet-Cjzavume.js → Wallet-B1PSsoH7.js} +4 -4
  81. package/src/assets/web-panel/assets/{WebAuthn-KbjxueWc.js → WebAuthn-BlawNPwk.js} +4 -4
  82. package/src/assets/web-panel/assets/{WorkflowEditor-Bz7UuLhK.js → WorkflowEditor-DT5tXYHC.js} +1 -1
  83. package/src/assets/web-panel/assets/{chat-BrSAQ_Gd.js → chat-Db1ggy-d.js} +1 -1
  84. package/src/assets/web-panel/assets/{colors-Bn8oqI93.js → colors-DvKRY65P.js} +1 -1
  85. package/src/assets/web-panel/assets/{compact-item-jxrLqj8Q.js → compact-item-ChJE-s12.js} +1 -1
  86. package/src/assets/web-panel/assets/{createContext-B0uxIvgB.js → createContext-C_n8N7R0.js} +1 -1
  87. package/src/assets/web-panel/assets/devWarning-8RHlZueh.js +1 -0
  88. package/src/assets/web-panel/assets/{hasIn-BFsfry47.js → hasIn-f5qrOyO8.js} +1 -1
  89. package/src/assets/web-panel/assets/{index-BRkK0yoO.js → index-6-pawsDV.js} +1 -1
  90. package/src/assets/web-panel/assets/{index-E6sYKDbw.js → index-B889nFIK.js} +1 -1
  91. package/src/assets/web-panel/assets/{index-CAIdm73g.js → index-BGcNc2FC.js} +1 -1
  92. package/src/assets/web-panel/assets/{index-CovEs7is.js → index-BLbUSjRl.js} +1 -1
  93. package/src/assets/web-panel/assets/{index-DSDgBgrL.js → index-BRPjpA9x.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-D08W2YxD.js → index-B_Db3y-q.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-_fgTMPd1.js → index-BlXvSz68.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-C6AmzUjG.js → index-BmDr3_dh.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-9iuxVwRC.js → index-Bv3rnRcv.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DcHQBw3b.js → index-BzfpAd-L.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-BiXyJmcf.js → index-C99Tx6W3.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DeHd8uSh.js → index-CBtvIJ1P.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-LLFwwG0R.js → index-CRpYACac.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-BY4oOQaA.js → index-CZM-f_GP.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-D1WrY_4z.js → index-CgVhpbwl.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-Bd-zsWvY.js → index-CkSc1UD0.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-CZ8gyTGc.js → index-CnBPm5VW.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-xRD9Fctn.js → index-Cwx25An4.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-Crqzhccj.js → index-D2vRDPxa.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BPpGWBAU.js → index-DBDuh9Q_.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-DjxJSCB8.js → index-DDwTm4HW.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-pMVcl-a3.js → index-DLJldKpu.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-CireH7ze.js → index-DNcqoZEW.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-BzZfG8Ft.js → index-DSn8UWj1.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-DmD-qtjF.js → index-DVWPEAS_.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-DdjhDnIk.js → index-D_ca6G9G.js} +1 -1
  115. package/src/assets/web-panel/assets/index-DiVQYFZe.js +1 -0
  116. package/src/assets/web-panel/assets/{index-BQZsB8nt.js → index-LADrnz2q.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-Bk_Tv7Ey.js → index-MW_Zh_HW.js} +1 -1
  118. package/src/assets/web-panel/assets/index-QQHpE5N6.js +1 -0
  119. package/src/assets/web-panel/assets/{index-CCVF9irI.js → index-ZIg1Yi8T.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-DOJYoYG7.js → index-aRdl6HAc.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DMPQqeLb.js → index-bYgSwFp_.js} +3 -3
  122. package/src/assets/web-panel/assets/{index-CR3QNisI.js → index-cNZUziLU.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-BQvlv_iE.js → index-dbd8KVOi.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-B9ZDJUc0.js → index-gEBZrC4a.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DteDdzDQ.js → index-ru1UNElJ.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-vma7bVdQ.js → index-xytEYrmf.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-C7q_gApa.js → index-zDFZeRny.js} +1 -1
  128. package/src/assets/web-panel/assets/{initDefaultProps-AKS5cCeZ.js → initDefaultProps-BmuULb3C.js} +1 -1
  129. package/src/assets/web-panel/assets/{motion-SDjWiFhF.js → motion-BPAdGPV0.js} +1 -1
  130. package/src/assets/web-panel/assets/{move-LEZnOtYR.js → move-CfQuWRIA.js} +1 -1
  131. package/src/assets/web-panel/assets/{omit-DhLBVNzX.js → omit-B4X1FaKf.js} +1 -1
  132. package/src/assets/web-panel/assets/{pickAttrs-DdVSELea.js → pickAttrs-CnNXE2Fs.js} +1 -1
  133. package/src/assets/web-panel/assets/{placementArrow-BaEGCCq9.js → placementArrow-Bb5asP1f.js} +1 -1
  134. package/src/assets/web-panel/assets/{responsiveObserve-DV6XM19W.js → responsiveObserve-CFYMBsLT.js} +1 -1
  135. package/src/assets/web-panel/assets/{slide-BOUnaBay.js → slide-Pf9K-RqE.js} +1 -1
  136. package/src/assets/web-panel/assets/{statusUtils-BAaMQ0VA.js → statusUtils-DmGXqpMA.js} +1 -1
  137. package/src/assets/web-panel/assets/{styleChecker-CsoP0nmm.js → styleChecker-3ymOCpPp.js} +1 -1
  138. package/src/assets/web-panel/assets/{useFlexGapSupport-t20RbINy.js → useFlexGapSupport-CiCbo3Hx.js} +1 -1
  139. package/src/assets/web-panel/assets/{useFs-DH_Emn7A.js → useFs-BbhWqkvH.js} +1 -1
  140. package/src/assets/web-panel/assets/{usePersonalDataHub-CeYW427U.js → usePersonalDataHub-BNjAwFwx.js} +1 -1
  141. package/src/assets/web-panel/assets/{vnode-CX5gGmGb.js → vnode-Dsmjnl6v.js} +1 -1
  142. package/src/assets/web-panel/assets/{zoom-CofyY9oD.js → zoom-Dx0p7V8W.js} +1 -1
  143. package/src/assets/web-panel/index.html +1 -1
  144. package/src/commands/agent.js +66 -51
  145. package/src/lib/llm-config-defaults.js +31 -0
  146. package/src/runtime/headless-stream.js +183 -4
  147. package/src/assets/web-panel/assets/Terminal-VR0JLDdw.js +0 -3
  148. package/src/assets/web-panel/assets/devWarning-rqonNzey.js +0 -1
  149. package/src/assets/web-panel/assets/index-BI1fCgPX.js +0 -1
  150. package/src/assets/web-panel/assets/index-D8iCZ8gl.js +0 -1
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Config-default LLM resolution for `cc agent` (parity with `cc ask`/`chat`):
3
+ * a bare run honors `~/.chainlesschain/config.json` `llm` —
4
+ * provider/model/baseUrl/apiKey — instead of silently assuming local ollama
5
+ * (the historical default that broke every cloud-configured setup the moment
6
+ * no --provider flag was passed, e.g. the editor chat panel's spawn).
7
+ *
8
+ * Rules (pure; mutates and returns `options` for call-site convenience):
9
+ * - An explicit --provider wins outright: config is NOT consulted at all
10
+ * (mixing config's model/key into a different provider would be wrong).
11
+ * - With no --provider but a configured one: provider + any of
12
+ * model/baseUrl/apiKey the user did not explicitly set come from config.
13
+ * - Model pairing: when the provider is adopted from config, the model must
14
+ * pair with it — only an EXPLICIT --model (opts.explicitModel) survives;
15
+ * a model that leaked in from .claude/settings.json (meant for whatever
16
+ * provider that file assumed) is replaced by config's own model. Same
17
+ * lesson as the --settings "opus"→404 vision trap.
18
+ * - No configured provider → unchanged (runner defaults apply: ollama).
19
+ */
20
+ export function applyConfigLlmDefaults(options = {}, cfgLlm = {}, opts = {}) {
21
+ if (options.provider || !cfgLlm.provider) return options;
22
+ options.provider = cfgLlm.provider;
23
+ if (opts.explicitModel) {
24
+ options.model = opts.explicitModel;
25
+ } else if (cfgLlm.model) {
26
+ options.model = cfgLlm.model;
27
+ }
28
+ if (!options.baseUrl && cfgLlm.baseUrl) options.baseUrl = cfgLlm.baseUrl;
29
+ if (!options.apiKey && cfgLlm.apiKey) options.apiKey = cfgLlm.apiKey;
30
+ return options;
31
+ }
@@ -37,6 +37,33 @@ import {
37
37
  rebuildMessages as jsonlRebuildMessages,
38
38
  sessionExists as jsonlSessionExists,
39
39
  } from "../harness/jsonl-session-store.js";
40
+ import { getPlanModeManager } from "../lib/plan-mode.js";
41
+
42
+ /**
43
+ * Structured view of the global plan-mode state for `plan_update` events
44
+ * (the chat panel renders its plan card from this). Pure read; never throws.
45
+ */
46
+ export function planSnapshot(pm) {
47
+ let items = [];
48
+ let risk = null;
49
+ try {
50
+ const plan = pm.currentPlan;
51
+ items = (plan?.items || []).map((i) => ({
52
+ id: i.id,
53
+ title: i.title,
54
+ tool: i.tool,
55
+ impact: i.estimatedImpact || "low",
56
+ status: i.status,
57
+ }));
58
+ if (items.length > 0) {
59
+ const r = pm.getRiskAssessment();
60
+ if (r) risk = { level: r.level, totalScore: r.totalScore };
61
+ }
62
+ } catch {
63
+ /* snapshot is best-effort */
64
+ }
65
+ return { active: pm.isActive(), state: pm.state || null, items, risk };
66
+ }
40
67
  import { withQuietStdout } from "./quiet-stdout.js";
41
68
 
42
69
  /**
@@ -51,6 +78,17 @@ export function parseInputEvent(line) {
51
78
  } catch {
52
79
  return { error: `invalid JSON line: ${trimmed.slice(0, 80)}` };
53
80
  }
81
+ // Plan-mode control events (chat-panel plan UI):
82
+ // {"type":"plan","action":"enter"|"approve"|"reject"}
83
+ if (obj && typeof obj === "object" && obj.type === "plan") {
84
+ const action = String(obj.action || "").toLowerCase();
85
+ return action ? { plan: action } : null;
86
+ }
87
+ // Turn interrupt (panel Stop / Claude-Code Esc parity): aborts the
88
+ // in-flight turn without ending the conversation. {"type":"interrupt"}
89
+ if (obj && typeof obj === "object" && obj.type === "interrupt") {
90
+ return { interrupt: true };
91
+ }
54
92
  const msg = obj && typeof obj === "object" ? obj.message || obj : {};
55
93
  let content = msg.content ?? obj.text ?? obj.prompt;
56
94
  if (Array.isArray(content)) {
@@ -441,9 +479,48 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
441
479
  let turns = 0;
442
480
  let sawError = false;
443
481
 
444
- for await (const line of readJsonLines(input)) {
445
- const parsed = parseInputEvent(line);
446
- if (parsed == null) continue; // blank line
482
+ // ── Concurrent stdin pump (turn-interrupt support) ────────────────────────
483
+ // Input is consumed AS IT ARRIVES — not between turns — so an
484
+ // {"type":"interrupt"} can abort the IN-FLIGHT turn immediately (chat-panel
485
+ // Stop / Claude-Code Esc parity) instead of waiting in line behind it.
486
+ // Normal events queue for the serial turn loop below; interrupts act on the
487
+ // live per-turn AbortController and are never queued.
488
+ const queue = [];
489
+ let wakeQueue = null;
490
+ let inputDone = false;
491
+ let currentAbort = null;
492
+ (async () => {
493
+ try {
494
+ for await (const line of readJsonLines(input)) {
495
+ const parsed = parseInputEvent(line);
496
+ if (parsed == null) continue;
497
+ if (parsed.interrupt) {
498
+ currentAbort?.abort();
499
+ continue;
500
+ }
501
+ queue.push(parsed);
502
+ if (wakeQueue) wakeQueue();
503
+ }
504
+ } catch {
505
+ /* input stream error → treat as EOF */
506
+ }
507
+ inputDone = true;
508
+ if (wakeQueue) wakeQueue();
509
+ })();
510
+ const nextEvent = async () => {
511
+ for (;;) {
512
+ if (queue.length > 0) return queue.shift();
513
+ if (inputDone) return null;
514
+ await new Promise((r) => {
515
+ wakeQueue = r;
516
+ });
517
+ wakeQueue = null;
518
+ }
519
+ };
520
+
521
+ for (;;) {
522
+ const parsed = await nextEvent();
523
+ if (parsed == null) break; // stdin closed
447
524
  if (parsed.error) {
448
525
  emit({
449
526
  type: "result",
@@ -455,6 +532,69 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
455
532
  continue;
456
533
  }
457
534
 
535
+ // Plan-mode control events (chat-panel plan UI). Mirrors the REPL's
536
+ // /plan verbs: enter blocks write tools (blocked calls become plan items),
537
+ // approve unlocks them and IMMEDIATELY runs a continuation turn, reject
538
+ // exits plan mode. Every control answers with a `plan_update` event.
539
+ if (parsed.plan) {
540
+ const pm = getPlanModeManager();
541
+ if (parsed.plan === "enter") {
542
+ if (!pm.isActive()) {
543
+ pm.enterPlanMode({ title: "Agent Plan" });
544
+ messages.push({
545
+ role: "system",
546
+ content:
547
+ "[PLAN MODE ACTIVE] You are now in plan mode. You can read " +
548
+ "files, search, and analyze — but write/execute tools are " +
549
+ "blocked. Any blocked tool calls will be recorded as plan " +
550
+ "items. Analyze the task thoroughly, then the user will " +
551
+ "approve your plan.",
552
+ });
553
+ }
554
+ emit({
555
+ type: "plan_update",
556
+ ...planSnapshot(pm),
557
+ session_id: sessionId,
558
+ });
559
+ continue;
560
+ }
561
+ if (parsed.plan === "reject") {
562
+ if (pm.isActive()) pm.rejectPlan("User rejected");
563
+ emit({
564
+ type: "plan_update",
565
+ ...planSnapshot(pm),
566
+ session_id: sessionId,
567
+ });
568
+ continue;
569
+ }
570
+ if (parsed.plan === "approve") {
571
+ if (!pm.isActive() || !(pm.currentPlan?.items?.length > 0)) {
572
+ emit({
573
+ type: "plan_update",
574
+ ...planSnapshot(pm),
575
+ session_id: sessionId,
576
+ note: "nothing to approve",
577
+ });
578
+ continue;
579
+ }
580
+ pm.approvePlan();
581
+ messages.push({
582
+ role: "system",
583
+ content: `[PLAN APPROVED] The user has approved your plan with ${pm.currentPlan.items.length} items. You can now use all tools including write_file, edit_file, run_shell, and run_skill. Execute the plan items in order.`,
584
+ });
585
+ emit({
586
+ type: "plan_update",
587
+ ...planSnapshot(pm),
588
+ session_id: sessionId,
589
+ });
590
+ // Fall through into the normal turn machinery with a continuation
591
+ // prompt — the agent starts executing without an extra user message.
592
+ parsed.text = "Proceed with the approved plan.";
593
+ } else if (!parsed.text) {
594
+ continue; // unknown plan action — ignored
595
+ }
596
+ }
597
+
458
598
  // Per-turn iteration budget so one turn can't starve the rest.
459
599
  const budget = Number.isFinite(options.maxTurns)
460
600
  ? new IterationBudget({
@@ -521,14 +661,39 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
521
661
  }
522
662
  turns += 1;
523
663
 
664
+ // Per-turn abort scope: an {"type":"interrupt"} from the pump above
665
+ // aborts THIS turn (LLM fetch included — the signal reaches chatWithTools)
666
+ // while the conversation/process stays alive for the next message.
667
+ currentAbort = new AbortController();
668
+ const turnSignal = options.signal
669
+ ? AbortSignal.any([options.signal, currentAbort.signal])
670
+ : currentAbort.signal;
671
+
524
672
  let outcome;
525
673
  try {
526
674
  outcome = await runTurn(
527
675
  messages,
528
- { ...loopOptionsBase, iterationBudget: budget },
676
+ { ...loopOptionsBase, iterationBudget: budget, signal: turnSignal },
529
677
  { runLoop, emit },
530
678
  );
531
679
  } catch (err) {
680
+ currentAbort = null;
681
+ const isAbort =
682
+ err?.name === "AbortError" || /abort/i.test(err?.message || "");
683
+ if (isAbort && !options.signal?.aborted) {
684
+ // User-initiated turn interrupt — not an error; no assistant message
685
+ // is recorded (the dangling user turn is fine for the next exchange).
686
+ emit({
687
+ type: "result",
688
+ subtype: "interrupted",
689
+ is_error: false,
690
+ interrupted: true,
691
+ session_id: sessionId,
692
+ turn: turns,
693
+ });
694
+ continue;
695
+ }
696
+ if (isAbort) break; // outer options.signal — caller is shutting down
532
697
  emit({
533
698
  type: "result",
534
699
  subtype: "error",
@@ -539,6 +704,7 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
539
704
  sawError = true;
540
705
  continue;
541
706
  }
707
+ currentAbort = null;
542
708
 
543
709
  // Grow the conversation so the next turn has context.
544
710
  messages.push({ role: "assistant", content: outcome.finalText });
@@ -565,6 +731,19 @@ export async function runAgentHeadlessStream(options = {}, deps = {}) {
565
731
  turn: turns,
566
732
  usage: outcome.usage,
567
733
  });
734
+
735
+ // While planning, blocked tool calls grew the plan during this turn —
736
+ // push the fresh snapshot so the panel's plan card stays live.
737
+ {
738
+ const pm = getPlanModeManager();
739
+ if (pm.isActive()) {
740
+ emit({
741
+ type: "plan_update",
742
+ ...planSnapshot(pm),
743
+ session_id: sessionId,
744
+ });
745
+ }
746
+ }
568
747
  }
569
748
 
570
749
  // Tear down ad-hoc MCP servers (--mcp-config) when stdin closes.
@@ -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-DMPQqeLb.js";import{I as z,J as x,U as _,Q as D,S as K,K as T,V as R,c as A,F as Q,Z as Y,R as E,o as 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-BvqAck49.js";import{R as ye,b as pe,as as ge}from"./icons-DP3uiYxy.js";const k=new Map,C=new Map,F=new Set,I=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)),F.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)),I.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)}):(F.add(a),()=>F.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)}):(I.add(a),()=>I.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 N(){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 N(),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 Z={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:N,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(Z,"__isScriptSetup",{enumerable:!1,value:!0}),Z}},be={class:"terminal-page"},ke={class:"terminal-header"},Ce={class:"page-sub"},Ae={class:"terminal-body"},Ee={class:"session-tabs"},Oe=["onClick"],Te={class:"session-shell"},Re={class:"session-id"},Me={key:0,class:"session-empty"},ze={class:"xterm-host"},Le=["data-session-id"],Pe={key:0,class:"xterm-placeholder"},De={key:1,class:"terminal-footer"},qe={key:0,class:"footer-exit"};function Be(c,o,s,e,i,w){const u=z("a-tag"),d=z("a-select"),f=z("a-button"),n=z("a-space"),a=z("a-alert");return y(),x("div",be,[_("div",ke,[_("div",null,[o[3]||(o[3]=_("h2",{class:"page-title"},"远程终端",-1)),_("p",Ce,[o[2]||(o[2]=D(" 桌面端托管的 PTY 会话;Android 端可远程操控同一通道 ",-1)),e.warning?(y(),K(u,{key:0,color:"orange",style:{"margin-left":"8px"}},{default:T(()=>[D(E(e.warning),1)]),_:1})):R("v-if",!0)])]),A(n,null,{default:T(()=>[A(d,{value:e.newShell,"onUpdate:value":o[0]||(o[0]=r=>e.newShell=r),style:{width:"130px"},size:"small",options:e.shellOptions},null,8,["value"]),A(f,{type:"primary",size:"small",loading:e.creating,onClick:e.onCreate},{icon:T(()=>[A(e.PlusOutlined)]),default:T(()=>[o[4]||(o[4]=D(" 新会话 ",-1))]),_:1},8,["loading"]),A(f,{size:"small",loading:e.loadingList,onClick:e.refreshList},{icon:T(()=>[A(e.ReloadOutlined)]),default:T(()=>[o[5]||(o[5]=D(" 刷新 ",-1))]),_:1},8,["loading"])]),_:1})]),e.error?(y(),K(a,{key:0,message:e.error,type:"error","show-icon":"",closable:"",style:{"margin-bottom":"12px"},onClose:o[1]||(o[1]=r=>e.error="")},null,8,["message"])):R("v-if",!0),_("div",Ae,[_("div",Ee,[(y(!0),x(Q,null,Y(e.sessions,r=>(y(),x("div",{key:r.id,class:ve(["session-tab",{active:r.id===e.activeId,dead:!r.alive}]),onClick:h=>e.activate(r.id)},[_("span",Te,E(r.shell),1),_("span",Re,E(e.shortId(r.id)),1),A(e.CloseOutlined,{class:"session-close",onClick:we(h=>e.onClose(r.id),["stop"])},null,8,["onClick"])],10,Oe))),128)),e.sessions.length===0?(y(),x("div",Me,' 点击 "新会话" 创建第一个终端 ')):R("v-if",!0)]),_("div",ze,[(y(!0),x(Q,null,Y(e.sessions,r=>he((y(),x("div",{key:r.id,ref_for:!0,ref:"xtermContainers","data-session-id":r.id,class:"xterm-container"},null,8,Le)),[[_e,r.id===e.activeId]])),128)),e.sessions.length===0?(y(),x("div",Pe,[...o[6]||(o[6]=[_("span",null,"无活跃会话",-1)])])):R("v-if",!0)])]),e.active?(y(),x("div",De,[_("span",null,E(e.active.shell)+" · "+E(e.active.cwd||"(默认 cwd)")+" · seq "+E(e.active.lastSeq),1),e.active.alive?R("v-if",!0):(y(),x("span",qe,"已退出 (code="+E(e.active.exitCode??"-")+")",1))])):R("v-if",!0)])}const Ie=me(Se,[["render",Be],["__scopeId","data-v-65366a29"],["__file","/tmp/cc-web-panel-Fa41ZI/repo/packages/web-panel/src/views/Terminal.vue"]]);export{Ie as default};
@@ -1 +0,0 @@
1
- import{O as r}from"./index-DMPQqeLb.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-DvfqASM7.js";import{U as t}from"./index-DMPQqeLb.js";import"./vendor-BvqAck49.js";import"./responsiveObserve-DV6XM19W.js";import"./useFlexGapSupport-t20RbINy.js";import"./styleChecker-CsoP0nmm.js";import"./index-CR3QNisI.js";import"./icons-DP3uiYxy.js";const l=t(o);export{l as default};
@@ -1 +0,0 @@
1
- import{C as o}from"./Col-BowFdito.js";import{U as t}from"./index-DMPQqeLb.js";import"./vendor-BvqAck49.js";import"./index-CR3QNisI.js";import"./icons-DP3uiYxy.js";const s=t(o);export{s as default};