claude-opencode-mcp 1.0.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 (121) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/LICENSE +21 -0
  3. package/README.md +514 -0
  4. package/SECURITY.md +80 -0
  5. package/agents/deepseek-coder.md +32 -0
  6. package/agents/deepseek-researcher.md +36 -0
  7. package/agents/deepseek-reviewer.md +31 -0
  8. package/agents/deepseek-tester.md +31 -0
  9. package/dist/cli/init.d.ts +6 -0
  10. package/dist/cli/init.js +208 -0
  11. package/dist/cli/init.js.map +1 -0
  12. package/dist/config/config.d.ts +109 -0
  13. package/dist/config/config.js +163 -0
  14. package/dist/config/config.js.map +1 -0
  15. package/dist/errors.d.ts +29 -0
  16. package/dist/errors.js +68 -0
  17. package/dist/errors.js.map +1 -0
  18. package/dist/index.d.ts +2 -0
  19. package/dist/index.js +116 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/mcp/execute.d.ts +30 -0
  22. package/dist/mcp/execute.js +128 -0
  23. package/dist/mcp/execute.js.map +1 -0
  24. package/dist/mcp/server.d.ts +19 -0
  25. package/dist/mcp/server.js +38 -0
  26. package/dist/mcp/server.js.map +1 -0
  27. package/dist/mcp/session-utils.d.ts +5 -0
  28. package/dist/mcp/session-utils.js +55 -0
  29. package/dist/mcp/session-utils.js.map +1 -0
  30. package/dist/mcp/tool-utils.d.ts +11 -0
  31. package/dist/mcp/tool-utils.js +44 -0
  32. package/dist/mcp/tool-utils.js.map +1 -0
  33. package/dist/mcp/tools/abort-session.d.ts +3 -0
  34. package/dist/mcp/tools/abort-session.js +48 -0
  35. package/dist/mcp/tools/abort-session.js.map +1 -0
  36. package/dist/mcp/tools/create-session.d.ts +3 -0
  37. package/dist/mcp/tools/create-session.js +53 -0
  38. package/dist/mcp/tools/create-session.js.map +1 -0
  39. package/dist/mcp/tools/delegate-task.d.ts +4 -0
  40. package/dist/mcp/tools/delegate-task.js +98 -0
  41. package/dist/mcp/tools/delegate-task.js.map +1 -0
  42. package/dist/mcp/tools/get-diff.d.ts +3 -0
  43. package/dist/mcp/tools/get-diff.js +97 -0
  44. package/dist/mcp/tools/get-diff.js.map +1 -0
  45. package/dist/mcp/tools/get-session.d.ts +3 -0
  46. package/dist/mcp/tools/get-session.js +79 -0
  47. package/dist/mcp/tools/get-session.js.map +1 -0
  48. package/dist/mcp/tools/list-agents.d.ts +3 -0
  49. package/dist/mcp/tools/list-agents.js +72 -0
  50. package/dist/mcp/tools/list-agents.js.map +1 -0
  51. package/dist/mcp/tools/send-message.d.ts +3 -0
  52. package/dist/mcp/tools/send-message.js +59 -0
  53. package/dist/mcp/tools/send-message.js.map +1 -0
  54. package/dist/opencode/agents.d.ts +46 -0
  55. package/dist/opencode/agents.js +239 -0
  56. package/dist/opencode/agents.js.map +1 -0
  57. package/dist/opencode/binary.d.ts +19 -0
  58. package/dist/opencode/binary.js +129 -0
  59. package/dist/opencode/binary.js.map +1 -0
  60. package/dist/opencode/client.d.ts +32 -0
  61. package/dist/opencode/client.js +55 -0
  62. package/dist/opencode/client.js.map +1 -0
  63. package/dist/opencode/manager.d.ts +66 -0
  64. package/dist/opencode/manager.js +492 -0
  65. package/dist/opencode/manager.js.map +1 -0
  66. package/dist/opencode/permission-watcher.d.ts +26 -0
  67. package/dist/opencode/permission-watcher.js +144 -0
  68. package/dist/opencode/permission-watcher.js.map +1 -0
  69. package/dist/opencode/run.d.ts +39 -0
  70. package/dist/opencode/run.js +318 -0
  71. package/dist/opencode/run.js.map +1 -0
  72. package/dist/opencode/sessions.d.ts +26 -0
  73. package/dist/opencode/sessions.js +105 -0
  74. package/dist/opencode/sessions.js.map +1 -0
  75. package/dist/opencode/setup.d.ts +38 -0
  76. package/dist/opencode/setup.js +109 -0
  77. package/dist/opencode/setup.js.map +1 -0
  78. package/dist/security/paths.d.ts +20 -0
  79. package/dist/security/paths.js +93 -0
  80. package/dist/security/paths.js.map +1 -0
  81. package/dist/security/policy.d.ts +17 -0
  82. package/dist/security/policy.js +86 -0
  83. package/dist/security/policy.js.map +1 -0
  84. package/dist/types/index.d.ts +131 -0
  85. package/dist/types/index.js +2 -0
  86. package/dist/types/index.js.map +1 -0
  87. package/dist/util/fs.d.ts +12 -0
  88. package/dist/util/fs.js +73 -0
  89. package/dist/util/fs.js.map +1 -0
  90. package/dist/util/git.d.ts +54 -0
  91. package/dist/util/git.js +202 -0
  92. package/dist/util/git.js.map +1 -0
  93. package/dist/util/logger.d.ts +21 -0
  94. package/dist/util/logger.js +129 -0
  95. package/dist/util/logger.js.map +1 -0
  96. package/dist/util/text.d.ts +11 -0
  97. package/dist/util/text.js +126 -0
  98. package/dist/util/text.js.map +1 -0
  99. package/dist/workspace/context.d.ts +12 -0
  100. package/dist/workspace/context.js +67 -0
  101. package/dist/workspace/context.js.map +1 -0
  102. package/dist/workspace/resolver.d.ts +35 -0
  103. package/dist/workspace/resolver.js +112 -0
  104. package/dist/workspace/resolver.js.map +1 -0
  105. package/dist/workspace/validator.d.ts +13 -0
  106. package/dist/workspace/validator.js +102 -0
  107. package/dist/workspace/validator.js.map +1 -0
  108. package/docs/agent-configuration.md +100 -0
  109. package/docs/architecture.md +115 -0
  110. package/docs/claude-code-setup.md +116 -0
  111. package/docs/configuration.md +184 -0
  112. package/docs/contributing.md +71 -0
  113. package/docs/deepseek-setup.md +84 -0
  114. package/docs/development.md +146 -0
  115. package/docs/installation.md +88 -0
  116. package/docs/opencode-setup.md +97 -0
  117. package/docs/security-audit.md +80 -0
  118. package/docs/security.md +128 -0
  119. package/docs/troubleshooting.md +126 -0
  120. package/docs/workspace-model.md +126 -0
  121. package/package.json +79 -0
