llm-cli-gateway 1.1.0 → 1.4.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/CHANGELOG.md +21 -0
- package/README.md +122 -8
- package/dist/approval-manager.d.ts +1 -1
- package/dist/async-job-manager.d.ts +53 -4
- package/dist/async-job-manager.js +237 -17
- package/dist/cli-updater.d.ts +38 -0
- package/dist/cli-updater.js +145 -0
- package/dist/flight-recorder.d.ts +1 -1
- package/dist/index.d.ts +27 -0
- package/dist/index.js +651 -26
- package/dist/job-store.d.ts +84 -0
- package/dist/job-store.js +251 -0
- package/dist/model-registry.d.ts +14 -0
- package/dist/model-registry.js +444 -134
- package/dist/request-helpers.d.ts +41 -0
- package/dist/request-helpers.js +40 -0
- package/dist/resources.js +44 -0
- package/dist/session-manager-pg.js +1 -0
- package/dist/session-manager.d.ts +1 -1
- package/dist/session-manager.js +2 -1
- package/package.json +3 -3
|
@@ -30,3 +30,44 @@ export declare function resolveSessionResumeArgs(opts: {
|
|
|
30
30
|
resumeLatest?: boolean;
|
|
31
31
|
createNewSession?: boolean;
|
|
32
32
|
}): SessionResumeResult;
|
|
33
|
+
/**
|
|
34
|
+
* Codex-specific resume planning.
|
|
35
|
+
*
|
|
36
|
+
* Codex CLI ≥ 0.30 exposes session resume as a subcommand (`codex exec resume`),
|
|
37
|
+
* not a flag pair like Claude/Gemini/Grok. So we can't return a simple list of
|
|
38
|
+
* args — we describe the *mode* and let the caller branch when building argv:
|
|
39
|
+
*
|
|
40
|
+
* - "new" → `codex exec [...flags] PROMPT`
|
|
41
|
+
* - "resume-by-id" → `codex exec resume [...resume-safe flags] <SESSION_ID> PROMPT`
|
|
42
|
+
* - "resume-latest" → `codex exec resume --last [...resume-safe flags] PROMPT`
|
|
43
|
+
*
|
|
44
|
+
* `codex exec resume` rejects `--full-auto`; the original session's approval
|
|
45
|
+
* policy is inherited. Callers MUST filter `--full-auto` out of the flag set
|
|
46
|
+
* when mode is one of the resume forms (see `prepareCodexRequest`).
|
|
47
|
+
*
|
|
48
|
+
* `sessionId` MUST be a real Codex session UUID (as recorded under
|
|
49
|
+
* `~/.codex/sessions/`). Gateway-generated `gw-*` IDs are rejected, since
|
|
50
|
+
* they are bookkeeping handles and would 404 against `codex resume`.
|
|
51
|
+
*/
|
|
52
|
+
export type CodexSessionMode = "new" | "resume-by-id" | "resume-latest";
|
|
53
|
+
export interface CodexSessionPlan {
|
|
54
|
+
mode: CodexSessionMode;
|
|
55
|
+
/** Real Codex session UUID. Present only when mode === "resume-by-id". */
|
|
56
|
+
sessionId?: string;
|
|
57
|
+
}
|
|
58
|
+
export declare function resolveCodexSessionArgs(opts: {
|
|
59
|
+
sessionId?: string;
|
|
60
|
+
resumeLatest?: boolean;
|
|
61
|
+
createNewSession?: boolean;
|
|
62
|
+
}): CodexSessionPlan;
|
|
63
|
+
/**
|
|
64
|
+
* Grok-specific resume args. Grok accepts `--resume <id>` to resume a named session,
|
|
65
|
+
* and `--continue` to resume the most recent session for the current working directory.
|
|
66
|
+
* Unlike `resolveSessionResumeArgs`, "resume latest" maps to `--continue` (not `--resume latest`)
|
|
67
|
+
* because Grok would interpret a literal "latest" as a session ID.
|
|
68
|
+
*/
|
|
69
|
+
export declare function resolveGrokSessionArgs(opts: {
|
|
70
|
+
sessionId?: string;
|
|
71
|
+
resumeLatest?: boolean;
|
|
72
|
+
createNewSession?: boolean;
|
|
73
|
+
}): SessionResumeResult;
|
package/dist/request-helpers.js
CHANGED
|
@@ -52,3 +52,43 @@ export function resolveSessionResumeArgs(opts) {
|
|
|
52
52
|
}
|
|
53
53
|
return { resumeArgs: [], effectiveSessionId: undefined, userProvidedSession: false };
|
|
54
54
|
}
|
|
55
|
+
export function resolveCodexSessionArgs(opts) {
|
|
56
|
+
if (opts.createNewSession) {
|
|
57
|
+
return { mode: "new" };
|
|
58
|
+
}
|
|
59
|
+
if (opts.sessionId) {
|
|
60
|
+
validateSessionId(opts.sessionId);
|
|
61
|
+
return { mode: "resume-by-id", sessionId: opts.sessionId };
|
|
62
|
+
}
|
|
63
|
+
if (opts.resumeLatest) {
|
|
64
|
+
return { mode: "resume-latest" };
|
|
65
|
+
}
|
|
66
|
+
return { mode: "new" };
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Grok-specific resume args. Grok accepts `--resume <id>` to resume a named session,
|
|
70
|
+
* and `--continue` to resume the most recent session for the current working directory.
|
|
71
|
+
* Unlike `resolveSessionResumeArgs`, "resume latest" maps to `--continue` (not `--resume latest`)
|
|
72
|
+
* because Grok would interpret a literal "latest" as a session ID.
|
|
73
|
+
*/
|
|
74
|
+
export function resolveGrokSessionArgs(opts) {
|
|
75
|
+
if (opts.createNewSession) {
|
|
76
|
+
return { resumeArgs: [], effectiveSessionId: undefined, userProvidedSession: false };
|
|
77
|
+
}
|
|
78
|
+
if (opts.resumeLatest && !opts.sessionId) {
|
|
79
|
+
return {
|
|
80
|
+
resumeArgs: ["--continue"],
|
|
81
|
+
effectiveSessionId: undefined,
|
|
82
|
+
userProvidedSession: false,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (opts.sessionId) {
|
|
86
|
+
validateSessionId(opts.sessionId);
|
|
87
|
+
return {
|
|
88
|
+
resumeArgs: ["--resume", opts.sessionId],
|
|
89
|
+
effectiveSessionId: opts.sessionId,
|
|
90
|
+
userProvidedSession: true,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
return { resumeArgs: [], effectiveSessionId: undefined, userProvidedSession: false };
|
|
94
|
+
}
|
package/dist/resources.js
CHANGED
|
@@ -54,6 +54,17 @@ export class ResourceProvider {
|
|
|
54
54
|
priority: 0.6,
|
|
55
55
|
},
|
|
56
56
|
},
|
|
57
|
+
{
|
|
58
|
+
uri: "sessions://grok",
|
|
59
|
+
name: "Grok Sessions",
|
|
60
|
+
title: "⚡ Grok Sessions",
|
|
61
|
+
description: "List of Grok conversation sessions",
|
|
62
|
+
mimeType: "application/json",
|
|
63
|
+
annotations: {
|
|
64
|
+
audience: ["user", "assistant"],
|
|
65
|
+
priority: 0.6,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
57
68
|
{
|
|
58
69
|
uri: "models://claude",
|
|
59
70
|
name: "Claude Models",
|
|
@@ -87,6 +98,17 @@ export class ResourceProvider {
|
|
|
87
98
|
priority: 0.8,
|
|
88
99
|
},
|
|
89
100
|
},
|
|
101
|
+
{
|
|
102
|
+
uri: "models://grok",
|
|
103
|
+
name: "Grok Models",
|
|
104
|
+
title: "⚡ Grok Models & Capabilities",
|
|
105
|
+
description: "Available Grok models and their capabilities",
|
|
106
|
+
mimeType: "application/json",
|
|
107
|
+
annotations: {
|
|
108
|
+
audience: ["user", "assistant"],
|
|
109
|
+
priority: 0.8,
|
|
110
|
+
},
|
|
111
|
+
},
|
|
90
112
|
{
|
|
91
113
|
uri: "metrics://performance",
|
|
92
114
|
name: "Performance Metrics",
|
|
@@ -121,6 +143,7 @@ export class ResourceProvider {
|
|
|
121
143
|
claude: (await this.sessionManager.getActiveSession("claude"))?.id || null,
|
|
122
144
|
codex: (await this.sessionManager.getActiveSession("codex"))?.id || null,
|
|
123
145
|
gemini: (await this.sessionManager.getActiveSession("gemini"))?.id || null,
|
|
146
|
+
grok: (await this.sessionManager.getActiveSession("grok"))?.id || null,
|
|
124
147
|
},
|
|
125
148
|
}, null, 2),
|
|
126
149
|
};
|
|
@@ -164,6 +187,19 @@ export class ResourceProvider {
|
|
|
164
187
|
}, null, 2),
|
|
165
188
|
};
|
|
166
189
|
}
|
|
190
|
+
if (uri === "sessions://grok") {
|
|
191
|
+
const sessions = await this.sessionManager.listSessions("grok");
|
|
192
|
+
return {
|
|
193
|
+
uri,
|
|
194
|
+
mimeType: "application/json",
|
|
195
|
+
text: JSON.stringify({
|
|
196
|
+
cli: "grok",
|
|
197
|
+
total: sessions.length,
|
|
198
|
+
sessions,
|
|
199
|
+
activeSession: (await this.sessionManager.getActiveSession("grok"))?.id || null,
|
|
200
|
+
}, null, 2),
|
|
201
|
+
};
|
|
202
|
+
}
|
|
167
203
|
// Model capability resources
|
|
168
204
|
if (uri === "models://claude") {
|
|
169
205
|
const cliInfo = getCliInfo();
|
|
@@ -189,6 +225,14 @@ export class ResourceProvider {
|
|
|
189
225
|
text: JSON.stringify(cliInfo.gemini, null, 2),
|
|
190
226
|
};
|
|
191
227
|
}
|
|
228
|
+
if (uri === "models://grok") {
|
|
229
|
+
const cliInfo = getCliInfo();
|
|
230
|
+
return {
|
|
231
|
+
uri,
|
|
232
|
+
mimeType: "application/json",
|
|
233
|
+
text: JSON.stringify(cliInfo.grok, null, 2),
|
|
234
|
+
};
|
|
235
|
+
}
|
|
192
236
|
if (uri === "metrics://performance") {
|
|
193
237
|
return {
|
|
194
238
|
uri,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Config } from "./config.js";
|
|
2
2
|
import type { DatabaseConnection } from "./db.js";
|
|
3
3
|
import type { Logger } from "./logger.js";
|
|
4
|
-
export declare const CLI_TYPES: readonly ["claude", "codex", "gemini"];
|
|
4
|
+
export declare const CLI_TYPES: readonly ["claude", "codex", "gemini", "grok"];
|
|
5
5
|
export type CliType = (typeof CLI_TYPES)[number];
|
|
6
6
|
export interface Session {
|
|
7
7
|
id: string;
|
package/dist/session-manager.js
CHANGED
|
@@ -4,12 +4,13 @@ import { join, dirname } from "path";
|
|
|
4
4
|
import { existsSync, mkdirSync, readFileSync, writeFileSync, renameSync, openSync, fsyncSync, closeSync, chmodSync, } from "fs";
|
|
5
5
|
import { DEFAULT_SESSION_TTL_SECONDS } from "./config.js";
|
|
6
6
|
import { noopLogger } from "./logger.js";
|
|
7
|
-
export const CLI_TYPES = ["claude", "codex", "gemini"];
|
|
7
|
+
export const CLI_TYPES = ["claude", "codex", "gemini", "grok"];
|
|
8
8
|
const createEmptyActiveSessions = () => Object.fromEntries(CLI_TYPES.map(cli => [cli, null]));
|
|
9
9
|
const DEFAULT_SESSION_DESCRIPTIONS = {
|
|
10
10
|
claude: "Claude Session",
|
|
11
11
|
codex: "Codex Session",
|
|
12
12
|
gemini: "Gemini Session",
|
|
13
|
+
grok: "Grok Session",
|
|
13
14
|
};
|
|
14
15
|
export class FileSessionManager {
|
|
15
16
|
storagePath;
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "llm-cli-gateway",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"mcpName": "io.github.verivus-oss/llm-cli-gateway",
|
|
5
|
-
"description": "MCP server providing unified access to Claude Code, Codex, and
|
|
5
|
+
"description": "MCP server providing unified access to Claude Code, Codex, Gemini, and Grok CLIs with session management, retry logic, async job orchestration, and durable job results.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "VerivusAI Labs",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
},
|
|
73
73
|
"dependencies": {
|
|
74
74
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
75
|
-
"better-sqlite3": "^
|
|
75
|
+
"better-sqlite3": "^12.9.0",
|
|
76
76
|
"ioredis": "^5.4.1",
|
|
77
77
|
"pg": "^8.12.0",
|
|
78
78
|
"toml": "^3.0.0",
|