@todoforai/edge 0.13.12 → 0.13.13

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 (2) hide show
  1. package/dist/index.js +27 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -48477,12 +48477,14 @@ var BRIDGE_PORT = parseInt(process.env.TODOFORAI_BROWSER_BRIDGE_PORT || "43127",
48477
48477
  var BRIDGE_EDGE_ID = "local-browser-bridge";
48478
48478
  var REQUEST_TIMEOUT_MS = 30000;
48479
48479
  var isOpen = (ws) => !!ws && ws.readyState === import_websocket.default.OPEN;
48480
+ var describeExt = (ext) => ext ? `${ext.build ?? "?"}@${ext.version ?? "?"} (${ext.browser ?? "?"})` : "unknown extension";
48480
48481
 
48481
48482
  class BrowserExtensionBridge {
48482
48483
  debug;
48483
48484
  server;
48484
48485
  wss;
48485
48486
  extensionWs = null;
48487
+ extIdentity = null;
48486
48488
  pending = new Map;
48487
48489
  constructor(debug = false) {
48488
48490
  this.debug = debug;
@@ -48563,8 +48565,18 @@ class BrowserExtensionBridge {
48563
48565
  console.log("[browser-bridge:recv]", data.type);
48564
48566
  if (data.type === "hello") {
48565
48567
  const isTabChannel = data.role === "extension-tab" || data.role === "extension";
48566
- if (data.role === "extension-control")
48568
+ if (data.role === "extension-control") {
48569
+ const ident = describeExt(data.ext);
48570
+ const prev = this.extensionWs;
48571
+ if (isOpen(prev) && prev !== ws) {
48572
+ console.log(`[browser-bridge] control taken over by ${ident} (was ${describeExt(this.extIdentity)})`);
48573
+ prev.send(JSON.stringify({ type: "control_superseded", payload: { by: ident } }));
48574
+ } else if (this.debug) {
48575
+ console.log(`[browser-bridge] control acquired by ${ident}`);
48576
+ }
48567
48577
  this.extensionWs = ws;
48578
+ this.extIdentity = data.ext ?? null;
48579
+ }
48568
48580
  if (data.role === "extension-control" || isTabChannel) {
48569
48581
  if (isOpen(ws))
48570
48582
  ws.send(JSON.stringify({ type: "connected_edge", payload: { edgeId: BRIDGE_EDGE_ID } }));
@@ -48617,8 +48629,12 @@ class BrowserExtensionBridge {
48617
48629
  }
48618
48630
  }
48619
48631
  handleClose(ws) {
48620
- if (this.extensionWs === ws)
48632
+ if (this.extensionWs === ws) {
48633
+ if (this.debug)
48634
+ console.log(`[browser-bridge] control released by ${describeExt(this.extIdentity)}`);
48621
48635
  this.extensionWs = null;
48636
+ this.extIdentity = null;
48637
+ }
48622
48638
  for (const [requestId, pending] of this.pending) {
48623
48639
  if (pending.ws !== ws)
48624
48640
  continue;
@@ -48849,6 +48865,15 @@ var tool_catalog_default = {
48849
48865
  description: "Use to generate speech audio from text, clone voices, or list voices. Needs ELEVENLABS_API_KEY.",
48850
48866
  versionCmd: "elevenlabs-api --version 2>/dev/null | head -1"
48851
48867
  },
48868
+ "codex-imagegen-api": {
48869
+ category: "media",
48870
+ pkg: "@todoforai/codex-imagegen-api",
48871
+ installer: "npm",
48872
+ label: "Image Gen",
48873
+ capabilities: "AI image generation & editing via TODOFORAI backend (gpt-image)",
48874
+ description: 'Use to generate or edit images. Subcommands: `codex-imagegen-api generate "<prompt>" -o out.png [--size 1024x1024] [--quality low|medium|high]` and `codex-imagegen-api edit "<instruction>" -i in.png -o out.png` (repeat `-i` for multiple reference images).',
48875
+ versionCmd: "codex-imagegen-api --version 2>/dev/null | head -1"
48876
+ },
48852
48877
  "suno-api": {
48853
48878
  category: "media",
48854
48879
  pkg: "@todoforai/suno-api",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@todoforai/edge",
3
- "version": "0.13.12",
3
+ "version": "0.13.13",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "todoforai-edge": "dist/index.js"