reasonix 0.43.0 → 0.44.0

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 (169) hide show
  1. package/README.md +49 -11
  2. package/README.zh-CN.md +35 -7
  3. package/dashboard/app.css +225 -4
  4. package/dashboard/dist/app.js +6441 -6080
  5. package/dashboard/dist/app.js.map +1 -1
  6. package/data/deepseek-tokenizer.json.gz +0 -0
  7. package/dist/cli/{acp-DAGPCVFZ.js → acp-TYZ2CTDL.js} +28 -30
  8. package/dist/cli/acp-TYZ2CTDL.js.map +1 -0
  9. package/dist/cli/chat-TH7VNNCJ.js +51 -0
  10. package/dist/cli/chunk-2425HK6U.js +0 -0
  11. package/dist/cli/chunk-25T6CVUP.js +0 -0
  12. package/dist/cli/chunk-2UQP6H6T.js +0 -0
  13. package/dist/cli/{chunk-3Z6IBU3D.js → chunk-2V6EAEUW.js} +95 -31
  14. package/dist/cli/chunk-2V6EAEUW.js.map +1 -0
  15. package/dist/cli/{chunk-XCGGEJTI.js → chunk-4CTDEJUF.js} +2 -2
  16. package/dist/cli/chunk-4QUNBQQ2.js +0 -0
  17. package/dist/cli/{chunk-74EX7SUH.js → chunk-5QCB62C4.js} +33 -7
  18. package/dist/cli/{chunk-74EX7SUH.js.map → chunk-5QCB62C4.js.map} +1 -1
  19. package/dist/cli/chunk-6OWJV3YW.js +390 -0
  20. package/dist/cli/chunk-6OWJV3YW.js.map +1 -0
  21. package/dist/cli/chunk-6PBZN4VI.js +0 -0
  22. package/dist/cli/{chunk-7O5ALB4C.js → chunk-7CIGMZT3.js} +2 -2
  23. package/dist/cli/{chunk-H6PS7IUE.js → chunk-7UCMM425.js} +7 -3
  24. package/dist/cli/chunk-7UCMM425.js.map +1 -0
  25. package/dist/cli/{chunk-TJX6BFZZ.js → chunk-AB2RED3C.js} +3 -3
  26. package/dist/cli/{chunk-XPDVG52A.js → chunk-AVFXO2EZ.js} +361 -13
  27. package/dist/cli/chunk-AVFXO2EZ.js.map +1 -0
  28. package/dist/cli/{chunk-FHOGSSCH.js → chunk-C53JQES5.js} +3 -3
  29. package/dist/cli/{chunk-RE4RAVFF.js → chunk-CGDR2ELH.js} +92 -30
  30. package/dist/cli/chunk-CGDR2ELH.js.map +1 -0
  31. package/dist/cli/{chunk-OSZC7C6F.js → chunk-CWZKQ5FE.js} +7 -4
  32. package/dist/cli/chunk-CWZKQ5FE.js.map +1 -0
  33. package/dist/cli/{devtools-YECO25QO.js → chunk-FEZK652I.js} +10 -85
  34. package/dist/cli/chunk-FEZK652I.js.map +1 -0
  35. package/dist/cli/{chunk-45U62RI3.js → chunk-HNXDZGC6.js} +104 -2
  36. package/dist/cli/chunk-HNXDZGC6.js.map +1 -0
  37. package/dist/cli/chunk-J5XJHLWM.js +0 -0
  38. package/dist/cli/chunk-JMBMLOBP.js +0 -0
  39. package/dist/cli/{chunk-5JJRUIPA.js → chunk-JNAQYELD.js} +16 -8
  40. package/dist/cli/{chunk-5JJRUIPA.js.map → chunk-JNAQYELD.js.map} +1 -1
  41. package/dist/cli/{chunk-YFGF5NKA.js → chunk-KGBG6M2X.js} +19 -15
  42. package/dist/cli/chunk-KGBG6M2X.js.map +1 -0
  43. package/dist/cli/{chunk-3BXRZFWS.js → chunk-KLQTAZIY.js} +12 -4
  44. package/dist/cli/chunk-KLQTAZIY.js.map +1 -0
  45. package/dist/cli/{chunk-VK5HG73G.js → chunk-KM465GST.js} +9 -9
  46. package/dist/cli/{chunk-DOYHN4KB.js → chunk-LIR2HBQH.js} +2 -2
  47. package/dist/cli/{chunk-YYQAUTTN.js → chunk-MJ6W5UN3.js} +2 -2
  48. package/dist/cli/{chunk-6PZ3CXBP.js → chunk-MRHHQJAQ.js} +5 -4
  49. package/dist/cli/chunk-MRHHQJAQ.js.map +1 -0
  50. package/dist/cli/{chunk-PQXPXJBJ.js → chunk-NVURFF27.js} +16 -5
  51. package/dist/cli/chunk-NVURFF27.js.map +1 -0
  52. package/dist/cli/{chunk-2R4QCDOZ.js → chunk-OPFUUYHL.js} +540 -287
  53. package/dist/cli/chunk-OPFUUYHL.js.map +1 -0
  54. package/dist/cli/chunk-PLHAZOLZ.js +0 -0
  55. package/dist/cli/{chunk-HFEAY5DT.js → chunk-R3CTO2HM.js} +2 -2
  56. package/dist/cli/{chunk-O52OLQL3.js → chunk-RDRC3XDT.js} +136 -38
  57. package/dist/cli/chunk-RDRC3XDT.js.map +1 -0
  58. package/dist/cli/chunk-S4XVGLRW.js +0 -0
  59. package/dist/cli/chunk-SZ5XES2N.js +0 -0
  60. package/dist/cli/{chunk-2K65GZBT.js → chunk-TEUDEGX2.js} +64 -19
  61. package/dist/cli/chunk-TEUDEGX2.js.map +1 -0
  62. package/dist/cli/{chunk-2Z35JOA4.js → chunk-TKVXTQ3T.js} +4 -4
  63. package/dist/cli/{chunk-2Z35JOA4.js.map → chunk-TKVXTQ3T.js.map} +1 -1
  64. package/dist/cli/chunk-TUK7OWJA.js +0 -0
  65. package/dist/cli/{chunk-32TIKD5U.js → chunk-TXJMRPIL.js} +3 -3
  66. package/dist/cli/{chunk-2KDUS647.js → chunk-V26WPN3J.js} +7 -4
  67. package/dist/cli/chunk-V26WPN3J.js.map +1 -0
  68. package/dist/cli/{chunk-F3PXYSNN.js → chunk-WK3UFQY3.js} +2 -2
  69. package/dist/cli/{chunk-6G3CUUFG.js → chunk-X53B3JIX.js} +3 -3
  70. package/dist/cli/{chunk-6G3CUUFG.js.map → chunk-X53B3JIX.js.map} +1 -1
  71. package/dist/cli/chunk-XJXDHAES.js +0 -0
  72. package/dist/cli/{chunk-6AK4EY3D.js → chunk-XSU4QVFW.js} +1 -81
  73. package/dist/cli/chunk-XSU4QVFW.js.map +1 -0
  74. package/dist/cli/chunk-XXC2BYTV.js +0 -0
  75. package/dist/cli/{chunk-P7EKE5ZQ.js → chunk-Z4S7EYXG.js} +4482 -1310
  76. package/dist/cli/chunk-Z4S7EYXG.js.map +1 -0
  77. package/dist/cli/chunk-ZZM6QJ4W.js +0 -0
  78. package/dist/cli/{chunk-YQ6NTIIE.js → chunk-ZZYBBX5N.js} +13 -5
  79. package/dist/cli/chunk-ZZYBBX5N.js.map +1 -0
  80. package/dist/cli/{code-SMKEW6CD.js → code-PSVJ3KEN.js} +48 -36
  81. package/dist/cli/code-PSVJ3KEN.js.map +1 -0
  82. package/dist/cli/{commands-FVVB5FZF.js → commands-OCU42XG4.js} +4 -4
  83. package/dist/cli/{commit-HE4VSPZ7.js → commit-XCQIQCYG.js} +3 -3
  84. package/dist/cli/{desktop-Q7NDXCON.js → desktop-KWGR4BNE.js} +210 -69
  85. package/dist/cli/desktop-KWGR4BNE.js.map +1 -0
  86. package/dist/cli/devtools-HW3WDT3Q.js +91 -0
  87. package/dist/cli/devtools-HW3WDT3Q.js.map +1 -0
  88. package/dist/cli/{diff-435UTPC5.js → diff-NHANTNC3.js} +9 -9
  89. package/dist/cli/{doctor-OT7KH75K.js → doctor-CC5CLOGG.js} +10 -10
  90. package/dist/cli/events-XEFAD5VX.js +0 -0
  91. package/dist/cli/index.js +132 -94
  92. package/dist/cli/index.js.map +1 -1
  93. package/dist/cli/{mcp-WUL2WO75.js → mcp-MPVGBBJF.js} +2 -2
  94. package/dist/cli/{mcp-browse-RR7R4XET.js → mcp-browse-4XOTC3FJ.js} +3 -3
  95. package/dist/cli/{mcp-inspect-REGLYBWT.js → mcp-inspect-CEMGKKAH.js} +14 -9
  96. package/dist/cli/mcp-inspect-CEMGKKAH.js.map +1 -0
  97. package/dist/cli/{prompt-UW6EFLVR.js → prompt-2D7ID24X.js} +4 -4
  98. package/dist/cli/prune-sessions-3RWUBYRS.js +0 -0
  99. package/dist/cli/{replay-YOURXV4C.js → replay-SR44E6RS.js} +10 -10
  100. package/dist/cli/{run-Q6BUXV66.js → run-MDGL27WL.js} +35 -36
  101. package/dist/cli/run-MDGL27WL.js.map +1 -0
  102. package/dist/cli/{server-XGDBRWMB.js → server-27ARQXIZ.js} +67 -24
  103. package/dist/cli/server-27ARQXIZ.js.map +1 -0
  104. package/dist/cli/{sessions-FH7QVYSY.js → sessions-CKQXCYGP.js} +18 -18
  105. package/dist/cli/sessions-CKQXCYGP.js.map +1 -0
  106. package/dist/cli/{setup-VDS6SVEP.js → setup-TPAGSVXO.js} +6 -6
  107. package/dist/cli/{stats-MQVI2XQH.js → stats-DPUBZNVX.js} +6 -4
  108. package/dist/cli/update-6ITLPRDV.js +0 -0
  109. package/dist/cli/{version-DAHGZY5N.js → version-2X3BHVVK.js} +15 -15
  110. package/dist/index.d.ts +181 -53
  111. package/dist/index.js +1322 -533
  112. package/dist/index.js.map +1 -1
  113. package/package.json +21 -8
  114. package/dist/cli/.-3G6VX5S7.js +0 -327
  115. package/dist/cli/.-6YRPB2C7.js +0 -329
  116. package/dist/cli/.-EYSVINK3.js +0 -317
  117. package/dist/cli/acp-DAGPCVFZ.js.map +0 -1
  118. package/dist/cli/chat-7ES4IBNH.js +0 -50
  119. package/dist/cli/chunk-2K65GZBT.js.map +0 -1
  120. package/dist/cli/chunk-2KDUS647.js.map +0 -1
  121. package/dist/cli/chunk-2R4QCDOZ.js.map +0 -1
  122. package/dist/cli/chunk-3BXRZFWS.js.map +0 -1
  123. package/dist/cli/chunk-3Z6IBU3D.js.map +0 -1
  124. package/dist/cli/chunk-45U62RI3.js.map +0 -1
  125. package/dist/cli/chunk-6AK4EY3D.js.map +0 -1
  126. package/dist/cli/chunk-6PZ3CXBP.js.map +0 -1
  127. package/dist/cli/chunk-H6PS7IUE.js.map +0 -1
  128. package/dist/cli/chunk-O52OLQL3.js.map +0 -1
  129. package/dist/cli/chunk-OSZC7C6F.js.map +0 -1
  130. package/dist/cli/chunk-P7EKE5ZQ.js.map +0 -1
  131. package/dist/cli/chunk-PQXPXJBJ.js.map +0 -1
  132. package/dist/cli/chunk-PV55UMTO.js +0 -200
  133. package/dist/cli/chunk-PV55UMTO.js.map +0 -1
  134. package/dist/cli/chunk-RE4RAVFF.js.map +0 -1
  135. package/dist/cli/chunk-XPDVG52A.js.map +0 -1
  136. package/dist/cli/chunk-YFGF5NKA.js.map +0 -1
  137. package/dist/cli/chunk-YQ6NTIIE.js.map +0 -1
  138. package/dist/cli/code-SMKEW6CD.js.map +0 -1
  139. package/dist/cli/desktop-Q7NDXCON.js.map +0 -1
  140. package/dist/cli/devtools-YECO25QO.js.map +0 -1
  141. package/dist/cli/doctor-OT7KH75K.js.map +0 -1
  142. package/dist/cli/mcp-inspect-REGLYBWT.js.map +0 -1
  143. package/dist/cli/prompt-UW6EFLVR.js.map +0 -1
  144. package/dist/cli/run-Q6BUXV66.js.map +0 -1
  145. package/dist/cli/server-XGDBRWMB.js.map +0 -1
  146. package/dist/cli/sessions-FH7QVYSY.js.map +0 -1
  147. package/dist/cli/stats-MQVI2XQH.js.map +0 -1
  148. /package/dist/cli/{.-3G6VX5S7.js.map → chat-TH7VNNCJ.js.map} +0 -0
  149. /package/dist/cli/{chunk-XCGGEJTI.js.map → chunk-4CTDEJUF.js.map} +0 -0
  150. /package/dist/cli/{chunk-7O5ALB4C.js.map → chunk-7CIGMZT3.js.map} +0 -0
  151. /package/dist/cli/{chunk-TJX6BFZZ.js.map → chunk-AB2RED3C.js.map} +0 -0
  152. /package/dist/cli/{chunk-FHOGSSCH.js.map → chunk-C53JQES5.js.map} +0 -0
  153. /package/dist/cli/{chunk-VK5HG73G.js.map → chunk-KM465GST.js.map} +0 -0
  154. /package/dist/cli/{chunk-DOYHN4KB.js.map → chunk-LIR2HBQH.js.map} +0 -0
  155. /package/dist/cli/{chunk-YYQAUTTN.js.map → chunk-MJ6W5UN3.js.map} +0 -0
  156. /package/dist/cli/{chunk-HFEAY5DT.js.map → chunk-R3CTO2HM.js.map} +0 -0
  157. /package/dist/cli/{chunk-32TIKD5U.js.map → chunk-TXJMRPIL.js.map} +0 -0
  158. /package/dist/cli/{chunk-F3PXYSNN.js.map → chunk-WK3UFQY3.js.map} +0 -0
  159. /package/dist/cli/{commands-FVVB5FZF.js.map → commands-OCU42XG4.js.map} +0 -0
  160. /package/dist/cli/{commit-HE4VSPZ7.js.map → commit-XCQIQCYG.js.map} +0 -0
  161. /package/dist/cli/{diff-435UTPC5.js.map → diff-NHANTNC3.js.map} +0 -0
  162. /package/dist/cli/{.-6YRPB2C7.js.map → doctor-CC5CLOGG.js.map} +0 -0
  163. /package/dist/cli/{mcp-WUL2WO75.js.map → mcp-MPVGBBJF.js.map} +0 -0
  164. /package/dist/cli/{mcp-browse-RR7R4XET.js.map → mcp-browse-4XOTC3FJ.js.map} +0 -0
  165. /package/dist/cli/{.-EYSVINK3.js.map → prompt-2D7ID24X.js.map} +0 -0
  166. /package/dist/cli/{replay-YOURXV4C.js.map → replay-SR44E6RS.js.map} +0 -0
  167. /package/dist/cli/{setup-VDS6SVEP.js.map → setup-TPAGSVXO.js.map} +0 -0
  168. /package/dist/cli/{chat-7ES4IBNH.js.map → stats-DPUBZNVX.js.map} +0 -0
  169. /package/dist/cli/{version-DAHGZY5N.js.map → version-2X3BHVVK.js.map} +0 -0
