@jacobbd/relay-ai 0.3.4 → 0.3.5
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/CHANGELOG.md +10 -0
- package/README.md +8 -5
- package/dist/cli.js +15 -13
- package/jacobbd-relay-ai-0.3.4.tgz +0 -0
- package/package.json +1 -1
- package/.gemini/xai-models.json +0 -165
- package/assets/demo-part1-thumbnail.png +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.3.5] - 2026-06-26
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **Windows: Claude Desktop 3P config now writes to the correct path** — relay-ai was writing the `configLibrary` to `%APPDATA%\Claude-3p` (Roaming) but Claude Desktop reads from `%LOCALAPPDATA%\Claude-3p` (Local). The config is now written to the correct location. Reported by Trojan28A ([#11](https://github.com/jacob-bd/relay-ai/issues/11)).
|
|
8
|
+
|
|
9
|
+
- **Windows: Claude Desktop and Codex App now launch correctly from MSIX installs** — `Start-Process 'shell:AppsFolder\...'` failed silently due to PowerShell backslash double-escaping via `JSON.stringify`. The launcher now uses `cmd /c start` with an argument array, which bypasses PowerShell string parsing entirely and correctly opens MSIX-packaged apps. ([#11](https://github.com/jacob-bd/relay-ai/issues/11)).
|
|
10
|
+
|
|
11
|
+
- **Windows: OpenCode CLI now discovered correctly when `where.exe` returns multiple results** — `where.exe opencode` returns both a bare script and a `.cmd` wrapper. relay-ai was taking the first result (the bare script), which Node's `spawn()` cannot execute directly. relay-ai now prefers the `.cmd` entry. The same fix applies to the `claude`, `codex`, and `gemini` binary lookups. The OpenCode `serve` subprocess also now uses `cmd.exe /c` on Windows to avoid Node 22's DEP0190 deprecation warning. ([#11](https://github.com/jacob-bd/relay-ai/issues/11)).
|
|
12
|
+
|
|
3
13
|
## [0.3.4] - 2026-06-23
|
|
4
14
|
|
|
5
15
|
### Fixed
|
package/README.md
CHANGED
|
@@ -13,11 +13,16 @@
|
|
|
13
13
|
|
|
14
14
|
<p align="center">
|
|
15
15
|
<a href="https://youtu.be/IvsUPHLhX0o">
|
|
16
|
-
<img src="
|
|
16
|
+
<img src="https://img.youtube.com/vi/IvsUPHLhX0o/maxresdefault.jpg" alt="relay-ai demo — installation, configuration, Claude Code, Claude Cowork & Claude Code Desktop (Part 1)" width="49%">
|
|
17
|
+
</a>
|
|
18
|
+
<a href="https://youtu.be/42oiOB8IAu4">
|
|
19
|
+
<img src="https://img.youtube.com/vi/42oiOB8IAu4/maxresdefault.jpg" alt="relay-ai demo — OpenAI Codex CLI & Codex Desktop App (Part 2)" width="49%">
|
|
17
20
|
</a>
|
|
18
21
|
</p>
|
|
19
22
|
|
|
20
|
-
> **
|
|
23
|
+
> 🎥 **Watch the Demos:**
|
|
24
|
+
> - **Demo (Part 1):** Installation · Configuration · Claude Code · Claude Cowork & Claude Code Desktop — [watch on YouTube](https://youtu.be/IvsUPHLhX0o)
|
|
25
|
+
> - **Demo (Part 2):** OpenAI Codex CLI & Codex Desktop App — [watch on YouTube](https://youtu.be/42oiOB8IAu4)
|
|
21
26
|
|
|
22
27
|
**relay-ai** is an interactive CLI that launches AI coding tools and runs local API gateways on your machine. Currently, it supports **Claude Code**, **Claude Desktop (Cowork + Code)**, the **OpenAI Codex CLI**, the **Codex desktop app (macOS + Windows)**, and the **Google Gemini CLI**.
|
|
23
28
|
|
|
@@ -44,8 +49,6 @@ Pick your backend:
|
|
|
44
49
|
| `relay-ai gemini` | Launch Google Gemini CLI with registry providers |
|
|
45
50
|
| `relay-ai --ai` | Full agent reference for scripts and alef-agent ([guide](docs/AI-AGENTS.md)) |
|
|
46
51
|
|
|
47
|
-
Bare `relay-ai` prints help and migration guidance. Use `relay-ai claude` for the wizard.
|
|
48
|
-
|
|
49
52
|
## Features
|
|
50
53
|
|
|
51
54
|
- **Native provider registry:** `relay-ai providers` stores config in `~/.relay-ai/providers.json` and secrets in the OS keychain — no OpenCode binary required at launch. See **[docs/PROVIDERS.md](docs/PROVIDERS.md)** for a full list of providers and known issues.
|
|
@@ -78,7 +81,7 @@ Bare `relay-ai` prints help and migration guidance. Use `relay-ai claude` for th
|
|
|
78
81
|
| Claude Desktop (Cowork + Code) | `relay-ai claude-app` | ✅ Supported macOS + Windows ([guide](docs/CLAUDE_DESKTOP_SETUP.md)) |
|
|
79
82
|
| Codex CLI | `relay-ai codex` | ✅ Supported ([guide](docs/CODEX.md)) |
|
|
80
83
|
| Codex desktop app | `relay-ai codex-app` | ✅ Supported macOS + Windows ([guide](docs/CODEX.md)) |
|
|
81
|
-
| Google Gemini CLI | `relay-ai gemini` |
|
|
84
|
+
| Google Gemini CLI | `relay-ai gemini` | ⚠️ Experimental, model switching is done via .model prompt |
|
|
82
85
|
|
|
83
86
|
## Prerequisites
|
|
84
87
|
|
package/dist/cli.js
CHANGED
|
@@ -35,7 +35,7 @@ import { join } from "path";
|
|
|
35
35
|
// package.json
|
|
36
36
|
var package_default = {
|
|
37
37
|
name: "@jacobbd/relay-ai",
|
|
38
|
-
version: "0.3.
|
|
38
|
+
version: "0.3.5",
|
|
39
39
|
publishConfig: {
|
|
40
40
|
access: "public"
|
|
41
41
|
},
|
|
@@ -1154,7 +1154,8 @@ function findClaudeBinary() {
|
|
|
1154
1154
|
encoding: "utf8",
|
|
1155
1155
|
stdio: ["pipe", "pipe", "pipe"]
|
|
1156
1156
|
});
|
|
1157
|
-
const
|
|
1157
|
+
const lines = result.trim().split("\n").map((l) => l.trim()).filter(Boolean);
|
|
1158
|
+
const path = (isWindows ? lines.find((l) => l.toLowerCase().endsWith(".cmd")) : null) ?? lines[0];
|
|
1158
1159
|
if (path) return path;
|
|
1159
1160
|
} catch {
|
|
1160
1161
|
}
|
|
@@ -3281,7 +3282,8 @@ function findOpencodeBinary() {
|
|
|
3281
3282
|
encoding: "utf8",
|
|
3282
3283
|
stdio: ["pipe", "pipe", "pipe"]
|
|
3283
3284
|
});
|
|
3284
|
-
const
|
|
3285
|
+
const lines = result.trim().split("\n").map((l) => l.trim()).filter(Boolean);
|
|
3286
|
+
const path = (isWindows2 ? lines.find((l) => l.toLowerCase().endsWith(".cmd")) : null) ?? lines[0];
|
|
3285
3287
|
if (path) return path;
|
|
3286
3288
|
} catch {
|
|
3287
3289
|
}
|
|
@@ -3311,9 +3313,7 @@ async function fetchRawOpencodeProviders() {
|
|
|
3311
3313
|
finish(null);
|
|
3312
3314
|
}, TIMEOUT_MS);
|
|
3313
3315
|
try {
|
|
3314
|
-
child = spawn2(binary, ["serve", "--port", "0"], {
|
|
3315
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
3316
|
-
});
|
|
3316
|
+
child = isWindows2 ? spawn2("cmd.exe", ["/c", binary, "serve", "--port", "0"], { stdio: ["pipe", "pipe", "pipe"] }) : spawn2(binary, ["serve", "--port", "0"], { stdio: ["pipe", "pipe", "pipe"] });
|
|
3317
3317
|
} catch {
|
|
3318
3318
|
finish(null);
|
|
3319
3319
|
return;
|
|
@@ -10558,7 +10558,8 @@ function findCodexBinary() {
|
|
|
10558
10558
|
encoding: "utf8",
|
|
10559
10559
|
stdio: ["pipe", "pipe", "pipe"]
|
|
10560
10560
|
});
|
|
10561
|
-
const
|
|
10561
|
+
const lines = result.trim().split("\n").map((l) => l.trim()).filter(Boolean);
|
|
10562
|
+
const path = (isWindows3 ? lines.find((l) => l.toLowerCase().endsWith(".cmd")) : null) ?? lines[0];
|
|
10562
10563
|
if (path) return path;
|
|
10563
10564
|
} catch {
|
|
10564
10565
|
}
|
|
@@ -11566,7 +11567,8 @@ function findGeminiBinary() {
|
|
|
11566
11567
|
encoding: "utf8",
|
|
11567
11568
|
stdio: ["pipe", "pipe", "pipe"]
|
|
11568
11569
|
});
|
|
11569
|
-
const
|
|
11570
|
+
const lines = result.trim().split("\n").map((l) => l.trim()).filter(Boolean);
|
|
11571
|
+
const path = (isWindows4 ? lines.find((l) => l.toLowerCase().endsWith(".cmd")) : null) ?? lines[0];
|
|
11570
11572
|
if (path) return path;
|
|
11571
11573
|
} catch {
|
|
11572
11574
|
}
|
|
@@ -12930,7 +12932,7 @@ function waitForShutdown2() {
|
|
|
12930
12932
|
}
|
|
12931
12933
|
|
|
12932
12934
|
// src/codex/app-launch.ts
|
|
12933
|
-
import { execSync as execSync5 } from "child_process";
|
|
12935
|
+
import { execSync as execSync5, spawn as spawn6 } from "child_process";
|
|
12934
12936
|
import { existsSync as existsSync16, readdirSync as readdirSync3, statSync as statSync4 } from "fs";
|
|
12935
12937
|
import { homedir as homedir11 } from "os";
|
|
12936
12938
|
import { join as join17 } from "path";
|
|
@@ -13073,7 +13075,7 @@ function openCodexAppAt(path) {
|
|
|
13073
13075
|
}
|
|
13074
13076
|
if (process.platform === "win32") {
|
|
13075
13077
|
if (path.startsWith("shell:AppsFolder\\")) {
|
|
13076
|
-
|
|
13078
|
+
spawn6("cmd.exe", ["/c", "start", "", path], { stdio: "ignore", detached: true }).unref();
|
|
13077
13079
|
} else {
|
|
13078
13080
|
runPowerShell(`Start-Process -FilePath '${path.replace(/'/g, "''")}'`);
|
|
13079
13081
|
}
|
|
@@ -13628,7 +13630,7 @@ import { join as join18, dirname as dirname7 } from "path";
|
|
|
13628
13630
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
13629
13631
|
function getClaudeDesktopHome() {
|
|
13630
13632
|
if (process.platform === "win32") {
|
|
13631
|
-
return join18(process.env.
|
|
13633
|
+
return join18(process.env.LOCALAPPDATA || join18(homedir12(), "AppData", "Local"), "Claude-3p");
|
|
13632
13634
|
}
|
|
13633
13635
|
return join18(homedir12(), "Library", "Application Support", "Claude-3p");
|
|
13634
13636
|
}
|
|
@@ -13789,7 +13791,7 @@ function setupExitCleanup(uuid) {
|
|
|
13789
13791
|
}
|
|
13790
13792
|
|
|
13791
13793
|
// src/claude-desktop/app-launch.ts
|
|
13792
|
-
import { execSync as execSync6 } from "child_process";
|
|
13794
|
+
import { execSync as execSync6, spawn as spawn7 } from "child_process";
|
|
13793
13795
|
import { existsSync as existsSync19, readdirSync as readdirSync4, statSync as statSync5 } from "fs";
|
|
13794
13796
|
import { homedir as homedir13 } from "os";
|
|
13795
13797
|
import { join as join20 } from "path";
|
|
@@ -13928,7 +13930,7 @@ function openClaudeAppAt(path) {
|
|
|
13928
13930
|
}
|
|
13929
13931
|
if (process.platform === "win32") {
|
|
13930
13932
|
if (path.startsWith("shell:AppsFolder\\")) {
|
|
13931
|
-
|
|
13933
|
+
spawn7("cmd.exe", ["/c", "start", "", path], { stdio: "ignore", detached: true }).unref();
|
|
13932
13934
|
} else {
|
|
13933
13935
|
runPowerShell2(`Start-Process -FilePath '${path.replace(/'/g, "''")}'`);
|
|
13934
13936
|
}
|
|
Binary file
|
package/package.json
CHANGED
package/.gemini/xai-models.json
DELETED
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"data": [
|
|
3
|
-
{
|
|
4
|
-
"id": "grok-4.20-0309-non-reasoning",
|
|
5
|
-
"aliases": [
|
|
6
|
-
"grok-4.20-non-reasoning",
|
|
7
|
-
"grok-4.20-non-reasoning-latest",
|
|
8
|
-
"grok-4.20-beta-non-reasoning",
|
|
9
|
-
"grok-4.20-beta-latest-non-reasoning",
|
|
10
|
-
"grok-4.20-experimental-beta-0304-non-reasoning",
|
|
11
|
-
"grok-4.20-experimental-beta-non-reasoning-latest",
|
|
12
|
-
"grok-4.20-beta-0309-non-reasoning",
|
|
13
|
-
"grok-4.20-non-reasoning-gv2"
|
|
14
|
-
],
|
|
15
|
-
"context_length": 1000000,
|
|
16
|
-
"created": 1773014400,
|
|
17
|
-
"object": "model",
|
|
18
|
-
"owned_by": "xai",
|
|
19
|
-
"prompt_text_token_price": 12500,
|
|
20
|
-
"cached_prompt_text_token_price": 2000,
|
|
21
|
-
"prompt_image_token_price": 12500,
|
|
22
|
-
"completion_text_token_price": 25000,
|
|
23
|
-
"prompt_text_token_price_long_context": 25000,
|
|
24
|
-
"cached_prompt_text_token_price_long_context": 4000,
|
|
25
|
-
"completion_text_token_price_long_context": 50000,
|
|
26
|
-
"long_context_threshold": 200000
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
"id": "grok-4.20-0309-reasoning",
|
|
30
|
-
"aliases": [
|
|
31
|
-
"grok-4.20-reasoning-latest",
|
|
32
|
-
"grok-4.20",
|
|
33
|
-
"grok-4.20-reasoning",
|
|
34
|
-
"grok-4.20-0309",
|
|
35
|
-
"grok-4.20-beta-0309-reasoning",
|
|
36
|
-
"grok-4.20-beta",
|
|
37
|
-
"grok-4.20-beta-0309",
|
|
38
|
-
"grok-4.20-beta-latest",
|
|
39
|
-
"grok-4.20-beta-latest-reasoning",
|
|
40
|
-
"grok-4.20-beta-reasoning",
|
|
41
|
-
"grok-4.20-experimental-beta-0304-reasoning",
|
|
42
|
-
"grok-4.20-experimental-beta-0304",
|
|
43
|
-
"grok-4.20-experimental-beta-reasoning-latest",
|
|
44
|
-
"grok-4.20-experimental-beta-latest",
|
|
45
|
-
"grok-4.20-reasoning-gv2"
|
|
46
|
-
],
|
|
47
|
-
"context_length": 1000000,
|
|
48
|
-
"created": 1773014400,
|
|
49
|
-
"object": "model",
|
|
50
|
-
"owned_by": "xai",
|
|
51
|
-
"prompt_text_token_price": 12500,
|
|
52
|
-
"cached_prompt_text_token_price": 2000,
|
|
53
|
-
"prompt_image_token_price": 12500,
|
|
54
|
-
"completion_text_token_price": 25000,
|
|
55
|
-
"prompt_text_token_price_long_context": 25000,
|
|
56
|
-
"cached_prompt_text_token_price_long_context": 4000,
|
|
57
|
-
"completion_text_token_price_long_context": 50000,
|
|
58
|
-
"long_context_threshold": 200000
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
"id": "grok-4.20-multi-agent-0309",
|
|
62
|
-
"aliases": [
|
|
63
|
-
"grok-4.20-multi-agent",
|
|
64
|
-
"grok-4.20-multi-agent-latest",
|
|
65
|
-
"grok-4.20-multi-agent-beta-latest",
|
|
66
|
-
"grok-4.20-multi-agent-experimental-beta-0304",
|
|
67
|
-
"grok-4.20-multi-agent-experimental-beta-latest",
|
|
68
|
-
"grok-4.20-multi-agent-beta-0309"
|
|
69
|
-
],
|
|
70
|
-
"context_length": 1000000,
|
|
71
|
-
"created": 1773014400,
|
|
72
|
-
"object": "model",
|
|
73
|
-
"owned_by": "xai",
|
|
74
|
-
"prompt_text_token_price": 12500,
|
|
75
|
-
"cached_prompt_text_token_price": 2000,
|
|
76
|
-
"prompt_image_token_price": 12500,
|
|
77
|
-
"completion_text_token_price": 25000,
|
|
78
|
-
"prompt_text_token_price_long_context": 25000,
|
|
79
|
-
"cached_prompt_text_token_price_long_context": 4000,
|
|
80
|
-
"completion_text_token_price_long_context": 50000,
|
|
81
|
-
"long_context_threshold": 200000
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
"id": "grok-4.3",
|
|
85
|
-
"aliases": [
|
|
86
|
-
"grok-4.3-latest",
|
|
87
|
-
"grok-latest"
|
|
88
|
-
],
|
|
89
|
-
"context_length": 1000000,
|
|
90
|
-
"created": 1776384000,
|
|
91
|
-
"object": "model",
|
|
92
|
-
"owned_by": "xai",
|
|
93
|
-
"prompt_text_token_price": 12500,
|
|
94
|
-
"cached_prompt_text_token_price": 2000,
|
|
95
|
-
"prompt_image_token_price": 12500,
|
|
96
|
-
"completion_text_token_price": 25000,
|
|
97
|
-
"prompt_text_token_price_long_context": 25000,
|
|
98
|
-
"cached_prompt_text_token_price_long_context": 4000,
|
|
99
|
-
"completion_text_token_price_long_context": 50000,
|
|
100
|
-
"long_context_threshold": 200000
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
"id": "grok-build-0.1",
|
|
104
|
-
"aliases": [
|
|
105
|
-
"grok-code-fast-1",
|
|
106
|
-
"grok-code-fast",
|
|
107
|
-
"grok-code-fast-1-0825"
|
|
108
|
-
],
|
|
109
|
-
"context_length": 256000,
|
|
110
|
-
"created": 1776297600,
|
|
111
|
-
"object": "model",
|
|
112
|
-
"owned_by": "xai",
|
|
113
|
-
"prompt_text_token_price": 10000,
|
|
114
|
-
"cached_prompt_text_token_price": 2000,
|
|
115
|
-
"prompt_image_token_price": 10000,
|
|
116
|
-
"completion_text_token_price": 20000,
|
|
117
|
-
"prompt_text_token_price_long_context": 20000,
|
|
118
|
-
"cached_prompt_text_token_price_long_context": 4000,
|
|
119
|
-
"completion_text_token_price_long_context": 40000,
|
|
120
|
-
"long_context_threshold": 200000
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
"id": "grok-imagine-image",
|
|
124
|
-
"aliases": [
|
|
125
|
-
"grok-imagine-image-2026-03-02"
|
|
126
|
-
],
|
|
127
|
-
"context_length": 8000,
|
|
128
|
-
"created": 1769558400,
|
|
129
|
-
"object": "model",
|
|
130
|
-
"owned_by": "xai",
|
|
131
|
-
"image_price": 200000000
|
|
132
|
-
},
|
|
133
|
-
{
|
|
134
|
-
"id": "grok-imagine-image-quality",
|
|
135
|
-
"aliases": [
|
|
136
|
-
"grok-imagine-image-quality-20260403",
|
|
137
|
-
"grok-imagine-image-quality-latest",
|
|
138
|
-
"grok-imagine-image-pro"
|
|
139
|
-
],
|
|
140
|
-
"context_length": 8000,
|
|
141
|
-
"created": 1775174400,
|
|
142
|
-
"object": "model",
|
|
143
|
-
"owned_by": "xai",
|
|
144
|
-
"image_price": 500000000
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
"id": "grok-imagine-video",
|
|
148
|
-
"aliases": [],
|
|
149
|
-
"created": 1769558400,
|
|
150
|
-
"object": "model",
|
|
151
|
-
"owned_by": "xai"
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
"id": "grok-imagine-video-1.5",
|
|
155
|
-
"aliases": [
|
|
156
|
-
"grok-imagine-video-1.5-preview",
|
|
157
|
-
"grok-imagine-video-1.5-2026-05-30"
|
|
158
|
-
],
|
|
159
|
-
"created": 1779840000,
|
|
160
|
-
"object": "model",
|
|
161
|
-
"owned_by": "xai"
|
|
162
|
-
}
|
|
163
|
-
],
|
|
164
|
-
"object": "list"
|
|
165
|
-
}
|
|
Binary file
|