@vymalo/opencode-browser 0.7.1 → 0.7.3

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.
package/README.md CHANGED
@@ -12,7 +12,8 @@ can call and hosts a localhost WebSocket **bridge**. A companion **browser exten
12
12
  (Chromium MV3 + Firefox) connects to the bridge and drives real tabs.
13
13
 
14
14
  > Browser extensions can't host servers, so the plugin is the server and the extension dials
15
- > out to it. The plugin runs on Bun (inside OpenCode) and serves the bridge with `Bun.serve`.
15
+ > out to it. The bridge is served with the `ws` package, which runs under both runtimes OpenCode
16
+ > uses — Bun (CLI / `opencode web`) and Node (the desktop app) — so it works in either.
16
17
 
17
18
  ```mermaid
18
19
  flowchart LR
@@ -14,6 +14,13 @@ export interface EndpointOptions {
14
14
  label?: string;
15
15
  /** Delay before retrying election after a drop. */
16
16
  reelectMs?: number;
17
+ /**
18
+ * Fired whenever this endpoint becomes the host — on the initial election AND
19
+ * on any later failover re-election. Use it for host-only side effects like
20
+ * advertising the bridge token, so they recur on every host transition rather
21
+ * than only once at startup.
22
+ */
23
+ onHost?: () => void;
17
24
  }
18
25
  export interface EndpointDeps {
19
26
  logger: Logger;
package/dist/endpoint.js CHANGED
@@ -34,26 +34,39 @@ export async function createEndpoint(opts, deps) {
34
34
  return;
35
35
  }
36
36
  mode = "electing";
37
- // 1) Try to host (win the bind).
38
- const transport = deps.createServerTransport();
39
- const candidate = new Broker({
40
- host: opts.host,
41
- port: opts.port,
42
- token: opts.token,
43
- executor: opts.executor,
44
- timeoutMs: opts.timeoutMs
45
- }, { logger: deps.logger, transport });
37
+ // 1) Try to host (win the bind). Everything is inside the try so a transport
38
+ // that throws at construction (or a Broker that fails to start) degrades to
39
+ // guest instead of crashing the plugin load.
40
+ let candidate = null;
46
41
  try {
42
+ const transport = deps.createServerTransport();
43
+ candidate = new Broker({
44
+ host: opts.host,
45
+ port: opts.port,
46
+ token: opts.token,
47
+ executor: opts.executor,
48
+ timeoutMs: opts.timeoutMs
49
+ }, { logger: deps.logger, transport });
47
50
  await candidate.start();
48
51
  broker = candidate;
49
52
  current = candidate.createLocalAgent();
50
53
  mode = "host";
51
54
  deps.logger.info("browser_endpoint_mode", { mode: "host" });
55
+ // Isolate the side-effect callback: a throw here must NOT reach the outer
56
+ // catch, which would stop the freshly-started broker and degrade to guest.
57
+ try {
58
+ opts.onHost?.();
59
+ }
60
+ catch (onHostErr) {
61
+ deps.logger.error("browser_endpoint_onhost_error", {
62
+ message: onHostErr instanceof Error ? onHostErr.message : String(onHostErr)
63
+ });
64
+ }
52
65
  return;
53
66
  }
54
67
  catch (err) {
55
68
  try {
56
- candidate.stop();
69
+ candidate?.stop();
57
70
  }
58
71
  catch {
59
72
  /* never bound */
@@ -79,7 +92,9 @@ export async function createEndpoint(opts, deps) {
79
92
  agentClient = client;
80
93
  current = client;
81
94
  mode = "guest";
82
- deps.logger.info("browser_endpoint_mode", { mode: "guest" });
95
+ // Guest election is routine and happens once per plugin load (every
96
+ // session) — keep it at debug so it doesn't dominate the log stream.
97
+ deps.logger.debug("browser_endpoint_mode", { mode: "guest" });
83
98
  }
84
99
  catch {
85
100
  scheduleReelect();
@@ -1 +1 @@
1
- {"version":3,"file":"endpoint.js","sourceRoot":"","sources":["../src/endpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAsB,MAAM,EAAE,MAAM,aAAa,CAAC;AAGzD,OAAO,EAAwB,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAyCnE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAqB,EAAE,IAAkB;IAC5E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,QAAQ,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;IACzD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,GAAG,CAAC;IAExC,IAAI,IAAI,GAAiB,UAAU,CAAC;IACpC,IAAI,MAAM,GAAkB,IAAI,CAAC;IACjC,IAAI,WAAW,GAAuB,IAAI,CAAC;IAC3C,IAAI,OAAO,GAAyB,IAAI,CAAC;IACzC,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,YAAY,GAAyC,IAAI,CAAC;IAE9D,MAAM,eAAe,GAAG,GAAS,EAAE;QACjC,MAAM,GAAG,IAAI,CAAC;QACd,WAAW,GAAG,IAAI,CAAC;QACnB,OAAO,GAAG,IAAI,CAAC;QACf,IAAI,GAAG,UAAU,CAAC;QAClB,IAAI,MAAM,IAAI,YAAY,EAAE,CAAC;YAC3B,OAAO;QACT,CAAC;QACD,YAAY,GAAG,UAAU,CAAC,GAAG,EAAE;YAC7B,YAAY,GAAG,IAAI,CAAC;YACpB,KAAK,KAAK,EAAE,CAAC;QACf,CAAC,EAAE,SAAS,CAAC,CAAC;IAChB,CAAC,CAAC;IAEF,KAAK,UAAU,KAAK;QAClB,IAAI,MAAM,EAAE,CAAC;YACX,OAAO;QACT,CAAC;QACD,IAAI,GAAG,UAAU,CAAC;QAElB,iCAAiC;QACjC,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC/C,MAAM,SAAS,GAAG,IAAI,MAAM,CAC1B;YACE,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,EACD,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,CACnC,CAAC;QACF,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;YACxB,MAAM,GAAG,SAAS,CAAC;YACnB,OAAO,GAAG,SAAS,CAAC,gBAAgB,EAAE,CAAC;YACvC,IAAI,GAAG,MAAM,CAAC;YACd,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YAC5D,OAAO;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC;gBACH,SAAS,CAAC,IAAI,EAAE,CAAC;YACnB,CAAC;YAAC,MAAM,CAAC;gBACP,iBAAiB;YACnB,CAAC;YACD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;gBACtB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,6BAA6B,EAAE;oBAC9C,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBAC1D,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,2CAA2C;QAC3C,MAAM,MAAM,GAAG,IAAI,WAAW,CAC5B,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,EACxE;YACE,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,YAAY,EAAE,IAAI,CAAC,iBAAiB;YACpC,OAAO,EAAE,GAAG,EAAE;gBACZ,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,eAAe,EAAE,CAAC;gBACpB,CAAC;YACH,CAAC;SACF,CACF,CAAC;QACF,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;YACvB,WAAW,GAAG,MAAM,CAAC;YACrB,OAAO,GAAG,MAAM,CAAC;YACjB,IAAI,GAAG,OAAO,CAAC;YACf,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAC/D,CAAC;QAAC,MAAM,CAAC;YACP,eAAe,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IAED,MAAM,KAAK,EAAE,CAAC;IAEd,OAAO;QACL,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,CAC9C,OAAO;YACL,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;YACrD,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QACxE,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE;QACjC,QAAQ,EAAE,GAAG,EAAE;YACb,MAAM,GAAG,IAAI,CAAC;YACd,IAAI,YAAY,EAAE,CAAC;gBACjB,YAAY,CAAC,YAAY,CAAC,CAAC;gBAC3B,YAAY,GAAG,IAAI,CAAC;YACtB,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,EAAE,IAAI,EAAE,CAAC;YACjB,CAAC;YAAC,MAAM,CAAC;gBACP,YAAY;YACd,CAAC;YACD,IAAI,CAAC;gBACH,WAAW,EAAE,IAAI,EAAE,CAAC;YACtB,CAAC;YAAC,MAAM,CAAC;gBACP,YAAY;YACd,CAAC;QACH,CAAC;QACD,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI;QAChB,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM;KACrB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"endpoint.js","sourceRoot":"","sources":["../src/endpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAsB,MAAM,EAAE,MAAM,aAAa,CAAC;AAGzD,OAAO,EAAwB,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAgDnE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAqB,EAAE,IAAkB;IAC5E,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,QAAQ,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;IACzD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,GAAG,CAAC;IAExC,IAAI,IAAI,GAAiB,UAAU,CAAC;IACpC,IAAI,MAAM,GAAkB,IAAI,CAAC;IACjC,IAAI,WAAW,GAAuB,IAAI,CAAC;IAC3C,IAAI,OAAO,GAAyB,IAAI,CAAC;IACzC,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,YAAY,GAAyC,IAAI,CAAC;IAE9D,MAAM,eAAe,GAAG,GAAS,EAAE;QACjC,MAAM,GAAG,IAAI,CAAC;QACd,WAAW,GAAG,IAAI,CAAC;QACnB,OAAO,GAAG,IAAI,CAAC;QACf,IAAI,GAAG,UAAU,CAAC;QAClB,IAAI,MAAM,IAAI,YAAY,EAAE,CAAC;YAC3B,OAAO;QACT,CAAC;QACD,YAAY,GAAG,UAAU,CAAC,GAAG,EAAE;YAC7B,YAAY,GAAG,IAAI,CAAC;YACpB,KAAK,KAAK,EAAE,CAAC;QACf,CAAC,EAAE,SAAS,CAAC,CAAC;IAChB,CAAC,CAAC;IAEF,KAAK,UAAU,KAAK;QAClB,IAAI,MAAM,EAAE,CAAC;YACX,OAAO;QACT,CAAC;QACD,IAAI,GAAG,UAAU,CAAC;QAElB,6EAA6E;QAC7E,4EAA4E;QAC5E,6CAA6C;QAC7C,IAAI,SAAS,GAAkB,IAAI,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC/C,SAAS,GAAG,IAAI,MAAM,CACpB;gBACE,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,SAAS,EAAE,IAAI,CAAC,SAAS;aAC1B,EACD,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,CACnC,CAAC;YACF,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;YACxB,MAAM,GAAG,SAAS,CAAC;YACnB,OAAO,GAAG,SAAS,CAAC,gBAAgB,EAAE,CAAC;YACvC,IAAI,GAAG,MAAM,CAAC;YACd,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YAC5D,0EAA0E;YAC1E,2EAA2E;YAC3E,IAAI,CAAC;gBACH,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YAClB,CAAC;YAAC,OAAO,SAAS,EAAE,CAAC;gBACnB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE;oBACjD,OAAO,EAAE,SAAS,YAAY,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC;iBAC5E,CAAC,CAAC;YACL,CAAC;YACD,OAAO;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC;gBACH,SAAS,EAAE,IAAI,EAAE,CAAC;YACpB,CAAC;YAAC,MAAM,CAAC;gBACP,iBAAiB;YACnB,CAAC;YACD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;gBACtB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,6BAA6B,EAAE;oBAC9C,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBAC1D,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,2CAA2C;QAC3C,MAAM,MAAM,GAAG,IAAI,WAAW,CAC5B,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,EACxE;YACE,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,YAAY,EAAE,IAAI,CAAC,iBAAiB;YACpC,OAAO,EAAE,GAAG,EAAE;gBACZ,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,eAAe,EAAE,CAAC;gBACpB,CAAC;YACH,CAAC;SACF,CACF,CAAC;QACF,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;YACvB,WAAW,GAAG,MAAM,CAAC;YACrB,OAAO,GAAG,MAAM,CAAC;YACjB,IAAI,GAAG,OAAO,CAAC;YACf,oEAAoE;YACpE,qEAAqE;YACrE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAChE,CAAC;QAAC,MAAM,CAAC;YACP,eAAe,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IAED,MAAM,KAAK,EAAE,CAAC;IAEd,OAAO;QACL,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,CAC9C,OAAO;YACL,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;YACrD,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QACxE,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE;QACjC,QAAQ,EAAE,GAAG,EAAE;YACb,MAAM,GAAG,IAAI,CAAC;YACd,IAAI,YAAY,EAAE,CAAC;gBACjB,YAAY,CAAC,YAAY,CAAC,CAAC;gBAC3B,YAAY,GAAG,IAAI,CAAC;YACtB,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,EAAE,IAAI,EAAE,CAAC;YACjB,CAAC;YAAC,MAAM,CAAC;gBACP,YAAY;YACd,CAAC;YACD,IAAI,CAAC;gBACH,WAAW,EAAE,IAAI,EAAE,CAAC;YACtB,CAAC;YAAC,MAAM,CAAC;gBACP,YAAY;YACd,CAAC;QACH,CAAC;QACD,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI;QAChB,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM;KACrB,CAAC;AACJ,CAAC"}
package/dist/lib.d.ts CHANGED
@@ -2,7 +2,8 @@ export { type BrowserPluginFactoryOptions, createBrowserPlugin, OpencodeBrowserP
2
2
  export { type AgentEndpoint, Broker, BrokerError, type BrokerDeps, type BrokerOptions } from "./broker.js";
3
3
  export { AgentClient, AgentClientError, type AgentClientDeps, type AgentClientOptions, type AgentSocket, type AgentSocketFactory, type AgentSocketHandlers } from "./agent-client.js";
4
4
  export { createEndpoint, type Endpoint, type EndpointDeps, type EndpointMode, type EndpointOptions } from "./endpoint.js";
5
- export { type BridgeTransport, type ClientConnection, createBunTransport, isAddrInUse, type TransportHandlers } from "./transport.js";
5
+ export { type BridgeTransport, type ClientConnection, isAddrInUse, type TransportHandlers } from "./transport.js";
6
+ export { createNodeAgentSocket, createNodeTransport } from "./node-transport.js";
6
7
  export { type BridgeFile, readBridgeFile, resolveSharedToken, type TokenSource, writeBridgeFile } from "./token-file.js";
7
8
  export { createBrowserTools, type SaveScreenshot, type SendFn, type ToolDeps } from "./tools.js";
8
9
  export { BROWSER_TOOLS, DEFAULT_GROUPS, type NeutralResult, TOOL_GROUPS, type ToolGroup, type ToolSpec } from "./catalog.js";
package/dist/lib.js CHANGED
@@ -2,7 +2,8 @@ export { createBrowserPlugin, OpencodeBrowserPlugin } from "./opencode.js";
2
2
  export { Broker, BrokerError } from "./broker.js";
3
3
  export { AgentClient, AgentClientError } from "./agent-client.js";
4
4
  export { createEndpoint } from "./endpoint.js";
5
- export { createBunTransport, isAddrInUse } from "./transport.js";
5
+ export { isAddrInUse } from "./transport.js";
6
+ export { createNodeAgentSocket, createNodeTransport } from "./node-transport.js";
6
7
  export { readBridgeFile, resolveSharedToken, writeBridgeFile } from "./token-file.js";
7
8
  export { createBrowserTools } from "./tools.js";
8
9
  export { BROWSER_TOOLS, DEFAULT_GROUPS, TOOL_GROUPS } from "./catalog.js";
package/dist/lib.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAEL,MAAM,EACN,WAAW,EAGZ,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,WAAW,EACX,gBAAgB,EAMjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,cAAc,EAKf,MAAM,eAAe,CAAC;AAEvB,OAAO,EAGL,kBAAkB,EAClB,WAAW,EAEZ,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAEL,cAAc,EACd,kBAAkB,EAElB,eAAe,EAChB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,kBAAkB,EAAmD,MAAM,YAAY,CAAC;AAEjG,OAAO,EACL,aAAa,EACb,cAAc,EAEd,WAAW,EAGZ,MAAM,cAAc,CAAC;AAEtB,OAAO,EAA+C,YAAY,EAAE,MAAM,aAAa,CAAC;AAExF,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EAIrB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,eAAe,EAKf,WAAW,EACX,WAAW,EAIX,UAAU,EACV,MAAM,EACN,gBAAgB,EAGjB,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAEL,MAAM,EACN,WAAW,EAGZ,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,WAAW,EACX,gBAAgB,EAMjB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,cAAc,EAKf,MAAM,eAAe,CAAC;AAEvB,OAAO,EAGL,WAAW,EAEZ,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAEjF,OAAO,EAEL,cAAc,EACd,kBAAkB,EAElB,eAAe,EAChB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,kBAAkB,EAAmD,MAAM,YAAY,CAAC;AAEjG,OAAO,EACL,aAAa,EACb,cAAc,EAEd,WAAW,EAGZ,MAAM,cAAc,CAAC;AAEtB,OAAO,EAA+C,YAAY,EAAE,MAAM,aAAa,CAAC;AAExF,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EAIrB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,eAAe,EAKf,WAAW,EACX,WAAW,EAIX,UAAU,EACV,MAAM,EACN,gBAAgB,EAGjB,MAAM,eAAe,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { AgentSocket, AgentSocketHandlers } from "./agent-client.js";
2
+ import type { BridgeTransport } from "./transport.js";
3
+ /**
4
+ * `BridgeTransport` backed by the Node `ws` package. This is the bridge's single
5
+ * host transport: `ws` runs under both Node *and* Bun, so it covers every
6
+ * runtime OpenCode loads the plugin in — the Bun CLI/web *and* the Node desktop
7
+ * app — without a Bun-specific code path. `listen` resolves once bound and
8
+ * rejects on `EADDRINUSE`, which drives the endpoint's host-vs-guest election.
9
+ */
10
+ export declare function createNodeTransport(): BridgeTransport;
11
+ /** Agent-socket factory backed by the Node `ws` client (guest mode). */
12
+ export declare function createNodeAgentSocket(url: string, handlers: AgentSocketHandlers): AgentSocket;
@@ -0,0 +1,52 @@
1
+ import { WebSocket, WebSocketServer } from "ws";
2
+ /**
3
+ * `BridgeTransport` backed by the Node `ws` package. This is the bridge's single
4
+ * host transport: `ws` runs under both Node *and* Bun, so it covers every
5
+ * runtime OpenCode loads the plugin in — the Bun CLI/web *and* the Node desktop
6
+ * app — without a Bun-specific code path. `listen` resolves once bound and
7
+ * rejects on `EADDRINUSE`, which drives the endpoint's host-vs-guest election.
8
+ */
9
+ export function createNodeTransport() {
10
+ let server = null;
11
+ return {
12
+ listen({ host, port }, handlers) {
13
+ return new Promise((resolve, reject) => {
14
+ const wss = new WebSocketServer({ host, port });
15
+ server = wss;
16
+ wss.once("listening", () => resolve());
17
+ wss.once("error", (err) => reject(err));
18
+ wss.on("connection", (ws) => {
19
+ const conn = {
20
+ send: (data) => ws.send(data),
21
+ close: () => ws.close()
22
+ };
23
+ handlers.onOpen(conn);
24
+ ws.on("message", (data) => handlers.onMessage(conn, data.toString()));
25
+ ws.on("close", () => handlers.onClose(conn));
26
+ ws.on("error", () => {
27
+ /* close follows */
28
+ });
29
+ });
30
+ });
31
+ },
32
+ stop() {
33
+ server?.close();
34
+ server = null;
35
+ }
36
+ };
37
+ }
38
+ /** Agent-socket factory backed by the Node `ws` client (guest mode). */
39
+ export function createNodeAgentSocket(url, handlers) {
40
+ const ws = new WebSocket(url);
41
+ ws.on("open", () => handlers.onOpen());
42
+ ws.on("message", (data) => handlers.onMessage(data.toString()));
43
+ ws.on("close", () => handlers.onClose());
44
+ ws.on("error", () => {
45
+ /* close follows */
46
+ });
47
+ return {
48
+ send: (data) => ws.send(data),
49
+ close: () => ws.close()
50
+ };
51
+ }
52
+ //# sourceMappingURL=node-transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-transport.js","sourceRoot":"","sources":["../src/node-transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAKhD;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB;IACjC,IAAI,MAAM,GAA2B,IAAI,CAAC;IAE1C,OAAO;QACL,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,QAAQ;YAC7B,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC3C,MAAM,GAAG,GAAG,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;gBAChD,MAAM,GAAG,GAAG,CAAC;gBACb,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;gBACvC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;gBACxC,GAAG,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,EAAa,EAAE,EAAE;oBACrC,MAAM,IAAI,GAAqB;wBAC7B,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;wBAC7B,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE;qBACxB,CAAC;oBACF,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;oBACtB,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;oBACtE,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;oBAC7C,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;wBAClB,mBAAmB;oBACrB,CAAC,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;QACD,IAAI;YACF,MAAM,EAAE,KAAK,EAAE,CAAC;YAChB,MAAM,GAAG,IAAI,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,qBAAqB,CAAC,GAAW,EAAE,QAA6B;IAC9E,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;IAC9B,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACvC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAChE,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACzC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QAClB,mBAAmB;IACrB,CAAC,CAAC,CAAC;IACH,OAAO;QACL,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;QAC7B,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE;KACxB,CAAC;AACJ,CAAC"}
@@ -2,7 +2,7 @@ import type { Plugin } from "@opencode-ai/plugin";
2
2
  import type { AgentSocketFactory } from "./agent-client.js";
3
3
  import { type Logger } from "./logging.js";
4
4
  import { type SaveScreenshot } from "./tools.js";
5
- import { type BridgeTransport } from "./transport.js";
5
+ import type { BridgeTransport } from "./transport.js";
6
6
  export interface BrowserPluginFactoryOptions {
7
7
  /** Inject a logger (defaults to the OpenCode-piped logger). */
8
8
  logger?: Logger;
package/dist/opencode.js CHANGED
@@ -3,21 +3,8 @@ import { DEFAULT_GROUPS, TOOL_GROUPS } from "./catalog.js";
3
3
  import { createEndpoint } from "./endpoint.js";
4
4
  import { createJsonConsoleLogger, DEFAULT_LOG_LEVEL, fromOpenCodeLogLevel, LOG_LEVEL_PRIORITY } from "./logging.js";
5
5
  import { resolveSharedToken, writeBridgeFile } from "./token-file.js";
6
+ import { createNodeAgentSocket, createNodeTransport } from "./node-transport.js";
6
7
  import { createBrowserTools } from "./tools.js";
7
- import { createBunTransport } from "./transport.js";
8
- /** Agent-socket factory using the runtime's global WebSocket (Bun provides one). */
9
- const bunAgentSocket = (url, handlers) => {
10
- const Ctor = globalThis.WebSocket;
11
- if (!Ctor) {
12
- throw new Error("global WebSocket is not available in this runtime");
13
- }
14
- const ws = new Ctor(url);
15
- ws.addEventListener("open", () => handlers.onOpen());
16
- ws.addEventListener("message", (event) => handlers.onMessage(typeof event.data === "string" ? event.data : String(event.data)));
17
- ws.addEventListener("close", () => handlers.onClose());
18
- ws.addEventListener("error", () => { });
19
- return { send: (data) => ws.send(data), close: () => ws.close() };
20
- };
21
8
  function resolveGroups(raw) {
22
9
  if (!Array.isArray(raw)) {
23
10
  return [...DEFAULT_GROUPS];
@@ -40,11 +27,19 @@ const DEFAULTS = {
40
27
  */
41
28
  function createOpenCodeLogger(client, getMinLevel) {
42
29
  const fallback = createJsonConsoleLogger("debug");
30
+ // OpenCode already captures plugin logs via client.app.log (and filters them
31
+ // by its own log level). Mirroring every event to stdout on top of that is
32
+ // what floods the terminal (e.g. `opencode web` re-loads the plugin per
33
+ // session). So only mirror warn/error to the JSON console by default; set
34
+ // VYMALO_PLUGIN_CONSOLE_LOG=1 to restore full console output for debugging.
35
+ const consoleAll = /^(1|true|yes|on)$/i.test(process.env.VYMALO_PLUGIN_CONSOLE_LOG ?? "");
43
36
  const write = (level, event, fields) => {
44
37
  if (LOG_LEVEL_PRIORITY[level] < LOG_LEVEL_PRIORITY[getMinLevel()]) {
45
38
  return;
46
39
  }
47
- fallback[level](event, fields);
40
+ if (consoleAll || level === "warn" || level === "error") {
41
+ fallback[level](event, fields);
42
+ }
48
43
  void client.app
49
44
  .log({ body: { service: PLUGIN_SERVICE_NAME, level, message: event, extra: fields } })
50
45
  .catch(() => {
@@ -98,6 +93,16 @@ export function createBrowserPlugin(factoryOptions = {}) {
98
93
  // Share the token across adapters via the per-user state file (explicit wins).
99
94
  const { token, source } = resolveSharedToken(options.port, tokenProvided ? options.token : undefined, generateToken);
100
95
  writeBridgeFile(options.port, token);
96
+ // Only the host advertises the token (guests reuse the same one from the
97
+ // shared file — reprinting it per session is just noise, and re-emits the
98
+ // secret). Fired via onHost so a host reached by failover re-election still
99
+ // advertises it, not only the initial host. The `paste_into_extension` field
100
+ // name dodges the logger's redaction filter so the value stays copyable.
101
+ const advertiseToken = () => {
102
+ if (source !== "explicit") {
103
+ logger.info("browser_bridge_token", { paste_into_extension: token, source, mode: "host" });
104
+ }
105
+ };
101
106
  // Auto-elect: host the broker (win the bind) or join an existing one as a guest.
102
107
  const endpoint = await createEndpoint({
103
108
  host: options.host,
@@ -105,11 +110,12 @@ export function createBrowserPlugin(factoryOptions = {}) {
105
110
  token,
106
111
  executor: executorProvided ? options.executor : undefined,
107
112
  timeoutMs: options.timeoutMs,
108
- label: "opencode-plugin"
113
+ label: "opencode-plugin",
114
+ onHost: advertiseToken
109
115
  }, {
110
116
  logger,
111
- createServerTransport: factoryOptions.createServerTransport ?? createBunTransport,
112
- createAgentSocket: factoryOptions.createAgentSocket ?? bunAgentSocket
117
+ createServerTransport: factoryOptions.createServerTransport ?? createNodeTransport,
118
+ createAgentSocket: factoryOptions.createAgentSocket ?? createNodeAgentSocket
113
119
  });
114
120
  // When OpenCode exits, hand the browser back automatically — the user
115
121
  // shouldn't have to click Disconnect.
@@ -121,15 +127,6 @@ export function createBrowserPlugin(factoryOptions = {}) {
121
127
  /* best-effort */
122
128
  }
123
129
  });
124
- if (source !== "explicit") {
125
- // Make the token visible so it can be pasted into the extension. The
126
- // `paste_into_extension` field name dodges the logger's redaction filter.
127
- logger.info("browser_bridge_token", {
128
- paste_into_extension: token,
129
- source,
130
- mode: endpoint.mode()
131
- });
132
- }
133
130
  const tools = createBrowserTools({
134
131
  send: endpoint.send,
135
132
  options,
@@ -1 +1 @@
1
- {"version":3,"file":"opencode.js","sourceRoot":"","sources":["../src/opencode.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"opencode.js","sourceRoot":"","sources":["../src/opencode.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  /**
2
- * The transport seam for the bridge/broker. The real implementation wraps
3
- * `Bun.serve`'s WebSocket support; the MCP server provides a Node `ws` variant;
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
4
  * tests inject a fake. `listen` is **async** and resolves only once the port is
5
5
  * actually bound (and rejects on `EADDRINUSE`) — that's what the broker election
6
6
  * relies on to decide host-vs-guest.
@@ -25,8 +25,3 @@ export interface BridgeTransport {
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;
28
- /**
29
- * Real transport backed by `Bun.serve` — the production path inside OpenCode
30
- * (which runs on Bun). Throws if invoked outside Bun.
31
- */
32
- export declare function createBunTransport(): BridgeTransport;
package/dist/transport.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
- * The transport seam for the bridge/broker. The real implementation wraps
3
- * `Bun.serve`'s WebSocket support; the MCP server provides a Node `ws` variant;
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
4
  * tests inject a fake. `listen` is **async** and resolves only once the port is
5
5
  * actually bound (and rejects on `EADDRINUSE`) — that's what the broker election
6
6
  * relies on to decide host-vs-guest.
@@ -10,62 +10,4 @@ export function isAddrInUse(err) {
10
10
  const msg = err instanceof Error ? err.message : String(err);
11
11
  return /eaddrinuse|address already in use|in use/i.test(msg);
12
12
  }
13
- /**
14
- * Real transport backed by `Bun.serve` — the production path inside OpenCode
15
- * (which runs on Bun). Throws if invoked outside Bun.
16
- */
17
- export function createBunTransport() {
18
- const bun = globalThis.Bun;
19
- if (!bun) {
20
- throw new Error("the opencode-browser bridge requires the Bun runtime (Bun.serve not found)");
21
- }
22
- let server = null;
23
- const conns = new WeakMap();
24
- return {
25
- listen({ host, port }, handlers) {
26
- return new Promise((resolve, reject) => {
27
- try {
28
- server = bun.serve({
29
- hostname: host,
30
- port,
31
- fetch(req, srv) {
32
- if (srv.upgrade(req)) {
33
- return undefined;
34
- }
35
- return new Response("opencode-browser bridge: websocket only", { status: 426 });
36
- },
37
- websocket: {
38
- open(ws) {
39
- const conn = { send: (d) => ws.send(d), close: () => ws.close() };
40
- conns.set(ws, conn);
41
- handlers.onOpen(conn);
42
- },
43
- message(ws, message) {
44
- const conn = conns.get(ws);
45
- if (conn) {
46
- handlers.onMessage(conn, typeof message === "string" ? message : Buffer.from(message).toString());
47
- }
48
- },
49
- close(ws) {
50
- const conn = conns.get(ws);
51
- conns.delete(ws);
52
- if (conn) {
53
- handlers.onClose(conn);
54
- }
55
- }
56
- }
57
- });
58
- resolve(); // Bun.serve throws synchronously on EADDRINUSE; reaching here = bound.
59
- }
60
- catch (err) {
61
- reject(err);
62
- }
63
- });
64
- },
65
- stop() {
66
- server?.stop(true);
67
- server = null;
68
- }
69
- };
70
- }
71
13
  //# 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;AAUD;;;GAGG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,GAAG,GAAI,UAAgC,CAAC,GAAG,CAAC;IAClD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,4EAA4E,CAAC,CAAC;IAChG,CAAC;IACD,IAAI,MAAM,GAAiD,IAAI,CAAC;IAChE,MAAM,KAAK,GAAG,IAAI,OAAO,EAA4B,CAAC;IAEtD,OAAO;QACL,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,QAAQ;YAC7B,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC3C,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC;wBACjB,QAAQ,EAAE,IAAI;wBACd,IAAI;wBACJ,KAAK,CAAC,GAAY,EAAE,GAAuC;4BACzD,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gCACrB,OAAO,SAAS,CAAC;4BACnB,CAAC;4BACD,OAAO,IAAI,QAAQ,CAAC,yCAAyC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;wBAClF,CAAC;wBACD,SAAS,EAAE;4BACT,IAAI,CAAC,EAAgB;gCACnB,MAAM,IAAI,GAAqB,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;gCACpF,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;gCACpB,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;4BACxB,CAAC;4BACD,OAAO,CAAC,EAAgB,EAAE,OAAiC;gCACzD,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gCAC3B,IAAI,IAAI,EAAE,CAAC;oCACT,QAAQ,CAAC,SAAS,CAChB,IAAI,EACJ,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,CACxE,CAAC;gCACJ,CAAC;4BACH,CAAC;4BACD,KAAK,CAAC,EAAgB;gCACpB,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gCAC3B,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gCACjB,IAAI,IAAI,EAAE,CAAC;oCACT,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gCACzB,CAAC;4BACH,CAAC;yBACF;qBACF,CAAC,CAAC;oBACH,OAAO,EAAE,CAAC,CAAC,uEAAuE;gBACpF,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,CAAC,GAAG,CAAC,CAAC;gBACd,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QACD,IAAI;YACF,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,MAAM,GAAG,IAAI,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC"}
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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vymalo/opencode-browser",
3
- "version": "0.7.1",
3
+ "version": "0.7.3",
4
4
  "description": "OpenCode plugin that gives the model hands in a real browser: it registers browser_* tools (open, click, type, scroll, screenshot, snapshot, …) and hosts a localhost WebSocket bridge that a companion Chromium/Firefox extension connects to. Tabs are organized into named groups so each task stays isolated and inspectable.",
5
5
  "license": "MIT",
6
6
  "author": "vymalo contributors",
@@ -49,9 +49,11 @@
49
49
  "access": "public"
50
50
  },
51
51
  "dependencies": {
52
- "@opencode-ai/plugin": "1.15.10"
52
+ "@opencode-ai/plugin": "1.15.10",
53
+ "ws": "^8.21.0"
53
54
  },
54
55
  "devDependencies": {
56
+ "@types/ws": "^8.18.0",
55
57
  "vite": "^8.0.14",
56
58
  "vitest": "^4.1.7"
57
59
  },