@vymalo/opencode-browser 0.12.0 → 0.14.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 (44) hide show
  1. package/dist/agent-client.d.ts +36 -36
  2. package/dist/agent-client.js +201 -189
  3. package/dist/agent-client.js.map +1 -1
  4. package/dist/broker.d.ts +85 -87
  5. package/dist/broker.js +614 -599
  6. package/dist/broker.js.map +1 -1
  7. package/dist/catalog.d.ts +76 -76
  8. package/dist/catalog.js +826 -596
  9. package/dist/catalog.js.map +1 -1
  10. package/dist/endpoint.d.ts +42 -42
  11. package/dist/endpoint.js +132 -131
  12. package/dist/endpoint.js.map +1 -1
  13. package/dist/index.js +1 -0
  14. package/dist/index.js.map +1 -1
  15. package/dist/lib.js +1 -0
  16. package/dist/lib.js.map +1 -1
  17. package/dist/logging.d.ts +6 -6
  18. package/dist/logging.js +60 -63
  19. package/dist/logging.js.map +1 -1
  20. package/dist/node-transport.d.ts +6 -6
  21. package/dist/node-transport.js +48 -44
  22. package/dist/node-transport.js.map +1 -1
  23. package/dist/opencode.d.ts +10 -10
  24. package/dist/opencode.js +143 -146
  25. package/dist/opencode.js.map +1 -1
  26. package/dist/protocol.d.ts +127 -127
  27. package/dist/protocol.js +148 -128
  28. package/dist/protocol.js.map +1 -1
  29. package/dist/schema.d.ts +32 -32
  30. package/dist/schema.js +39 -44
  31. package/dist/schema.js.map +1 -1
  32. package/dist/token-file.d.ts +4 -4
  33. package/dist/token-file.js +68 -60
  34. package/dist/token-file.js.map +1 -1
  35. package/dist/tools.d.ts +11 -11
  36. package/dist/tools.js +128 -123
  37. package/dist/tools.js.map +1 -1
  38. package/dist/transport.d.ts +17 -17
  39. package/dist/transport.js +3 -9
  40. package/dist/transport.js.map +1 -1
  41. package/dist/types.d.ts +61 -61
  42. package/dist/types.js +1 -0
  43. package/dist/types.js.map +1 -1
  44. package/package.json +3 -3
