@wrongstack/cli 1.0.1 → 1.0.4

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 (109) hide show
  1. package/data/providers.json +21 -21
  2. package/dist/{acp-3LARESEO.js → acp-AB54FWM2.js} +122 -39
  3. package/dist/acp-agent-list.d.ts +14 -0
  4. package/dist/acp-hq-telemetry.d.ts +9 -2
  5. package/dist/acp-mcp-servers.d.ts +49 -0
  6. package/dist/acp-server-agent.d.ts +18 -6
  7. package/dist/{auth-ZUMCDNE5.js → auth-WDMSNZ3S.js} +79 -55
  8. package/dist/auth-menu/index.d.ts +1 -0
  9. package/dist/auth-menu/oauth-menu.d.ts +3 -1
  10. package/dist/auth-menu/panel-service.d.ts +2 -0
  11. package/dist/auth-menu/provider-auth-login.d.ts +12 -0
  12. package/dist/auth-menu/types.d.ts +3 -0
  13. package/dist/auto-discover-providers-DXR25GTG.js +7 -0
  14. package/dist/boot/dispatch-webui.d.ts +1 -0
  15. package/dist/boot/short-circuit-hq.d.ts +2 -0
  16. package/dist/boot/system-prompt-builder.d.ts +7 -0
  17. package/dist/boot/system-prompt.d.ts +2 -1
  18. package/dist/boot/tool-registry.d.ts +18 -1
  19. package/dist/chimera-reviewer-policy.d.ts +1 -1
  20. package/dist/{chunk-C2E24IXZ.js → chunk-3I5ZJXM5.js} +147 -241
  21. package/dist/{chunk-JHPXJRRI.js → chunk-4XCBEUBX.js} +13 -3
  22. package/dist/{chunk-FPIWTJ2G.js → chunk-6WRKAACA.js} +4 -4
  23. package/dist/chunk-AUQDGU5D.js +32 -0
  24. package/dist/{chunk-D2VCUN7M.js → chunk-BIWE22O5.js} +17 -17
  25. package/dist/{chunk-VOTTENR5.js → chunk-CDY4D5QK.js} +2 -2
  26. package/dist/chunk-D5GB5MHA.js +87 -0
  27. package/dist/chunk-DAKVBMD4.js +36 -0
  28. package/dist/{chunk-E6RFXHWD.js → chunk-EK2P53GL.js} +3 -2
  29. package/dist/chunk-I7V2OYVH.js +242 -0
  30. package/dist/{chunk-MXEJEYT7.js → chunk-JX6KL7OF.js} +15 -5
  31. package/dist/{chunk-ZSZ3EYWH.js → chunk-KEPABQYT.js} +109 -6
  32. package/dist/{chunk-IMWXXF4J.js → chunk-KNMIBKLV.js} +79 -1
  33. package/dist/{chunk-MNQQ4ZNF.js → chunk-ONOT5OJ2.js} +290 -687
  34. package/dist/chunk-Q7E3BPDU.js +62 -0
  35. package/dist/chunk-SIGUWXAA.js +43 -0
  36. package/dist/{chunk-TEBMCYZN.js → chunk-SIS37L3W.js} +58 -2
  37. package/dist/{chunk-KHWDTNBZ.js → chunk-U6PGWDMZ.js} +5 -5
  38. package/dist/{chunk-5IA5337I.js → chunk-XJ7K67PP.js} +8 -2
  39. package/dist/{cli-context-7X3M6U73.js → cli-context-WFC3BNGM.js} +131 -25
  40. package/dist/{cli-main-53KG6HAV.js → cli-main-GU3YZLMO.js} +3986 -2827
  41. package/dist/{diag-doctor-7LYUYU35.js → diag-doctor-PCER6KHH.js} +2 -2
  42. package/dist/execute-deps.d.ts +1 -0
  43. package/dist/{execution-MIBWBYB6.js → execution-RAZDDQFC.js} +115 -16
  44. package/dist/execution-specialist-trigger.d.ts +28 -0
  45. package/dist/fleet/acp-live-progress.d.ts +19 -0
  46. package/dist/fleet/host-acp-runner-cache.d.ts +3 -1
  47. package/dist/fleet/host-acp.d.ts +14 -2
  48. package/dist/fleet/host.d.ts +1 -0
  49. package/dist/{hq-IG3YRGCO.js → hq-5XHEIIH6.js} +127 -8
  50. package/dist/hq-command-controller.d.ts +31 -2
  51. package/dist/hq-server/client-address.d.ts +2 -0
  52. package/dist/hq-server/ip-allowlist.d.ts +16 -0
  53. package/dist/hq-server/preflight.d.ts +1 -0
  54. package/dist/hq-server/routes/auth/password-routes.d.ts +1 -1
  55. package/dist/hq-server/routes.d.ts +5 -4
  56. package/dist/hq-server/secret-input.d.ts +7 -0
  57. package/dist/hq-server/types.d.ts +3 -2
  58. package/dist/hq-server/upgrade-handler.d.ts +2 -0
  59. package/dist/hq-server/utils.d.ts +6 -0
  60. package/dist/{hq-server-OILU3NPI.js → hq-server-CNUTBWTK.js} +4 -3
  61. package/dist/hq-server.d.ts +4 -0
  62. package/dist/hq-service-L5INQFM4.js +507 -0
  63. package/dist/hq-service.d.ts +22 -0
  64. package/dist/index.js +4 -4
  65. package/dist/ip-allowlist-NHXO6AKJ.js +9 -0
  66. package/dist/live-settings-input.d.ts +4 -0
  67. package/dist/{mailbox-serve-VUCWZ2SJ.js → mailbox-serve-X3CR6VFW.js} +4 -3
  68. package/dist/{modeldiag-FMJT37SN.js → modeldiag-46CMWUNM.js} +31 -24
  69. package/dist/{per-subcommand-help-BWBHYVJO.js → per-subcommand-help-DHTYU524.js} +2 -2
  70. package/dist/{plugin-usage-HFBI3TFT.js → plugin-usage-M6KET4OZ.js} +2 -2
  71. package/dist/{plugins-PZ2VZL7V.js → plugins-WJLW6ULV.js} +3 -3
  72. package/dist/projects-LMNAGGEU.js +36 -0
  73. package/dist/{providers-models-YVMVYWRS.js → providers-models-6MOGAOVK.js} +2 -2
  74. package/dist/{proxy-wiring-MGRSKZZB.js → proxy-wiring-K2DORFFL.js} +3 -3
  75. package/dist/short-circuit-flags-YDMLAQ5R.js +10 -0
  76. package/dist/slash-commands/acp.d.ts +3 -0
  77. package/dist/slash-commands/codebase-map.d.ts +11 -0
  78. package/dist/slash-commands/command-context.d.ts +29 -0
  79. package/dist/slash-commands/context.d.ts +10 -0
  80. package/dist/slash-commands/ensemble.d.ts +1 -1
  81. package/dist/slash-commands/openai-quota.d.ts +31 -0
  82. package/dist/slash-commands/profile.d.ts +7 -0
  83. package/dist/subcommands/handlers/hq.d.ts +1 -0
  84. package/dist/subcommands/handlers/projects.d.ts +14 -0
  85. package/dist/{subcommands-WJLBHVKC.js → subcommands-7N4RIK6H.js} +2 -2
  86. package/dist/{version-help-MYKF724O.js → version-help-WXI42PZ3.js} +2 -2
  87. package/dist/{webui-server-5R35BHWZ.js → webui-server-OBV5JYJV.js} +27 -4
  88. package/dist/webui-server-options.d.ts +1 -0
  89. package/dist/wiring/atlas-prompt-contributor.d.ts +54 -0
  90. package/dist/wiring/cli-execute-builder.d.ts +1 -0
  91. package/dist/wiring/cli-slash-commands-setup.d.ts +7 -0
  92. package/dist/wiring/codebase-embeddings.d.ts +31 -0
  93. package/dist/wiring/command-host-state.d.ts +9 -0
  94. package/dist/wiring/concept-summarizer.d.ts +32 -0
  95. package/dist/wiring/external-plugins.d.ts +1 -0
  96. package/dist/wiring/lifecycle-plugins.d.ts +2 -1
  97. package/dist/wiring/pipeline.d.ts +2 -0
  98. package/dist/wiring/plugins.d.ts +2 -1
  99. package/dist/wiring/provider-runtime-setup.d.ts +1 -1
  100. package/dist/wiring/provider.d.ts +2 -1
  101. package/dist/wiring/session-command-handlers.d.ts +2 -1
  102. package/dist/wiring/slash-commands.d.ts +1 -0
  103. package/package.json +29 -29
  104. package/dist/auto-discover-providers-VQU3IZMR.js +0 -7
  105. package/dist/chunk-52C7PD2H.js +0 -61
  106. package/dist/chunk-Q5GTM25S.js +0 -17
  107. package/dist/chunk-TNK6237M.js +0 -262
  108. package/dist/projects-L6C6XLDY.js +0 -37
  109. package/dist/short-circuit-flags-UREFSYBL.js +0 -10