@@ -0,0 +1,492 @@
1
+ import { spawn } from "node:child_process";
2
+ import { deepMerge } from "../config/config.js";
3
+ import { BridgeError } from "../errors.js";
4
+ import { BinaryResolver } from "./binary.js";
5
+ import { createWorkspaceClient, fetchHealth, normalizeBaseUrl, } from "./client.js";
6
+ import { PermissionWatcher } from "./permission-watcher.js";
7
+ function buildConfigHash(config, agentConfig) {
8
+ return JSON.stringify({
9
+ agents: agentConfig,
10
+ hostname: config.opencode.hostname,
11
+ port: config.opencode.port,
12
+ logLevel: config.opencode.logLevel,
13
+ binary: config.opencode.binary,
14
+ defaults: config.defaults,
15
+ security: config.security,
16
+ });
17
+ }
18
+ function mergeInlineConfig(existing, agentConfig) {
19
+ let base = {};
20
+ if (existing?.trim()) {
21
+ try {
22
+ const parsed = JSON.parse(existing);
23
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
24
+ base = parsed;
25
+ }
26
+ }
27
+ catch {
28
+ // ignore malformed inherited config content
29
+ }
30
+ }
31
+ return JSON.stringify(deepMerge(base, { agent: agentConfig }));
32
+ }
33
+ export class OpenCodeManager {
34
+ servers = new Map();
35
+ /** Every spawned child, tracked from creation so shutdown can always kill it. */
36
+ children = new Set();
37
+ logger;
38
+ env;
39
+ resolver;
40
+ stopping = false;
41
+ constructor(options) {
42
+ this.logger = options.logger;
43
+ this.env = options.env ?? process.env;
44
+ this.resolver = new BinaryResolver(options.binaryOptions ?? {});
45
+ }
46
+ resolveAuth(config) {
47
+ const password = config.opencode.password ?? this.env.OPENCODE_SERVER_PASSWORD ?? null;
48
+ if (!password)
49
+ return null;
50
+ const username = config.opencode.username ?? this.env.OPENCODE_SERVER_USERNAME ?? "opencode";
51
+ return { username, password };
52
+ }
53
+ /** Ensure an OpenCode server exists for the workspace and return its record key. */
54
+ async ensure(input) {
55
+ if (this.stopping) {
56
+ throw new BridgeError("OPENCODE_UNAVAILABLE", "The bridge is shutting down.");
57
+ }
58
+ if (input.config.opencode.url) {
59
+ return this.ensureExternal(input);
60
+ }
61
+ return this.ensureLocal(input);
62
+ }
63
+ async clientFor(input) {
64
+ const key = await this.ensure(input);
65
+ const record = this.servers.get(key);
66
+ if (!record) {
67
+ throw new BridgeError("OPENCODE_UNAVAILABLE", "OpenCode server disappeared unexpectedly.");
68
+ }
69
+ record.lastUsedAt = Date.now();
70
+ let client = record.clients.get(input.cwd);
71
+ if (!client) {
72
+ client = createWorkspaceClient({
73
+ baseUrl: record.baseUrl,
74
+ directory: input.cwd,
75
+ auth: record.auth,
76
+ });
77
+ record.clients.set(input.cwd, client);
78
+ }
79
+ return client;
80
+ }
81
+ /**
82
+ * Return a client for a workspace only when a live server already serves it.
83
+ * Used by read-only tools (get_session, get_diff, abort_session) that must
84
+ * not start an OpenCode process as a side effect.
85
+ */
86
+ existingClient(cwd) {
87
+ for (const record of this.servers.values()) {
88
+ if (record.dead)
89
+ continue;
90
+ if (!record.external && record.cwd !== cwd)
91
+ continue;
92
+ let client = record.clients.get(cwd);
93
+ if (!client) {
94
+ client = createWorkspaceClient({
95
+ baseUrl: record.baseUrl,
96
+ directory: cwd,
97
+ auth: record.auth,
98
+ });
99
+ record.clients.set(cwd, client);
100
+ }
101
+ record.lastUsedAt = Date.now();
102
+ return client;
103
+ }
104
+ return null;
105
+ }
106
+ getExistingServerVersion(cwd) {
107
+ for (const record of this.servers.values()) {
108
+ if (record.dead)
109
+ continue;
110
+ if (!record.external && record.cwd !== cwd)
111
+ continue;
112
+ return record.version;
113
+ }
114
+ return null;
115
+ }
116
+ externalKey(url) {
117
+ return `external:${normalizeBaseUrl(url)}`;
118
+ }
119
+ async ensureExternal(input) {
120
+ const rawUrl = input.config.opencode.url;
121
+ if (!rawUrl) {
122
+ throw new BridgeError("OPENCODE_UNAVAILABLE", "opencode.url is not configured.");
123
+ }
124
+ const parsed = new URL(rawUrl);
125
+ let auth = this.resolveAuth(input.config);
126
+ if (parsed.username || parsed.password) {
127
+ auth = {
128
+ username: decodeURIComponent(parsed.username || "opencode"),
129
+ password: decodeURIComponent(parsed.password),
130
+ };
131
+ parsed.username = "";
132
+ parsed.password = "";
133
+ }
134
+ const baseUrl = normalizeBaseUrl(parsed.toString());
135
+ const key = this.externalKey(baseUrl);
136
+ let record = this.servers.get(key);
137
+ if (record && !record.dead) {
138
+ record.lastUsedAt = Date.now();
139
+ await this.assertAgentsAvailable(record, input.agentConfig, input.cwd);
140
+ return key;
141
+ }
142
+ const client = createWorkspaceClient({ baseUrl, directory: input.cwd, auth });
143
+ const health = await this.tryHealth(baseUrl, auth);
144
+ if (!health) {
145
+ throw new BridgeError("OPENCODE_UNAVAILABLE", `Could not reach the configured OpenCode server at ${baseUrl}.`, { details: { url: baseUrl } });
146
+ }
147
+ record = {
148
+ key,
149
+ baseUrl,
150
+ cwd: input.cwd,
151
+ external: true,
152
+ process: null,
153
+ version: health.version,
154
+ auth,
155
+ lastUsedAt: Date.now(),
156
+ activeRuns: 0,
157
+ configHash: "external",
158
+ clients: new Map([[input.cwd, client]]),
159
+ watcher: new PermissionWatcher(baseUrl, auth, this.logger),
160
+ dead: false,
161
+ stderr: [],
162
+ };
163
+ this.servers.set(key, record);
164
+ await this.assertAgentsAvailable(record, input.agentConfig, input.cwd);
165
+ this.logger.info("connected to external OpenCode server", {
166
+ url: baseUrl,
167
+ version: health.version,
168
+ });
169
+ return key;
170
+ }
171
+ async assertAgentsAvailable(record, agentConfig, cwd) {
172
+ const required = Object.keys(agentConfig);
173
+ if (required.length === 0)
174
+ return;
175
+ const client = record.clients.get(cwd) ??
176
+ createWorkspaceClient({ baseUrl: record.baseUrl, directory: cwd, auth: record.auth });
177
+ record.clients.set(cwd, client);
178
+ let available;
179
+ try {
180
+ const result = await client.app.agents();
181
+ available = new Set((result.data ?? []).map((agent) => agent.name));
182
+ }
183
+ catch (error) {
184
+ throw new BridgeError("OPENCODE_UNAVAILABLE", `Could not list agents from the external OpenCode server: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
185
+ }
186
+ const missing = required.filter((name) => !available.has(name));
187
+ if (missing.length > 0) {
188
+ throw new BridgeError("AGENT_NOT_FOUND", [
189
+ `The external OpenCode server is missing required agent(s): ${missing.join(", ")}.`,
190
+ "Add them to the server's OpenCode configuration (for example .opencode/agents/)",
191
+ "or run `claude-opencode init` to materialize the agent definitions,",
192
+ "or let the bridge start its own server by unsetting opencode.url.",
193
+ ].join(" "), { details: { missing, url: record.baseUrl } });
194
+ }
195
+ }
196
+ async ensureLocal(input) {
197
+ const key = `local:${input.cwd}`;
198
+ const hash = buildConfigHash(input.config, input.agentConfig);
199
+ let record = this.servers.get(key);
200
+ if (record && !record.dead) {
201
+ if (record.configHash === hash) {
202
+ record.lastUsedAt = Date.now();
203
+ return key;
204
+ }
205
+ if (record.activeRuns > 0) {
206
+ this.logger.warn("agent configuration changed while a delegated run is active; keeping the existing OpenCode server", { cwd: input.cwd });
207
+ record.lastUsedAt = Date.now();
208
+ return key;
209
+ }
210
+ await this.stop(key);
211
+ record = undefined;
212
+ }
213
+ const binary = await this.resolver.resolve(input.config.opencode.binary);
214
+ const auth = this.resolveAuth(input.config);
215
+ const stderr = [];
216
+ const { url, process: child } = await this.spawnServer(input, binary.command, auth, stderr);
217
+ if (this.stopping) {
218
+ child.kill("SIGKILL");
219
+ throw new BridgeError("OPENCODE_UNAVAILABLE", "The bridge is shutting down.");
220
+ }
221
+ const client = createWorkspaceClient({ baseUrl: url, directory: input.cwd, auth });
222
+ const health = await this.waitForHealth(url, auth);
223
+ if (!health) {
224
+ child.kill("SIGKILL");
225
+ if (this.stopping) {
226
+ throw new BridgeError("OPENCODE_UNAVAILABLE", "The bridge is shutting down.");
227
+ }
228
+ throw new BridgeError("OPENCODE_UNAVAILABLE", `OpenCode server started at ${url} but never became healthy.`, { details: { url, stderr: stderr.join("").slice(-2000) } });
229
+ }
230
+ if (this.stopping) {
231
+ child.kill("SIGKILL");
232
+ throw new BridgeError("OPENCODE_UNAVAILABLE", "The bridge is shutting down.");
233
+ }
234
+ record = {
235
+ key,
236
+ baseUrl: url,
237
+ cwd: input.cwd,
238
+ external: false,
239
+ process: child,
240
+ version: health.version,
241
+ auth,
242
+ lastUsedAt: Date.now(),
243
+ activeRuns: 0,
244
+ configHash: hash,
245
+ clients: new Map([[input.cwd, client]]),
246
+ watcher: new PermissionWatcher(url, auth, this.logger),
247
+ dead: false,
248
+ stderr,
249
+ };
250
+ this.servers.set(key, record);
251
+ child.on("exit", (code, signal) => {
252
+ record.dead = true;
253
+ record.clients.clear();
254
+ void record.watcher?.stop();
255
+ if (!this.stopping) {
256
+ this.logger.error("OpenCode server exited", {
257
+ cwd: input.cwd,
258
+ code,
259
+ signal,
260
+ activeRuns: record.activeRuns,
261
+ stderr: stderr.join("").slice(-1000),
262
+ });
263
+ }
264
+ });
265
+ child.unref?.();
266
+ this.logger.info("started OpenCode server", {
267
+ cwd: input.cwd,
268
+ url,
269
+ version: health.version,
270
+ binary: binary.command,
271
+ source: binary.source,
272
+ });
273
+ await this.evictIfNeeded(input.config.opencode.maxServers);
274
+ return key;
275
+ }
276
+ spawnServer(input, command, auth, stderr) {
277
+ const { config } = input;
278
+ const args = [
279
+ "serve",
280
+ `--hostname=${config.opencode.hostname}`,
281
+ `--port=${config.opencode.port}`,
282
+ ];
283
+ if (config.opencode.logLevel)
284
+ args.push(`--log-level=${config.opencode.logLevel}`);
285
+ const childEnv = { ...this.env };
286
+ delete childEnv.OPENCODE_CLIENT;
287
+ childEnv.OPENCODE_CONFIG_CONTENT = mergeInlineConfig(this.env.OPENCODE_CONFIG_CONTENT, input.agentConfig);
288
+ if (auth) {
289
+ childEnv.OPENCODE_SERVER_USERNAME = auth.username;
290
+ childEnv.OPENCODE_SERVER_PASSWORD = auth.password;
291
+ }
292
+ const child = spawn(command, args, {
293
+ cwd: input.cwd,
294
+ env: childEnv,
295
+ stdio: ["ignore", "pipe", "pipe"],
296
+ windowsHide: true,
297
+ });
298
+ // Track the child from the instant it exists: shutdown may race with
299
+ // startup, and anything spawned must be killable even before ensureLocal
300
+ // registers a server record.
301
+ this.children.add(child);
302
+ child.once("exit", () => this.children.delete(child));
303
+ return new Promise((resolve, reject) => {
304
+ let settled = false;
305
+ let output = "";
306
+ const timeout = setTimeout(() => {
307
+ if (settled)
308
+ return;
309
+ settled = true;
310
+ child.kill("SIGKILL");
311
+ reject(new BridgeError("OPENCODE_START_TIMEOUT", `OpenCode did not start within ${config.opencode.startupTimeout}ms.`, { details: { stderr: stderr.join("").slice(-2000) }, retryable: true }));
312
+ }, config.opencode.startupTimeout);
313
+ const finish = (fn) => {
314
+ if (settled)
315
+ return;
316
+ settled = true;
317
+ clearTimeout(timeout);
318
+ fn();
319
+ };
320
+ // Ensure a rejected startup never leaves a process behind.
321
+ const fail = (error) => {
322
+ finish(() => {
323
+ if (child.exitCode === null && child.signalCode === null) {
324
+ child.kill("SIGKILL");
325
+ }
326
+ reject(error);
327
+ });
328
+ };
329
+ child.stdout?.on("data", (chunk) => {
330
+ if (settled)
331
+ return;
332
+ if (this.stopping) {
333
+ fail(new BridgeError("OPENCODE_UNAVAILABLE", "The bridge is shutting down."));
334
+ return;
335
+ }
336
+ output += chunk.toString("utf8");
337
+ const lines = output.split("\n");
338
+ for (const line of lines) {
339
+ if (line.startsWith("opencode server listening")) {
340
+ const match = line.match(/on\s+(https?:\/\/\S+)/);
341
+ if (match?.[1]) {
342
+ const url = normalizeBaseUrl(match[1]);
343
+ finish(() => resolve({ url, process: child }));
344
+ return;
345
+ }
346
+ fail(new BridgeError("OPENCODE_ERROR", `Could not parse server URL from: ${line}`));
347
+ return;
348
+ }
349
+ }
350
+ });
351
+ child.stderr?.on("data", (chunk) => {
352
+ const text = chunk.toString("utf8");
353
+ stderr.push(text);
354
+ if (stderr.length > 200)
355
+ stderr.splice(0, stderr.length - 200);
356
+ });
357
+ child.on("error", (error) => {
358
+ fail(new BridgeError("OPENCODE_NOT_AVAILABLE", `Failed to launch OpenCode: ${error.message}`, {
359
+ cause: error,
360
+ }));
361
+ });
362
+ child.on("exit", (code) => {
363
+ finish(() => reject(new BridgeError("OPENCODE_UNAVAILABLE", `OpenCode exited during startup with code ${code}.`, { details: { stderr: stderr.join("").slice(-2000) } })));
364
+ });
365
+ });
366
+ }
367
+ async tryHealth(baseUrl, auth) {
368
+ return fetchHealth(baseUrl, auth);
369
+ }
370
+ async waitForHealth(baseUrl, auth) {
371
+ for (let attempt = 0; attempt < 15; attempt += 1) {
372
+ if (this.stopping)
373
+ return null;
374
+ const health = await this.tryHealth(baseUrl, auth);
375
+ if (health)
376
+ return health;
377
+ await new Promise((resolve) => setTimeout(resolve, 300));
378
+ }
379
+ return null;
380
+ }
381
+ beginRun(key, sessionId) {
382
+ const record = this.servers.get(key);
383
+ if (!record)
384
+ return;
385
+ record.activeRuns += 1;
386
+ record.lastUsedAt = Date.now();
387
+ if (sessionId)
388
+ record.watcher?.activate(sessionId);
389
+ }
390
+ endRun(key, sessionId) {
391
+ const record = this.servers.get(key);
392
+ if (!record)
393
+ return;
394
+ record.activeRuns = Math.max(0, record.activeRuns - 1);
395
+ if (sessionId)
396
+ record.watcher?.deactivate(sessionId);
397
+ }
398
+ isDead(key) {
399
+ const record = this.servers.get(key);
400
+ return !record || record.dead;
401
+ }
402
+ getStatus() {
403
+ return [...this.servers.values()].map((record) => ({
404
+ key: record.key,
405
+ url: record.baseUrl,
406
+ cwd: record.cwd,
407
+ external: record.external,
408
+ version: record.version,
409
+ activeRuns: record.activeRuns,
410
+ lastUsedAt: record.lastUsedAt,
411
+ }));
412
+ }
413
+ getRunningServerKeys() {
414
+ return [...this.servers.values()].filter((record) => !record.dead).map((record) => record.key);
415
+ }
416
+ async evictIfNeeded(maxServers) {
417
+ if (this.servers.size <= maxServers)
418
+ return;
419
+ const candidates = [...this.servers.values()]
420
+ .filter((record) => !record.external && record.activeRuns === 0)
421
+ .sort((a, b) => a.lastUsedAt - b.lastUsedAt);
422
+ while (this.servers.size > maxServers && candidates.length > 0) {
423
+ const candidate = candidates.shift();
424
+ if (!candidate)
425
+ break;
426
+ this.logger.info("evicting idle OpenCode server", { cwd: candidate.cwd });
427
+ await this.stop(candidate.key);
428
+ }
429
+ }
430
+ async stop(key) {
431
+ const record = this.servers.get(key);
432
+ if (!record)
433
+ return;
434
+ this.servers.delete(key);
435
+ record.clients.clear();
436
+ await record.watcher?.stop();
437
+ const child = record.process;
438
+ if (!child || child.exitCode !== null || child.signalCode !== null)
439
+ return;
440
+ await new Promise((resolve) => {
441
+ let done = false;
442
+ const finalize = () => {
443
+ if (done)
444
+ return;
445
+ done = true;
446
+ resolve();
447
+ };
448
+ child.once("exit", finalize);
449
+ try {
450
+ child.kill("SIGTERM");
451
+ }
452
+ catch {
453
+ finalize();
454
+ return;
455
+ }
456
+ const killTimer = setTimeout(() => {
457
+ try {
458
+ child.kill("SIGKILL");
459
+ }
460
+ catch {
461
+ // already gone
462
+ }
463
+ finalize();
464
+ }, 5000);
465
+ killTimer.unref?.();
466
+ });
467
+ }
468
+ async stopAll() {
469
+ this.stopping = true;
470
+ const keys = [...this.servers.keys()];
471
+ await Promise.allSettled(keys.map((key) => this.stop(key)));
472
+ }
473
+ /**
474
+ * Synchronous last-resort cleanup for `process.on("exit")`: kills any child
475
+ * that was spawned but not yet registered (shutdown races) so no OpenCode
476
+ * process is orphaned when the bridge exits.
477
+ */
478
+ killAllSync() {
479
+ for (const child of this.children) {
480
+ if (child.exitCode === null && child.signalCode === null) {
481
+ try {
482
+ child.kill("SIGKILL");
483
+ }
484
+ catch {
485
+ // already gone
486
+ }
487
+ }
488
+ }
489
+ this.children.clear();
490
+ }
491
+ }
492
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/opencode/manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE9D,OAAO,EAAE,SAAS,EAAuB,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAE,cAAc,EAA6B,MAAM,aAAa,CAAC;AACxE,OAAO,EAEL,qBAAqB,EACrB,WAAW,EACX,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AA8C5D,SAAS,eAAe,CAAC,MAAsB,EAAE,WAAoC;IACnF,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,MAAM,EAAE,WAAW;QACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ;QAClC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI;QAC1B,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ;QAClC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM;QAC9B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC1B,CAAC,CAAC;AACL,CAAC;AAED,SAAS,iBAAiB,CACxB,QAA4B,EAC5B,WAAoC;IAEpC,IAAI,IAAI,GAA4B,EAAE,CAAC;IACvC,IAAI,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC;QACrB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACpC,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBACnE,IAAI,GAAG,MAAiC,CAAC;YAC3C,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,4CAA4C;QAC9C,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,OAAO,eAAe;IACT,OAAO,GAAG,IAAI,GAAG,EAAwB,CAAC;IAC3D,iFAAiF;IAChE,QAAQ,GAAG,IAAI,GAAG,EAAgB,CAAC;IACnC,MAAM,CAAS;IACf,GAAG,CAAoB;IACvB,QAAQ,CAAiB;IAClC,QAAQ,GAAG,KAAK,CAAC;IAEzB,YAAY,OAA+B;QACzC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;QACtC,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,WAAW,CAAC,MAAsB;QAChC,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,wBAAwB,IAAI,IAAI,CAAC;QACvF,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAC3B,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,wBAAwB,IAAI,UAAU,CAAC;QAC7F,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;IAChC,CAAC;IAED,oFAAoF;IACpF,KAAK,CAAC,MAAM,CAAC,KAAwB;QACnC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,IAAI,WAAW,CAAC,sBAAsB,EAAE,8BAA8B,CAAC,CAAC;QAChF,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,KAAwB;QACtC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,WAAW,CAAC,sBAAsB,EAAE,2CAA2C,CAAC,CAAC;QAC7F,CAAC;QACD,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC/B,IAAI,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,qBAAqB,CAAC;gBAC7B,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,SAAS,EAAE,KAAK,CAAC,GAAG;gBACpB,IAAI,EAAE,MAAM,CAAC,IAAI;aAClB,CAAC,CAAC;YACH,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;OAIG;IACH,cAAc,CAAC,GAAW;QACxB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3C,IAAI,MAAM,CAAC,IAAI;gBAAE,SAAS;YAC1B,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,GAAG,KAAK,GAAG;gBAAE,SAAS;YACrD,IAAI,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACrC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,GAAG,qBAAqB,CAAC;oBAC7B,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,SAAS,EAAE,GAAG;oBACd,IAAI,EAAE,MAAM,CAAC,IAAI;iBAClB,CAAC,CAAC;gBACH,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAClC,CAAC;YACD,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC/B,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,wBAAwB,CAAC,GAAW;QAClC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;YAC3C,IAAI,MAAM,CAAC,IAAI;gBAAE,SAAS;YAC1B,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,GAAG,KAAK,GAAG;gBAAE,SAAS;YACrD,OAAO,MAAM,CAAC,OAAO,CAAC;QACxB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,WAAW,CAAC,GAAW;QAC7B,OAAO,YAAY,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;IAC7C,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,KAAwB;QACnD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;QACzC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,WAAW,CAAC,sBAAsB,EAAE,iCAAiC,CAAC,CAAC;QACnF,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACvC,IAAI,GAAG;gBACL,QAAQ,EAAE,kBAAkB,CAAC,MAAM,CAAC,QAAQ,IAAI,UAAU,CAAC;gBAC3D,QAAQ,EAAE,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC;aAC9C,CAAC;YACF,MAAM,CAAC,QAAQ,GAAG,EAAE,CAAC;YACrB,MAAM,CAAC,QAAQ,GAAG,EAAE,CAAC;QACvB,CAAC;QACD,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAEtC,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAC3B,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC/B,MAAM,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;YACvE,OAAO,GAAG,CAAC;QACb,CAAC;QAED,MAAM,MAAM,GAAG,qBAAqB,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,WAAW,CACnB,sBAAsB,EACtB,qDAAqD,OAAO,GAAG,EAC/D,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,CAC9B,CAAC;QACJ,CAAC;QAED,MAAM,GAAG;YACP,GAAG;YACH,OAAO;YACP,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,IAAI;YACJ,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;YACtB,UAAU,EAAE,CAAC;YACb,UAAU,EAAE,UAAU;YACtB,OAAO,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;YACvC,OAAO,EAAE,IAAI,iBAAiB,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;YAC1D,IAAI,EAAE,KAAK;YACX,MAAM,EAAE,EAAE;SACX,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAC9B,MAAM,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QACvE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uCAAuC,EAAE;YACxD,GAAG,EAAE,OAAO;YACZ,OAAO,EAAE,MAAM,CAAC,OAAO;SACxB,CAAC,CAAC;QACH,OAAO,GAAG,CAAC;IACb,CAAC;IAEO,KAAK,CAAC,qBAAqB,CACjC,MAAoB,EACpB,WAAoC,EACpC,GAAW;QAEX,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC1C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAClC,MAAM,MAAM,GACV,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;YACvB,qBAAqB,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACxF,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAChC,IAAI,SAAsB,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;YACzC,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QACtE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,WAAW,CACnB,sBAAsB,EACtB,4DACE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CACvD,EAAE,EACF,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QAChE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,WAAW,CACnB,iBAAiB,EACjB;gBACE,8DAA8D,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;gBACnF,iFAAiF;gBACjF,qEAAqE;gBACrE,mEAAmE;aACpE,CAAC,IAAI,CAAC,GAAG,CAAC,EACX,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,OAAO,EAAE,EAAE,CAC9C,CAAC;QACJ,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,KAAwB;QAChD,MAAM,GAAG,GAAG,SAAS,KAAK,CAAC,GAAG,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;QAC9D,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEnC,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAC3B,IAAI,MAAM,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;gBAC/B,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC/B,OAAO,GAAG,CAAC;YACb,CAAC;YACD,IAAI,MAAM,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;gBAC1B,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,mGAAmG,EACnG,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CACnB,CAAC;gBACF,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC/B,OAAO,GAAG,CAAC;YACb,CAAC;YACD,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACrB,MAAM,GAAG,SAAS,CAAC;QACrB,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACzE,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAE5F,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACtB,MAAM,IAAI,WAAW,CAAC,sBAAsB,EAAE,8BAA8B,CAAC,CAAC;QAChF,CAAC;QAED,MAAM,MAAM,GAAG,qBAAqB,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QACnF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACtB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClB,MAAM,IAAI,WAAW,CAAC,sBAAsB,EAAE,8BAA8B,CAAC,CAAC;YAChF,CAAC;YACD,MAAM,IAAI,WAAW,CACnB,sBAAsB,EACtB,8BAA8B,GAAG,4BAA4B,EAC7D,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAC3D,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACtB,MAAM,IAAI,WAAW,CAAC,sBAAsB,EAAE,8BAA8B,CAAC,CAAC;QAChF,CAAC;QAED,MAAM,GAAG;YACP,GAAG;YACH,OAAO,EAAE,GAAG;YACZ,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,IAAI;YACJ,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;YACtB,UAAU,EAAE,CAAC;YACb,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;YACvC,OAAO,EAAE,IAAI,iBAAiB,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;YACtD,IAAI,EAAE,KAAK;YACX,MAAM;SACP,CAAC;QACF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAE9B,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;YAChC,MAAO,CAAC,IAAI,GAAG,IAAI,CAAC;YACpB,MAAO,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACxB,KAAK,MAAO,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACnB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE;oBAC1C,GAAG,EAAE,KAAK,CAAC,GAAG;oBACd,IAAI;oBACJ,MAAM;oBACN,UAAU,EAAE,MAAO,CAAC,UAAU;oBAC9B,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC;iBACrC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;QAEhB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,EAAE;YAC1C,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,GAAG;YACH,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,MAAM,EAAE,MAAM,CAAC,OAAO;YACtB,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC3D,OAAO,GAAG,CAAC;IACb,CAAC;IAEO,WAAW,CACjB,KAAwB,EACxB,OAAe,EACf,IAA4B,EAC5B,MAAgB;QAEhB,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;QACzB,MAAM,IAAI,GAAG;YACX,OAAO;YACP,cAAc,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE;YACxC,UAAU,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE;SACjC,CAAC;QACF,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ;YAAE,IAAI,CAAC,IAAI,CAAC,eAAe,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEnF,MAAM,QAAQ,GAAsB,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACpD,OAAO,QAAQ,CAAC,eAAe,CAAC;QAChC,QAAQ,CAAC,uBAAuB,GAAG,iBAAiB,CAClD,IAAI,CAAC,GAAG,CAAC,uBAAuB,EAChC,KAAK,CAAC,WAAW,CAClB,CAAC;QACF,IAAI,IAAI,EAAE,CAAC;YACT,QAAQ,CAAC,wBAAwB,GAAG,IAAI,CAAC,QAAQ,CAAC;YAClD,QAAQ,CAAC,wBAAwB,GAAG,IAAI,CAAC,QAAQ,CAAC;QACpD,CAAC;QAED,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;YACjC,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,GAAG,EAAE,QAAQ;YACb,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;YACjC,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;QAEH,qEAAqE;QACrE,yEAAyE;QACzE,6BAA6B;QAC7B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAEtD,OAAO,IAAI,OAAO,CAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACnD,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC9B,IAAI,OAAO;oBAAE,OAAO;gBACpB,OAAO,GAAG,IAAI,CAAC;gBACf,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACtB,MAAM,CACJ,IAAI,WAAW,CACb,wBAAwB,EACxB,iCAAiC,MAAM,CAAC,QAAQ,CAAC,cAAc,KAAK,EACpE,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CACvE,CACF,CAAC;YACJ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;YAEnC,MAAM,MAAM,GAAG,CAAC,EAAc,EAAE,EAAE;gBAChC,IAAI,OAAO;oBAAE,OAAO;gBACpB,OAAO,GAAG,IAAI,CAAC;gBACf,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,EAAE,EAAE,CAAC;YACP,CAAC,CAAC;YAEF,2DAA2D;YAC3D,MAAM,IAAI,GAAG,CAAC,KAAkB,EAAE,EAAE;gBAClC,MAAM,CAAC,GAAG,EAAE;oBACV,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;wBACzD,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBACxB,CAAC;oBACD,MAAM,CAAC,KAAK,CAAC,CAAC;gBAChB,CAAC,CAAC,CAAC;YACL,CAAC,CAAC;YAEF,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBACzC,IAAI,OAAO;oBAAE,OAAO;gBACpB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAClB,IAAI,CAAC,IAAI,WAAW,CAAC,sBAAsB,EAAE,8BAA8B,CAAC,CAAC,CAAC;oBAC9E,OAAO;gBACT,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACjC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,IAAI,IAAI,CAAC,UAAU,CAAC,2BAA2B,CAAC,EAAE,CAAC;wBACjD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;wBAClD,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;4BACf,MAAM,GAAG,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;4BACvC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;4BAC/C,OAAO;wBACT,CAAC;wBACD,IAAI,CAAC,IAAI,WAAW,CAAC,gBAAgB,EAAE,oCAAoC,IAAI,EAAE,CAAC,CAAC,CAAC;wBACpF,OAAO;oBACT,CAAC;gBACH,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBACzC,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACpC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAClB,IAAI,MAAM,CAAC,MAAM,GAAG,GAAG;oBAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;YACjE,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC1B,IAAI,CACF,IAAI,WAAW,CAAC,wBAAwB,EAAE,8BAA8B,KAAK,CAAC,OAAO,EAAE,EAAE;oBACvF,KAAK,EAAE,KAAK;iBACb,CAAC,CACH,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBACxB,MAAM,CAAC,GAAG,EAAE,CACV,MAAM,CACJ,IAAI,WAAW,CACb,sBAAsB,EACtB,4CAA4C,IAAI,GAAG,EACnD,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CACtD,CACF,CACF,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,SAAS,CACrB,OAAe,EACf,IAA4B;QAE5B,OAAO,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACpC,CAAC;IAEO,KAAK,CAAC,aAAa,CACzB,OAAe,EACf,IAA4B;QAE5B,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,EAAE,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;YACjD,IAAI,IAAI,CAAC,QAAQ;gBAAE,OAAO,IAAI,CAAC;YAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACnD,IAAI,MAAM;gBAAE,OAAO,MAAM,CAAC;YAC1B,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QAC3D,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,QAAQ,CAAC,GAAW,EAAE,SAAkB;QACtC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC;QACvB,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC/B,IAAI,SAAS;YAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,CAAC,GAAW,EAAE,SAAkB;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;QACvD,IAAI,SAAS;YAAE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrC,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC;IAChC,CAAC;IAED,SAAS;QACP,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YACjD,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,GAAG,EAAE,MAAM,CAAC,OAAO;YACnB,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,UAAU,EAAE,MAAM,CAAC,UAAU;SAC9B,CAAC,CAAC,CAAC;IACN,CAAC;IAED,oBAAoB;QAClB,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjG,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,UAAkB;QAC5C,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,UAAU;YAAE,OAAO;QAC5C,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;aAC1C,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,UAAU,KAAK,CAAC,CAAC;aAC/D,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/D,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC;YACrC,IAAI,CAAC,SAAS;gBAAE,MAAM;YACtB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,+BAA+B,EAAE,EAAE,GAAG,EAAE,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC;YAC1E,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAW;QACpB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACzB,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACvB,MAAM,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC;QAC7B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI;YAAE,OAAO;QAE3E,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAClC,IAAI,IAAI,GAAG,KAAK,CAAC;YACjB,MAAM,QAAQ,GAAG,GAAG,EAAE;gBACpB,IAAI,IAAI;oBAAE,OAAO;gBACjB,IAAI,GAAG,IAAI,CAAC;gBACZ,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC;YACF,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAC7B,IAAI,CAAC;gBACH,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACxB,CAAC;YAAC,MAAM,CAAC;gBACP,QAAQ,EAAE,CAAC;gBACX,OAAO;YACT,CAAC;YACD,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;gBAChC,IAAI,CAAC;oBACH,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACxB,CAAC;gBAAC,MAAM,CAAC;oBACP,eAAe;gBACjB,CAAC;gBACD,QAAQ,EAAE,CAAC;YACb,CAAC,EAAE,IAAI,CAAC,CAAC;YACT,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACtC,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED;;;;OAIG;IACH,WAAW;QACT,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClC,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;gBACzD,IAAI,CAAC;oBACH,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACxB,CAAC;gBAAC,MAAM,CAAC;oBACP,eAAe;gBACjB,CAAC;YACH,CAAC;QACH,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;CACF"}
@@ -0,0 +1,26 @@
1
+ import type { Logger } from "../util/logger.js";
2
+ import { type AuthCredentials } from "./client.js";
3
+ /**
4
+ * Listens to the OpenCode event stream and rejects permission requests that
5
+ * would otherwise wait forever (the bridge is headless: there is no human to
6
+ * answer an `ask` rule). The bridge's own agents never emit `ask` rules, but a
7
+ * user's global OpenCode configuration might.
8
+ */
9
+ export declare class PermissionWatcher {
10
+ private readonly baseUrl;
11
+ private readonly auth;
12
+ private readonly logger;
13
+ private readonly active;
14
+ private controller;
15
+ private loopPromise;
16
+ private stopped;
17
+ constructor(baseUrl: string, auth: AuthCredentials | null, logger: Logger);
18
+ activate(sessionId: string): void;
19
+ deactivate(sessionId: string): void;
20
+ private ensureStarted;
21
+ stop(): Promise<void>;
22
+ private loop;
23
+ private consume;
24
+ private handleLine;
25
+ private reject;
26
+ }