@jacobbd/relay-ai 0.3.3 → 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 +16 -0
- package/README.md +8 -5
- package/dist/cli.js +21 -15
- 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/coverage/base.css +0 -224
- package/coverage/block-navigation.js +0 -87
- package/coverage/clover.xml +0 -13654
- package/coverage/coverage-final.json +0 -106
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +0 -221
- package/coverage/prettify.css +0 -1
- package/coverage/prettify.js +0 -2
- package/coverage/scripts/index.html +0 -116
- package/coverage/scripts/refresh-models-dev-cache.mjs.html +0 -187
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +0 -210
- package/vitest.log +0 -33
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
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
|
+
|
|
13
|
+
## [0.3.4] - 2026-06-23
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **Go models no longer mislabeled as Anthropic format** — OpenCode Go models (e.g. `minimax-m3`, `qwen3.7-plus`, `minimax-m2.7`, `qwen3.7-max`, `qwen3.6-plus`) were incorrectly classified as `modelFormat: 'anthropic'` due to stale `@ai-sdk/anthropic` npm entries written by the OpenCode cache. The Go backend is an OpenAI-compatible gateway only; relay-ai now clamps any `anthropic` format classification to `openai` for all Go models regardless of cache data. Reported by Philip2050 ([#10](https://github.com/jacob-bd/relay-ai/issues/10)).
|
|
18
|
+
|
|
3
19
|
## [0.3.3] - 2026-06-22
|
|
4
20
|
|
|
5
21
|
### 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
|
}
|
|
@@ -3137,7 +3138,8 @@ function readModelsFromCache(backendId) {
|
|
|
3137
3138
|
for (const entry of Object.values(providerData.models)) {
|
|
3138
3139
|
if (!entry.id || entry.status === "deprecated") continue;
|
|
3139
3140
|
const isFree = entry.cost !== void 0 && entry.cost.input === 0 && entry.cost.output === 0;
|
|
3140
|
-
const
|
|
3141
|
+
const rawFormat = classifyModelFormat(entry.id, entry.provider?.npm);
|
|
3142
|
+
const modelFormat = backendId === "go" && rawFormat === "anthropic" ? "openai" : rawFormat;
|
|
3141
3143
|
result.set(entry.id, {
|
|
3142
3144
|
id: entry.id,
|
|
3143
3145
|
name: entry.name ?? entry.id,
|
|
@@ -3169,7 +3171,10 @@ async function fetchModelsFromApi(backend) {
|
|
|
3169
3171
|
function mergeModels(apiIds, cache, backendId) {
|
|
3170
3172
|
return apiIds.filter((id) => !shouldHideModel({ providerId: backendId, modelId: id, agent: "claude" })).map((id) => {
|
|
3171
3173
|
const cached = cache?.get(id);
|
|
3172
|
-
if (cached)
|
|
3174
|
+
if (cached) {
|
|
3175
|
+
const modelFormat2 = backendId === "go" && cached.modelFormat === "anthropic" ? "openai" : cached.modelFormat;
|
|
3176
|
+
return { ...cached, sourceBackend: backendId, modelFormat: modelFormat2 };
|
|
3177
|
+
}
|
|
3173
3178
|
const modelFormat = classifyModelFormat(id, void 0);
|
|
3174
3179
|
return {
|
|
3175
3180
|
id,
|
|
@@ -3277,7 +3282,8 @@ function findOpencodeBinary() {
|
|
|
3277
3282
|
encoding: "utf8",
|
|
3278
3283
|
stdio: ["pipe", "pipe", "pipe"]
|
|
3279
3284
|
});
|
|
3280
|
-
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];
|
|
3281
3287
|
if (path) return path;
|
|
3282
3288
|
} catch {
|
|
3283
3289
|
}
|
|
@@ -3307,9 +3313,7 @@ async function fetchRawOpencodeProviders() {
|
|
|
3307
3313
|
finish(null);
|
|
3308
3314
|
}, TIMEOUT_MS);
|
|
3309
3315
|
try {
|
|
3310
|
-
child = spawn2(binary, ["serve", "--port", "0"], {
|
|
3311
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
3312
|
-
});
|
|
3316
|
+
child = isWindows2 ? spawn2("cmd.exe", ["/c", binary, "serve", "--port", "0"], { stdio: ["pipe", "pipe", "pipe"] }) : spawn2(binary, ["serve", "--port", "0"], { stdio: ["pipe", "pipe", "pipe"] });
|
|
3313
3317
|
} catch {
|
|
3314
3318
|
finish(null);
|
|
3315
3319
|
return;
|
|
@@ -10554,7 +10558,8 @@ function findCodexBinary() {
|
|
|
10554
10558
|
encoding: "utf8",
|
|
10555
10559
|
stdio: ["pipe", "pipe", "pipe"]
|
|
10556
10560
|
});
|
|
10557
|
-
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];
|
|
10558
10563
|
if (path) return path;
|
|
10559
10564
|
} catch {
|
|
10560
10565
|
}
|
|
@@ -11562,7 +11567,8 @@ function findGeminiBinary() {
|
|
|
11562
11567
|
encoding: "utf8",
|
|
11563
11568
|
stdio: ["pipe", "pipe", "pipe"]
|
|
11564
11569
|
});
|
|
11565
|
-
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];
|
|
11566
11572
|
if (path) return path;
|
|
11567
11573
|
} catch {
|
|
11568
11574
|
}
|
|
@@ -12926,7 +12932,7 @@ function waitForShutdown2() {
|
|
|
12926
12932
|
}
|
|
12927
12933
|
|
|
12928
12934
|
// src/codex/app-launch.ts
|
|
12929
|
-
import { execSync as execSync5 } from "child_process";
|
|
12935
|
+
import { execSync as execSync5, spawn as spawn6 } from "child_process";
|
|
12930
12936
|
import { existsSync as existsSync16, readdirSync as readdirSync3, statSync as statSync4 } from "fs";
|
|
12931
12937
|
import { homedir as homedir11 } from "os";
|
|
12932
12938
|
import { join as join17 } from "path";
|
|
@@ -13069,7 +13075,7 @@ function openCodexAppAt(path) {
|
|
|
13069
13075
|
}
|
|
13070
13076
|
if (process.platform === "win32") {
|
|
13071
13077
|
if (path.startsWith("shell:AppsFolder\\")) {
|
|
13072
|
-
|
|
13078
|
+
spawn6("cmd.exe", ["/c", "start", "", path], { stdio: "ignore", detached: true }).unref();
|
|
13073
13079
|
} else {
|
|
13074
13080
|
runPowerShell(`Start-Process -FilePath '${path.replace(/'/g, "''")}'`);
|
|
13075
13081
|
}
|
|
@@ -13624,7 +13630,7 @@ import { join as join18, dirname as dirname7 } from "path";
|
|
|
13624
13630
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
13625
13631
|
function getClaudeDesktopHome() {
|
|
13626
13632
|
if (process.platform === "win32") {
|
|
13627
|
-
return join18(process.env.
|
|
13633
|
+
return join18(process.env.LOCALAPPDATA || join18(homedir12(), "AppData", "Local"), "Claude-3p");
|
|
13628
13634
|
}
|
|
13629
13635
|
return join18(homedir12(), "Library", "Application Support", "Claude-3p");
|
|
13630
13636
|
}
|
|
@@ -13785,7 +13791,7 @@ function setupExitCleanup(uuid) {
|
|
|
13785
13791
|
}
|
|
13786
13792
|
|
|
13787
13793
|
// src/claude-desktop/app-launch.ts
|
|
13788
|
-
import { execSync as execSync6 } from "child_process";
|
|
13794
|
+
import { execSync as execSync6, spawn as spawn7 } from "child_process";
|
|
13789
13795
|
import { existsSync as existsSync19, readdirSync as readdirSync4, statSync as statSync5 } from "fs";
|
|
13790
13796
|
import { homedir as homedir13 } from "os";
|
|
13791
13797
|
import { join as join20 } from "path";
|
|
@@ -13924,7 +13930,7 @@ function openClaudeAppAt(path) {
|
|
|
13924
13930
|
}
|
|
13925
13931
|
if (process.platform === "win32") {
|
|
13926
13932
|
if (path.startsWith("shell:AppsFolder\\")) {
|
|
13927
|
-
|
|
13933
|
+
spawn7("cmd.exe", ["/c", "start", "", path], { stdio: "ignore", detached: true }).unref();
|
|
13928
13934
|
} else {
|
|
13929
13935
|
runPowerShell2(`Start-Process -FilePath '${path.replace(/'/g, "''")}'`);
|
|
13930
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
|
package/coverage/base.css
DELETED
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
body, html {
|
|
2
|
-
margin:0; padding: 0;
|
|
3
|
-
height: 100%;
|
|
4
|
-
}
|
|
5
|
-
body {
|
|
6
|
-
font-family: Helvetica Neue, Helvetica, Arial;
|
|
7
|
-
font-size: 14px;
|
|
8
|
-
color:#333;
|
|
9
|
-
}
|
|
10
|
-
.small { font-size: 12px; }
|
|
11
|
-
*, *:after, *:before {
|
|
12
|
-
-webkit-box-sizing:border-box;
|
|
13
|
-
-moz-box-sizing:border-box;
|
|
14
|
-
box-sizing:border-box;
|
|
15
|
-
}
|
|
16
|
-
h1 { font-size: 20px; margin: 0;}
|
|
17
|
-
h2 { font-size: 14px; }
|
|
18
|
-
pre {
|
|
19
|
-
font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
|
20
|
-
margin: 0;
|
|
21
|
-
padding: 0;
|
|
22
|
-
-moz-tab-size: 2;
|
|
23
|
-
-o-tab-size: 2;
|
|
24
|
-
tab-size: 2;
|
|
25
|
-
}
|
|
26
|
-
a { color:#0074D9; text-decoration:none; }
|
|
27
|
-
a:hover { text-decoration:underline; }
|
|
28
|
-
.strong { font-weight: bold; }
|
|
29
|
-
.space-top1 { padding: 10px 0 0 0; }
|
|
30
|
-
.pad2y { padding: 20px 0; }
|
|
31
|
-
.pad1y { padding: 10px 0; }
|
|
32
|
-
.pad2x { padding: 0 20px; }
|
|
33
|
-
.pad2 { padding: 20px; }
|
|
34
|
-
.pad1 { padding: 10px; }
|
|
35
|
-
.space-left2 { padding-left:55px; }
|
|
36
|
-
.space-right2 { padding-right:20px; }
|
|
37
|
-
.center { text-align:center; }
|
|
38
|
-
.clearfix { display:block; }
|
|
39
|
-
.clearfix:after {
|
|
40
|
-
content:'';
|
|
41
|
-
display:block;
|
|
42
|
-
height:0;
|
|
43
|
-
clear:both;
|
|
44
|
-
visibility:hidden;
|
|
45
|
-
}
|
|
46
|
-
.fl { float: left; }
|
|
47
|
-
@media only screen and (max-width:640px) {
|
|
48
|
-
.col3 { width:100%; max-width:100%; }
|
|
49
|
-
.hide-mobile { display:none!important; }
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
.quiet {
|
|
53
|
-
color: #7f7f7f;
|
|
54
|
-
color: rgba(0,0,0,0.5);
|
|
55
|
-
}
|
|
56
|
-
.quiet a { opacity: 0.7; }
|
|
57
|
-
|
|
58
|
-
.fraction {
|
|
59
|
-
font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
|
|
60
|
-
font-size: 10px;
|
|
61
|
-
color: #555;
|
|
62
|
-
background: #E8E8E8;
|
|
63
|
-
padding: 4px 5px;
|
|
64
|
-
border-radius: 3px;
|
|
65
|
-
vertical-align: middle;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
div.path a:link, div.path a:visited { color: #333; }
|
|
69
|
-
table.coverage {
|
|
70
|
-
border-collapse: collapse;
|
|
71
|
-
margin: 10px 0 0 0;
|
|
72
|
-
padding: 0;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
table.coverage td {
|
|
76
|
-
margin: 0;
|
|
77
|
-
padding: 0;
|
|
78
|
-
vertical-align: top;
|
|
79
|
-
}
|
|
80
|
-
table.coverage td.line-count {
|
|
81
|
-
text-align: right;
|
|
82
|
-
padding: 0 5px 0 20px;
|
|
83
|
-
}
|
|
84
|
-
table.coverage td.line-coverage {
|
|
85
|
-
text-align: right;
|
|
86
|
-
padding-right: 10px;
|
|
87
|
-
min-width:20px;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
table.coverage td span.cline-any {
|
|
91
|
-
display: inline-block;
|
|
92
|
-
padding: 0 5px;
|
|
93
|
-
width: 100%;
|
|
94
|
-
}
|
|
95
|
-
.missing-if-branch {
|
|
96
|
-
display: inline-block;
|
|
97
|
-
margin-right: 5px;
|
|
98
|
-
border-radius: 3px;
|
|
99
|
-
position: relative;
|
|
100
|
-
padding: 0 4px;
|
|
101
|
-
background: #333;
|
|
102
|
-
color: yellow;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.skip-if-branch {
|
|
106
|
-
display: none;
|
|
107
|
-
margin-right: 10px;
|
|
108
|
-
position: relative;
|
|
109
|
-
padding: 0 4px;
|
|
110
|
-
background: #ccc;
|
|
111
|
-
color: white;
|
|
112
|
-
}
|
|
113
|
-
.missing-if-branch .typ, .skip-if-branch .typ {
|
|
114
|
-
color: inherit !important;
|
|
115
|
-
}
|
|
116
|
-
.coverage-summary {
|
|
117
|
-
border-collapse: collapse;
|
|
118
|
-
width: 100%;
|
|
119
|
-
}
|
|
120
|
-
.coverage-summary tr { border-bottom: 1px solid #bbb; }
|
|
121
|
-
.keyline-all { border: 1px solid #ddd; }
|
|
122
|
-
.coverage-summary td, .coverage-summary th { padding: 10px; }
|
|
123
|
-
.coverage-summary tbody { border: 1px solid #bbb; }
|
|
124
|
-
.coverage-summary td { border-right: 1px solid #bbb; }
|
|
125
|
-
.coverage-summary td:last-child { border-right: none; }
|
|
126
|
-
.coverage-summary th {
|
|
127
|
-
text-align: left;
|
|
128
|
-
font-weight: normal;
|
|
129
|
-
white-space: nowrap;
|
|
130
|
-
}
|
|
131
|
-
.coverage-summary th.file { border-right: none !important; }
|
|
132
|
-
.coverage-summary th.pct { }
|
|
133
|
-
.coverage-summary th.pic,
|
|
134
|
-
.coverage-summary th.abs,
|
|
135
|
-
.coverage-summary td.pct,
|
|
136
|
-
.coverage-summary td.abs { text-align: right; }
|
|
137
|
-
.coverage-summary td.file { white-space: nowrap; }
|
|
138
|
-
.coverage-summary td.pic { min-width: 120px !important; }
|
|
139
|
-
.coverage-summary tfoot td { }
|
|
140
|
-
|
|
141
|
-
.coverage-summary .sorter {
|
|
142
|
-
height: 10px;
|
|
143
|
-
width: 7px;
|
|
144
|
-
display: inline-block;
|
|
145
|
-
margin-left: 0.5em;
|
|
146
|
-
background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
|
|
147
|
-
}
|
|
148
|
-
.coverage-summary .sorted .sorter {
|
|
149
|
-
background-position: 0 -20px;
|
|
150
|
-
}
|
|
151
|
-
.coverage-summary .sorted-desc .sorter {
|
|
152
|
-
background-position: 0 -10px;
|
|
153
|
-
}
|
|
154
|
-
.status-line { height: 10px; }
|
|
155
|
-
/* yellow */
|
|
156
|
-
.cbranch-no { background: yellow !important; color: #111; }
|
|
157
|
-
/* dark red */
|
|
158
|
-
.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 }
|
|
159
|
-
.low .chart { border:1px solid #C21F39 }
|
|
160
|
-
.highlighted,
|
|
161
|
-
.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{
|
|
162
|
-
background: #C21F39 !important;
|
|
163
|
-
}
|
|
164
|
-
/* medium red */
|
|
165
|
-
.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE }
|
|
166
|
-
/* light red */
|
|
167
|
-
.low, .cline-no { background:#FCE1E5 }
|
|
168
|
-
/* light green */
|
|
169
|
-
.high, .cline-yes { background:rgb(230,245,208) }
|
|
170
|
-
/* medium green */
|
|
171
|
-
.cstat-yes { background:rgb(161,215,106) }
|
|
172
|
-
/* dark green */
|
|
173
|
-
.status-line.high, .high .cover-fill { background:rgb(77,146,33) }
|
|
174
|
-
.high .chart { border:1px solid rgb(77,146,33) }
|
|
175
|
-
/* dark yellow (gold) */
|
|
176
|
-
.status-line.medium, .medium .cover-fill { background: #f9cd0b; }
|
|
177
|
-
.medium .chart { border:1px solid #f9cd0b; }
|
|
178
|
-
/* light yellow */
|
|
179
|
-
.medium { background: #fff4c2; }
|
|
180
|
-
|
|
181
|
-
.cstat-skip { background: #ddd; color: #111; }
|
|
182
|
-
.fstat-skip { background: #ddd; color: #111 !important; }
|
|
183
|
-
.cbranch-skip { background: #ddd !important; color: #111; }
|
|
184
|
-
|
|
185
|
-
span.cline-neutral { background: #eaeaea; }
|
|
186
|
-
|
|
187
|
-
.coverage-summary td.empty {
|
|
188
|
-
opacity: .5;
|
|
189
|
-
padding-top: 4px;
|
|
190
|
-
padding-bottom: 4px;
|
|
191
|
-
line-height: 1;
|
|
192
|
-
color: #888;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
.cover-fill, .cover-empty {
|
|
196
|
-
display:inline-block;
|
|
197
|
-
height: 12px;
|
|
198
|
-
}
|
|
199
|
-
.chart {
|
|
200
|
-
line-height: 0;
|
|
201
|
-
}
|
|
202
|
-
.cover-empty {
|
|
203
|
-
background: white;
|
|
204
|
-
}
|
|
205
|
-
.cover-full {
|
|
206
|
-
border-right: none !important;
|
|
207
|
-
}
|
|
208
|
-
pre.prettyprint {
|
|
209
|
-
border: none !important;
|
|
210
|
-
padding: 0 !important;
|
|
211
|
-
margin: 0 !important;
|
|
212
|
-
}
|
|
213
|
-
.com { color: #999 !important; }
|
|
214
|
-
.ignore-none { color: #999; font-weight: normal; }
|
|
215
|
-
|
|
216
|
-
.wrapper {
|
|
217
|
-
min-height: 100%;
|
|
218
|
-
height: auto !important;
|
|
219
|
-
height: 100%;
|
|
220
|
-
margin: 0 auto -48px;
|
|
221
|
-
}
|
|
222
|
-
.footer, .push {
|
|
223
|
-
height: 48px;
|
|
224
|
-
}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
var jumpToCode = (function init() {
|
|
3
|
-
// Classes of code we would like to highlight in the file view
|
|
4
|
-
var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no'];
|
|
5
|
-
|
|
6
|
-
// Elements to highlight in the file listing view
|
|
7
|
-
var fileListingElements = ['td.pct.low'];
|
|
8
|
-
|
|
9
|
-
// We don't want to select elements that are direct descendants of another match
|
|
10
|
-
var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > `
|
|
11
|
-
|
|
12
|
-
// Selector that finds elements on the page to which we can jump
|
|
13
|
-
var selector =
|
|
14
|
-
fileListingElements.join(', ') +
|
|
15
|
-
', ' +
|
|
16
|
-
notSelector +
|
|
17
|
-
missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b`
|
|
18
|
-
|
|
19
|
-
// The NodeList of matching elements
|
|
20
|
-
var missingCoverageElements = document.querySelectorAll(selector);
|
|
21
|
-
|
|
22
|
-
var currentIndex;
|
|
23
|
-
|
|
24
|
-
function toggleClass(index) {
|
|
25
|
-
missingCoverageElements
|
|
26
|
-
.item(currentIndex)
|
|
27
|
-
.classList.remove('highlighted');
|
|
28
|
-
missingCoverageElements.item(index).classList.add('highlighted');
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function makeCurrent(index) {
|
|
32
|
-
toggleClass(index);
|
|
33
|
-
currentIndex = index;
|
|
34
|
-
missingCoverageElements.item(index).scrollIntoView({
|
|
35
|
-
behavior: 'smooth',
|
|
36
|
-
block: 'center',
|
|
37
|
-
inline: 'center'
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function goToPrevious() {
|
|
42
|
-
var nextIndex = 0;
|
|
43
|
-
if (typeof currentIndex !== 'number' || currentIndex === 0) {
|
|
44
|
-
nextIndex = missingCoverageElements.length - 1;
|
|
45
|
-
} else if (missingCoverageElements.length > 1) {
|
|
46
|
-
nextIndex = currentIndex - 1;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
makeCurrent(nextIndex);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function goToNext() {
|
|
53
|
-
var nextIndex = 0;
|
|
54
|
-
|
|
55
|
-
if (
|
|
56
|
-
typeof currentIndex === 'number' &&
|
|
57
|
-
currentIndex < missingCoverageElements.length - 1
|
|
58
|
-
) {
|
|
59
|
-
nextIndex = currentIndex + 1;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
makeCurrent(nextIndex);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return function jump(event) {
|
|
66
|
-
if (
|
|
67
|
-
document.getElementById('fileSearch') === document.activeElement &&
|
|
68
|
-
document.activeElement != null
|
|
69
|
-
) {
|
|
70
|
-
// if we're currently focused on the search input, we don't want to navigate
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
switch (event.which) {
|
|
75
|
-
case 78: // n
|
|
76
|
-
case 74: // j
|
|
77
|
-
goToNext();
|
|
78
|
-
break;
|
|
79
|
-
case 66: // b
|
|
80
|
-
case 75: // k
|
|
81
|
-
case 80: // p
|
|
82
|
-
goToPrevious();
|
|
83
|
-
break;
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
})();
|
|
87
|
-
window.addEventListener('keydown', jumpToCode);
|