@@ -3,90 +3,98 @@ import { chmodSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSy
3
3
  import { homedir, tmpdir } from "node:os";
4
4
  import { dirname, isAbsolute, join } from "node:path";
5
5
  /**
6
- * Per-user state file so multiple adapters (plugin + MCP server) on one machine
7
- * share a bridge token without the operator wiring one up. It lives in the
8
- * persistent per-OS app-data dir (NOT the temp dir), so a generated token
9
- * survives reboots — you paste it into the extension once, not every session.
10
- * Best-effort: a simultaneous cold start can race (each generates its own token
11
- * before either writes); set an explicit token if you need that guaranteed.
12
- */
6
+ * Per-user state file so multiple adapters (plugin + MCP server) on one machine
7
+ * share a bridge token without the operator wiring one up. It lives in the
8
+ * persistent per-OS app-data dir (NOT the temp dir), so a generated token
9
+ * survives reboots — you paste it into the extension once, not every session.
10
+ * Best-effort: a simultaneous cold start can race (each generates its own token
11
+ * before either writes); set an explicit token if you need that guaranteed.
12
+ */
13
13
  // Only honor an env-provided root if it's a usable absolute path — an empty or
14
14
  // relative value (e.g. exported `XDG_STATE_HOME=""`) would otherwise resolve the
15
15
  // state file relative to the process cwd, scattering per-directory tokens. Fall
16
16
  // back to the home-based default instead.
17
17
  function envRoot(value, fallback) {
18
- return value && isAbsolute(value) ? value : fallback;
18
+ return value && isAbsolute(value) ? value : fallback;
19
19
  }
20
20
  // Resolved lazily (not at module load) so a sandboxed homedir() failure can't
21
21
  // break import, and tests can vary process.env / platform between calls.
22
22
  function resolveStateRoot() {
23
- if (process.platform === "win32") {
24
- return envRoot(process.env.APPDATA, join(homedir(), "AppData", "Roaming"));
25
- }
26
- if (process.platform === "darwin") {
27
- return join(homedir(), "Library", "Application Support");
28
- }
29
- return envRoot(process.env.XDG_STATE_HOME, join(homedir(), ".local", "state"));
23
+ if (process.platform === "win32") {
24
+ return envRoot(process.env.APPDATA, join(homedir(), "AppData", "Roaming"));
25
+ }
26
+ if (process.platform === "darwin") {
27
+ return join(homedir(), "Library", "Application Support");
28
+ }
29
+ return envRoot(process.env.XDG_STATE_HOME, join(homedir(), ".local", "state"));
30
30
  }
31
31
  function bridgeFilePath() {
32
- return join(resolveStateRoot(), "opencode-browser", "bridge.json");
32
+ return join(resolveStateRoot(), "opencode-browser", "bridge.json");
33
33
  }
34
34
  // ≤0.7.x kept this in the temp dir, where the OS clears it on reboot (so the
35
35
  // token kept changing). Read it once as a fallback so upgrading doesn't force a
36
36
  // re-paste; the next write migrates it to the persistent location above.
37
37
  function legacyBridgeFilePath() {
38
- return join(tmpdir(), "opencode-browser-bridge.json");
38
+ return join(tmpdir(), "opencode-browser-bridge.json");
39
39
  }
40
40
  function readFileAt(path) {
41
- try {
42
- return JSON.parse(readFileSync(path, "utf8"));
43
- }
44
- catch {
45
- return null;
46
- }
41
+ try {
42
+ return JSON.parse(readFileSync(path, "utf8"));
43
+ } catch {
44
+ return null;
45
+ }
47
46
  }
48
47
  export function readBridgeFile() {
49
- return readFileAt(bridgeFilePath()) ?? readFileAt(legacyBridgeFilePath());
48
+ return readFileAt(bridgeFilePath()) ?? readFileAt(legacyBridgeFilePath());
50
49
  }
51
50
  export function writeBridgeFile(port, token) {
52
- try {
53
- const file = bridgeFilePath();
54
- mkdirSync(dirname(file), { recursive: true, mode: 0o700 });
55
- // Atomic write: a per-writer temp file then `rename` onto the real path. A
56
- // plain `writeFileSync` is briefly truncated mid-write, and a concurrent
57
- // reader that catches that empty/torn window falls through to GENERATE a
58
- // fresh token (resolveSharedToken) and overwrite the shared one — the root
59
- // of host/extension token divergence when many instances boot at once. The
60
- // pid+uuid suffix keeps concurrent writers from colliding on the temp path.
61
- const tmp = `${file}.${process.pid}.${randomUUID()}.tmp`;
62
- try {
63
- writeFileSync(tmp, JSON.stringify({ port, token }), { mode: 0o600 });
64
- renameSync(tmp, file);
65
- }
66
- catch (err) {
67
- try {
68
- unlinkSync(tmp);
69
- }
70
- catch {
71
- /* nothing to clean up */
72
- }
73
- throw err;
74
- }
75
- chmodSync(file, 0o600);
76
- }
77
- catch {
78
- /* best-effort */
79
- }
51
+ try {
52
+ const file = bridgeFilePath();
53
+ mkdirSync(dirname(file), {
54
+ recursive: true,
55
+ mode: 448
56
+ });
57
+ // Atomic write: a per-writer temp file then `rename` onto the real path. A
58
+ // plain `writeFileSync` is briefly truncated mid-write, and a concurrent
59
+ // reader that catches that empty/torn window falls through to GENERATE a
60
+ // fresh token (resolveSharedToken) and overwrite the shared one — the root
61
+ // of host/extension token divergence when many instances boot at once. The
62
+ // pid+uuid suffix keeps concurrent writers from colliding on the temp path.
63
+ const tmp = `${file}.${process.pid}.${randomUUID()}.tmp`;
64
+ try {
65
+ writeFileSync(tmp, JSON.stringify({
66
+ port,
67
+ token
68
+ }), { mode: 384 });
69
+ renameSync(tmp, file);
70
+ } catch (err) {
71
+ try {
72
+ unlinkSync(tmp);
73
+ } catch {}
74
+ throw err;
75
+ }
76
+ chmodSync(file, 384);
77
+ } catch {}
80
78
  }
81
79
  /** Resolve the bridge token: explicit option wins, else a shared file, else generate. */
82
80
  export function resolveSharedToken(port, explicit, generate) {
83
- if (explicit && explicit.length > 0) {
84
- return { token: explicit, source: "explicit" };
85
- }
86
- const existing = readBridgeFile();
87
- if (existing?.token && (existing.port === undefined || existing.port === port)) {
88
- return { token: existing.token, source: "file" };
89
- }
90
- return { token: generate(), source: "generated" };
81
+ if (explicit && explicit.length > 0) {
82
+ return {
83
+ token: explicit,
84
+ source: "explicit"
85
+ };
86
+ }
87
+ const existing = readBridgeFile();
88
+ if (existing?.token && (existing.port === undefined || existing.port === port)) {
89
+ return {
90
+ token: existing.token,
91
+ source: "file"
92
+ };
93
+ }
94
+ return {
95
+ token: generate(),
96
+ source: "generated"
97
+ };
91
98
  }
99
+
92
100
  //# sourceMappingURL=token-file.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"token-file.js","sourceRoot":"","sources":["../src/token-file.ts"],"names":[],"mappings":"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"}
1
+ {"mappings":"AAAA,SAAS,kBAAkB;AAC3B,SAAS,WAAW,WAAW,cAAc,YAAY,YAAY,qBAAqB;AAC1F,SAAS,SAAS,cAAc;AAChC,SAAS,SAAS,YAAY,YAAY;;;;;;;;;;;;;AAe1C,SAAS,QAAQ,OAA2B,UAA0B;CACpE,OAAO,SAAS,WAAW,KAAK,IAAI,QAAQ;AAC9C;;;AAIA,SAAS,mBAA2B;CAClC,IAAI,QAAQ,aAAa,SAAS;EAChC,OAAO,QAAQ,QAAQ,IAAI,SAAS,KAAK,QAAQ,GAAG,WAAW,SAAS,CAAC;CAC3E;CACA,IAAI,QAAQ,aAAa,UAAU;EACjC,OAAO,KAAK,QAAQ,GAAG,WAAW,qBAAqB;CACzD;CACA,OAAO,QAAQ,QAAQ,IAAI,gBAAgB,KAAK,QAAQ,GAAG,UAAU,OAAO,CAAC;AAC/E;AAEA,SAAS,iBAAyB;CAChC,OAAO,KAAK,iBAAiB,GAAG,oBAAoB,aAAa;AACnE;;;;AAKA,SAAS,uBAA+B;CACtC,OAAO,KAAK,OAAO,GAAG,8BAA8B;AACtD;AAOA,SAAS,WAAW,MAAiC;CACnD,IAAI;EACF,OAAO,KAAK,MAAM,aAAa,MAAM,MAAM,CAAC;CAC9C,QAAQ;EACN,OAAO;CACT;AACF;AAEA,OAAO,SAAS,iBAAoC;CAClD,OAAO,WAAW,eAAe,CAAC,KAAK,WAAW,qBAAqB,CAAC;AAC1E;AAEA,OAAO,SAAS,gBAAgB,MAAc,OAAqB;CACjE,IAAI;EACF,MAAM,OAAO,eAAe;EAC5B,UAAU,QAAQ,IAAI,GAAG;GAAE,WAAW;GAAM,MAAM;EAAM,CAAC;;;;;;;EAOzD,MAAM,MAAM,GAAG,KAAK,GAAG,QAAQ,IAAI,GAAG,WAAW,EAAE;EACnD,IAAI;GACF,cAAc,KAAK,KAAK,UAAU;IAAE;IAAM;GAAM,CAAC,GAAG,EAAE,MAAM,IAAM,CAAC;GACnE,WAAW,KAAK,IAAI;EACtB,SAAS,KAAK;GACZ,IAAI;IACF,WAAW,GAAG;GAChB,QAAQ,CAER;GACA,MAAM;EACR;EACA,UAAU,MAAM,GAAK;CACvB,QAAQ,CAER;AACF;;AAKA,OAAO,SAAS,mBACd,MACA,UACA,UACwC;CACxC,IAAI,YAAY,SAAS,SAAS,GAAG;EACnC,OAAO;GAAE,OAAO;GAAU,QAAQ;EAAW;CAC/C;CACA,MAAM,WAAW,eAAe;CAChC,IAAI,UAAU,UAAU,SAAS,SAAS,aAAa,SAAS,SAAS,OAAO;EAC9E,OAAO;GAAE,OAAO,SAAS;GAAO,QAAQ;EAAO;CACjD;CACA,OAAO;EAAE,OAAO,SAAS;EAAG,QAAQ;CAAY;AAClD","names":[],"sources":["../src/token-file.ts"],"version":3,"file":"token-file.js","sourceRoot":""}
package/dist/tools.d.ts CHANGED
@@ -6,19 +6,19 @@ import type { ResolvedBrowserOptions, ScreenshotResult } from "./types.js";
6
6
  export type SendFn = AgentEndpoint["send"];
7
7
  /** Where the screenshot tool gets its disk-write behavior; swappable in tests. */
8
8
  export type SaveScreenshot = (input: {
9
- group: string;
10
- worktree: string;
11
- shot: ScreenshotResult;
9
+ group: string;
10
+ worktree: string;
11
+ shot: ScreenshotResult;
12
12
  }) => Promise<string>;
13
13
  export interface ToolDeps {
14
- send: SendFn;
15
- options: ResolvedBrowserOptions;
16
- logger: Logger;
17
- saveScreenshot?: SaveScreenshot;
14
+ send: SendFn;
15
+ options: ResolvedBrowserOptions;
16
+ logger: Logger;
17
+ saveScreenshot?: SaveScreenshot;
18
18
  }
19
19
  /**
20
- * Build the `browser_*` tool map registered under `Hooks.tool`, filtered to the
21
- * enabled groups. Each tool is a thin adapter over the shared catalog: validate
22
- * args (zod), forward to the bridge, render the neutral result.
23
- */
20
+ * Build the `browser_*` tool map registered under `Hooks.tool`, filtered to the
21
+ * enabled groups. Each tool is a thin adapter over the shared catalog: validate
22
+ * args (zod), forward to the bridge, render the neutral result.
23
+ */
24
24
  export declare function createBrowserTools(deps: ToolDeps): Record<string, ToolDefinition>;
package/dist/tools.js CHANGED
@@ -4,144 +4,149 @@ import { tool } from "@opencode-ai/plugin";
4
4
  import { BROWSER_TOOLS } from "./catalog.js";
5
5
  const z = tool.schema;
6
6
  function asRecord(value) {
7
- return typeof value === "object" && value !== null ? value : {};
7
+ return typeof value === "object" && value !== null ? value : {};
8
8
  }
9
9
  /**
10
- * Replace anything that isn't filesystem-friendly so a group name is path-safe.
11
- * Dots are intentionally NOT allowed — otherwise a group like `..` or `a/../b`
12
- * could traverse out of the screenshot directory.
13
- */
10
+ * Replace anything that isn't filesystem-friendly so a group name is path-safe.
11
+ * Dots are intentionally NOT allowed — otherwise a group like `..` or `a/../b`
12
+ * could traverse out of the screenshot directory.
13
+ */
14
14
  function slugifyGroup(group) {
15
- const slug = group.replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
16
- return slug.length > 0 ? slug : "default";
15
+ const slug = group.replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
16
+ return slug.length > 0 ? slug : "default";
17
17
  }
18
18
  /** Build the real disk-writer bound to the resolved screenshot directory. */
19
19
  function makeSaveScreenshot(options) {
20
- return async ({ group, worktree, shot }) => {
21
- const base = isAbsolute(options.screenshotDir)
22
- ? options.screenshotDir
23
- : join(worktree, options.screenshotDir);
24
- const dir = join(base, slugifyGroup(group));
25
- await mkdir(dir, { recursive: true });
26
- const stamp = new Date().toISOString().replace(/[:.]/g, "-");
27
- const finalPath = join(dir, `${stamp}.png`);
28
- const tmpPath = `${finalPath}.tmp`;
29
- await writeFile(tmpPath, Buffer.from(shot.base64, "base64"), { mode: 0o600 });
30
- await rename(tmpPath, finalPath);
31
- return finalPath;
32
- };
20
+ return async ({ group, worktree, shot }) => {
21
+ const base = isAbsolute(options.screenshotDir) ? options.screenshotDir : join(worktree, options.screenshotDir);
22
+ const dir = join(base, slugifyGroup(group));
23
+ await mkdir(dir, { recursive: true });
24
+ const stamp = new Date().toISOString().replace(/[:.]/g, "-");
25
+ const finalPath = join(dir, `${stamp}.png`);
26
+ const tmpPath = `${finalPath}.tmp`;
27
+ await writeFile(tmpPath, Buffer.from(shot.base64, "base64"), { mode: 384 });
28
+ await rename(tmpPath, finalPath);
29
+ return finalPath;
30
+ };
33
31
  }
34
32
  function fieldToZod(field) {
35
- let schema;
36
- switch (field.type) {
37
- case "string":
38
- schema = (field.enum
39
- ? z.enum(field.enum)
40
- : z.string());
41
- break;
42
- case "number":
43
- schema = z.number();
44
- break;
45
- case "boolean":
46
- schema = z.boolean();
47
- break;
48
- case "array":
49
- schema = z.array(fieldToZod(field.items));
50
- break;
51
- case "object":
52
- schema = z.object(buildShape(field.properties));
53
- break;
54
- }
55
- if (field.description) {
56
- schema = schema.describe(field.description);
57
- }
58
- if (field.optional) {
59
- schema = schema.optional();
60
- }
61
- return schema;
33
+ let schema;
34
+ switch (field.type) {
35
+ case "string":
36
+ schema = field.enum ? z.enum(field.enum) : z.string();
37
+ break;
38
+ case "number":
39
+ schema = z.number();
40
+ break;
41
+ case "boolean":
42
+ schema = z.boolean();
43
+ break;
44
+ case "array":
45
+ schema = z.array(fieldToZod(field.items));
46
+ break;
47
+ case "object":
48
+ schema = z.object(buildShape(field.properties));
49
+ break;
50
+ }
51
+ if (field.description) {
52
+ schema = schema.describe(field.description);
53
+ }
54
+ if (field.optional) {
55
+ schema = schema.optional();
56
+ }
57
+ return schema;
62
58
  }
63
59
  function buildShape(input) {
64
- const shape = {};
65
- for (const [key, field] of Object.entries(input)) {
66
- shape[key] = fieldToZod(field);
67
- }
68
- return shape;
60
+ const shape = {};
61
+ for (const [key, field] of Object.entries(input)) {
62
+ shape[key] = fieldToZod(field);
63
+ }
64
+ return shape;
69
65
  }
70
66
  /** Render an adapter-neutral result into OpenCode's text-only ToolResult. */
71
67
  async function renderOpenCode(result, deps) {
72
- if (result.kind === "text") {
73
- return result.text;
74
- }
75
- if (result.kind === "json") {
76
- return { output: result.text, metadata: asRecord(result.data) };
77
- }
78
- // image → write the PNG to disk and hand back the path (tool output is text).
79
- const path = await deps.saveScreenshot({
80
- group: deps.group,
81
- worktree: deps.worktree,
82
- shot: {
83
- base64: result.base64,
84
- width: result.width,
85
- height: result.height,
86
- partial: result.partial
87
- }
88
- });
89
- deps.logger.info("browser_screenshot_saved", { group: deps.group, path });
90
- const partialNote = result.partial
91
- ? " Note: only the viewport was captured — this executor can't capture beyond it."
92
- : "";
93
- return {
94
- output: `Saved screenshot to ${path} (${result.width}×${result.height}). Use the read tool to view it.${partialNote}`,
95
- metadata: {
96
- path,
97
- width: result.width,
98
- height: result.height,
99
- partial: Boolean(result.partial),
100
- group: deps.group
101
- }
102
- };
68
+ if (result.kind === "text") {
69
+ return result.text;
70
+ }
71
+ if (result.kind === "json") {
72
+ return {
73
+ output: result.text,
74
+ metadata: asRecord(result.data)
75
+ };
76
+ }
77
+ // image → write the PNG to disk and hand back the path (tool output is text).
78
+ const path = await deps.saveScreenshot({
79
+ group: deps.group,
80
+ worktree: deps.worktree,
81
+ shot: {
82
+ base64: result.base64,
83
+ width: result.width,
84
+ height: result.height,
85
+ partial: result.partial
86
+ }
87
+ });
88
+ deps.logger.info("browser_screenshot_saved", {
89
+ group: deps.group,
90
+ path
91
+ });
92
+ const partialNote = result.partial ? " Note: only the viewport was captured — this executor can't capture beyond it." : "";
93
+ return {
94
+ output: `Saved screenshot to ${path} (${result.width}×${result.height}). Use the read tool to view it.${partialNote}`,
95
+ metadata: {
96
+ path,
97
+ width: result.width,
98
+ height: result.height,
99
+ partial: Boolean(result.partial),
100
+ group: deps.group
101
+ }
102
+ };
103
103
  }
104
104
  /**
105
- * Build the `browser_*` tool map registered under `Hooks.tool`, filtered to the
106
- * enabled groups. Each tool is a thin adapter over the shared catalog: validate
107
- * args (zod), forward to the bridge, render the neutral result.
108
- */
105
+ * Build the `browser_*` tool map registered under `Hooks.tool`, filtered to the
106
+ * enabled groups. Each tool is a thin adapter over the shared catalog: validate
107
+ * args (zod), forward to the bridge, render the neutral result.
108
+ */
109
109
  export function createBrowserTools(deps) {
110
- const enabled = new Set(deps.options.groups);
111
- const saveScreenshot = deps.saveScreenshot ?? makeSaveScreenshot(deps.options);
112
- const tools = {};
113
- for (const spec of BROWSER_TOOLS) {
114
- if (!enabled.has(spec.group)) {
115
- continue;
116
- }
117
- const definition = {
118
- description: spec.description,
119
- args: buildShape(spec.input),
120
- async execute(args, ctx) {
121
- const group = typeof args.group === "string" ? args.group : "";
122
- const target = typeof args.target === "string" ? args.target : undefined;
123
- const params = spec.params ? spec.params(args) : args;
124
- deps.logger.trace("browser_tool_invoked", {
125
- tool: spec.name,
126
- action: spec.action,
127
- group,
128
- target
129
- });
130
- const data = await deps.send(spec.action, group, params, ctx.abort, target, spec.timeoutMs);
131
- deps.logger.trace("browser_tool_completed", { tool: spec.name, group });
132
- const result = spec.result
133
- ? spec.result(data, args)
134
- : { kind: "text", text: `${spec.name} ok` };
135
- return renderOpenCode(result, {
136
- group,
137
- worktree: ctx.worktree,
138
- saveScreenshot,
139
- logger: deps.logger
140
- });
141
- }
142
- };
143
- tools[spec.name] = definition;
144
- }
145
- return tools;
110
+ const enabled = new Set(deps.options.groups);
111
+ const saveScreenshot = deps.saveScreenshot ?? makeSaveScreenshot(deps.options);
112
+ const tools = {};
113
+ for (const spec of BROWSER_TOOLS) {
114
+ if (!enabled.has(spec.group)) {
115
+ continue;
116
+ }
117
+ const definition = {
118
+ description: spec.description,
119
+ args: buildShape(spec.input),
120
+ async execute(args, ctx) {
121
+ const group = typeof args.group === "string" ? args.group : "";
122
+ const target = typeof args.target === "string" ? args.target : undefined;
123
+ const params = spec.params ? spec.params(args) : args;
124
+ deps.logger.trace("browser_tool_invoked", {
125
+ tool: spec.name,
126
+ action: spec.action,
127
+ group,
128
+ target
129
+ });
130
+ const data = await deps.send(spec.action, group, params, ctx.abort, target, spec.timeoutMs);
131
+ deps.logger.trace("browser_tool_completed", {
132
+ tool: spec.name,
133
+ group
134
+ });
135
+ const result = spec.result ? spec.result(data, args) : {
136
+ kind: "text",
137
+ text: `${spec.name} ok`
138
+ };
139
+ return renderOpenCode(result, {
140
+ group,
141
+ worktree: ctx.worktree,
142
+ saveScreenshot,
143
+ logger: deps.logger
144
+ });
145
+ }
146
+ };
147
+ tools[spec.name] = definition;
148
+ }
149
+ return tools;
146
150
  }
151
+
147
152
  //# sourceMappingURL=tools.js.map
package/dist/tools.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
1
+ {"mappings":"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","names":[],"sources":["../src/tools.ts"],"version":3,"file":"tools.js","sourceRoot":""}
@@ -1,27 +1,27 @@
1
1
  /**
2
- * The transport seam for the bridge/broker. The real implementation is the Node
3
- * `ws` variant in `node-transport.ts` (which runs under both Node and Bun);
4
- * tests inject a fake. `listen` is **async** and resolves only once the port is
5
- * actually bound (and rejects on `EADDRINUSE`) — that's what the broker election
6
- * relies on to decide host-vs-guest.
7
- */
2
+ * The transport seam for the bridge/broker. The real implementation is the Node
3
+ * `ws` variant in `node-transport.ts` (which runs under both Node and Bun);
4
+ * tests inject a fake. `listen` is **async** and resolves only once the port is
5
+ * actually bound (and rejects on `EADDRINUSE`) — that's what the broker election
6
+ * relies on to decide host-vs-guest.
7
+ */
8
8
  /** A single connected client (an extension executor or an agent). */
9
9
  export interface ClientConnection {
10
- send(data: string): void;
11
- close(): void;
10
+ send(data: string): void;
11
+ close(): void;
12
12
  }
13
13
  export interface TransportHandlers {
14
- onOpen(conn: ClientConnection): void;
15
- onMessage(conn: ClientConnection, data: string): void;
16
- onClose(conn: ClientConnection): void;
14
+ onOpen(conn: ClientConnection): void;
15
+ onMessage(conn: ClientConnection, data: string): void;
16
+ onClose(conn: ClientConnection): void;
17
17
  }
18
18
  export interface BridgeTransport {
19
- /** Bind + start listening. Resolves when bound; rejects on bind failure. */
20
- listen(opts: {
21
- host: string;
22
- port: number;
23
- }, handlers: TransportHandlers): Promise<void>;
24
- stop(): void;
19
+ /** Bind + start listening. Resolves when bound; rejects on bind failure. */
20
+ listen(opts: {
21
+ host: string;
22
+ port: number;
23
+ }, handlers: TransportHandlers): Promise<void>;
24
+ stop(): void;
25
25
  }
26
26
  /** True for an "address already in use" style bind error (→ become a guest). */
27
27
  export declare function isAddrInUse(err: unknown): boolean;
package/dist/transport.js CHANGED
@@ -1,13 +1,7 @@
1
- /**
2
- * The transport seam for the bridge/broker. The real implementation is the Node
3
- * `ws` variant in `node-transport.ts` (which runs under both Node and Bun);
4
- * tests inject a fake. `listen` is **async** and resolves only once the port is
5
- * actually bound (and rejects on `EADDRINUSE`) — that's what the broker election
6
- * relies on to decide host-vs-guest.
7
- */
8
1
  /** True for an "address already in use" style bind error (→ become a guest). */
9
2
  export function isAddrInUse(err) {
10
- const msg = err instanceof Error ? err.message : String(err);
11
- return /eaddrinuse|address already in use|in use/i.test(msg);
3
+ const msg = err instanceof Error ? err.message : String(err);
4
+ return /eaddrinuse|address already in use|in use/i.test(msg);
12
5
  }
6
+
13
7
  //# sourceMappingURL=transport.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAoBH,gFAAgF;AAChF,MAAM,UAAU,WAAW,CAAC,GAAY;IACtC,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7D,OAAO,2CAA2C,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/D,CAAC"}
1
+ {"mappings":";AA2BA,OAAO,SAAS,YAAY,KAAuB;CACjD,MAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;CAC3D,OAAO,4CAA4C,KAAK,GAAG;AAC7D","names":[],"sources":["../src/transport.ts"],"version":3,"file":"transport.js","sourceRoot":""}