@@ -22,7 +22,7 @@
22
22
  "output": ["text"]
23
23
  },
24
24
  "limit": {
25
- "context": 1050000,
25
+ "context": 872000,
26
26
  "output": 128000
27
27
  }
28
28
  },
@@ -44,22 +44,7 @@
44
44
  "output": ["text"]
45
45
  },
46
46
  "limit": {
47
- "context": 1050000,
48
- "output": 128000
49
- }
50
- },
51
- "gpt-5.5": {
52
- "id": "gpt-5.5",
53
- "name": "GPT-5.5",
54
- "description": "Frontier model for complex coding, research, and real-world work.",
55
- "reasoning": true,
56
- "tool_call": true,
57
- "modalities": {
58
- "input": ["text", "image"],
59
- "output": ["text"]
60
- },
61
- "limit": {
62
- "context": 1050000,
47
+ "context": 872000,
63
48
  "output": 128000
64
49
  }
65
50
  },
@@ -81,7 +66,7 @@
81
66
  "output": ["text"]
82
67
  },
83
68
  "limit": {
84
- "context": 1050000,
69
+ "context": 872000,
85
70
  "output": 128000
86
71
  }
87
72
  },
@@ -103,7 +88,22 @@
103
88
  "output": ["text"]
104
89
  },
