llm-cli-gateway 1.17.4 → 1.17.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 +15 -0
- package/README.md +1 -1
- package/dist/approval-manager.js +0 -8
- package/dist/async-job-manager.d.ts +0 -113
- package/dist/async-job-manager.js +6 -124
- package/dist/cache-stats.d.ts +0 -89
- package/dist/cache-stats.js +0 -62
- package/dist/claude-mcp-config.js +0 -1
- package/dist/cli-updater.d.ts +0 -8
- package/dist/cli-updater.js +0 -12
- package/dist/codex-json-parser.d.ts +0 -20
- package/dist/codex-json-parser.js +0 -21
- package/dist/config.d.ts +0 -31
- package/dist/config.js +2 -72
- package/dist/db.d.ts +0 -18
- package/dist/db.js +0 -22
- package/dist/doctor.d.ts +0 -49
- package/dist/doctor.js +0 -47
- package/dist/endpoint-exposure.js +0 -1
- package/dist/executor.d.ts +0 -19
- package/dist/executor.js +3 -38
- package/dist/flight-recorder.d.ts +0 -26
- package/dist/flight-recorder.js +1 -70
- package/dist/gemini-json-parser.d.ts +0 -25
- package/dist/gemini-json-parser.js +0 -28
- package/dist/health.d.ts +0 -3
- package/dist/health.js +0 -3
- package/dist/index.d.ts +1 -221
- package/dist/index.js +14 -563
- package/dist/job-store.d.ts +0 -74
- package/dist/job-store.js +1 -73
- package/dist/logger.d.ts +0 -7
- package/dist/logger.js +0 -6
- package/dist/migrate-sessions.d.ts +0 -3
- package/dist/migrate-sessions.js +0 -16
- package/dist/migrate.js +1 -18
- package/dist/mistral-meta-json-parser.js +0 -67
- package/dist/model-registry.js +0 -13
- package/dist/pricing.d.ts +0 -46
- package/dist/pricing.js +0 -47
- package/dist/process-monitor.d.ts +0 -15
- package/dist/process-monitor.js +2 -31
- package/dist/prompt-parts.d.ts +0 -25
- package/dist/prompt-parts.js +0 -11
- package/dist/provider-status.d.ts +0 -8
- package/dist/provider-status.js +0 -11
- package/dist/request-helpers.d.ts +0 -334
- package/dist/request-helpers.js +1 -229
- package/dist/resources.d.ts +0 -20
- package/dist/resources.js +1 -34
- package/dist/retry.d.ts +0 -45
- package/dist/retry.js +3 -40
- package/dist/session-manager-pg.d.ts +0 -32
- package/dist/session-manager-pg.js +0 -32
- package/dist/session-manager.d.ts +0 -21
- package/dist/session-manager.js +1 -15
- package/dist/stream-json-parser.d.ts +0 -18
- package/dist/stream-json-parser.js +0 -22
- package/dist/upstream-contracts.d.ts +0 -55
- package/dist/upstream-contracts.js +0 -77
- package/dist/validation-orchestrator.js +0 -3
- package/dist/worktree-manager.d.ts +0 -9
- package/dist/worktree-manager.js +0 -21
- package/package.json +1 -1
|
@@ -47,9 +47,7 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
47
47
|
"excludeDynamicSystemPromptSections",
|
|
48
48
|
"fallbackModel",
|
|
49
49
|
"jsonSchema",
|
|
50
|
-
// Phase 4 slice ζ
|
|
51
50
|
"addDir",
|
|
52
|
-
// Claude 2.x session / settings / tools surface
|
|
53
51
|
"noSessionPersistence",
|
|
54
52
|
"settingSources",
|
|
55
53
|
"settings",
|
|
@@ -101,12 +99,6 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
101
99
|
pattern: /^[0-9]+(?:\.[0-9]+)?$/,
|
|
102
100
|
description: "Budget cap in USD",
|
|
103
101
|
},
|
|
104
|
-
// NOTE: `--probe-installed` reports --max-turns as "missing from binary"
|
|
105
|
-
// because claude 2.x hides it from the `--help` body. It is nonetheless a
|
|
106
|
-
// real, accepted flag (verified: `claude --max-turns N --help` parses
|
|
107
|
-
// without an "unknown option" error, while a genuinely unknown flag errors
|
|
108
|
-
// loudly). Keep it in the contract; the probe drift here is a known
|
|
109
|
-
// help-text false-positive, not a removed flag.
|
|
110
102
|
"--max-turns": { arity: "one", pattern: /^[1-9][0-9]*$/, description: "Turn cap" },
|
|
111
103
|
"--effort": { arity: "one", values: EFFORT_LEVELS, description: "Reasoning effort" },
|
|
112
104
|
"--exclude-dynamic-system-prompt-sections": {
|
|
@@ -127,7 +119,6 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
127
119
|
},
|
|
128
120
|
"--continue": { arity: "none", description: "Continue active session" },
|
|
129
121
|
"--session-id": { arity: "one", description: "Session id" },
|
|
130
|
-
// Claude 2.x session / settings / tools surface
|
|
131
122
|
"--no-session-persistence": {
|
|
132
123
|
arity: "none",
|
|
133
124
|
description: "Do not persist the session to disk (ephemeral; mirrors Codex --ephemeral)",
|
|
@@ -160,16 +151,12 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
160
151
|
expect: "fail",
|
|
161
152
|
},
|
|
162
153
|
{
|
|
163
|
-
// Phase 4 slice η: --fallback-model wired through prepareClaudeRequest.
|
|
164
154
|
id: "claude-fallback-model",
|
|
165
155
|
description: "Phase 4 slice η: --fallback-model accepted",
|
|
166
156
|
args: ["-p", "hello", "--fallback-model", "claude-haiku-4-5-20251001"],
|
|
167
157
|
expect: "pass",
|
|
168
158
|
},
|
|
169
159
|
{
|
|
170
|
-
// Phase 4 slice η: --json-schema accepts an inline JSON Schema literal
|
|
171
|
-
// (per `claude --help` example), not a path. Codex parity for
|
|
172
|
-
// structured-output validation in one slice.
|
|
173
160
|
id: "claude-json-schema",
|
|
174
161
|
description: "Phase 4 slice η: --json-schema accepts inline JSON literal",
|
|
175
162
|
args: [
|
|
@@ -183,8 +170,6 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
183
170
|
expect: "pass",
|
|
184
171
|
},
|
|
185
172
|
{
|
|
186
|
-
// Phase 4 slice ζ: --add-dir wired through prepareClaudeHighImpactFlags.
|
|
187
|
-
// Repeated once per directory; each instance has arity:"one".
|
|
188
173
|
id: "claude-add-dir",
|
|
189
174
|
description: "Phase 4 slice ζ: repeated --add-dir is accepted",
|
|
190
175
|
args: ["-p", "hello", "--add-dir", "/tmp/a", "--add-dir", "/tmp/b"],
|
|
@@ -208,10 +193,6 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
208
193
|
expect: "pass",
|
|
209
194
|
},
|
|
210
195
|
{
|
|
211
|
-
// Claude CLI 2.x: stream-json requires --verbose alongside --print.
|
|
212
|
-
// The gateway emits all three together; this fixture pins the combo
|
|
213
|
-
// so a future removal of --verbose breaks loudly here instead of
|
|
214
|
-
// silently at runtime against the upstream CLI.
|
|
215
196
|
id: "claude-stream-json-requires-verbose",
|
|
216
197
|
description: "Claude CLI 2.x: --output-format stream-json + --include-partial-messages + --verbose accepted together",
|
|
217
198
|
args: [
|
|
@@ -225,12 +206,6 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
225
206
|
expect: "pass",
|
|
226
207
|
},
|
|
227
208
|
{
|
|
228
|
-
// Slice κ: when caller marks promptParts with cache_control, the
|
|
229
|
-
// gateway emits `-p` as a standalone flag and pipes the JSON
|
|
230
|
-
// content-blocks payload over stdin via `--input-format
|
|
231
|
-
// stream-json`. The fixture pins the exact argv combination so
|
|
232
|
-
// a future regression (re-emitting a positional prompt, dropping
|
|
233
|
-
// `--input-format`, etc.) trips loudly here.
|
|
234
209
|
id: "claude-input-format-stream-json",
|
|
235
210
|
description: "Slice κ: `-p` standalone + --input-format stream-json + --output-format stream-json + --include-partial-messages + --verbose",
|
|
236
211
|
args: [
|
|
@@ -297,15 +272,10 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
297
272
|
"images",
|
|
298
273
|
"ignoreUserConfig",
|
|
299
274
|
"ignoreRules",
|
|
300
|
-
// Phase 4 slice ζ
|
|
301
275
|
"workingDir",
|
|
302
276
|
"addDir",
|
|
303
277
|
],
|
|
304
278
|
resumeOnlyFlags: ["--last", "--all"],
|
|
305
|
-
// Phase 4 slice α (v1.8.0) verified that `codex exec resume` accepts
|
|
306
|
-
// `--output-schema` and `-c` (codex-cli 0.133.0 `exec resume --help`),
|
|
307
|
-
// so they're no longer forbidden. Current resume help does not accept
|
|
308
|
-
// session-profile or working-directory policy flags.
|
|
309
279
|
resumeForbiddenFlags: ["--sandbox", "-C", "--cd", "--add-dir", "--profile"],
|
|
310
280
|
flags: {
|
|
311
281
|
"--last": { arity: "none", description: "Resume latest session" },
|
|
@@ -368,8 +338,6 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
368
338
|
arity: "none",
|
|
369
339
|
description: "Resume picker: show all sessions without cwd filtering",
|
|
370
340
|
},
|
|
371
|
-
// The gateway emits the short form `-C`, and the advisory contract also
|
|
372
|
-
// tracks the long `--cd` alias advertised by current Codex exec help.
|
|
373
341
|
"-C": {
|
|
374
342
|
arity: "one",
|
|
375
343
|
description: "Working root for the session (Phase 4 slice ζ; new sessions only)",
|
|
@@ -410,9 +378,6 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
410
378
|
expect: "fail",
|
|
411
379
|
},
|
|
412
380
|
{
|
|
413
|
-
// Phase 4 slice α: --output-schema IS accepted on resume per
|
|
414
|
-
// codex-cli 0.133.0; this fixture pins the new behaviour so future
|
|
415
|
-
// contract changes can't silently regress.
|
|
416
381
|
id: "codex-resume-output-schema",
|
|
417
382
|
description: "Phase 4 slice α: --output-schema accepted on resume (codex-cli 0.133.0)",
|
|
418
383
|
args: ["exec", "resume", "--output-schema", "/tmp/schema.json", "session-id", "hello"],
|
|
@@ -521,9 +486,7 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
521
486
|
"policyFiles",
|
|
522
487
|
"adminPolicyFiles",
|
|
523
488
|
"attachments",
|
|
524
|
-
// Phase 4 slice γ
|
|
525
489
|
"skipTrust",
|
|
526
|
-
// Auto-approve-all ergonomic alias (equivalent to approvalMode "yolo")
|
|
527
490
|
"yolo",
|
|
528
491
|
],
|
|
529
492
|
flags: {
|
|
@@ -623,17 +586,13 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
623
586
|
"mcpServers",
|
|
624
587
|
"allowedTools",
|
|
625
588
|
"disallowedTools",
|
|
626
|
-
// Phase 4 slice δ
|
|
627
589
|
"maxTurns",
|
|
628
|
-
// Phase 4 slice ζ
|
|
629
590
|
"workingDir",
|
|
630
|
-
// Phase 4 slice θ — Grok HIGH parity
|
|
631
591
|
"sandbox",
|
|
632
592
|
"rules",
|
|
633
593
|
"systemPromptOverride",
|
|
634
594
|
"allow",
|
|
635
595
|
"deny",
|
|
636
|
-
// Grok 0.2.x context/compaction controls
|
|
637
596
|
"compactionMode",
|
|
638
597
|
"compactionDetail",
|
|
639
598
|
],
|
|
@@ -669,10 +628,6 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
669
628
|
arity: "one",
|
|
670
629
|
description: "Working directory for the invocation (Phase 4 slice ζ)",
|
|
671
630
|
},
|
|
672
|
-
// Phase 4 slice θ — Grok HIGH parity. `--sandbox` is freeform per
|
|
673
|
-
// `grok --help` on 0.1.210 (no `[possible values: …]` list, unlike
|
|
674
|
-
// --effort / --permission-mode / --output-format), so we register
|
|
675
|
-
// it without a `values` constraint.
|
|
676
631
|
"--sandbox": {
|
|
677
632
|
arity: "one",
|
|
678
633
|
description: "Sandbox profile for filesystem + network access (Phase 4 slice θ; freeform passthrough; env: GROK_SANDBOX)",
|
|
@@ -725,7 +680,6 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
725
680
|
arity: "optional",
|
|
726
681
|
description: "Start the session in a new git worktree, optionally named",
|
|
727
682
|
},
|
|
728
|
-
// Grok 0.2.x context/compaction controls (both enum, env-backed):
|
|
729
683
|
"--compaction-mode": {
|
|
730
684
|
arity: "one",
|
|
731
685
|
values: ["summary", "transcript", "segments"],
|
|
@@ -874,13 +828,10 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
874
828
|
"mcpServers",
|
|
875
829
|
"allowedTools",
|
|
876
830
|
"disallowedTools",
|
|
877
|
-
// Phase 4 slice γ
|
|
878
831
|
"trust",
|
|
879
|
-
// Phase 4 slice δ
|
|
880
832
|
"maxTurns",
|
|
881
833
|
"maxPrice",
|
|
882
834
|
"maxTokens",
|
|
883
|
-
// Phase 4 slice ζ
|
|
884
835
|
"workingDir",
|
|
885
836
|
"addDir",
|
|
886
837
|
],
|
|
@@ -896,12 +847,6 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
896
847
|
values: ["default", "plan", "accept-edits", "auto-approve", "chat", "explore", "lean"],
|
|
897
848
|
description: "Agent/permission mode",
|
|
898
849
|
},
|
|
899
|
-
// NOTE: vibe has no reasoning-effort surface. `--effort` / `--reasoning-effort`
|
|
900
|
-
// were declared speculatively (mirroring Grok) in the provider-modernisation
|
|
901
|
-
// commit but were never accepted by the CLI: vibe 2.x argparse hard-rejects them
|
|
902
|
-
// ("error: unrecognized arguments: --effort"), failing the whole request before
|
|
903
|
-
// any model call. Removed from the contract, builder, and request schema; the
|
|
904
|
-
// mistral-effort-rejected / mistral-reasoning-effort-rejected fixtures lock it in.
|
|
905
850
|
"--enabled-tools": { arity: "one", description: "Enabled tool" },
|
|
906
851
|
"--resume": { arity: "one", description: "Resume session" },
|
|
907
852
|
"--continue": { arity: "none", description: "Continue latest session" },
|
|
@@ -916,8 +861,6 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
916
861
|
},
|
|
917
862
|
"--max-price": {
|
|
918
863
|
arity: "one",
|
|
919
|
-
// Decimal-only: matches the MAX_PRICE_SCHEMA min(1e-6) lower bound
|
|
920
|
-
// that keeps String(N) in decimal form (no scientific notation).
|
|
921
864
|
pattern: /^(0|[1-9][0-9]*)(\.[0-9]+)?$/,
|
|
922
865
|
description: "Cumulative cost cap in USD (Phase 4 slice δ, programmatic mode only)",
|
|
923
866
|
},
|
|
@@ -1192,24 +1135,8 @@ function validateFlagValue(cli, arg, flag, value, index, violations) {
|
|
|
1192
1135
|
});
|
|
1193
1136
|
}
|
|
1194
1137
|
}
|
|
1195
|
-
/**
|
|
1196
|
-
* Best-effort, advisory-only extraction of long-form flags from raw --help text.
|
|
1197
|
-
* Returns a sorted array of unique `--foo-bar` style flags discovered in the output.
|
|
1198
|
-
*
|
|
1199
|
-
* Heuristics:
|
|
1200
|
-
* - Matches common option declaration lines emitted by clap, yargs, commander, custom TUIs, etc.
|
|
1201
|
-
* - Lowercases for stable comparison against our contract keys.
|
|
1202
|
-
* - Intentionally conservative: ignores obvious noise (URLs, prose in descriptions).
|
|
1203
|
-
*
|
|
1204
|
-
* This powers the bidirectional drift detector (extra flags the installed binary
|
|
1205
|
-
* advertises that our contract does not yet allow). It is NEVER used for argv
|
|
1206
|
-
* validation — only for the upstream scanner and `upstream_contracts` probe reports.
|
|
1207
|
-
*/
|
|
1208
1138
|
export function extractDiscoveredFlags(helpText) {
|
|
1209
1139
|
const discovered = new Set();
|
|
1210
|
-
// Long flags: --foo, --foo-bar, --foo_bar (some CLIs normalize _ to - in display).
|
|
1211
|
-
// Only inspect option declaration lines so prose such as
|
|
1212
|
-
// "(Claude Code: --allowedTools)" does not create false drift.
|
|
1213
1140
|
const longRe = /--([a-z0-9][a-z0-9_-]{1,}[a-z0-9]?)/g;
|
|
1214
1141
|
for (const line of helpText.split(/\r?\n/)) {
|
|
1215
1142
|
const trimmed = line.trimStart();
|
|
@@ -1274,7 +1201,6 @@ export function probeInstalledCliContract(cli, timeoutMs = 5_000) {
|
|
|
1274
1201
|
const discoveredFlags = extractDiscoveredFlags(helpText);
|
|
1275
1202
|
const contractFlagSet = new Set(Object.keys(contract.flags));
|
|
1276
1203
|
const extraFlags = discoveredFlags.filter(f => !contractFlagSet.has(f));
|
|
1277
|
-
// Cheap version hint: first line that looks like a version banner
|
|
1278
1204
|
const versionMatch = helpText.match(/^\s*(?:[A-Za-z][\w .-]+)?v?\d+\.\d+\S*/m);
|
|
1279
1205
|
const versionHint = versionMatch ? versionMatch[0].trim().slice(0, 80) : undefined;
|
|
1280
1206
|
const helpHash = createHash("sha256").update(helpText).digest("hex");
|
|
@@ -1303,9 +1229,6 @@ export function buildUpstreamContractReport(options = {}) {
|
|
|
1303
1229
|
{
|
|
1304
1230
|
executable: contract.executable,
|
|
1305
1231
|
upstream: contract.upstream,
|
|
1306
|
-
// Pure metadata pointers (changelog URLs, package name, watch
|
|
1307
|
-
// categories). Enriched from the CliContract — the single source of
|
|
1308
|
-
// truth — so report consumers and the scanner read the same values.
|
|
1309
1232
|
upstreamMetadata: contract.upstreamMetadata
|
|
1310
1233
|
? {
|
|
1311
1234
|
sourceUrls: contract.upstreamMetadata.sourceUrls,
|
|
@@ -131,9 +131,6 @@ function plannedJudgeSynthesis(input) {
|
|
|
131
131
|
}
|
|
132
132
|
function buildProviderArgs(provider, prompt) {
|
|
133
133
|
if (provider === "claude" || provider === "grok" || provider === "mistral") {
|
|
134
|
-
// Mistral Vibe mirrors Grok's `-p PROMPT` headless surface. Model selection
|
|
135
|
-
// is via VIBE_ACTIVE_MODEL env var (no --model flag); for validation runs we
|
|
136
|
-
// let the user's environment pick the active model.
|
|
137
134
|
return ["-p", prompt];
|
|
138
135
|
}
|
|
139
136
|
if (provider === "codex")
|
|
@@ -25,15 +25,6 @@ export declare class WorktreeCollisionError extends WorktreeError {
|
|
|
25
25
|
}
|
|
26
26
|
export declare function sanitizeWorktreeName(input: string): string;
|
|
27
27
|
export declare function createWorktree(opts: CreateWorktreeOptions): Promise<WorktreeHandle>;
|
|
28
|
-
/**
|
|
29
|
-
* Build a SessionCleanupHook that tears down per-session worktrees. The
|
|
30
|
-
* hook reads `session.metadata.worktreePath` (recorded by
|
|
31
|
-
* `resolveWorktreeForRequest`) and the optional `session.metadata.worktreeName`,
|
|
32
|
-
* derives `repoRoot` from the path layout (`<repoRoot>/.worktrees/<name>`),
|
|
33
|
-
* and fires `removeWorktree` asynchronously. Failures are logged by
|
|
34
|
-
* `removeWorktree` itself — the hook always resolves so session deletion
|
|
35
|
-
* never blocks on git.
|
|
36
|
-
*/
|
|
37
28
|
export declare function createWorktreeSessionCleanupHook(logger: Logger): (session: {
|
|
38
29
|
id: string;
|
|
39
30
|
metadata?: Record<string, unknown>;
|
package/dist/worktree-manager.js
CHANGED
|
@@ -67,7 +67,6 @@ async function execGit(repoRoot, args, logger) {
|
|
|
67
67
|
proc.kill("SIGKILL");
|
|
68
68
|
}
|
|
69
69
|
catch {
|
|
70
|
-
// ignore — process may already be gone
|
|
71
70
|
}
|
|
72
71
|
rejectExec(new WorktreeError(`git ${args.join(" ")} timed out after ${GIT_TIMEOUT_MS}ms`));
|
|
73
72
|
}, GIT_TIMEOUT_MS);
|
|
@@ -116,8 +115,6 @@ export async function createWorktree(opts) {
|
|
|
116
115
|
const worktreesDir = join(opts.repoRoot, ".worktrees");
|
|
117
116
|
const expectedPrefix = worktreesDir + sep;
|
|
118
117
|
const worktreePath = resolvePath(opts.repoRoot, ".worktrees", name);
|
|
119
|
-
// Defense in depth — sanitizeWorktreeName already blocks slashes, but
|
|
120
|
-
// double-check that the resolved path is under <repoRoot>/.worktrees/.
|
|
121
118
|
if (!worktreePath.startsWith(expectedPrefix)) {
|
|
122
119
|
throw new WorktreeError(`resolved worktree path escapes the expected prefix: ${worktreePath} (expected under ${expectedPrefix})`);
|
|
123
120
|
}
|
|
@@ -134,8 +131,6 @@ export async function createWorktree(opts) {
|
|
|
134
131
|
if (!registered) {
|
|
135
132
|
throw new WorktreeCollisionError(worktreePath);
|
|
136
133
|
}
|
|
137
|
-
// Resume reuse: the worktree already exists and is registered with git.
|
|
138
|
-
// Return a handle pointing at it without touching anything.
|
|
139
134
|
logger.info?.(`reusing existing worktree at ${worktreePath}`);
|
|
140
135
|
return {
|
|
141
136
|
name,
|
|
@@ -145,9 +140,6 @@ export async function createWorktree(opts) {
|
|
|
145
140
|
};
|
|
146
141
|
}
|
|
147
142
|
if (registered) {
|
|
148
|
-
// Path is registered but the directory is gone — let git prune it
|
|
149
|
-
// before we recreate, so `worktree add` doesn't error on the stale
|
|
150
|
-
// registration.
|
|
151
143
|
const prune = await execGit(opts.repoRoot, ["worktree", "prune"], logger);
|
|
152
144
|
if (prune.code !== 0) {
|
|
153
145
|
logWarn(logger, `git worktree prune failed before creating ${name}: ${prune.stderr.trim()}`);
|
|
@@ -165,15 +157,6 @@ export async function createWorktree(opts) {
|
|
|
165
157
|
createdAt: new Date().toISOString(),
|
|
166
158
|
};
|
|
167
159
|
}
|
|
168
|
-
/**
|
|
169
|
-
* Build a SessionCleanupHook that tears down per-session worktrees. The
|
|
170
|
-
* hook reads `session.metadata.worktreePath` (recorded by
|
|
171
|
-
* `resolveWorktreeForRequest`) and the optional `session.metadata.worktreeName`,
|
|
172
|
-
* derives `repoRoot` from the path layout (`<repoRoot>/.worktrees/<name>`),
|
|
173
|
-
* and fires `removeWorktree` asynchronously. Failures are logged by
|
|
174
|
-
* `removeWorktree` itself — the hook always resolves so session deletion
|
|
175
|
-
* never blocks on git.
|
|
176
|
-
*/
|
|
177
160
|
export function createWorktreeSessionCleanupHook(logger) {
|
|
178
161
|
return async (session) => {
|
|
179
162
|
const meta = session.metadata ?? {};
|
|
@@ -181,8 +164,6 @@ export function createWorktreeSessionCleanupHook(logger) {
|
|
|
181
164
|
if (!worktreePath)
|
|
182
165
|
return;
|
|
183
166
|
const worktreeName = typeof meta.worktreeName === "string" ? meta.worktreeName : undefined;
|
|
184
|
-
// Layout invariant from createWorktree: <repoRoot>/.worktrees/<name>.
|
|
185
|
-
// Strip the trailing two segments to recover repoRoot.
|
|
186
167
|
const marker = `${sep}.worktrees${sep}`;
|
|
187
168
|
const markerIdx = worktreePath.lastIndexOf(marker);
|
|
188
169
|
if (markerIdx === -1) {
|
|
@@ -206,8 +187,6 @@ export async function removeWorktree(opts) {
|
|
|
206
187
|
const branch = `gateway/${opts.name}`;
|
|
207
188
|
const del = await execGit(opts.repoRoot, ["branch", "-D", branch], logger);
|
|
208
189
|
if (del.code !== 0) {
|
|
209
|
-
// Branch may already be gone (user deleted, never existed if add
|
|
210
|
-
// half-failed, etc.). Demote to debug — this is best-effort cleanup.
|
|
211
190
|
logger.debug?.(`git branch -D ${branch} returned code ${del.code}: ${del.stderr.trim()}`);
|
|
212
191
|
}
|
|
213
192
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "llm-cli-gateway",
|
|
3
|
-
"version": "1.17.
|
|
3
|
+
"version": "1.17.5",
|
|
4
4
|
"mcpName": "io.github.verivus-oss/llm-cli-gateway",
|
|
5
5
|
"description": "MCP server providing unified access to Claude Code, Codex, Gemini, Grok, and Mistral Vibe CLIs with session management, retry logic, async job orchestration, durable job results, and cross-LLM validation.",
|
|
6
6
|
"license": "MIT",
|