Binary file
@@ -2,75 +2,74 @@
2
2
  import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
3
3
  import {
4
4
  buildCodeToolset
5
- } from "./chunk-YFGF5NKA.js";
5
+ } from "./chunk-KGBG6M2X.js";
6
6
  import {
7
7
  Eventizer,
8
8
  autoResolveVerdict
9
- } from "./chunk-45U62RI3.js";
9
+ } from "./chunk-HNXDZGC6.js";
10
10
  import {
11
11
  formatMcpLifecycleEvent,
12
12
  formatMcpSlowToast
13
- } from "./chunk-H6PS7IUE.js";
13
+ } from "./chunk-7UCMM425.js";
14
14
  import {
15
15
  buildTransportFromSpec,
16
16
  preflightStdioSpec
17
- } from "./chunk-PQXPXJBJ.js";
17
+ } from "./chunk-NVURFF27.js";
18
18
  import {
19
19
  CacheFirstLoop,
20
20
  ImmutablePrefix,
21
21
  bridgeMcpTools
22
- } from "./chunk-2R4QCDOZ.js";
23
- import "./chunk-F3PXYSNN.js";
22
+ } from "./chunk-OPFUUYHL.js";
23
+ import "./chunk-WK3UFQY3.js";
24
24
  import {
25
25
  openTranscriptFile,
26
26
  recordFromLoopEvent,
27
27
  writeRecord
28
- } from "./chunk-FHOGSSCH.js";
28
+ } from "./chunk-C53JQES5.js";
29
29
  import {
30
- McpClient,
31
- parseMcpSpec
32
- } from "./chunk-6AK4EY3D.js";
30
+ McpClient
31
+ } from "./chunk-XSU4QVFW.js";
33
32
  import {
34
33
  codeSystemPrompt
35
- } from "./chunk-5JJRUIPA.js";
34
+ } from "./chunk-JNAQYELD.js";
36
35
  import {
37
36
  canonicalPresetName,
38
37
  resolvePreset
39
38
  } from "./chunk-2425HK6U.js";
40
- import "./chunk-PV55UMTO.js";
39
+ import "./chunk-6OWJV3YW.js";
41
40
  import {
42
41
  DeepSeekClient
43
- } from "./chunk-2KDUS647.js";
42
+ } from "./chunk-V26WPN3J.js";
44
43
  import "./chunk-25T6CVUP.js";
45
44
  import {
46
45
  loadDotenv
47
46
  } from "./chunk-2UQP6H6T.js";
48
- import "./chunk-YYQAUTTN.js";
47
+ import "./chunk-MJ6W5UN3.js";
49
48
  import {
50
49
  pauseGate
51
- } from "./chunk-O52OLQL3.js";
52
- import "./chunk-2K65GZBT.js";
50
+ } from "./chunk-RDRC3XDT.js";
51
+ import "./chunk-TEUDEGX2.js";
53
52
  import "./chunk-PLHAZOLZ.js";
54
- import "./chunk-XCGGEJTI.js";
55
- import "./chunk-7O5ALB4C.js";
53
+ import "./chunk-4CTDEJUF.js";
54
+ import "./chunk-7CIGMZT3.js";
56
55
  import "./chunk-S4XVGLRW.js";
57
56
  import {
58
57
  timestampSuffix
59
58
  } from "./chunk-6PBZN4VI.js";
59
+ import "./chunk-R3CTO2HM.js";
60
+ import "./chunk-ZZYBBX5N.js";
60
61
  import {
61
62
  t
62
- } from "./chunk-RE4RAVFF.js";
63
+ } from "./chunk-CGDR2ELH.js";
63
64
  import {
64
65
  loadApiKey,
65
66
  loadBaseUrl,
66
67
  loadEditMode,
67
68
  loadPreset,
68
69
  loadReasoningEffort,
69
- mcpEnvFor,
70
+ normalizeMcpConfig,
70
71
  readConfig
71
- } from "./chunk-XPDVG52A.js";
72
- import "./chunk-HFEAY5DT.js";
73
- import "./chunk-YQ6NTIIE.js";
72
+ } from "./chunk-AVFXO2EZ.js";
74
73
  import {
75
74
  VERSION
76
75
  } from "./chunk-XXC2BYTV.js";