105
90
  "limit": {
106
- "context": 1050000,
91
+ "context": 872000,
92
+ "output": 128000
93
+ }
94
+ },
95
+ "gpt-5.5": {
96
+ "id": "gpt-5.5",
97
+ "name": "GPT-5.5",
98
+ "description": "Proven previous-generation model for coding and general work.",
99
+ "reasoning": true,
100
+ "tool_call": true,
101
+ "modalities": {
102
+ "input": ["text", "image"],
103
+ "output": ["text"]
104
+ },
105
+ "limit": {
106
+ "context": 272000,
107
107
  "output": 128000
108
108
  }
109
109
  },
@@ -118,7 +118,7 @@
118
118
  "output": ["text"]
119
119
  },
120
120
  "limit": {
121
- "context": 1050000,
121
+ "context": 272000,
122
122
  "output": 128000
123
123
  }
124
124
  },
@@ -133,7 +133,7 @@
133
133
  "output": ["text"]
134
134
  },
135
135
  "limit": {
136
- "context": 1050000,
136
+ "context": 128000,
137
137
  "output": 128000
138
138
  }
139
139
  }
@@ -1,13 +1,15 @@
1
1
  import {
2
2
  createGracefulShutdown,
3
+ formatAcpAgentList,
3
4
  loadCachedAcpRegistry,
4
5
  refreshAcpRegistry,
5
6
  setupProvider
6
- } from "./chunk-ZSZ3EYWH.js";
7
+ } from "./chunk-KEPABQYT.js";
7
8
  import {
8
9
  startCliHqConnection
9
10
  } from "./chunk-TE3Q32JP.js";
10
- import "./chunk-TNK6237M.js";
11
+ import "./chunk-SIGUWXAA.js";
12
+ import "./chunk-DAKVBMD4.js";
11
13
  import "./chunk-DR2OXU46.js";
