@elvatis_com/openclaw-cli-bridge-elvatis 1.3.1 → 1.3.2

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/index.ts CHANGED
@@ -322,12 +322,32 @@ async function cleanupBrowsers(log: (msg: string) => void): Promise<void> {
322
322
  log("[cli-bridge] browser resources cleaned up");
323
323
  }
324
324
 
325
+ /**
326
+ * Singleton guard for ensureAllProviderContexts — prevents concurrent spawns.
327
+ * If a run is already in progress, callers await the same promise instead of
328
+ * spawning a new Chromium each time.
329
+ */
330
+ let _ensureAllRunning: Promise<void> | null = null;
331
+
325
332
  /**
326
333
  * Ensure all browser provider contexts are connected.
327
334
  * 1. Try the shared OpenClaw browser (CDP 18800)
328
335
  * 2. Fallback: launch a persistent headless Chromium per provider (saved profile with cookies)
336
+ *
337
+ * SAFETY: Only one concurrent run allowed. Extra callers await the existing run.
329
338
  */
330
339
  async function ensureAllProviderContexts(log: (msg: string) => void): Promise<void> {
340
+ if (_ensureAllRunning) {
341
+ log("[cli-bridge] ensureAllProviderContexts already running — awaiting existing run");
342
+ return _ensureAllRunning;
343
+ }
344
+ _ensureAllRunning = _doEnsureAllProviderContexts(log).finally(() => {
345
+ _ensureAllRunning = null;
346
+ });
347
+ return _ensureAllRunning;
348
+ }
349
+
350
+ async function _doEnsureAllProviderContexts(log: (msg: string) => void): Promise<void> {
331
351
  const { chromium } = await import("playwright");
332
352
 
333
353
  // Try CDP first (OpenClaw browser)
@@ -848,8 +868,7 @@ const plugin = {
848
868
  const editor = await page.locator(".ProseMirror").isVisible().catch(() => false);
849
869
  if (editor) { claudeContext = ctx; return ctx; }
850
870
  }
851
- // Fallback: try persistent context
852
- await ensureAllProviderContexts((msg) => api.logger.info(msg));
871
+ // No fallback spawn — return existing context or null to avoid Chromium leak
853
872
  return claudeContext;
854
873
  },
855
874
  getGeminiContext: () => geminiContext,
@@ -861,8 +880,7 @@ const plugin = {
861
880
  const editor = await page.locator(".ql-editor").isVisible().catch(() => false);
862
881
  if (editor) { geminiContext = ctx; return ctx; }
863
882
  }
864
- // Fallback: try persistent context
865
- await ensureAllProviderContexts((msg) => api.logger.info(msg));
883
+ // No fallback spawn — return existing context or null to avoid Chromium leak
866
884
  return geminiContext;
867
885
  },
868
886
  getChatGPTContext: () => chatgptContext,
@@ -874,8 +892,7 @@ const plugin = {
874
892
  const editor = await page.locator("#prompt-textarea").isVisible().catch(() => false);
875
893
  if (editor) { chatgptContext = ctx; return ctx; }
876
894
  }
877
- // Fallback: try persistent context
878
- await ensureAllProviderContexts((msg) => api.logger.info(msg));
895
+ // No fallback spawn — return existing context or null to avoid Chromium leak
879
896
  return chatgptContext;
880
897
  },
881
898
  });
@@ -919,8 +936,7 @@ const plugin = {
919
936
  const editor = await page.locator(".ProseMirror").isVisible().catch(() => false);
920
937
  if (editor) { claudeContext = ctx; return ctx; }
921
938
  }
922
- // Fallback: try persistent context
923
- await ensureAllProviderContexts((msg) => api.logger.info(msg));
939
+ // No fallback spawn — return existing context or null to avoid Chromium leak
924
940
  return claudeContext;
925
941
  },
926
942
  getGeminiContext: () => geminiContext,
@@ -932,8 +948,7 @@ const plugin = {
932
948
  const editor = await page.locator(".ql-editor").isVisible().catch(() => false);
933
949
  if (editor) { geminiContext = ctx; return ctx; }
934
950
  }
935
- // Fallback: try persistent context
936
- await ensureAllProviderContexts((msg) => api.logger.info(msg));
951
+ // No fallback spawn — return existing context or null to avoid Chromium leak
937
952
  return geminiContext;
938
953
  },
939
954
  getChatGPTContext: () => chatgptContext,
@@ -945,8 +960,7 @@ const plugin = {
945
960
  const editor = await page.locator("#prompt-textarea").isVisible().catch(() => false);
946
961
  if (editor) { chatgptContext = ctx; return ctx; }
947
962
  }
948
- // Fallback: try persistent context
949
- await ensureAllProviderContexts((msg) => api.logger.info(msg));
963
+ // No fallback spawn — return existing context or null to avoid Chromium leak
950
964
  return chatgptContext;
951
965
  },
952
966
  });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "openclaw-cli-bridge-elvatis",
3
3
  "name": "OpenClaw CLI Bridge",
4
- "version": "1.3.1",
4
+ "version": "1.3.2",
5
5
  "description": "Phase 1: openai-codex auth bridge. Phase 2: local HTTP proxy routing model calls through gemini/claude CLIs (vllm provider).",
6
6
  "providers": [
7
7
  "openai-codex"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elvatis_com/openclaw-cli-bridge-elvatis",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "description": "Bridges gemini, claude, and codex CLI tools as OpenClaw model providers. Reads existing CLI auth without re-login.",
5
5
  "type": "module",
6
6
  "openclaw": {
@@ -22,4 +22,4 @@
22
22
  "dependencies": {
23
23
  "playwright": "^1.58.2"
24
24
  }
25
- }
25
+ }