@elvatis_com/openclaw-cli-bridge-elvatis 2.1.2 → 2.2.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.
- package/.ai/handoff/DASHBOARD.md +11 -15
- package/.ai/handoff/LOG.md +29 -0
- package/.ai/handoff/MANIFEST.json +130 -24
- package/.ai/handoff/NEXT_ACTIONS.md +3 -2
- package/.ai/handoff/STATUS.md +5 -4
- package/README.md +29 -6
- package/SKILL.md +1 -1
- package/index.ts +60 -23
- package/openclaw.plugin.json +1 -1
- package/package.json +4 -4
- package/src/proxy-server.ts +14 -2
- package/src/session-manager.ts +7 -0
package/.ai/handoff/DASHBOARD.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# DASHBOARD.md — openclaw-cli-bridge-elvatis
|
|
2
2
|
|
|
3
|
-
_Last updated: 2026-
|
|
3
|
+
_Last updated: 2026-04-09_
|
|
4
4
|
|
|
5
5
|
<!-- SECTION: plugin_status -->
|
|
6
6
|
## Plugin Status
|
|
7
7
|
|
|
8
8
|
| Component | Version | Build | Tests | Status |
|
|
9
9
|
|-----------|---------|-------|-------|--------|
|
|
10
|
-
| openclaw-cli-bridge-elvatis |
|
|
10
|
+
| openclaw-cli-bridge-elvatis | 2.2.0 | ✅ | ✅ | ✅ Stable |
|
|
11
11
|
<!-- /SECTION: plugin_status -->
|
|
12
12
|
|
|
13
13
|
<!-- SECTION: release_state -->
|
|
@@ -15,8 +15,9 @@ _Last updated: 2026-03-13_
|
|
|
15
15
|
|
|
16
16
|
| Platform | Published Version | Status |
|
|
17
17
|
|----------|------------------|--------|
|
|
18
|
-
| GitHub |
|
|
19
|
-
|
|
|
18
|
+
| GitHub | v2.2.0 | ✅ Pushed to main |
|
|
19
|
+
| npm | 2.1.3 | ⏳ Pending publish |
|
|
20
|
+
| ClawHub | 2.1.3 | ⏳ Pending publish |
|
|
20
21
|
<!-- /SECTION: release_state -->
|
|
21
22
|
|
|
22
23
|
<!-- SECTION: open_tasks -->
|
|
@@ -30,19 +31,14 @@ _No open tasks._
|
|
|
30
31
|
|
|
31
32
|
| Task | Title | Version |
|
|
32
33
|
|------|-------|---------|
|
|
33
|
-
| T-
|
|
34
|
-
| T-
|
|
34
|
+
| T-017 | Fix log spam, restart loops, CLI blocking | 2.2.0 |
|
|
35
|
+
| T-016 | Issue #2: Codex auth auto-import into agent auth store | 2.1.0 |
|
|
36
|
+
| T-015 | Issue #4: Background session mgmt with workdir isolation | 2.1.0 |
|
|
37
|
+
| T-014 | Issue #6: Workdir isolation (createIsolatedWorkdir, cleanup, sweep) | 2.1.0 |
|
|
38
|
+
| T-013 | Fix cookie expiry tracking — longest-lived auth cookie (all 4) | 1.7.3 |
|
|
39
|
+
| T-012 | Persistent browser fallback for Claude/Gemini/ChatGPT (no CDP) | 1.4.0 |
|
|
35
40
|
| T-011 | Session-safe staged model switching (/cli-apply, /cli-pending, --now) | 0.2.25 |
|
|
36
41
|
| T-009 | Stability: sleep-resilient token refresh + stopTokenRefresh cleanup | 0.2.25 |
|
|
37
|
-
| T-103 | Explicit model allowlist for CLI execution | 0.2.23 |
|
|
38
|
-
| T-102 | Proxy auth key rotation via config | 0.2.23 |
|
|
39
|
-
| T-101 | Unit tests for prompt formatter + model router | 0.2.23 |
|
|
40
42
|
| T-008 | Validate proxy endpoints + vllm model calls end-to-end | 0.2.21 |
|
|
41
43
|
| T-007 | Create GitHub repo and push initial code | 0.2.5 |
|
|
42
|
-
| T-006 | Implement Claude Code CLI request bridge | 0.2.5 |
|
|
43
|
-
| T-005 | Implement Gemini CLI request bridge | 0.2.5 |
|
|
44
|
-
| T-004 | Verify model call: gpt-5.2 / gpt-5.3-codex responds | 0.2.5 |
|
|
45
|
-
| T-003 | Test auth flow: openclaw models auth login --provider openai-codex | 0.2.5 |
|
|
46
|
-
| T-002 | Implement openai-codex provider (Codex CLI auth bridge) | 0.2.5 |
|
|
47
|
-
| T-001 | Scaffold plugin structure + AAHP handoff | 0.2.5 |
|
|
48
44
|
<!-- /SECTION: completed_tasks -->
|
package/.ai/handoff/LOG.md
CHANGED
|
@@ -4,6 +4,35 @@ _Last 10 sessions. Older entries in LOG-ARCHIVE.md._
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## 2026-04-09 — Session 9 (Claude Opus 4.6)
|
|
8
|
+
|
|
9
|
+
> **Agent:** claude-opus-4-6
|
|
10
|
+
> **Phase:** fix
|
|
11
|
+
> **Commit before:** v2.1.3
|
|
12
|
+
> **Commit after:** v2.2.0
|
|
13
|
+
|
|
14
|
+
**T-017: Fix log spam, restart loops, CLI blocking**
|
|
15
|
+
|
|
16
|
+
### Problems
|
|
17
|
+
1. `register()` called per-agent (~11×) — every call logged Chrome check, provider registration, and all 32 commands
|
|
18
|
+
2. `fuser -k` port cleanup killed the gateway process itself (proxy runs in-process), causing systemd restart loops
|
|
19
|
+
3. `openclaw models status` (and other CLI commands) hung indefinitely because session restore launched 4 Chromium instances
|
|
20
|
+
|
|
21
|
+
### Fixes (index.ts, src/proxy-server.ts)
|
|
22
|
+
- Module-level `_registerLoggedOnce` guard — Chrome/provider/commands logged once per process start
|
|
23
|
+
- Module-level `_proxyStarted` guard — proxy start runs once, not per-agent
|
|
24
|
+
- Shortened command log: count + `/cli-list` reference instead of listing all 32 names
|
|
25
|
+
- Removed `fuser -k` — EADDRINUSE handled gracefully (skip + log)
|
|
26
|
+
- `_proxyOwnedByThisProcess` flag — session restore only runs in gateway mode, skipped for CLI commands
|
|
27
|
+
- Codex auth import runs once per startup, not per-agent
|
|
28
|
+
|
|
29
|
+
### Also in this session
|
|
30
|
+
- Installed cli-bridge plugin on production server (chef-linux@192.168.177.6)
|
|
31
|
+
- Set default model to `vllm/cli-claude/claude-sonnet-4-6` (Claude CLI, no API costs)
|
|
32
|
+
- Merged 3 Dependabot PRs (#13, #17, #19)
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
7
36
|
## 2026-03-13 — Session 8 (Claude Opus 4.6)
|
|
8
37
|
|
|
9
38
|
> **Agent:** claude-opus-4-6
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
"aahp_version": "3.0",
|
|
3
3
|
"project": "openclaw-cli-bridge-elvatis",
|
|
4
4
|
"last_session": {
|
|
5
|
-
"agent": "claude-
|
|
6
|
-
"session_id": "
|
|
7
|
-
"timestamp": "2026-
|
|
8
|
-
"commit": "
|
|
9
|
-
"phase": "
|
|
10
|
-
"duration_minutes":
|
|
5
|
+
"agent": "claude-opus-4-6",
|
|
6
|
+
"session_id": "fix-log-spam-2026-04-09",
|
|
7
|
+
"timestamp": "2026-04-09T14:30:00Z",
|
|
8
|
+
"commit": "2704a46",
|
|
9
|
+
"phase": "fix",
|
|
10
|
+
"duration_minutes": 120
|
|
11
11
|
},
|
|
12
12
|
"files": {
|
|
13
13
|
"STATUS.md": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"checksum": "sha256:2a2c1696de45106e01063afa35859955f0d8827c1ea3bbc117d7b46769f89a6c",
|
|
21
21
|
"updated": "2026-03-11T17:39:00Z",
|
|
22
22
|
"lines": 48,
|
|
23
|
-
"summary": "1 task ready: T-010
|
|
23
|
+
"summary": "1 task ready: T-010 \u2014 Publish v0.2.25. No blockers."
|
|
24
24
|
},
|
|
25
25
|
"LOG.md": {
|
|
26
26
|
"checksum": "sha256:b23892518fd5a5faa0b402bd2553d1d1cbca7b46675ba6dd4d413e1cbf03e19d",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"checksum": "sha256:cf1c47a18f52e0b94b932177d4e9b455a0e3ae7f29b1a34802088ffa7ad98cef",
|
|
33
33
|
"updated": "2026-03-11T17:39:00Z",
|
|
34
34
|
"lines": 50,
|
|
35
|
-
"summary": "Build
|
|
35
|
+
"summary": "Build \u2705 Tests 51/51 \u2705. Local v0.2.25, last published v0.2.23. T-010 (publish) ready."
|
|
36
36
|
},
|
|
37
37
|
"TRUST.md": {
|
|
38
38
|
"checksum": "sha256:cbfc8dcc17c00f8da8e220eba106aac56c63782caac655c30ba60c463994adc1",
|
|
@@ -50,27 +50,133 @@
|
|
|
50
50
|
"checksum": "sha256:f9224bf9e993863b2b9e17f36ee605950359ba43d420fa7b4c829a6fbdc92482",
|
|
51
51
|
"updated": "2026-03-07T00:00:00Z",
|
|
52
52
|
"lines": 152,
|
|
53
|
-
"summary": "4-phase AAHP pipeline: Research
|
|
53
|
+
"summary": "4-phase AAHP pipeline: Research \u2192 Architecture \u2192 Implementation \u2192 Review \u2192 Handoff."
|
|
54
54
|
}
|
|
55
55
|
},
|
|
56
|
-
"quick_context": "
|
|
56
|
+
"quick_context": "v2.2.0 pushed to main. Key changes: module-level guards prevent log spam from per-agent register() calls, removed fuser -k (caused restart loops), session restore only in gateway mode (CLI commands no longer hang), EADDRINUSE graceful handling. Plugin deployed on chef-linux production server.",
|
|
57
57
|
"token_budget": {
|
|
58
58
|
"manifest_only": 90,
|
|
59
59
|
"manifest_plus_core": 380,
|
|
60
60
|
"full_read": 850
|
|
61
61
|
},
|
|
62
|
-
"next_task_id":
|
|
62
|
+
"next_task_id": 18,
|
|
63
63
|
"tasks": {
|
|
64
|
-
"T-001": {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
"T-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
64
|
+
"T-001": {
|
|
65
|
+
"title": "Scaffold plugin structure + AAHP handoff",
|
|
66
|
+
"status": "done",
|
|
67
|
+
"priority": "high",
|
|
68
|
+
"depends_on": [],
|
|
69
|
+
"created": "2026-03-07T20:40:00Z",
|
|
70
|
+
"completed": "2026-03-07T20:56:00Z"
|
|
71
|
+
},
|
|
72
|
+
"T-002": {
|
|
73
|
+
"title": "Implement openai-codex provider (Codex CLI auth bridge)",
|
|
74
|
+
"status": "done",
|
|
75
|
+
"priority": "high",
|
|
76
|
+
"depends_on": [
|
|
77
|
+
"T-001"
|
|
78
|
+
],
|
|
79
|
+
"created": "2026-03-07T20:40:00Z",
|
|
80
|
+
"completed": "2026-03-07T20:56:00Z"
|
|
81
|
+
},
|
|
82
|
+
"T-003": {
|
|
83
|
+
"title": "Test auth flow: openclaw models auth login --provider openai-codex",
|
|
84
|
+
"status": "done",
|
|
85
|
+
"priority": "high",
|
|
86
|
+
"depends_on": [
|
|
87
|
+
"T-002"
|
|
88
|
+
],
|
|
89
|
+
"created": "2026-03-07T20:56:00Z",
|
|
90
|
+
"completed": "2026-03-07T21:01:00Z"
|
|
91
|
+
},
|
|
92
|
+
"T-004": {
|
|
93
|
+
"title": "Verify model call: test gpt-5.2 or gpt-5.3-codex responds",
|
|
94
|
+
"status": "done",
|
|
95
|
+
"priority": "high",
|
|
96
|
+
"depends_on": [
|
|
97
|
+
"T-003"
|
|
98
|
+
],
|
|
99
|
+
"created": "2026-03-07T20:56:00Z",
|
|
100
|
+
"completed": "2026-03-07T21:27:00Z"
|
|
101
|
+
},
|
|
102
|
+
"T-005": {
|
|
103
|
+
"title": "Implement Gemini CLI request bridge",
|
|
104
|
+
"status": "done",
|
|
105
|
+
"priority": "medium",
|
|
106
|
+
"depends_on": [
|
|
107
|
+
"T-003"
|
|
108
|
+
],
|
|
109
|
+
"created": "2026-03-07T20:56:00Z",
|
|
110
|
+
"completed": "2026-03-07T21:23:00Z"
|
|
111
|
+
},
|
|
112
|
+
"T-006": {
|
|
113
|
+
"title": "Implement Claude Code CLI request bridge",
|
|
114
|
+
"status": "done",
|
|
115
|
+
"priority": "medium",
|
|
116
|
+
"depends_on": [
|
|
117
|
+
"T-003"
|
|
118
|
+
],
|
|
119
|
+
"created": "2026-03-07T20:56:00Z",
|
|
120
|
+
"completed": "2026-03-07T21:23:00Z"
|
|
121
|
+
},
|
|
122
|
+
"T-007": {
|
|
123
|
+
"title": "Create GitHub repo and push initial code",
|
|
124
|
+
"status": "done",
|
|
125
|
+
"priority": "high",
|
|
126
|
+
"depends_on": [
|
|
127
|
+
"T-004"
|
|
128
|
+
],
|
|
129
|
+
"created": "2026-03-07T21:20:00Z",
|
|
130
|
+
"completed": "2026-03-07T21:24:00Z"
|
|
131
|
+
},
|
|
132
|
+
"T-008": {
|
|
133
|
+
"title": "Validate proxy endpoints + vllm model calls end-to-end",
|
|
134
|
+
"status": "done",
|
|
135
|
+
"priority": "high",
|
|
136
|
+
"depends_on": [
|
|
137
|
+
"T-005",
|
|
138
|
+
"T-006"
|
|
139
|
+
],
|
|
140
|
+
"created": "2026-03-07T21:29:00Z",
|
|
141
|
+
"completed": "2026-03-08T08:08:44Z"
|
|
142
|
+
},
|
|
143
|
+
"T-009": {
|
|
144
|
+
"title": "Stability: sleep-resilient token refresh + stopTokenRefresh cleanup",
|
|
145
|
+
"status": "done",
|
|
146
|
+
"priority": "high",
|
|
147
|
+
"depends_on": [
|
|
148
|
+
"T-008"
|
|
149
|
+
],
|
|
150
|
+
"created": "2026-03-11T15:00:00Z",
|
|
151
|
+
"completed": "2026-03-11T16:30:00Z"
|
|
152
|
+
},
|
|
153
|
+
"T-010": {
|
|
154
|
+
"title": "Publish v0.2.25 to GitHub + npm + ClawHub",
|
|
155
|
+
"status": "ready",
|
|
156
|
+
"priority": "medium",
|
|
157
|
+
"depends_on": [
|
|
158
|
+
"T-011"
|
|
159
|
+
],
|
|
160
|
+
"created": "2026-03-11T16:30:00Z"
|
|
161
|
+
},
|
|
162
|
+
"T-011": {
|
|
163
|
+
"title": "Session-safe staged model switching (/cli-apply, /cli-pending, --now)",
|
|
164
|
+
"status": "done",
|
|
165
|
+
"priority": "high",
|
|
166
|
+
"depends_on": [
|
|
167
|
+
"T-009"
|
|
168
|
+
],
|
|
169
|
+
"created": "2026-03-11T17:00:00Z",
|
|
170
|
+
"completed": "2026-03-11T17:39:00Z"
|
|
171
|
+
},
|
|
172
|
+
"T-017": {
|
|
173
|
+
"title": "Fix log spam, restart loops, CLI blocking",
|
|
174
|
+
"status": "done",
|
|
175
|
+
"priority": "high",
|
|
176
|
+
"depends_on": [],
|
|
177
|
+
"created": "2026-04-09T14:00:00Z",
|
|
178
|
+
"completed": "2026-04-09T16:30:00Z"
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
"version": "2.2.0"
|
|
182
|
+
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# NEXT_ACTIONS.md — openclaw-cli-bridge-elvatis
|
|
2
2
|
|
|
3
|
-
_Last updated: 2026-
|
|
3
|
+
_Last updated: 2026-04-09_
|
|
4
4
|
|
|
5
5
|
<!-- SECTION: summary -->
|
|
6
6
|
## Status Summary
|
|
7
7
|
|
|
8
8
|
| Status | Count |
|
|
9
9
|
|---------|-------|
|
|
10
|
-
| Done |
|
|
10
|
+
| Done | 17 |
|
|
11
11
|
| Ready | 0 |
|
|
12
12
|
| Blocked | 0 |
|
|
13
13
|
<!-- /SECTION: summary -->
|
|
@@ -30,6 +30,7 @@ _No blocked tasks._
|
|
|
30
30
|
|
|
31
31
|
| Task | Title | Date |
|
|
32
32
|
|-------|--------------------------------------------------------------------|------------|
|
|
33
|
+
| T-017 | Fix log spam, restart loops, CLI blocking (v2.2.0) | 2026-04-09 |
|
|
33
34
|
| T-016 | Issue #2: Codex auth auto-import into agent auth store | 2026-03-19 |
|
|
34
35
|
| T-015 | Issue #4: Background session mgmt with workdir isolation | 2026-03-19 |
|
|
35
36
|
| T-014 | Issue #6: Workdir isolation (createIsolatedWorkdir, cleanup, sweep) | 2026-03-19 |
|
package/.ai/handoff/STATUS.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# STATUS — openclaw-cli-bridge-elvatis
|
|
2
2
|
|
|
3
|
-
## Current Version: 2.
|
|
3
|
+
## Current Version: 2.2.0
|
|
4
4
|
|
|
5
|
-
- **npm:** @elvatis_com/openclaw-cli-bridge-elvatis (
|
|
6
|
-
- **ClawHub:** openclaw-cli-bridge-elvatis@
|
|
7
|
-
- **GitHub:** https://github.com/elvatis/openclaw-cli-bridge-elvatis
|
|
5
|
+
- **npm:** @elvatis_com/openclaw-cli-bridge-elvatis@2.2.0 (pending publish)
|
|
6
|
+
- **ClawHub:** openclaw-cli-bridge-elvatis@2.2.0 (pending publish)
|
|
7
|
+
- **GitHub:** https://github.com/elvatis/openclaw-cli-bridge-elvatis (pushed to main)
|
|
8
8
|
|
|
9
9
|
## CLI Model Token Limits (corrected in v1.9.2)
|
|
10
10
|
| Model | Context Window | Max Output |
|
|
@@ -47,6 +47,7 @@ This is by design — CLI tools output plain text only.
|
|
|
47
47
|
- /bridge-status shows cookie-based status
|
|
48
48
|
|
|
49
49
|
## Release History (recent)
|
|
50
|
+
- v2.2.0 (2026-04-09): Fix log spam (module-level guards), remove fuser -k restart loops, session restore gateway-only, EADDRINUSE graceful handling
|
|
50
51
|
- v2.1.0 (2026-03-19): Issue #6 workdir isolation, Issue #4 session mgmt enhancements, Issue #2 codex auth auto-import
|
|
51
52
|
- v2.0.0: Major version bump
|
|
52
53
|
- v1.9.2 (2026-03-15): Fix maxTokens/contextWindow for all CLI_MODELS (were 8192, now correct per vendor specs)
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> OpenClaw plugin that bridges locally installed AI CLIs (Codex, Gemini, Claude Code, OpenCode, Pi) as model providers — with slash commands for instant model switching, restore, health testing, and model listing.
|
|
4
4
|
|
|
5
|
-
**Current version:** `
|
|
5
|
+
**Current version:** `2.2.0`
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -191,11 +191,10 @@ openclaw gateway restart
|
|
|
191
191
|
### 2. Verify (check gateway logs)
|
|
192
192
|
|
|
193
193
|
```
|
|
194
|
-
[cli-bridge]
|
|
195
|
-
[cli-bridge]
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
/cli-back, /cli-test, /cli-list
|
|
194
|
+
[cli-bridge] system Chrome found: Google Chrome 146.x
|
|
195
|
+
[cli-bridge] openai-codex provider registered
|
|
196
|
+
[cli-bridge] registered 32 commands (use /cli-list to see all)
|
|
197
|
+
[cli-bridge] proxy ready on :31337 — vllm/cli-gemini/* and vllm/cli-claude/* available
|
|
199
198
|
```
|
|
200
199
|
|
|
201
200
|
### 3. Register Codex auth (optional — Phase 1 only)
|
|
@@ -377,6 +376,30 @@ npm run ci # lint + typecheck + test
|
|
|
377
376
|
|
|
378
377
|
## Changelog
|
|
379
378
|
|
|
379
|
+
### v2.2.0
|
|
380
|
+
- **fix:** Module-level guards prevent duplicate log spam — `register()` is called per-agent (~11×), now logs Chrome/provider/commands only once
|
|
381
|
+
- **fix:** Shortened command registration log: count + `/cli-list` reference instead of listing all 32 commands
|
|
382
|
+
- **fix:** Removed `fuser -k` port cleanup — was killing the gateway process itself, causing systemd restart loops
|
|
383
|
+
- **fix:** EADDRINUSE now handled gracefully (skip + log) instead of process killing
|
|
384
|
+
- **fix:** Session restore (4× Chromium) only runs in gateway mode — CLI commands like `openclaw models status` no longer hang
|
|
385
|
+
- **fix:** Codex auth import runs once per startup, not per-agent
|
|
386
|
+
|
|
387
|
+
### v2.1.3
|
|
388
|
+
- **docs:** All documentation updated to reflect current version (README, SKILL.md, STATUS.md, MANIFEST.json)
|
|
389
|
+
|
|
390
|
+
### v2.1.2
|
|
391
|
+
- **fix:** Updated ChatGPT web session model list: gpt-4o, gpt-4o-mini, gpt-4.1, gpt-4.1-mini, o3, o4-mini, gpt-5, gpt-5-mini
|
|
392
|
+
- **fix:** `server.unref()` — proxy server no longer keeps `openclaw doctor` hanging indefinitely
|
|
393
|
+
|
|
394
|
+
### v2.1.1
|
|
395
|
+
- **fix:** `server.unref()` on proxy server so `openclaw doctor` (and short-lived CLI commands) exit cleanly
|
|
396
|
+
|
|
397
|
+
### v2.1.0
|
|
398
|
+
- **feat:** Session manager for isolated per-request workdirs
|
|
399
|
+
- **feat:** Register OpenCode and Pi slash commands (`/cli-opencode`, `/cli-pi`)
|
|
400
|
+
- **feat:** Codex auth auto-import support
|
|
401
|
+
- **feat:** Workdir isolation for all CLI runners
|
|
402
|
+
|
|
380
403
|
### v1.9.2
|
|
381
404
|
- **fix:** Correct `maxTokens` and `contextWindow` for all CLI_MODELS — were hardcoded to 8192 output tokens
|
|
382
405
|
- Claude Opus 4.6: 1M context / 128k output (was 200k/8k)
|
package/SKILL.md
CHANGED
package/index.ts
CHANGED
|
@@ -240,6 +240,22 @@ let _cdpBrowserLaunchPromise: Promise<import("playwright").BrowserContext | null
|
|
|
240
240
|
// Set to true after first run; hot-reloads see true and skip the restore loop.
|
|
241
241
|
let _startupRestoreDone = false;
|
|
242
242
|
|
|
243
|
+
// Registration guard — register() is called once per agent (~11 times on a
|
|
244
|
+
// typical gateway). Only log noisy one-time info (Chrome check, provider
|
|
245
|
+
// registration, command list, proxy status) on the FIRST call.
|
|
246
|
+
let _registerLoggedOnce = false;
|
|
247
|
+
|
|
248
|
+
// Proxy start guard — prevents multiple concurrent startProxy() calls from
|
|
249
|
+
// racing. The first call wins; subsequent calls detect the running proxy via
|
|
250
|
+
// probeExisting() and reuse it silently.
|
|
251
|
+
let _proxyStarted = false;
|
|
252
|
+
|
|
253
|
+
// Tracks whether THIS process owns the proxy (freshly started it, not just reusing
|
|
254
|
+
// an external one). Used to decide if heavyweight startup tasks (session restores,
|
|
255
|
+
// keep-alive intervals) should run. Short-lived CLI commands (models status, doctor)
|
|
256
|
+
// reuse the gateway's proxy but should NOT launch Chromium instances.
|
|
257
|
+
let _proxyOwnedByThisProcess = false;
|
|
258
|
+
|
|
243
259
|
// Session keep-alive interval — refreshes browser cookies every 20h
|
|
244
260
|
let _keepAliveInterval: ReturnType<typeof setInterval> | null = null;
|
|
245
261
|
|
|
@@ -1010,14 +1026,16 @@ const plugin = {
|
|
|
1010
1026
|
// Stealth mode uses channel: "chrome" (real system Chrome). If it's missing,
|
|
1011
1027
|
// browser launches will fail or Cloudflare will block the bundled Chromium.
|
|
1012
1028
|
const chromeCheck = checkSystemChrome();
|
|
1013
|
-
if (
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1029
|
+
if (!_registerLoggedOnce) {
|
|
1030
|
+
if (chromeCheck.available) {
|
|
1031
|
+
api.logger.info(`[cli-bridge] system Chrome found: ${chromeCheck.version ?? chromeCheck.path}`);
|
|
1032
|
+
} else {
|
|
1033
|
+
api.logger.warn(
|
|
1034
|
+
`[cli-bridge] ⚠ system Chrome not found! Web browser providers (/grok-login, /gemini-login, etc.) ` +
|
|
1035
|
+
`require Google Chrome or Chromium installed system-wide. ` +
|
|
1036
|
+
`Install with: sudo apt install google-chrome-stable (or chromium-browser)`
|
|
1037
|
+
);
|
|
1038
|
+
}
|
|
1021
1039
|
}
|
|
1022
1040
|
|
|
1023
1041
|
// ── Session restore: only on first plugin load (not on hot-reloads) ──────
|
|
@@ -1027,7 +1045,13 @@ const plugin = {
|
|
|
1027
1045
|
// restore once, on the very first load (when all contexts are null).
|
|
1028
1046
|
//
|
|
1029
1047
|
// Guard: _startupRestoreDone is module-level and persists across hot-reloads.
|
|
1030
|
-
|
|
1048
|
+
// IMPORTANT: Only restore sessions when the proxy is enabled (gateway mode).
|
|
1049
|
+
// Short-lived CLI commands (openclaw models status, openclaw doctor, etc.)
|
|
1050
|
+
// must NOT launch 4 Chromium instances — they block the process from exiting.
|
|
1051
|
+
// Only restore browser sessions when this process OWNS the proxy (gateway mode).
|
|
1052
|
+
// Short-lived CLI commands (openclaw models status) reuse an external proxy and
|
|
1053
|
+
// must not launch 4 Chromium instances that block the process from exiting.
|
|
1054
|
+
if (!_startupRestoreDone && _proxyOwnedByThisProcess) {
|
|
1031
1055
|
_startupRestoreDone = true;
|
|
1032
1056
|
void (async () => {
|
|
1033
1057
|
await new Promise(r => setTimeout(r, 5000)); // wait for proxy + gateway to settle
|
|
@@ -1260,23 +1284,27 @@ const plugin = {
|
|
|
1260
1284
|
},
|
|
1261
1285
|
});
|
|
1262
1286
|
|
|
1263
|
-
|
|
1287
|
+
if (!_registerLoggedOnce) {
|
|
1288
|
+
api.logger.info("[cli-bridge] openai-codex provider registered");
|
|
1289
|
+
}
|
|
1264
1290
|
|
|
1265
1291
|
// Auto-import Codex CLI credentials into the agent auth store (Issue #2).
|
|
1266
1292
|
// This ensures `openai-codex/*` models work immediately without manual
|
|
1267
1293
|
// `openclaw models auth login`. Runs async, non-blocking.
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1294
|
+
// Only run Codex auth import once — it fires per-agent and spams logs otherwise
|
|
1295
|
+
if (!_registerLoggedOnce) {
|
|
1296
|
+
void importCodexAuth({
|
|
1297
|
+
codexAuthPath,
|
|
1298
|
+
log: (msg) => api.logger.info(`[cli-bridge:codex-import] ${msg}`),
|
|
1299
|
+
}).then((result) => {
|
|
1300
|
+
if (result.imported) {
|
|
1301
|
+
api.logger.info("[cli-bridge] Codex auth auto-imported into agent auth store ✅");
|
|
1302
|
+
} else if (result.error) {
|
|
1303
|
+
api.logger.warn(`[cli-bridge] Codex auth import failed: ${result.error}`);
|
|
1304
|
+
}
|
|
1305
|
+
// skipped = already current → no log needed
|
|
1306
|
+
});
|
|
1307
|
+
}
|
|
1280
1308
|
}
|
|
1281
1309
|
|
|
1282
1310
|
// ── Phase 2: CLI request proxy ─────────────────────────────────────────────
|
|
@@ -1302,6 +1330,11 @@ const plugin = {
|
|
|
1302
1330
|
};
|
|
1303
1331
|
|
|
1304
1332
|
const startProxy = async (): Promise<void> => {
|
|
1333
|
+
// Guard: only the first register() call starts the proxy.
|
|
1334
|
+
// Subsequent per-agent calls skip entirely.
|
|
1335
|
+
if (_proxyStarted) return;
|
|
1336
|
+
_proxyStarted = true;
|
|
1337
|
+
|
|
1305
1338
|
// If a healthy proxy is already up, reuse it — no need to rebind.
|
|
1306
1339
|
const alive = await probeExisting();
|
|
1307
1340
|
if (alive) {
|
|
@@ -1369,6 +1402,7 @@ const plugin = {
|
|
|
1369
1402
|
}),
|
|
1370
1403
|
});
|
|
1371
1404
|
proxyServer = server;
|
|
1405
|
+
_proxyOwnedByThisProcess = true;
|
|
1372
1406
|
api.logger.info(
|
|
1373
1407
|
`[cli-bridge] proxy ready on :${port} — vllm/cli-gemini/* and vllm/cli-claude/* available`
|
|
1374
1408
|
);
|
|
@@ -2442,7 +2476,10 @@ const plugin = {
|
|
|
2442
2476
|
"/bridge-status",
|
|
2443
2477
|
"/cli-help",
|
|
2444
2478
|
];
|
|
2445
|
-
|
|
2479
|
+
if (!_registerLoggedOnce) {
|
|
2480
|
+
api.logger.info(`[cli-bridge] registered ${allCommands.length} commands (use /cli-list to see all)`);
|
|
2481
|
+
}
|
|
2482
|
+
_registerLoggedOnce = true;
|
|
2446
2483
|
},
|
|
2447
2484
|
};
|
|
2448
2485
|
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "openclaw-cli-bridge-elvatis",
|
|
3
3
|
"slug": "openclaw-cli-bridge-elvatis",
|
|
4
4
|
"name": "OpenClaw CLI Bridge",
|
|
5
|
-
"version": "2.
|
|
5
|
+
"version": "2.2.0",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"description": "Phase 1: openai-codex auth bridge. Phase 2: local HTTP proxy routing model calls through gemini/claude CLIs (vllm provider).",
|
|
8
8
|
"providers": [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elvatis_com/openclaw-cli-bridge-elvatis",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
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": {
|
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
"@eslint/js": "^10.0.1",
|
|
20
20
|
"@types/node": "^25.3.2",
|
|
21
21
|
"eslint": "^10.0.3",
|
|
22
|
-
"typescript": "^
|
|
23
|
-
"typescript-eslint": "^8.
|
|
22
|
+
"typescript": "^6.0.2",
|
|
23
|
+
"typescript-eslint": "^8.58.1",
|
|
24
24
|
"vitest": "^4.0.18"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"playwright": "^1.58.2"
|
|
28
28
|
},
|
|
29
29
|
"license": "Apache-2.0"
|
|
30
|
-
}
|
|
30
|
+
}
|
package/src/proxy-server.ts
CHANGED
|
@@ -144,10 +144,22 @@ export function startProxyServer(opts: ProxyServerOptions): Promise<http.Server>
|
|
|
144
144
|
sessionManager.stop();
|
|
145
145
|
});
|
|
146
146
|
|
|
147
|
-
server.on("error", (err) =>
|
|
147
|
+
server.on("error", (err: NodeJS.ErrnoException) => {
|
|
148
|
+
if (err.code === "EADDRINUSE") {
|
|
149
|
+
// Port is held by a previous gateway process. probeExisting() should have
|
|
150
|
+
// caught a healthy proxy and reused it. If we get here, the old proxy is
|
|
151
|
+
// unhealthy but the OS hasn't released the socket yet. Just log and skip —
|
|
152
|
+
// do NOT fuser -k: the proxy runs in-process and killing the port holder
|
|
153
|
+
// would kill the gateway itself, causing a systemd restart loop.
|
|
154
|
+
opts.log(`[cli-bridge] port ${opts.port} in use by another process — proxy skipped (will retry on next gateway restart)`);
|
|
155
|
+
resolve(server); // resolve without a listening server — probeExisting handles reuse
|
|
156
|
+
} else {
|
|
157
|
+
reject(err);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
148
160
|
server.listen(opts.port, "127.0.0.1", () => {
|
|
149
161
|
opts.log(
|
|
150
|
-
`[cli-bridge] proxy
|
|
162
|
+
`[cli-bridge] proxy listening on :${opts.port}`
|
|
151
163
|
);
|
|
152
164
|
// unref() so the proxy server does not keep the Node.js event loop alive
|
|
153
165
|
// when openclaw doctor or other short-lived CLI commands load plugins.
|
package/src/session-manager.ts
CHANGED
|
@@ -111,6 +111,13 @@ export class SessionManager {
|
|
|
111
111
|
* Returns a unique sessionId (random hex).
|
|
112
112
|
*/
|
|
113
113
|
spawn(model: string, messages: ChatMessage[], opts: SpawnOptions = {}): string {
|
|
114
|
+
// Validate model ID before it reaches spawn() args to prevent command injection
|
|
115
|
+
// (CodeQL js/command-line-injection). Allow only safe chars: letters, digits,
|
|
116
|
+
// dots, hyphens, underscores, and forward slashes (for provider prefixes).
|
|
117
|
+
if (!/^[a-zA-Z0-9._\-\/]+$/.test(model)) {
|
|
118
|
+
throw new Error(`Invalid model ID: "${model}". Only alphanumeric characters, dots, hyphens, underscores, and slashes are allowed.`);
|
|
119
|
+
}
|
|
120
|
+
|
|
114
121
|
const sessionId = randomBytes(8).toString("hex");
|
|
115
122
|
const prompt = formatPrompt(messages);
|
|
116
123
|
|