12
14
 
13
15
  // src/subcommands/handlers/acp.ts
@@ -88,14 +90,15 @@ function startAcpHqTelemetry(options) {
88
90
  };
89
91
  return {
90
92
  wrapAgentFactory(agentFor) {
91
- const wrapped = async (sessionId, cwd, api) => {
92
- const agent = await agentFor(sessionId, cwd, api);
93
+ const wrapped = async (sessionId, cwd, ...rest) => {
94
+ const agent = await agentFor(sessionId, cwd, ...rest);
93
95
  try {
94
96
  attach(sessionId, agent, cwd);
95
97
  } catch {
96
98
  }
97
99
  return agent;
98
100
  };
101
+ Object.assign(wrapped, agentFor);
99
102
  return wrapped;
100
103
  },
101
104
  wrapDispose(dispose) {
@@ -119,7 +122,6 @@ function startAcpHqTelemetry(options) {
119
122
  // src/acp-server-agent.ts
120
123
  import { Agent, Context, createDefaultPipelines } from "@wrongstack/core/agent";
121
124
  import { ToolExecutor } from "@wrongstack/core/execution";
122
- import { wireKanbanPorts } from "@wrongstack/runtime";
123
125
  import { DefaultLogger, DefaultTokenCounter } from "@wrongstack/core/infrastructure";
124
126
  import { EventBus, TOKENS } from "@wrongstack/core/kernel";
125
127
  import { ToolRegistry } from "@wrongstack/core/registry";
@@ -127,7 +129,65 @@ import { AutoApprovePermissionPolicy, ToolCapabilities } from "@wrongstack/core/
127
129
  import {
128
130
  ToolValidationError
129
131
  } from "@wrongstack/core/types";
130
- import { createDefaultContainer } from "@wrongstack/runtime";
132
+ import { createDefaultContainer, wireKanbanPorts } from "@wrongstack/runtime";
133
+
134
+ // src/acp-mcp-servers.ts
135
+ import { MCPRegistry } from "@wrongstack/mcp";
136
+ function pairsToRecord(pairs) {
137
+ if (!pairs || pairs.length === 0) return void 0;
138
+ const out = {};
139
+ for (const { name, value } of pairs) out[name] = value;
140
+ return out;
141
+ }
142
+ function acpMcpServerToConfig(server) {
143
+ const type = "type" in server ? server.type : "stdio";
144
+ if (type === "http" || type === "sse") {
145
+ const headers = pairsToRecord(
146
+ server.headers
147
+ );
148
+ return {
149
+ name: server.name,
150
+ transport: type === "http" ? "streamable-http" : "sse",
151
+ url: server.url,
152
+ ...headers ? { headers } : {},
153
+ description: "Supplied by the ACP client for this session."
154
+ };
155
+ }
156
+ const stdio = server;
157
+ const env = pairsToRecord(server.env);
158
+ return {
159
+ name: server.name,
160
+ transport: "stdio",
161
+ command: stdio.command,
162
+ ...stdio.args && stdio.args.length > 0 ? { args: [...stdio.args] } : {},
163
+ ...env ? { env } : {},
164
+ description: "Supplied by the ACP client for this session."
165
+ };
166
+ }
167
+ async function connectAcpSessionMcpServers(opts) {
168
+ if (opts.servers.length === 0) return void 0;
169
+ const registry = new MCPRegistry({
170
+ toolRegistry: opts.toolRegistry,
171
+ events: opts.events,
172
+ log: opts.logger,
173
+ // Eager, not lazy: the tool list has to be complete before the session's
174
+ // Context snapshots `listForProvider()`, which happens immediately below
175
+ // this call. A lazily registered tool would exist in the registry but be
176
+ // absent from the very first turn's provider payload.
177
+ lazyMode: false,
178
+ ...opts.cacheDir ? { cacheDir: opts.cacheDir } : {}
179
+ });
180
+ for (const server of opts.servers) {
181
+ try {
182
+ await registry.start(acpMcpServerToConfig(server));
183
+ } catch (err) {
184
+ opts.logger.warn(`ACP client MCP server "${server.name}" failed to start`, err);
185
+ }
186
+ }
187
+ return registry;
188
+ }
189
+
190
+ // src/acp-server-agent.ts
131
191
  var AcpServerConfigError = class extends Error {
132
192
  constructor(message) {
133
193
  super(message);
@@ -310,7 +370,8 @@ function buildAcpServerAgentFactory(deps, options = {}) {
310
370
  logger,
311
371
  modelsRegistry: deps.modelsRegistry
312
372
  });
313
- return async function agentFor(_sessionId, cwd, api) {
373
+ const sessionMcp = /* @__PURE__ */ new Map();
374
+ const agentFor = async function agentFor2(sessionId, cwd, api, mcpServers) {
314
375
  await container.resolve(TOKENS.MemoryStore).initialize();
315
376
  const { provider, providerRegistry } = await bootProvider();
316
377
  const events = new EventBus();
@@ -320,6 +381,19 @@ function buildAcpServerAgentFactory(deps, options = {}) {
320
381
  if (api) {
321
382
  wireClientBackedTools(tools, api);
322
383
  }
384
+ if (mcpServers && mcpServers.length > 0) {
385
+ const previous = sessionMcp.get(sessionId);
386
+ if (previous) void previous.stopAll().catch(() => {
387
+ });
388
+ const mcp = await connectAcpSessionMcpServers({
389
+ servers: mcpServers,
390
+ toolRegistry: tools,
391
+ events,
392
+ logger,
393
+ ...wpaths.cacheDir ? { cacheDir: wpaths.cacheDir } : {}
394
+ });
395
+ if (mcp) sessionMcp.set(sessionId, mcp);
396
+ }
323
397
  const permissionPolicy = api?.requestPermission ? new ACPClientPermissionPolicy(api.requestPermission) : new AutoApprovePermissionPolicy();
324
398
  const tokenCounter = new DefaultTokenCounter({
325
399
  registry: deps.modelsRegistry,
@@ -365,9 +439,25 @@ function buildAcpServerAgentFactory(deps, options = {}) {
365
439
  context,
366
440
  permissionPolicy,
367
441
  toolExecutor,
368
- loopDetection: config.tools?.loopDetection
442
+ loopDetection: config.tools?.loopDetection,
443
+ // `tools.maxIterations` was never read on this host, so an operator who
444
+ // set a turn budget got it honoured on the CLI and WebUI hosts and
445
+ // silently ignored here. Only a POSITIVE value is forwarded: the shipped
446
+ // default is `0` ("no hard limit"), and handing that to the agent loop
447
+ // would trade a missing setting for a missing safety net. Absent an
448
+ // explicit budget the Agent keeps its own DEFAULT_MAX_ITERATIONS.
449
+ ...typeof config.tools?.maxIterations === "number" && Number.isFinite(config.tools.maxIterations) && config.tools.maxIterations > 0 ? { maxIterations: config.tools.maxIterations } : {}
369
450
  });
370
451
  };
452
+ agentFor.disposeSession = (sessionId) => {
453
+ const mcp = sessionMcp.get(sessionId);
454
+ if (!mcp) return;
455
+ sessionMcp.delete(sessionId);
456
+ void mcp.stopAll().catch((err) => {
457
+ logger.warn(`ACP session ${sessionId}: MCP teardown failed`, err);
458
+ });
459
+ };
460
+ return agentFor;
371
461
  }
372
462
 
373
463
  // src/subcommands/handlers/acp-connection-gate.ts
@@ -515,10 +605,20 @@ function parseWsPort(flag) {
515
605
  const n = Number(flag);
516
606
  return Number.isInteger(n) && n > 0 && n < 65536 ? n : 8889;
517
607
  }
608
+ function composeDispose(disposeTurn, factory) {
609
+ return (sessionId) => {
610
+ try {
611
+ disposeTurn(sessionId);
612
+ } finally {
613
+ factory?.disposeSession(sessionId);
614
+ }
615
+ };
616
+ }
518
617
  async function runACPWebSocketServer(deps, port) {
519
618
  const host = "127.0.0.1";
520
619
  const echo = deps.flags?.echo === true || deps.flags?.echo === "true";
521
620
  let turnFactory;
621
+ let wsAgentFactory;
522
622
  let echoTurn;
523
623
  let store;
524
624
  let hqTelemetry;
@@ -542,6 +642,7 @@ async function runACPWebSocketServer(deps, port) {
542
642
  appConfig: deps.config
543
643
  });
544
644
  const tracked = hqTelemetry.wrapAgentFactory(agentFor);
645
+ wsAgentFactory = agentFor;
545
646
  turnFactory = () => makeACPServerAgentTurn({ agentFor: tracked });
546
647
  store = deps.paths?.projectDir ? new ACPSessionStore({ dir: path.join(deps.paths.projectDir, "acp-sessions") }) : void 0;
547
648
  }
@@ -575,7 +676,10 @@ async function runACPWebSocketServer(deps, port) {
575
676
  ...connectionTurn ? {
576
677
  replayFor: connectionTurn.replay,
577
678
  seedFor: connectionTurn.seed,
578
- disposeFor: hqTelemetry?.wrapDispose(connectionTurn.dispose) ?? connectionTurn.dispose
679
+ disposeFor: composeDispose(
680
+ hqTelemetry?.wrapDispose(connectionTurn.dispose) ?? connectionTurn.dispose,
681
+ wsAgentFactory
682
+ )
579
683
  } : {},
580
684
  ...store ? { store } : {}
581
685
  });
@@ -650,6 +754,7 @@ async function runACPServer(deps) {
650
754
  projectName: path.basename(deps.cwd ?? process.cwd()),
651
755
  appConfig: deps.config
652
756
  });
757
+ const stdioAgentFactory = agentFor;
653
758
  const turn = makeACPServerAgentTurn({
654
759
  agentFor: stdioHqTelemetry.wrapAgentFactory(agentFor)
655
760
  });
@@ -658,7 +763,10 @@ async function runACPServer(deps) {
658
763
  runTurn: turn,
659
764
  replayFor: turn.replay,
660
765
  seedFor: turn.seed,
661
- disposeFor: stdioHqTelemetry.wrapDispose(turn.dispose),
766
+ disposeFor: composeDispose(
767
+ stdioHqTelemetry.wrapDispose(turn.dispose),
768
+ stdioAgentFactory
769
+ ),
662
770
  ...store ? { store } : {}
663
771
  };
664
772
  })()
@@ -701,35 +809,10 @@ async function runACPServer(deps) {
701
809
  return 0;
702
810
  }
703
811
  async function listACPAgents(deps) {
704
- const registry = new EnsembleRegistry();
705
- const detected = await registry.list();
706
- deps.renderer.write("Detected ACP agents:\n\n");
707
- const installed = detected.filter((a) => a.installed);
708
- const missing = detected.filter((a) => !a.installed);
709
- for (const a of installed) {
710
- const ver = a.version ? ` (${a.version.split("\n")[0]})` : "";
711
- deps.renderer.write(` \u2713 ${a.id.padEnd(16)} ${a.displayName}${ver}
712
- `);
713
- }
714
- for (const a of missing) {
715
- deps.renderer.write(
716
- ` \u2717 ${a.id.padEnd(16)} ${a.displayName} (${a.reason ?? "not installed"})
717
- `
718
- );
719
- }
720
- deps.renderer.write(`
721
- ${installed.length} of ${detected.length} agents available.
722
- `);
812
+ const detected = await new EnsembleRegistry().list();
723
813
  const live = await loadLive(deps);
724
- if (live && live.agents.length > 0) {
725
- deps.renderer.write(
726
- `Synced registry: ${live.agents.length} agents available (run \`wstack acp spawn <id> <task>\`).
727
- `
728
- );
729
- } else {
730
- deps.renderer.write("Run `wstack acp sync` to pull the full official registry (37+ agents).\n");
731
- }
732
- deps.renderer.write("Use `wstack acp spawn <agent-id> <task>` to delegate a task.\n");
814
+ deps.renderer.write(`${formatAcpAgentList({ live, detected })}
815
+ `);
733
816
  return 0;
734
817
  }
735
818
  async function syncACPRegistry(deps) {
@@ -1016,4 +1099,4 @@ ${renderAcpBenchText(result)}
1016
1099
  export {
1017
1100
  acpCmd
1018
1101
  };
1019
- //# sourceMappingURL=acp-3LARESEO.js.map
1102
+ //# sourceMappingURL=acp-AB54FWM2.js.map
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Shared `/acp` + `wstack acp list` renderer.
3
+ *
4
+ * After `sync`, the official registry is the list the user sees — not the
5
+ * 13-entry bundled offline catalog (which still includes experimental ids
6
+ * that are not in https://github.com/agentclientprotocol/registry).
7
+ */
8
+ import { type DetectedAgent } from '@wrongstack/acp';
9
+ import type { LoadedAcpRegistry } from './acp-registry-cache.js';
10
+ export declare function formatAcpAgentList(opts: {
11
+ live: LoadedAcpRegistry | null;
12
+ detected: readonly DetectedAgent[];
13
+ }): string;
14
+ //# sourceMappingURL=acp-agent-list.d.ts.map
@@ -23,8 +23,15 @@
23
23
  */
24
24
  import type { Agent } from '@wrongstack/core/agent';
25
25
  import type { Config } from '@wrongstack/core/types';
26
- /** The per-session Agent factory shape `makeACPServerAgentTurn` consumes. */
27
- type AcpAgentFactory = (sessionId: string, cwd: string, api?: never) => Promise<Agent>;
26
+ /**
27
+ * The per-session Agent factory shape `makeACPServerAgentTurn` consumes.
28
+ *
29
+ * Typed on `...args` rather than a fixed parameter list on purpose: the
30
+ * wrapper below must forward every argument the adapter passes, and the list
31
+ * has grown (it now carries the client's `mcpServers`). A wrapper that names
32
+ * its parameters silently drops the ones added after it was written.
33
+ */
34
+ type AcpAgentFactory = (sessionId: string, cwd: string, ...rest: never[]) => Promise<Agent>;
28
35
  export interface AcpHqTelemetryOptions {
29
36
  projectRoot: string;
30
37
  projectName?: string | undefined;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Client-supplied MCP servers for ACP sessions.
3
+ *
4
+ * The ACP spec lets a client hand the agent a list of MCP servers with
5
+ * `session/new` (and `session/load` / `session/fork`): the editor owns the
6
+ * user's MCP configuration, and the agent is expected to connect to those
7
+ * servers and expose their tools for the session's lifetime.
8
+ *
9
+ * WrongStack advertised `mcpCapabilities: {http: false, sse: false}` and then
10
+ * destructured `mcpServers` at every entry point without ever reading it — so
11
+ * even the mandatory stdio transport was silently dropped. A client got a
12
+ * successful `session/new` and no tools, with nothing anywhere saying why.
13
+ * This module is the missing half: it maps the ACP wire shape onto
14
+ * `MCPServerConfig` and drives a per-session `MCPRegistry` whose tools land in
15
+ * that session's own `ToolRegistry` clone.
16
+ *
17
+ * Per-session, not per-process, deliberately: two ACP sessions may ask for
18
+ * different servers, and closing one must not tear down the other's.
19
+ */
20
+ import type { McpServer } from '@wrongstack/acp/agent';
21
+ import type { EventBus } from '@wrongstack/core/kernel';
22
+ import type { ToolRegistry } from '@wrongstack/core/registry';
23
+ import type { Logger, MCPServerConfig } from '@wrongstack/core/types';
24
+ import { MCPRegistry } from '@wrongstack/mcp';
25
+ /**
26
+ * Translate one ACP server entry into the config shape `MCPRegistry` consumes.
27
+ *
28
+ * Transport names differ between the two specs: ACP's `http` is MCP's
29
+ * `streamable-http`, and an entry with no `type` is stdio (the spec's default,
30
+ * and the only transport a client may assume).
31
+ */
32
+ export declare function acpMcpServerToConfig(server: McpServer): MCPServerConfig;
33
+ export interface AcpSessionMcpOptions {
34
+ servers: readonly McpServer[];
35
+ toolRegistry: ToolRegistry;
36
+ events: EventBus;
37
+ logger: Logger;
38
+ cacheDir?: string | undefined;
39
+ }
40
+ /**
41
+ * Connect the session's MCP servers and register their tools.
42
+ *
43
+ * Returns the registry so the caller can stop it when the session ends, or
44
+ * `undefined` when the client asked for nothing. A server that fails to start
45
+ * is logged and skipped — one unreachable server must not cost the client its
46
+ * whole session, and the failure is visible in `wstack mcp` health output.
47
+ */
48
+ export declare function connectAcpSessionMcpServers(opts: AcpSessionMcpOptions): Promise<MCPRegistry | undefined>;
49
+ //# sourceMappingURL=acp-mcp-servers.d.ts.map
@@ -8,12 +8,14 @@
8
8
  * module is that factory, reusing the same boot pieces the interactive CLI
9
9
  * uses (`setupProvider`, `createDefaultContainer`, builtin tools).
10
10
  *
11
- * Scope: a minimal but real agent. It deliberately does NOT wire MCP servers,
12
- * compaction middleware, model-runtime overlays, or lifecycle hooks — those
13
- * belong in the interactive host. The ACP server is a headless single-turn
14
- * surface; a future PR can layer richer session behaviour if needed.
11
+ * Scope: a minimal but real agent. It deliberately does NOT wire compaction
12
+ * middleware, model-runtime overlays, or lifecycle hooks — those belong in the
13
+ * interactive host. It DOES wire the MCP servers the ACP client supplies with
14
+ * `session/new`, because the spec makes those part of the session contract:
15
+ * the client hands over its MCP configuration and expects the tools to be
16
+ * there (see `acp-mcp-servers.ts`).
15
17
  */
16
- import type { RunTurnApi } from '@wrongstack/acp/agent';
18
+ import type { McpServer, RunTurnApi } from '@wrongstack/acp/agent';
17
19
  import { Agent } from '@wrongstack/core/agent';
18
20
  import { type Logger, type PermissionDecision, type PermissionPolicy, type Tool } from '@wrongstack/core/types';
19
21
  import type { SubcommandDeps } from './subcommands/contracts.js';
@@ -25,6 +27,16 @@ import type { SubcommandDeps } from './subcommands/contracts.js';
25
27
  export declare class AcpServerConfigError extends Error {
26
28
  constructor(message: string);
27
29
  }
30
+ /**
31
+ * The per-session Agent factory, plus the teardown hook for anything the
32
+ * session owns outside the Agent itself (currently the client's MCP servers).
33
+ * `dispose` on the turn adapter drops the Agent; this drops the connections.
34
+ */
35
+ export interface AcpServerAgentFactory {
36
+ (sessionId: string, cwd: string, api?: RunTurnApi, mcpServers?: readonly McpServer[]): Promise<Agent>;
37
+ /** Stop and forget the MCP servers connected for this ACP session. */
38
+ disposeSession(sessionId: string): void;
39
+ }
28
40
  interface AcpAgentFactoryOptions {
29
41
  /** Caller-supplied logger; a minimal stderr logger is created when omitted. */
30
42
  logger?: Logger | undefined;
@@ -63,6 +75,6 @@ export declare class ACPClientPermissionPolicy implements PermissionPolicy {
63
75
  *
64
76
  * Throws `AcpServerConfigError` up front if no provider is configured.
65
77
  */
66
- export declare function buildAcpServerAgentFactory(deps: SubcommandDeps, options?: AcpAgentFactoryOptions): (sessionId: string, cwd: string, api?: RunTurnApi) => Promise<Agent>;
78
+ export declare function buildAcpServerAgentFactory(deps: SubcommandDeps, options?: AcpAgentFactoryOptions): AcpServerAgentFactory;
67
79
  export {};
68
80
  //# sourceMappingURL=acp-server-agent.d.ts.map