@elvatis_com/openclaw-cli-bridge-elvatis 0.2.7 → 0.2.9
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/.ai/handoff/DASHBOARD.md +4 -4
- package/.ai/handoff/STATUS.md +1 -1
- package/README.md +1 -1
- package/index.ts +46 -9
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/.ai/handoff/DASHBOARD.md
CHANGED
|
@@ -6,15 +6,15 @@ _Last updated: 2026-03-07_
|
|
|
6
6
|
|
|
7
7
|
| Component | Version | Build | Tests | Status |
|
|
8
8
|
|-----------|---------|-------|-------|--------|
|
|
9
|
-
| openclaw-cli-bridge-elvatis | 0.2.
|
|
9
|
+
| openclaw-cli-bridge-elvatis | 0.2.7 | ✅ | 5/5 ✅ | ✅ Stable |
|
|
10
10
|
|
|
11
11
|
## 🚀 Release State
|
|
12
12
|
|
|
13
13
|
| Platform | Version | Status |
|
|
14
14
|
|----------|---------|--------|
|
|
15
|
-
| GitHub | v0.2.
|
|
16
|
-
| npm | 0.2.
|
|
17
|
-
| ClawHub | 0.2.
|
|
15
|
+
| GitHub | v0.2.7 | ✅ Tagged + Release |
|
|
16
|
+
| npm | 0.2.7 | ✅ Published |
|
|
17
|
+
| ClawHub | 0.2.7 | ✅ Published |
|
|
18
18
|
|
|
19
19
|
## 📋 Open Tasks
|
|
20
20
|
|
package/.ai/handoff/STATUS.md
CHANGED
package/README.md
CHANGED
package/index.ts
CHANGED
|
@@ -354,9 +354,32 @@ const plugin = {
|
|
|
354
354
|
let proxyServer: import("node:http").Server | null = null;
|
|
355
355
|
|
|
356
356
|
if (enableProxy) {
|
|
357
|
-
//
|
|
358
|
-
//
|
|
359
|
-
|
|
357
|
+
// Probe whether a healthy proxy is already listening on our port.
|
|
358
|
+
// This handles hot-reloads where the previous plugin instance's server.close()
|
|
359
|
+
// may not have completed yet — rather than killing anything (dangerous: fuser -k
|
|
360
|
+
// can kill the gateway process itself during in-process hot-reloads), we just
|
|
361
|
+
// check if the existing server still responds and reuse it if so.
|
|
362
|
+
const probeExisting = (): Promise<boolean> => {
|
|
363
|
+
return new Promise((resolve) => {
|
|
364
|
+
const req = http.request(
|
|
365
|
+
{ hostname: "127.0.0.1", port, path: "/v1/models", method: "GET",
|
|
366
|
+
headers: { Authorization: `Bearer ${apiKey}` } },
|
|
367
|
+
(res) => { res.resume(); resolve(res.statusCode === 200); }
|
|
368
|
+
);
|
|
369
|
+
req.setTimeout(800, () => { req.destroy(); resolve(false); });
|
|
370
|
+
req.on("error", () => resolve(false));
|
|
371
|
+
req.end();
|
|
372
|
+
});
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
const startProxy = async (): Promise<void> => {
|
|
376
|
+
// If a healthy proxy is already up, reuse it — no need to rebind.
|
|
377
|
+
const alive = await probeExisting();
|
|
378
|
+
if (alive) {
|
|
379
|
+
api.logger.info(`[cli-bridge] proxy already running on :${port} — reusing`);
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
|
|
360
383
|
try {
|
|
361
384
|
const server = await startProxyServer({
|
|
362
385
|
port,
|
|
@@ -377,15 +400,29 @@ const plugin = {
|
|
|
377
400
|
}
|
|
378
401
|
} catch (err: unknown) {
|
|
379
402
|
const msg = (err as Error).message ?? String(err);
|
|
380
|
-
if (
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
403
|
+
if (msg.includes("EADDRINUSE")) {
|
|
404
|
+
// Port is busy but probe didn't respond — wait for the OS to release it
|
|
405
|
+
api.logger.warn(`[cli-bridge] port ${port} busy, waiting 1s for OS release…`);
|
|
406
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
407
|
+
// One final attempt
|
|
408
|
+
try {
|
|
409
|
+
const server = await startProxyServer({
|
|
410
|
+
port, apiKey, timeoutMs,
|
|
411
|
+
log: (msg) => api.logger.info(msg),
|
|
412
|
+
warn: (msg) => api.logger.warn(msg),
|
|
413
|
+
});
|
|
414
|
+
proxyServer = server;
|
|
415
|
+
api.logger.info(`[cli-bridge] proxy ready on :${port} (retry)`);
|
|
416
|
+
} catch (e2: unknown) {
|
|
417
|
+
api.logger.warn(`[cli-bridge] proxy unavailable after retry: ${(e2 as Error).message}`);
|
|
418
|
+
}
|
|
419
|
+
} else {
|
|
420
|
+
api.logger.warn(`[cli-bridge] proxy failed to start on port ${port}: ${msg}`);
|
|
384
421
|
}
|
|
385
|
-
api.logger.warn(`[cli-bridge] proxy failed to start on port ${port}: ${msg}`);
|
|
386
422
|
}
|
|
387
423
|
};
|
|
388
|
-
|
|
424
|
+
|
|
425
|
+
startProxy().catch(() => {});
|
|
389
426
|
}
|
|
390
427
|
|
|
391
428
|
// ── Cleanup: close proxy server on plugin stop (hot-reload / gateway restart) ──
|
package/openclaw.plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "openclaw-cli-bridge-elvatis",
|
|
3
3
|
"name": "OpenClaw CLI Bridge",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.9",
|
|
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": "0.2.
|
|
3
|
+
"version": "0.2.9",
|
|
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": {
|