@@ -475,14 +474,13 @@ async function loadMcpServers(tools, specs, globalPrefix) {
475
474
  const clients = [];
476
475
  if (specs.length === 0) return clients;
477
476
  const cfg = readConfig();
478
- const disabledNames = new Set(cfg.mcpDisabled ?? []);
479
- for (const raw of specs) {
477
+ const normalizedSpecs = normalizeMcpConfig(cfg, specs);
478
+ for (const spec of normalizedSpecs) {
480
479
  let label = "anon";
481
480
  let mcp;
482
481
  try {
483
- const spec = parseMcpSpec(raw);
484
482
  label = spec.name ?? "anon";
485
- if (spec.name && disabledNames.has(spec.name)) {
483
+ if (spec.disabled) {
486
484
  process.stderr.write(`${formatMcpLifecycleEvent({ state: "disabled", name: label })}
487
485
  `);
488
486
  continue;
@@ -490,9 +488,9 @@ async function loadMcpServers(tools, specs, globalPrefix) {
490
488
  process.stderr.write(`${formatMcpLifecycleEvent({ state: "handshake", name: label })}
491
489
  `);
492
490
  const t0 = Date.now();
493
- const prefix = resolveMcpPrefix(spec.name, specs.length, globalPrefix);
491
+ const prefix = resolveMcpPrefix(spec.name, normalizedSpecs.length, globalPrefix);
494
492
  if (spec.transport === "stdio") preflightStdioSpec(spec);
495
- const transport = buildTransportFromSpec(spec, { env: mcpEnvFor(spec.name, cfg) });
493
+ const transport = buildTransportFromSpec(spec);
496
494
  mcp = new McpClient({ transport });
497
495
  await mcp.initialize();
498
496
  const bridge = await bridgeMcpTools(mcp, {
@@ -710,4 +708,4 @@ export {
710
708
  acpCommand,
711
709
  loadMcpServers
712
710
  };
713
- //# sourceMappingURL=acp-DAGPCVFZ.js.map
711
+ //# sourceMappingURL=acp-TYZ2CTDL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/cli/commands/acp.ts","../../src/acp/dispatch.ts","../../src/acp/gates.ts","../../src/acp/protocol.ts","../../src/acp/server.ts"],"sourcesContent":["/** ACP (Agent Client Protocol) agent — drives the cache-first loop over stdio NDJSON JSON-RPC. */\n\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { type WriteStream, existsSync, statSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { dispatchKernelEvent } from \"../../acp/dispatch.js\";\nimport { requestPermissionForGate } from \"../../acp/gates.js\";\nimport {\n ACP_PROTOCOL_VERSION,\n type ContentBlock,\n ERR_INVALID_PARAMS,\n type InitializeParams,\n type InitializeResult,\n type SessionCancelParams,\n type SessionNewParams,\n type SessionNewResult,\n type SessionPromptParams,\n type SessionPromptResult,\n type SessionUpdateParams,\n type StopReason,\n flattenPrompt,\n} from \"../../acp/protocol.js\";\nimport { AcpServer } from \"../../acp/server.js\";\nimport { codeSystemPrompt } from \"../../code/prompt.js\";\nimport { buildCodeToolset } from \"../../code/setup.js\";\nimport {\n loadApiKey,\n loadBaseUrl,\n loadPreset,\n loadReasoningEffort,\n normalizeMcpConfig,\n readConfig,\n} from \"../../config.js\";\nimport { loadEditMode } from \"../../config.js\";\nimport { Eventizer } from \"../../core/eventize.js\";\nimport { pauseGate } from \"../../core/pause-gate.js\";\nimport { autoResolveVerdict } from \"../../core/pause-policy.js\";\nimport { loadDotenv } from \"../../env.js\";\nimport { t } from \"../../i18n/index.js\";\nimport { CacheFirstLoop, DeepSeekClient, ImmutablePrefix } from \"../../index.js\";\nimport { McpClient } from \"../../mcp/client.js\";\nimport { preflightStdioSpec } from \"../../mcp/preflight.js\";\nimport { bridgeMcpTools } from \"../../mcp/registry.js\";\nimport { buildTransportFromSpec } from \"../../mcp/transport-from-spec.js\";\nimport { timestampSuffix } from \"../../memory/session.js\";\nimport { openTranscriptFile, recordFromLoopEvent, writeRecord } from \"../../transcript/log.js\";\nimport { VERSION } from \"../../version.js\";\nimport { formatMcpLifecycleEvent } from \"../ui/mcp-lifecycle.js\";\nimport { formatMcpSlowToast } from \"../ui/mcp-toast.js\";\nimport { canonicalPresetName, resolvePreset } from \"../ui/presets.js\";\n\nexport interface AcpOptions {\n model?: string;\n dir?: string;\n budgetUsd?: number;\n transcript?: string;\n yolo?: boolean;\n /** Zero or more MCP server specs. Each: `\"name=cmd args...\"` or `\"cmd args...\"`. */\n mcpSpecs?: string[];\n /** Global prefix — only honored when a single anonymous server is given. */\n mcpPrefix?: string;\n}\n\ninterface Session {\n id: string;\n rootDir: string;\n model: string;\n toolset: Awaited<ReturnType<typeof buildCodeToolset>>;\n mcpClients: McpClient[];\n loop: CacheFirstLoop;\n eventizer: Eventizer;\n ctx: { model: string; prefixHash: string; reasoningEffort: \"high\" | \"max\" };\n aborter: AbortController | null;\n}\n\nfunction resolveMcpPrefix(\n specName: string | null | undefined,\n specCount: number,\n globalPrefix: string | undefined,\n): string {\n if (specName) return `${specName}_`;\n if (specCount === 1 && globalPrefix) return globalPrefix;\n return \"\";\n}\n\n// Mirrors run.ts:81-142.\nexport async function loadMcpServers(\n tools: import(\"../../tools.js\").ToolRegistry,\n specs: string[],\n globalPrefix: string | undefined,\n): Promise<McpClient[]> {\n const clients: McpClient[] = [];\n if (specs.length === 0) return clients;\n const cfg = readConfig();\n const normalizedSpecs = normalizeMcpConfig(cfg, specs);\n for (const spec of normalizedSpecs) {\n let label = \"anon\";\n let mcp: McpClient | undefined;\n try {\n label = spec.name ?? \"anon\";\n if (spec.disabled) {\n process.stderr.write(`${formatMcpLifecycleEvent({ state: \"disabled\", name: label })}\\n`);\n continue;\n }\n process.stderr.write(`${formatMcpLifecycleEvent({ state: \"handshake\", name: label })}\\n`);\n const t0 = Date.now();\n const prefix = resolveMcpPrefix(spec.name, normalizedSpecs.length, globalPrefix);\n if (spec.transport === \"stdio\") preflightStdioSpec(spec);\n const transport = buildTransportFromSpec(spec);\n mcp = new McpClient({ transport });\n await mcp.initialize();\n const bridge = await bridgeMcpTools(mcp, {\n registry: tools,\n namePrefix: prefix,\n serverName: label,\n onSlow: (info) =>\n process.stderr.write(\n `${formatMcpSlowToast({ name: info.serverName, p95Ms: info.p95Ms, sampleSize: info.sampleSize })}\\n`,\n ),\n });\n process.stderr.write(\n `${formatMcpLifecycleEvent({\n state: \"connected\",\n name: label,\n tools: bridge.registeredNames.length,\n ms: Date.now() - t0,\n })}\\n`,\n );\n clients.push(mcp);\n } catch (err) {\n await mcp?.close().catch(() => undefined);\n process.stderr.write(\n `${formatMcpLifecycleEvent({ state: \"failed\", name: label, reason: (err as Error).message })}\\n → ${t(\"mcpLifecycle.failedSetupConfigHint\")}\\n`,\n );\n }\n }\n return clients;\n}\n\nfunction resolveDir(raw: string | undefined, fallback: string): string {\n if (!raw) return fallback;\n const abs = resolve(raw);\n if (!existsSync(abs) || !statSync(abs).isDirectory()) {\n throw new Error(`workspace directory not found: ${abs}`);\n }\n return abs;\n}\n\nasync function buildSession(opts: {\n rootDir: string;\n modelOverride?: string;\n budgetUsd?: number;\n mcpSpecs?: string[];\n mcpPrefix?: string;\n}): Promise<Session> {\n const preset = canonicalPresetName(loadPreset());\n const resolved = resolvePreset(preset);\n const model = opts.modelOverride || resolved.model;\n const toolset = await buildCodeToolset({ rootDir: opts.rootDir });\n // Bridge MCP tools BEFORE building the prefix so their specs make it into the cache key.\n const mcpClients = await loadMcpServers(toolset.tools, opts.mcpSpecs ?? [], opts.mcpPrefix);\n const system = codeSystemPrompt(opts.rootDir, {\n hasSemanticSearch: toolset.semantic.enabled,\n modelId: model,\n });\n const client = new DeepSeekClient({ baseUrl: loadBaseUrl() });\n const prefix = new ImmutablePrefix({ system, toolSpecs: toolset.tools.specs() });\n const loop = new CacheFirstLoop({\n client,\n prefix,\n tools: toolset.tools,\n model,\n budgetUsd: opts.budgetUsd,\n session: `acp-${timestampSuffix()}`,\n });\n return {\n id: `sess_${timestampSuffix()}-${Math.random().toString(36).slice(2, 8)}`,\n rootDir: opts.rootDir,\n model,\n toolset,\n mcpClients,\n loop,\n eventizer: new Eventizer(),\n ctx: {\n model,\n prefixHash: prefix.fingerprint,\n reasoningEffort: loadReasoningEffort(),\n },\n aborter: null,\n };\n}\n\nexport async function acpCommand(opts: AcpOptions): Promise<void> {\n loadDotenv();\n if (loadApiKey()) {\n process.env.DEEPSEEK_API_KEY = loadApiKey();\n }\n\n const defaultDir = resolveDir(opts.dir, process.cwd());\n const sessions = new Map<string, Session>();\n const sessionContext = new AsyncLocalStorage<string>();\n const server = new AcpServer();\n\n let transcriptStream: WriteStream | null = null;\n if (opts.transcript) {\n const defaultModel = opts.model || resolvePreset(canonicalPresetName(loadPreset())).model;\n transcriptStream = openTranscriptFile(opts.transcript, {\n version: 1,\n source: \"reasonix acp\",\n model: defaultModel,\n startedAt: new Date().toISOString(),\n });\n }\n\n pauseGate.on((req) => {\n const editMode = opts.yolo ? \"yolo\" : loadEditMode();\n const auto = autoResolveVerdict(req, editMode);\n if (auto !== null) {\n pauseGate.resolve(req.id, auto);\n return;\n }\n const activeSessionId = sessionContext.getStore();\n if (!activeSessionId || !sessions.has(activeSessionId)) {\n pauseGate.cancel(req.id);\n return;\n }\n void (async () => {\n const verdict = await requestPermissionForGate(server, activeSessionId, req);\n pauseGate.resolve(req.id, verdict);\n })();\n });\n\n server.onRequest<InitializeParams, InitializeResult>(\"initialize\", (params) => {\n if (!params || typeof params !== \"object\") {\n throw Object.assign(new Error(\"initialize: missing params\"), { code: ERR_INVALID_PARAMS });\n }\n return {\n protocolVersion: ACP_PROTOCOL_VERSION,\n agentCapabilities: {\n loadSession: false,\n promptCapabilities: { image: false, audio: false, embeddedContext: true },\n mcpCapabilities: { http: false, sse: false },\n },\n agentInfo: { name: \"reasonix\", title: \"Reasonix\", version: VERSION },\n authMethods: [],\n };\n });\n\n server.onRequest<SessionNewParams, SessionNewResult>(\"session/new\", async (params) => {\n const rootDir = resolveDir(params?.cwd, defaultDir);\n const session = await buildSession({\n rootDir,\n modelOverride: opts.model,\n budgetUsd: opts.budgetUsd,\n mcpSpecs: opts.mcpSpecs,\n mcpPrefix: opts.mcpPrefix,\n });\n sessions.set(session.id, session);\n return { sessionId: session.id };\n });\n\n server.onRequest<SessionPromptParams, SessionPromptResult>(\"session/prompt\", async (params) => {\n if (!params?.sessionId) {\n throw Object.assign(new Error(\"session/prompt: missing sessionId\"), {\n code: ERR_INVALID_PARAMS,\n });\n }\n const session = sessions.get(params.sessionId);\n if (!session) {\n throw Object.assign(new Error(`session/prompt: unknown session ${params.sessionId}`), {\n code: ERR_INVALID_PARAMS,\n });\n }\n const text = flattenPrompt(params.prompt as ContentBlock[]);\n if (!text) {\n throw Object.assign(new Error(\"session/prompt: empty prompt\"), { code: ERR_INVALID_PARAMS });\n }\n session.aborter = new AbortController();\n let stopReason: StopReason = \"end_turn\";\n try {\n await sessionContext.run(session.id, async () => {\n for await (const ev of session.loop.step(text)) {\n if (session.aborter?.signal.aborted) {\n stopReason = \"cancelled\";\n break;\n }\n // transcript needs raw LoopEvent (usage/cost/stats); kernel events lose those fields\n if (transcriptStream) {\n writeRecord(\n transcriptStream,\n recordFromLoopEvent(ev, {\n model: session.ctx.model,\n prefixHash: session.ctx.prefixHash,\n }),\n );\n }\n for (const kev of session.eventizer.consume(ev, session.ctx)) {\n dispatchKernelEvent(server, session.id, kev);\n if (kev.type === \"error\") stopReason = \"error\";\n }\n }\n });\n } catch (err) {\n const message = (err as Error).message;\n server.sendNotification(\"session/update\", {\n sessionId: session.id,\n update: {\n sessionUpdate: \"agent_message_chunk\",\n content: { type: \"text\", text: `\\n\\n[error] ${message}` },\n },\n } satisfies SessionUpdateParams);\n stopReason = \"error\";\n } finally {\n session.aborter = null;\n }\n return { stopReason };\n });\n\n server.onNotification<SessionCancelParams>(\"session/cancel\", (params) => {\n const session = params?.sessionId ? sessions.get(params.sessionId) : undefined;\n session?.aborter?.abort();\n });\n\n try {\n await server.done();\n } finally {\n transcriptStream?.end();\n // Tear down MCP children so spawned servers don't outlive the agent.\n const closes: Promise<unknown>[] = [];\n for (const session of sessions.values()) {\n for (const mcp of session.mcpClients) {\n closes.push(mcp.close().catch(() => undefined));\n }\n }\n await Promise.all(closes);\n }\n}\n","/** Map kernel events (model.delta / tool.preparing|intent|result) to ACP session/update notifications. */\n\nimport type { Event as KernelEvent } from \"../core/events.js\";\nimport type { SessionUpdateParams } from \"./protocol.js\";\nimport type { AcpServer } from \"./server.js\";\n\nconst READ_TOOLS = new Set([\n \"read_file\",\n \"list_directory\",\n \"directory_tree\",\n \"get_file_info\",\n \"glob\",\n]);\nconst EDIT_TOOLS = new Set([\n \"write_file\",\n \"edit_file\",\n \"multi_edit\",\n \"create_directory\",\n \"delete_file\",\n \"delete_directory\",\n \"move_file\",\n \"copy_file\",\n]);\nconst SEARCH_TOOLS = new Set([\"search_content\", \"search_files\"]);\nconst EXECUTE_TOOLS = new Set([\"run_command\", \"run_background\"]);\n\nexport type AcpToolKind = \"read\" | \"edit\" | \"search\" | \"execute\" | \"other\";\n\nexport function toolKindFor(name: string): AcpToolKind {\n if (READ_TOOLS.has(name)) return \"read\";\n if (EDIT_TOOLS.has(name)) return \"edit\";\n if (SEARCH_TOOLS.has(name)) return \"search\";\n if (EXECUTE_TOOLS.has(name)) return \"execute\";\n return \"other\";\n}\n\nfunction tryParseJson(raw: string): unknown {\n if (!raw) return undefined;\n try {\n return JSON.parse(raw);\n } catch {\n return raw;\n }\n}\n\n/** Stateless mapping from one kernel event to (zero or more) ACP session/update notifications. */\nexport function dispatchKernelEvent(server: AcpServer, sessionId: string, ev: KernelEvent): void {\n switch (ev.type) {\n case \"model.delta\": {\n if (!ev.text) return;\n const variant = ev.channel === \"reasoning\" ? \"agent_thought_chunk\" : \"agent_message_chunk\";\n emit(server, {\n sessionId,\n update: { sessionUpdate: variant, content: { type: \"text\", text: ev.text } },\n });\n return;\n }\n case \"tool.preparing\": {\n emit(server, {\n sessionId,\n update: {\n sessionUpdate: \"tool_call\",\n toolCallId: ev.callId,\n title: ev.name,\n kind: toolKindFor(ev.name),\n status: \"pending\",\n },\n });\n return;\n }\n case \"tool.intent\": {\n emit(server, {\n sessionId,\n update: {\n sessionUpdate: \"tool_call_update\",\n toolCallId: ev.callId,\n status: \"in_progress\",\n },\n });\n const rawInput = tryParseJson(ev.args);\n if (rawInput !== undefined) {\n emit(server, {\n sessionId,\n update: {\n sessionUpdate: \"tool_call\",\n toolCallId: ev.callId,\n title: ev.name,\n kind: toolKindFor(ev.name),\n status: \"in_progress\",\n rawInput,\n },\n });\n }\n return;\n }\n case \"tool.result\": {\n emit(server, {\n sessionId,\n update: {\n sessionUpdate: \"tool_call_update\",\n toolCallId: ev.callId,\n status: ev.ok ? \"completed\" : \"failed\",\n content: [\n {\n type: \"content\",\n content: { type: \"text\", text: clip(ev.output) },\n },\n ],\n },\n });\n return;\n }\n default:\n return;\n }\n}\n\nconst MAX_RESULT_CHARS = 8000;\nfunction clip(text: string): string {\n if (text.length <= MAX_RESULT_CHARS) return text;\n return `${text.slice(0, MAX_RESULT_CHARS)}\\n…(${text.length - MAX_RESULT_CHARS} more chars truncated)`;\n}\n\nfunction emit(server: AcpServer, params: SessionUpdateParams): void {\n server.sendNotification(\"session/update\", params);\n}\n","/** Bridges Reasonix's internal `PauseGate` requests onto ACP `session/request_permission` round-trips. */\n\nimport type {\n CheckpointVerdict,\n ChoiceVerdict,\n ConfirmationChoice,\n PauseRequest,\n PlanVerdict,\n RevisionVerdict,\n} from \"../core/pause-gate.js\";\nimport type {\n PermissionOption,\n PermissionRequestParams,\n PermissionRequestResult,\n} from \"./protocol.js\";\nimport type { AcpServer } from \"./server.js\";\n\nconst ID_ALLOW_ONCE = \"allow_once\";\nconst ID_ALLOW_ALWAYS = \"allow_always\";\nconst ID_REJECT = \"reject\";\nconst ID_REFINE = \"refine\";\nconst ID_REVISE = \"revise\";\nconst ID_STOP = \"stop\";\nconst ID_CANCEL = \"cancel\";\nconst ID_ACCEPT = \"accept\";\n\n/** Build the `options` list shown to the host for a given gate kind. The IDs are what the host echoes back in the response. */\nexport function permissionOptionsFor(req: PauseRequest): PermissionOption[] {\n switch (req.kind) {\n case \"run_command\":\n case \"run_background\":\n case \"path_access\":\n return [\n { optionId: ID_ALLOW_ONCE, name: \"Allow once\", kind: \"allow_once\" },\n { optionId: ID_ALLOW_ALWAYS, name: \"Allow always\", kind: \"allow_always\" },\n { optionId: ID_REJECT, name: \"Reject\", kind: \"reject_once\" },\n ];\n case \"plan_proposed\":\n return [\n { optionId: ID_ALLOW_ONCE, name: \"Approve plan\", kind: \"allow_once\" },\n { optionId: ID_REFINE, name: \"Refine\", kind: \"allow_once\" },\n { optionId: ID_CANCEL, name: \"Cancel\", kind: \"reject_once\" },\n ];\n case \"plan_checkpoint\":\n return [\n { optionId: ID_ALLOW_ONCE, name: \"Continue\", kind: \"allow_once\" },\n { optionId: ID_REVISE, name: \"Revise\", kind: \"allow_once\" },\n { optionId: ID_STOP, name: \"Stop\", kind: \"reject_once\" },\n ];\n case \"plan_revision\":\n return [\n { optionId: ID_ACCEPT, name: \"Accept revision\", kind: \"allow_once\" },\n { optionId: ID_REJECT, name: \"Keep original plan\", kind: \"reject_once\" },\n ];\n case \"choice\": {\n const payload = req.payload as { options: { id: string; title?: string }[] };\n const opts: PermissionOption[] = (payload.options ?? []).map((o) => ({\n optionId: o.id,\n name: o.title ?? o.id,\n kind: \"allow_once\",\n }));\n opts.push({ optionId: ID_CANCEL, name: \"Cancel\", kind: \"reject_once\" });\n return opts;\n }\n }\n}\n\nfunction commandPrefix(command: string): string {\n const first = command.trim().split(/\\s+/)[0] ?? command.trim();\n return `${first} *`;\n}\n\nfunction pathPrefix(p: string): string {\n return p;\n}\n\n/** Map an ACP permission response back into the internal verdict shape PauseGate.resolve expects. */\nexport function verdictFor(\n req: PauseRequest,\n result: PermissionRequestResult,\n): ConfirmationChoice | PlanVerdict | CheckpointVerdict | RevisionVerdict | ChoiceVerdict {\n const cancelled = result.outcome.outcome === \"cancelled\";\n const optionId = result.outcome.outcome === \"selected\" ? result.outcome.optionId : null;\n switch (req.kind) {\n case \"run_command\":\n case \"run_background\": {\n if (cancelled || optionId === ID_REJECT) return { type: \"deny\" };\n if (optionId === ID_ALLOW_ALWAYS) {\n const payload = req.payload as { command?: string };\n return { type: \"always_allow\", prefix: commandPrefix(payload.command ?? \"\") };\n }\n return { type: \"run_once\" };\n }\n case \"path_access\": {\n if (cancelled || optionId === ID_REJECT) return { type: \"deny\" };\n if (optionId === ID_ALLOW_ALWAYS) {\n const payload = req.payload as { allowPrefix: string };\n return { type: \"always_allow\", prefix: pathPrefix(payload.allowPrefix) };\n }\n return { type: \"run_once\" };\n }\n case \"plan_proposed\": {\n if (cancelled || optionId === ID_CANCEL) return { type: \"cancel\" };\n if (optionId === ID_REFINE) return { type: \"refine\" };\n return { type: \"approve\" };\n }\n case \"plan_checkpoint\": {\n if (cancelled || optionId === ID_STOP) return { type: \"stop\" };\n if (optionId === ID_REVISE) return { type: \"revise\" };\n return { type: \"continue\" };\n }\n case \"plan_revision\": {\n if (cancelled) return { type: \"cancelled\" };\n if (optionId === ID_ACCEPT) return { type: \"accepted\" };\n return { type: \"rejected\" };\n }\n case \"choice\": {\n if (cancelled || optionId === ID_CANCEL || !optionId) return { type: \"cancel\" };\n return { type: \"pick\", optionId };\n }\n }\n}\n\nfunction permissionTitleFor(req: PauseRequest): string {\n switch (req.kind) {\n case \"run_command\":\n case \"run_background\":\n return `Run command — ${((req.payload as { command?: string }).command ?? \"\").slice(0, 80)}`;\n case \"path_access\":\n return `Access path — ${(req.payload as { path: string }).path}`;\n case \"plan_proposed\":\n return \"Approve plan\";\n case \"plan_checkpoint\":\n return `Checkpoint — ${(req.payload as { title?: string }).title ?? \"step complete\"}`;\n case \"plan_revision\":\n return \"Approve plan revision\";\n case \"choice\":\n return (req.payload as { question?: string }).question ?? \"Choose an option\";\n }\n}\n\nfunction permissionKindFor(req: PauseRequest): \"execute\" | \"edit\" | \"other\" {\n if (req.kind === \"run_command\" || req.kind === \"run_background\") return \"execute\";\n if (req.kind === \"path_access\") {\n return (req.payload as { intent?: string }).intent === \"write\" ? \"edit\" : \"other\";\n }\n return \"other\";\n}\n\n/** Forward a PauseGate request as an ACP session/request_permission outbound call. Returns the verdict to pass into pauseGate.resolve. */\nexport async function requestPermissionForGate(\n server: AcpServer,\n sessionId: string,\n req: PauseRequest,\n): Promise<ConfirmationChoice | PlanVerdict | CheckpointVerdict | RevisionVerdict | ChoiceVerdict> {\n const params: PermissionRequestParams = {\n sessionId,\n toolCall: {\n toolCallId: `gate-${req.id}`,\n title: permissionTitleFor(req),\n kind: permissionKindFor(req),\n status: \"pending\",\n rawInput: req.payload,\n },\n options: permissionOptionsFor(req),\n };\n let result: PermissionRequestResult;\n try {\n result = await server.sendRequest<PermissionRequestResult>(\n \"session/request_permission\",\n params,\n );\n } catch {\n result = { outcome: { outcome: \"cancelled\" } };\n }\n return verdictFor(req, result);\n}\n","/** Wire types for the Agent Client Protocol — https://agentclientprotocol.com */\n\nexport const ACP_PROTOCOL_VERSION = 1;\n\nexport type JsonRpcId = string | number;\n\nexport interface JsonRpcRequest<P = unknown> {\n jsonrpc: \"2.0\";\n id: JsonRpcId;\n method: string;\n params?: P;\n}\n\nexport interface JsonRpcNotification<P = unknown> {\n jsonrpc: \"2.0\";\n method: string;\n params?: P;\n}\n\nexport interface JsonRpcError {\n code: number;\n message: string;\n data?: unknown;\n}\n\nexport interface JsonRpcResponse<R = unknown> {\n jsonrpc: \"2.0\";\n id: JsonRpcId | null;\n result?: R;\n error?: JsonRpcError;\n}\n\nexport interface InitializeParams {\n protocolVersion: number;\n clientCapabilities?: {\n fs?: { readTextFile?: boolean; writeTextFile?: boolean };\n terminal?: boolean;\n };\n clientInfo?: { name: string; title?: string; version?: string };\n}\n\nexport interface InitializeResult {\n protocolVersion: number;\n agentCapabilities: {\n loadSession?: boolean;\n promptCapabilities?: { image?: boolean; audio?: boolean; embeddedContext?: boolean };\n mcpCapabilities?: { http?: boolean; sse?: boolean };\n };\n agentInfo: { name: string; title?: string; version: string };\n authMethods: never[];\n}\n\nexport interface SessionNewParams {\n cwd?: string;\n mcpServers?: Array<{\n name: string;\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n }>;\n}\n\nexport interface SessionNewResult {\n sessionId: string;\n}\n\nexport type ContentBlock =\n | { type: \"text\"; text: string }\n | { type: \"resource\"; resource: { uri: string; mimeType?: string; text?: string } }\n | { type: \"image\"; mimeType: string; data: string }\n | { type: \"audio\"; mimeType: string; data: string };\n\nexport interface SessionPromptParams {\n sessionId: string;\n prompt: ContentBlock[];\n}\n\nexport type StopReason = \"end_turn\" | \"tool_use_complete\" | \"cancelled\" | \"error\";\n\nexport interface SessionPromptResult {\n stopReason: StopReason;\n}\n\nexport type SessionUpdate =\n | {\n sessionUpdate: \"agent_message_chunk\";\n content: { type: \"text\"; text: string };\n }\n | {\n sessionUpdate: \"agent_thought_chunk\";\n content: { type: \"text\"; text: string };\n }\n | {\n sessionUpdate: \"tool_call\";\n toolCallId: string;\n title?: string;\n kind?: \"read\" | \"edit\" | \"search\" | \"execute\" | \"other\";\n status?: \"pending\" | \"in_progress\" | \"completed\" | \"failed\";\n rawInput?: unknown;\n }\n | {\n sessionUpdate: \"tool_call_update\";\n toolCallId: string;\n status?: \"pending\" | \"in_progress\" | \"completed\" | \"failed\";\n content?: Array<{ type: \"content\"; content: { type: \"text\"; text: string } }>;\n }\n | {\n sessionUpdate: \"plan\";\n entries: Array<{\n content: string;\n priority: \"high\" | \"medium\" | \"low\";\n status: \"pending\" | \"in_progress\" | \"completed\";\n }>;\n };\n\nexport interface SessionUpdateParams {\n sessionId: string;\n update: SessionUpdate;\n}\n\nexport interface SessionCancelParams {\n sessionId: string;\n}\n\nexport type PermissionOptionKind = \"allow_once\" | \"allow_always\" | \"reject_once\" | \"reject_always\";\n\nexport interface PermissionOption {\n optionId: string;\n name: string;\n kind: PermissionOptionKind;\n}\n\nexport interface PermissionRequestParams {\n sessionId: string;\n toolCall: {\n toolCallId: string;\n title?: string;\n kind?: \"read\" | \"edit\" | \"search\" | \"execute\" | \"other\";\n status?: \"pending\";\n rawInput?: unknown;\n };\n options: PermissionOption[];\n}\n\nexport type PermissionOutcome =\n | { outcome: \"selected\"; optionId: string }\n | { outcome: \"cancelled\" };\n\nexport interface PermissionRequestResult {\n outcome: PermissionOutcome;\n}\n\nexport const ERR_PARSE = -32700;\nexport const ERR_INVALID_REQUEST = -32600;\nexport const ERR_METHOD_NOT_FOUND = -32601;\nexport const ERR_INVALID_PARAMS = -32602;\nexport const ERR_INTERNAL = -32603;\n\n/** Extract the user prompt text out of ACP content blocks. Resource blocks contribute their inline `text` if present. */\nexport function flattenPrompt(blocks: ContentBlock[]): string {\n const parts: string[] = [];\n for (const b of blocks) {\n if (b.type === \"text\") parts.push(b.text);\n else if (b.type === \"resource\" && b.resource.text) parts.push(b.resource.text);\n }\n return parts.join(\"\\n\\n\").trim();\n}\n","/** NDJSON JSON-RPC 2.0 server — per the ACP transport spec, one JSON object per line, no embedded newlines. */\n\nimport { type Interface, createInterface } from \"node:readline\";\nimport type { Readable, Writable } from \"node:stream\";\nimport {\n ERR_INTERNAL,\n ERR_METHOD_NOT_FOUND,\n ERR_PARSE,\n type JsonRpcId,\n type JsonRpcNotification,\n type JsonRpcRequest,\n type JsonRpcResponse,\n} from \"./protocol.js\";\n\nexport type RequestHandler<P = unknown, R = unknown> = (params: P) => Promise<R> | R;\nexport type NotificationHandler<P = unknown> = (params: P) => Promise<void> | void;\n\nexport interface AcpServerOptions {\n input?: Readable;\n output?: Writable;\n}\n\ninterface PendingOutbound {\n resolve: (value: unknown) => void;\n reject: (err: Error) => void;\n}\n\nexport class AcpServer {\n private requestHandlers = new Map<string, RequestHandler>();\n private notificationHandlers = new Map<string, NotificationHandler>();\n private pending = new Map<JsonRpcId, PendingOutbound>();\n private nextOutboundId = 1;\n private readonly output: Writable;\n private readonly rl: Interface;\n private closed = false;\n\n constructor(opts: AcpServerOptions = {}) {\n this.output = opts.output ?? process.stdout;\n const input = opts.input ?? process.stdin;\n this.rl = createInterface({ input });\n this.rl.on(\"line\", (line) => {\n void this.handleLine(line);\n });\n }\n\n onRequest<P, R>(method: string, handler: RequestHandler<P, R>): void {\n this.requestHandlers.set(method, handler as RequestHandler);\n }\n\n onNotification<P>(method: string, handler: NotificationHandler<P>): void {\n this.notificationHandlers.set(method, handler as NotificationHandler);\n }\n\n sendNotification(method: string, params: unknown): void {\n this.write({ jsonrpc: \"2.0\", method, params });\n }\n\n /** Send an outbound JSON-RPC request and resolve when the peer responds. */\n sendRequest<R = unknown>(method: string, params: unknown): Promise<R> {\n const id = this.nextOutboundId++;\n return new Promise<R>((resolve, reject) => {\n this.pending.set(id, {\n resolve: resolve as (v: unknown) => void,\n reject,\n });\n this.write({ jsonrpc: \"2.0\", id, method, params });\n });\n }\n\n close(): void {\n if (this.closed) return;\n this.closed = true;\n for (const p of this.pending.values()) p.reject(new Error(\"server closed\"));\n this.pending.clear();\n this.rl.close();\n }\n\n /** Wait for the input stream to end. */\n done(): Promise<void> {\n return new Promise((resolve) => this.rl.once(\"close\", () => resolve()));\n }\n\n private write(msg: JsonRpcRequest | JsonRpcNotification | JsonRpcResponse): void {\n this.output.write(`${JSON.stringify(msg)}\\n`);\n }\n\n private writeError(id: JsonRpcId | null, code: number, message: string): void {\n this.write({ jsonrpc: \"2.0\", id, error: { code, message } });\n }\n\n private async handleLine(raw: string): Promise<void> {\n const line = raw.trim();\n if (!line) return;\n let parsed: unknown;\n try {\n parsed = JSON.parse(line);\n } catch {\n this.writeError(null, ERR_PARSE, \"parse error\");\n return;\n }\n if (!parsed || typeof parsed !== \"object\") {\n this.writeError(null, ERR_PARSE, \"expected JSON object\");\n return;\n }\n const msg = parsed as Partial<JsonRpcRequest>;\n if (typeof msg.method === \"string\" && msg.id !== undefined) {\n const id = msg.id as JsonRpcId;\n const handler = this.requestHandlers.get(msg.method);\n if (!handler) {\n this.writeError(id, ERR_METHOD_NOT_FOUND, `method not found: ${msg.method}`);\n return;\n }\n try {\n const result = await handler(msg.params);\n this.write({ jsonrpc: \"2.0\", id, result });\n } catch (err) {\n this.writeError(id, ERR_INTERNAL, (err as Error).message);\n }\n return;\n }\n if (typeof msg.method === \"string\" && msg.id === undefined) {\n const handler = this.notificationHandlers.get(msg.method);\n if (!handler) return;\n try {\n await handler(msg.params);\n } catch {\n // notifications can't be replied to — log channel would help, but stderr would pollute the wire\n }\n return;\n }\n if (msg.id !== undefined && msg.method === undefined) {\n const response = parsed as JsonRpcResponse;\n const pending = this.pending.get(response.id as JsonRpcId);\n if (!pending) return;\n this.pending.delete(response.id as JsonRpcId);\n if (response.error) {\n pending.reject(new Error(response.error.message));\n } else {\n pending.resolve(response.result);\n }\n }\n }\n}\n"],"mappings":"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","names":["resolve"]}
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
3
+ import {
4
+ chatCommand
5
+ } from "./chunk-Z4S7EYXG.js";
6
+ import "./chunk-TKVXTQ3T.js";
7
+ import "./chunk-JMBMLOBP.js";
8
+ import "./chunk-2V6EAEUW.js";
9
+ import "./chunk-HNXDZGC6.js";
10
+ import "./chunk-7UCMM425.js";
11
+ import "./chunk-NVURFF27.js";
12
+ import "./chunk-ZZM6QJ4W.js";
13
+ import "./chunk-OPFUUYHL.js";
14
+ import "./chunk-WK3UFQY3.js";
15
+ import "./chunk-C53JQES5.js";
16
+ import "./chunk-XSU4QVFW.js";
17
+ import "./chunk-JNAQYELD.js";
18
+ import "./chunk-FEZK652I.js";
19
+ import "./chunk-MRHHQJAQ.js";
20
+ import "./chunk-AB2RED3C.js";
21
+ import "./chunk-X53B3JIX.js";
22
+ import "./chunk-2425HK6U.js";
23
+ import "./chunk-KM465GST.js";
24
+ import "./chunk-5QCB62C4.js";
25
+ import "./chunk-6OWJV3YW.js";
26
+ import "./chunk-V26WPN3J.js";
27
+ import "./chunk-25T6CVUP.js";
28
+ import "./chunk-2UQP6H6T.js";
29
+ import "./chunk-CWZKQ5FE.js";
30
+ import "./chunk-SZ5XES2N.js";
31
+ import "./chunk-KLQTAZIY.js";
32
+ import "./chunk-4QUNBQQ2.js";
33
+ import "./chunk-XJXDHAES.js";
34
+ import "./chunk-RDRC3XDT.js";
35
+ import "./chunk-TEUDEGX2.js";
36
+ import "./chunk-PLHAZOLZ.js";
37
+ import "./chunk-LIR2HBQH.js";
38
+ import "./chunk-4CTDEJUF.js";
39
+ import "./chunk-7CIGMZT3.js";
40
+ import "./chunk-S4XVGLRW.js";
41
+ import "./chunk-6PBZN4VI.js";
42
+ import "./chunk-R3CTO2HM.js";
43
+ import "./chunk-ZZYBBX5N.js";
44
+ import "./chunk-CGDR2ELH.js";
45
+ import "./chunk-AVFXO2EZ.js";
46
+ import "./chunk-XXC2BYTV.js";
47
+ import "./chunk-TUK7OWJA.js";
48
+ export {
49
+ chatCommand
50
+ };
51
+ //# sourceMappingURL=chat-TH7VNNCJ.js.map
File without changes
File without changes
File without changes
@@ -3,26 +3,28 @@ import { createRequire as __cr } from 'node:module'; if (typeof globalThis.requi
3
3
  import {
4
4
  formatMcpLifecycleEvent,
5
5
  formatMcpSlowToast
6
- } from "./chunk-H6PS7IUE.js";
6
+ } from "./chunk-7UCMM425.js";
7
7
  import {
8
8
  buildTransportFromSpec,
9
9
  preflightStdioSpec
10
- } from "./chunk-PQXPXJBJ.js";
10
+ } from "./chunk-NVURFF27.js";
11
11
  import {
12
12
  bridgeMcpTools
13
- } from "./chunk-2R4QCDOZ.js";
13
+ } from "./chunk-OPFUUYHL.js";
14
14
  import {
15
15
  McpClient,
16
- inspectMcpServer,
17
- parseMcpSpec
18
- } from "./chunk-6AK4EY3D.js";
16
+ inspectMcpServer
17
+ } from "./chunk-XSU4QVFW.js";
19
18
  import {
20
19
  t
21
- } from "./chunk-RE4RAVFF.js";
20
+ } from "./chunk-CGDR2ELH.js";
22
21
  import {
23
- mcpEnvFor,
24
- readConfig
25
- } from "./chunk-XPDVG52A.js";
22
+ normalizeMcpConfig,
23
+ overlayMatchedSpec,
24
+ parseMcpSpec,
25
+ readConfig,
26
+ specToRaw
27
+ } from "./chunk-AVFXO2EZ.js";
26
28
 
27
29
  // src/mcp/summary.ts
28
30
  function buildMcpServerSummary(opts) {
@@ -73,8 +75,24 @@ var stderrLifecycleSink = (n) => {
73
75
  );
74
76
  return;
75
77
  }
76
- process.stderr.write(`${formatMcpLifecycleEvent({ state: n.kind, name: n.name })}
77
- `);
78
+ if (n.kind === "tools-ready") {
79
+ process.stderr.write(
80
+ `${formatMcpLifecycleEvent({ state: "tools-ready", name: n.name, tools: n.tools, ms: n.ms })}
81
+ `
82
+ );
83
+ return;
84
+ }
85
+ if (n.kind === "warn") {
86
+ process.stderr.write(
87
+ `${formatMcpLifecycleEvent({ state: "warn", name: n.name, reason: n.reason })}
88
+ `
89
+ );
90
+ return;
91
+ }
92
+ process.stderr.write(
93
+ `${formatMcpLifecycleEvent({ state: n.kind, name: n.name })}
94
+ `
95
+ );
78
96
  };
79
97
  function createMcpRuntime(ctx) {
80
98
  const records = /* @__PURE__ */ new Map();
@@ -86,7 +104,8 @@ function createMcpRuntime(ctx) {
86
104
  }
87
105
  const tools = ctx.getTools();
88
106
  if (!tools) return { ok: false, reason: "no tool registry available" };
89
- const disabledNames = new Set(readConfig().mcpDisabled ?? []);
107
+ const cfg = readConfig();
108
+ const normalized = normalizeMcpConfig(cfg);
90
109
  let label = "anon";
91
110
  let mcp;
92
111
  let resolveReady;
@@ -97,9 +116,11 @@ function createMcpRuntime(ctx) {
97
116
  });
98
117
  ready.catch(() => void 0);
99
118
  try {
100
- const spec = parseMcpSpec(raw);
101
- label = spec.name ?? "anon";
102
- if (spec.name && disabledNames.has(spec.name)) {
119
+ const parsed = parseMcpSpec(raw);
120
+ label = parsed.name ?? "anon";
121
+ const matched = parsed.name ? normalized.find((s) => s.name === parsed.name) : void 0;
122
+ const spec = overlayMatchedSpec(parsed, matched);
123
+ if (spec.disabled) {
103
124
  sink({ kind: "disabled", name: label });
104
125
  rejectReady(new Error(`MCP server "${label}" is disabled`));
105
126
  return { ok: false, reason: "disabled by user" };
@@ -108,7 +129,7 @@ function createMcpRuntime(ctx) {
108
129
  const t0 = Date.now();
109
130
  const namePrefix = spec.name ? `${spec.name}_` : ctx.getRequestedCount() === 1 && ctx.getMcpPrefix() ? ctx.getMcpPrefix() : "";
110
131
  if (spec.transport === "stdio") preflightStdioSpec(spec);
111
- const transport = buildTransportFromSpec(spec, { env: mcpEnvFor(spec.name, readConfig()) });
132
+ const transport = buildTransportFromSpec(spec);
112
133
  mcp = new McpClient({ transport });
113
134
  await mcp.initialize();
114
135
  const host = { client: mcp };
@@ -126,6 +147,41 @@ function createMcpRuntime(ctx) {
126
147
  sampleSize: info.sampleSize
127
148
  })
128
149
  });
150
+ const ms = Date.now() - t0;
151
+ const allSpecs = tools.specs();
152
+ const registeredSpecs = allSpecs.filter(
153
+ (s) => bridge.registeredNames.includes(s.function.name)
154
+ );
155
+ records.set(raw, {
156
+ spec: raw,
157
+ client: mcp,
158
+ summary: buildMcpServerSummary({
159
+ label,
160
+ spec: raw,
161
+ toolCount: bridge.registeredNames.length,
162
+ report: {
163
+ protocolVersion: mcp.protocolVersion,
164
+ serverInfo: mcp.serverInfo,
165
+ capabilities: mcp.serverCapabilities ?? {},
166
+ tools: { supported: true, items: [] },
167
+ resources: { supported: false, reason: "still inspecting" },
168
+ prompts: { supported: false, reason: "still inspecting" },
169
+ elapsedMs: ms
170
+ },
171
+ host,
172
+ bridgeEnv: bridge.env
173
+ }),
174
+ registeredNames: bridge.registeredNames,
175
+ registeredSpecs
176
+ });
177
+ insertionOrder.push(raw);
178
+ resolveReady();
179
+ sink({
180
+ kind: "tools-ready",
181
+ name: label,
182
+ tools: bridge.registeredNames.length,
183
+ ms
184
+ });
129
185
  let report;
130
186
  try {
131
187
  report = await inspectMcpServer(mcp);
@@ -140,7 +196,6 @@ function createMcpRuntime(ctx) {
140
196
  elapsedMs: 0
141
197
  };
142
198
  }
143
- const ms = Date.now() - t0;
144
199
  const resourceCount = report.resources.supported ? report.resources.items.length : 0;
145
200
  const promptCount = report.prompts.supported ? report.prompts.items.length : 0;
146
201
  sink({
@@ -151,7 +206,6 @@ function createMcpRuntime(ctx) {
151
206
  prompts: promptCount,
152
207
  ms
153
208
  });
154
- resolveReady();
155
209
  const summary = buildMcpServerSummary({
156
210
  label,
157
211
  spec: raw,
@@ -160,10 +214,6 @@ function createMcpRuntime(ctx) {
160
214
  host,
161
215
  bridgeEnv: bridge.env
162
216
  });
163
- const allSpecs = tools.specs();
164
- const registeredSpecs = allSpecs.filter(
165
- (s) => bridge.registeredNames.includes(s.function.name)
166
- );
167
217
  records.set(raw, {
168
218
  spec: raw,
169
219
  client: mcp,
@@ -171,15 +221,28 @@ function createMcpRuntime(ctx) {
171
221
  registeredNames: bridge.registeredNames,
172
222
  registeredSpecs
173
223
  });
174
- insertionOrder.push(raw);
175
- if (loop) for (const s of registeredSpecs) loop.prefix.addTool(s);
224
+ if (loop)
225
+ for (const s of registeredSpecs)
226
+ try {
227
+ loop.prefix.addTool(s);
228
+ } catch (err) {
229
+ sink({
230
+ kind: "warn",
231
+ name: label,
232
+ reason: `addTool failed for ${s.function.name}: ${err.message}`
233
+ });
234
+ }
176
235
  return { ok: true, summary };
177
236
  } catch (err) {
178
- await mcp?.close().catch(() => void 0);
179
237
  const reason = err.message;
180
- sink({ kind: "failed", name: label, reason });
181
- rejectReady(new Error(`MCP server "${label}" failed to start: ${reason}`));
182
- return { ok: false, reason };
238
+ if (!records.has(raw)) {
239
+ await mcp?.close().catch(() => void 0);
240
+ rejectReady(new Error(`MCP server "${label}" failed to start: ${reason}`));
241
+ sink({ kind: "failed", name: label, reason });
242
+ return { ok: false, reason };
243
+ }
244
+ sink({ kind: "warn", name: label, reason });
245
+ return { ok: true, summary: records.get(raw).summary };
183
246
  }
184
247
  }
185
248
  async function removeSpec(raw, loop) {
@@ -197,7 +260,8 @@ function createMcpRuntime(ctx) {
197
260
  return true;
198
261
  }
199
262
  async function reloadFromConfig(loop) {
200
- const desired = readConfig().mcp ?? [];
263
+ const normalized = normalizeMcpConfig(readConfig());
264
+ const desired = normalized.map(specToRaw);
201
265
  const desiredSet = new Set(desired);
202
266
  const currentSet = new Set(records.keys());
203
267
  const added = [];
@@ -246,4 +310,4 @@ function createMcpRuntime(ctx) {
246
310
  export {
247
311
  createMcpRuntime
248
312
  };
249
- //# sourceMappingURL=chunk-3Z6IBU3D.js.map
313
+ //# sourceMappingURL=chunk-2V6EAEUW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/mcp/summary.ts","../../src/cli/commands/mcp-runtime.ts"],"sourcesContent":["import type { InspectionReport } from \"./inspect.js\";\nimport type { BridgeEnv, McpClientHost } from \"./registry.js\";\nimport type { GetPromptResult, ReadResourceResult } from \"./types.js\";\n\nexport interface McpServerSummary {\n label: string;\n spec: string;\n toolCount: number;\n report: InspectionReport;\n host: McpClientHost;\n bridgeEnv: BridgeEnv;\n readResource(uri: string): Promise<ReadResourceResult>;\n getPrompt(name: string, args?: Record<string, string>): Promise<GetPromptResult>;\n}\n\nexport function buildMcpServerSummary(opts: {\n label: string;\n spec: string;\n toolCount: number;\n report: InspectionReport;\n host: McpClientHost;\n bridgeEnv: BridgeEnv;\n}): McpServerSummary {\n return {\n label: opts.label,\n spec: opts.spec,\n toolCount: opts.toolCount,\n report: opts.report,\n host: opts.host,\n bridgeEnv: opts.bridgeEnv,\n readResource(uri) {\n return opts.host.client.readResource(uri);\n },\n getPrompt(name, args) {\n return args !== undefined\n ? opts.host.client.getPrompt(name, args)\n : opts.host.client.getPrompt(name);\n },\n };\n}\n","import { normalizeMcpConfig, readConfig } from \"../../config.js\";\nimport { t } from \"../../i18n/index.js\";\nimport type { CacheFirstLoop } from \"../../loop.js\";\nimport { McpClient } from \"../../mcp/client.js\";\nimport { type InspectionReport, inspectMcpServer } from \"../../mcp/inspect.js\";\nimport { preflightStdioSpec } from \"../../mcp/preflight.js\";\nimport { type McpClientHost, bridgeMcpTools } from \"../../mcp/registry.js\";\nimport { overlayMatchedSpec, parseMcpSpec, specToRaw } from \"../../mcp/spec.js\";\nimport { buildMcpServerSummary } from \"../../mcp/summary.js\";\nimport { buildTransportFromSpec } from \"../../mcp/transport-from-spec.js\";\nimport type { ToolRegistry } from \"../../tools.js\";\nimport type { ToolSpec } from \"../../types.js\";\nimport { type McpLifecycleEvent, formatMcpLifecycleEvent } from \"../ui/mcp-lifecycle.js\";\nimport { formatMcpSlowToast } from \"../ui/mcp-toast.js\";\nimport type { McpServerSummary } from \"../ui/slash.js\";\n\nexport interface ProgressInfo {\n toolName: string;\n progress: number;\n total?: number;\n message?: string;\n}\n\ninterface SpecRecord {\n spec: string;\n client: McpClient;\n summary: McpServerSummary;\n /** Names of bridged tools — used for hot-unbridge. */\n registeredNames: string[];\n /** ToolSpec snapshots captured AFTER bridge — handed to loop.prefix.addTool on hot-add. */\n registeredSpecs: ToolSpec[];\n}\n\nexport interface RuntimeContext {\n getTools: () => ToolRegistry | undefined;\n getMcpPrefix: () => string | undefined;\n getRequestedCount: () => number;\n progressSink: { current: ((info: ProgressInfo) => void) | null };\n}\n\nexport type McpLifecycleNotice =\n | { kind: \"handshake\"; name: string }\n | {\n kind: \"connected\";\n name: string;\n tools: number;\n resources: number;\n prompts: number;\n ms: number;\n }\n | { kind: \"disabled\"; name: string }\n | { kind: \"failed\"; name: string; reason: string }\n | { kind: \"slow\"; serverName: string; p95Ms: number; sampleSize: number }\n | { kind: \"tools-ready\"; name: string; tools: number; ms: number }\n | { kind: \"warn\"; name: string; reason: string };\n\nexport type McpLifecycleSink = (notice: McpLifecycleNotice) => void;\n\nexport const stderrLifecycleSink: McpLifecycleSink = (n) => {\n if (n.kind === \"slow\") {\n process.stderr.write(\n `${formatMcpSlowToast({ name: n.serverName, p95Ms: n.p95Ms, sampleSize: n.sampleSize })}\\n`,\n );\n return;\n }\n if (n.kind === \"failed\") {\n process.stderr.write(\n `${formatMcpLifecycleEvent({ state: \"failed\", name: n.name, reason: n.reason })}\\n → ${t(\"mcpLifecycle.failedSetupHint\")}\\n`,\n );\n return;\n }\n if (n.kind === \"connected\") {\n process.stderr.write(\n `${formatMcpLifecycleEvent({\n state: \"connected\",\n name: n.name,\n tools: n.tools,\n resources: n.resources,\n prompts: n.prompts,\n ms: n.ms,\n })}\\n`,\n );\n return;\n }\n if (n.kind === \"tools-ready\") {\n process.stderr.write(\n `${formatMcpLifecycleEvent({ state: \"tools-ready\", name: n.name, tools: n.tools, ms: n.ms })}\\n`,\n );\n return;\n }\n if (n.kind === \"warn\") {\n process.stderr.write(\n `${formatMcpLifecycleEvent({ state: \"warn\", name: n.name, reason: n.reason })}\\n`,\n );\n return;\n }\n // handshake / disabled — no extra fields needed\n process.stderr.write(\n `${formatMcpLifecycleEvent({ state: n.kind as \"handshake\" | \"disabled\", name: n.name })}\\n`,\n );\n};\n\nexport interface McpRuntime {\n size(): number;\n specs(): string[];\n summaries(): McpServerSummary[];\n addSpec(\n raw: string,\n loop?: CacheFirstLoop,\n ): Promise<{ ok: true; summary: McpServerSummary } | { ok: false; reason: string }>;\n removeSpec(raw: string, loop?: CacheFirstLoop): Promise<boolean>;\n reloadFromConfig(loop?: CacheFirstLoop): Promise<{\n added: string[];\n removed: string[];\n failed: Array<{ spec: string; reason: string }>;\n summaries: McpServerSummary[];\n }>;\n closeAll(): Promise<void>;\n /** Replace the sink that lifecycle events flow through — App.tsx swaps this in on mount so toasts land in the alt-screen UI instead of corrupting it via stderr. */\n setLifecycleSink(sink: McpLifecycleSink): void;\n}\n\nexport function createMcpRuntime(ctx: RuntimeContext): McpRuntime {\n const records = new Map<string, SpecRecord>();\n const insertionOrder: string[] = [];\n let sink: McpLifecycleSink = stderrLifecycleSink;\n\n async function addSpec(\n raw: string,\n loop?: CacheFirstLoop,\n ): Promise<{ ok: true; summary: McpServerSummary } | { ok: false; reason: string }> {\n if (records.has(raw)) {\n return { ok: true, summary: records.get(raw)!.summary };\n }\n const tools = ctx.getTools();\n if (!tools) return { ok: false, reason: \"no tool registry available\" };\n const cfg = readConfig();\n const normalized = normalizeMcpConfig(cfg);\n let label = \"anon\";\n let mcp: McpClient | undefined;\n // Per-server readiness gate — tool dispatches via the bridge await\n // this before calling into `live.callTool`. Resolved on `connected`,\n // rejected on `failed`, so a tool invoked mid-handshake waits\n // (capped by `bridgeMcpTools`'s `readyTimeoutMs`) instead of\n // surfacing a transport error.\n let resolveReady!: () => void;\n let rejectReady!: (err: Error) => void;\n const ready = new Promise<void>((resolve, reject) => {\n resolveReady = resolve;\n rejectReady = reject;\n });\n // Avoid unhandledRejection if no consumer awaits `ready` yet.\n ready.catch(() => undefined);\n try {\n const parsed = parseMcpSpec(raw);\n label = parsed.name ?? \"anon\";\n const matched = parsed.name ? normalized.find((s) => s.name === parsed.name) : undefined;\n const spec = overlayMatchedSpec(parsed, matched);\n if (spec.disabled) {\n sink({ kind: \"disabled\", name: label });\n rejectReady(new Error(`MCP server \"${label}\" is disabled`));\n return { ok: false, reason: \"disabled by user\" };\n }\n sink({ kind: \"handshake\", name: label });\n const t0 = Date.now();\n const namePrefix = spec.name\n ? `${spec.name}_`\n : ctx.getRequestedCount() === 1 && ctx.getMcpPrefix()\n ? (ctx.getMcpPrefix() as string)\n : \"\";\n if (spec.transport === \"stdio\") preflightStdioSpec(spec);\n const transport = buildTransportFromSpec(spec);\n mcp = new McpClient({ transport });\n await mcp.initialize();\n const host: McpClientHost = { client: mcp };\n const bridge = await bridgeMcpTools(mcp, {\n registry: tools,\n namePrefix,\n serverName: label,\n host,\n ready,\n onProgress: (info) => ctx.progressSink.current?.(info),\n onSlow: (info) =>\n sink({\n kind: \"slow\",\n serverName: info.serverName,\n p95Ms: info.p95Ms,\n sampleSize: info.sampleSize,\n }),\n });\n // Tools are registered — record the bridge NOW so the UI shows\n // \"bridged\" even if later non-critical steps (inspect, hot-add) fail.\n const ms = Date.now() - t0;\n const allSpecs = tools.specs();\n const registeredSpecs = allSpecs.filter((s) =>\n bridge.registeredNames.includes(s.function.name),\n );\n // Create a provisional record immediately (tools already usable).\n records.set(raw, {\n spec: raw,\n client: mcp,\n summary: buildMcpServerSummary({\n label,\n spec: raw,\n toolCount: bridge.registeredNames.length,\n report: {\n protocolVersion: mcp.protocolVersion,\n serverInfo: mcp.serverInfo,\n capabilities: mcp.serverCapabilities ?? {},\n tools: { supported: true, items: [] },\n resources: { supported: false, reason: \"still inspecting\" },\n prompts: { supported: false, reason: \"still inspecting\" },\n elapsedMs: ms,\n },\n host,\n bridgeEnv: bridge.env,\n }),\n registeredNames: bridge.registeredNames,\n registeredSpecs,\n });\n insertionOrder.push(raw);\n resolveReady();\n sink({\n kind: \"tools-ready\",\n name: label,\n tools: bridge.registeredNames.length,\n ms,\n });\n\n // Non-critical: inspect + hot-add. Failures here don't un-bridge.\n let report: InspectionReport;\n try {\n report = await inspectMcpServer(mcp);\n } catch {\n report = {\n protocolVersion: mcp.protocolVersion,\n serverInfo: mcp.serverInfo,\n capabilities: mcp.serverCapabilities ?? {},\n tools: { supported: true, items: [] },\n resources: { supported: false, reason: \"inspect failed\" },\n prompts: { supported: false, reason: \"inspect failed\" },\n elapsedMs: 0,\n };\n }\n const resourceCount = report.resources.supported ? report.resources.items.length : 0;\n const promptCount = report.prompts.supported ? report.prompts.items.length : 0;\n // Re-emit with full inspection data (the provisional event reported 0).\n sink({\n kind: \"connected\",\n name: label,\n tools: bridge.registeredNames.length,\n resources: resourceCount,\n prompts: promptCount,\n ms,\n });\n const summary = buildMcpServerSummary({\n label,\n spec: raw,\n toolCount: bridge.registeredNames.length,\n report,\n host,\n bridgeEnv: bridge.env,\n });\n // Replace the provisional record with the fully-inspected summary.\n records.set(raw, {\n spec: raw,\n client: mcp,\n summary,\n registeredNames: bridge.registeredNames,\n registeredSpecs,\n });\n // Hot-add: shift the prefix so the live loop sees the new tools\n // on the very next turn. Each addTool is one cache-miss turn.\n if (loop)\n for (const s of registeredSpecs)\n try {\n loop.prefix.addTool(s);\n } catch (err) {\n sink({\n kind: \"warn\",\n name: label,\n reason: `addTool failed for ${s.function.name}: ${(err as Error).message}`,\n });\n }\n return { ok: true, summary };\n } catch (err) {\n // If we got far enough to create a provisional record, keep it —\n // tools are already registered and usable even after a late failure.\n const reason = (err as Error).message;\n if (!records.has(raw)) {\n await mcp?.close().catch(() => undefined);\n rejectReady(new Error(`MCP server \"${label}\" failed to start: ${reason}`));\n sink({ kind: \"failed\", name: label, reason });\n return { ok: false, reason };\n }\n sink({ kind: \"warn\", name: label, reason });\n return { ok: true, summary: records.get(raw)!.summary };\n }\n }\n\n async function removeSpec(raw: string, loop?: CacheFirstLoop): Promise<boolean> {\n const record = records.get(raw);\n if (!record) return false;\n await record.client.close().catch(() => undefined);\n const tools = ctx.getTools();\n for (const name of record.registeredNames) {\n tools?.unregister(name);\n loop?.prefix.removeTool(name);\n }\n records.delete(raw);\n const idx = insertionOrder.indexOf(raw);\n if (idx >= 0) insertionOrder.splice(idx, 1);\n return true;\n }\n\n async function reloadFromConfig(loop?: CacheFirstLoop): Promise<{\n added: string[];\n removed: string[];\n failed: Array<{ spec: string; reason: string }>;\n summaries: McpServerSummary[];\n }> {\n const normalized = normalizeMcpConfig(readConfig());\n const desired = normalized.map(specToRaw);\n const desiredSet = new Set(desired);\n const currentSet = new Set(records.keys());\n const added: string[] = [];\n const removed: string[] = [];\n const failed: Array<{ spec: string; reason: string }> = [];\n\n for (const spec of [...currentSet]) {\n if (!desiredSet.has(spec)) {\n await removeSpec(spec, loop);\n removed.push(spec);\n }\n }\n for (const spec of desired) {\n if (currentSet.has(spec)) continue;\n const result = await addSpec(spec, loop);\n if (result.ok) added.push(spec);\n else failed.push({ spec, reason: result.reason });\n }\n return { added, removed, failed, summaries: summaries() };\n }\n\n function specs(): string[] {\n return [...insertionOrder];\n }\n function summaries(): McpServerSummary[] {\n return insertionOrder\n .map((s) => records.get(s)?.summary)\n .filter((s): s is McpServerSummary => Boolean(s));\n }\n async function closeAll(): Promise<void> {\n for (const r of records.values()) await r.client.close().catch(() => undefined);\n records.clear();\n insertionOrder.length = 0;\n }\n function setLifecycleSink(s: McpLifecycleSink): void {\n sink = s;\n }\n return {\n size: () => records.size,\n specs,\n summaries,\n addSpec,\n removeSpec,\n reloadFromConfig,\n closeAll,\n setLifecycleSink,\n };\n}\n"],"mappings":"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","names":[]}
@@ -8,7 +8,7 @@ import {
8
8
  compileFilters,
9
9
  defaultIndexConfig,
10
10
  resolveSemanticEmbeddingConfig
11
- } from "./chunk-XPDVG52A.js";
11
+ } from "./chunk-AVFXO2EZ.js";
12
12
 
13
13
  // src/index/semantic/builder.ts
14
14
  import { promises as fs3 } from "fs";
@@ -870,4 +870,4 @@ export {
870
870
  indexExists,
871
871
  indexCompatible
872
872
  };
873
- //# sourceMappingURL=chunk-XCGGEJTI.js.map
873
+ //# sourceMappingURL=chunk-4CTDEJUF.js.map
File without changes
@@ -25268,14 +25268,40 @@ function detectProxyUrl(env = process.env) {
25268
25268
  }
25269
25269
  return null;
25270
25270
  }
25271
+ function normalizeProxyUrl(raw) {
25272
+ const trimmed = raw.trim();
25273
+ if (!trimmed) return null;
25274
+ const candidate = /^[a-z][a-z0-9+.-]*:\/\//i.test(trimmed) ? trimmed : `http://${trimmed}`;
25275
+ try {
25276
+ return new URL(candidate).toString();
25277
+ } catch {
25278
+ return null;
25279
+ }
25280
+ }
25271
25281
  var installed = false;
25272
25282
  function installProxyIfConfigured(env = process.env) {
25273
- const url = detectProxyUrl(env);
25274
- if (!url) return null;
25275
- const reinstalled = installed;
25276
- (0, import_undici.setGlobalDispatcher)(new import_undici.ProxyAgent(url));
25277
- installed = true;
25278
- return { url, reinstalled };
25283
+ const raw = detectProxyUrl(env);
25284
+ if (!raw) return null;
25285
+ const url = normalizeProxyUrl(raw);
25286
+ if (!url) {
25287
+ process.stderr.write(
25288
+ `\u25B2 ignoring proxy env value ${JSON.stringify(raw)} \u2014 not a valid URL. Expected something like \`http://host:port\` or \`socks5://host:port\`.
25289
+ `
25290
+ );
25291
+ return null;
25292
+ }
25293
+ try {
25294
+ const reinstalled = installed;
25295
+ (0, import_undici.setGlobalDispatcher)(new import_undici.ProxyAgent(url));
25296
+ installed = true;
25297
+ return { url, reinstalled };
25298
+ } catch (err) {
25299
+ process.stderr.write(
25300
+ `\u25B2 proxy install failed (${err.message}); continuing without proxy.
25301
+ `
25302
+ );
25303
+ return null;
25304
+ }
25279
25305
  }
25280
25306
 
25281
25307
  export {
@@ -25290,4 +25316,4 @@ undici/lib/web/fetch/body.js:
25290
25316
  undici/lib/web/websocket/frame.js:
25291
25317
  (*! ws. MIT License. Einar Otto Stangvik <einaros@gmail.com> *)
25292
25318
  */
25293
- //# sourceMappingURL=chunk-74EX7SUH.js.map
25319
+ //# sourceMappingURL=chunk-5QCB62C4.js.map