llm-cli-gateway 1.17.3 → 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 +45 -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 +12 -208
- package/dist/index.js +116 -588
- 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 +6 -31
- 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 +4 -316
- package/dist/request-helpers.js +13 -231
- 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 +86 -64
- 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,8 +47,11 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
47
47
|
"excludeDynamicSystemPromptSections",
|
|
48
48
|
"fallbackModel",
|
|
49
49
|
"jsonSchema",
|
|
50
|
-
// Phase 4 slice ζ
|
|
51
50
|
"addDir",
|
|
51
|
+
"noSessionPersistence",
|
|
52
|
+
"settingSources",
|
|
53
|
+
"settings",
|
|
54
|
+
"tools",
|
|
52
55
|
"approvalStrategy",
|
|
53
56
|
"mcpServers",
|
|
54
57
|
"strictMcpConfig",
|
|
@@ -116,6 +119,22 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
116
119
|
},
|
|
117
120
|
"--continue": { arity: "none", description: "Continue active session" },
|
|
118
121
|
"--session-id": { arity: "one", description: "Session id" },
|
|
122
|
+
"--no-session-persistence": {
|
|
123
|
+
arity: "none",
|
|
124
|
+
description: "Do not persist the session to disk (ephemeral; mirrors Codex --ephemeral)",
|
|
125
|
+
},
|
|
126
|
+
"--setting-sources": {
|
|
127
|
+
arity: "one",
|
|
128
|
+
description: "Comma-separated setting sources to load (user|project|local)",
|
|
129
|
+
},
|
|
130
|
+
"--settings": {
|
|
131
|
+
arity: "one",
|
|
132
|
+
description: "Settings JSON file path or literal (can define hooks/permissions/model)",
|
|
133
|
+
},
|
|
134
|
+
"--tools": {
|
|
135
|
+
arity: "variadic",
|
|
136
|
+
description: 'Restrict the available built-in tool set ("" disables all)',
|
|
137
|
+
},
|
|
119
138
|
},
|
|
120
139
|
env: {},
|
|
121
140
|
conformanceFixtures: [
|
|
@@ -132,16 +151,12 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
132
151
|
expect: "fail",
|
|
133
152
|
},
|
|
134
153
|
{
|
|
135
|
-
// Phase 4 slice η: --fallback-model wired through prepareClaudeRequest.
|
|
136
154
|
id: "claude-fallback-model",
|
|
137
155
|
description: "Phase 4 slice η: --fallback-model accepted",
|
|
138
156
|
args: ["-p", "hello", "--fallback-model", "claude-haiku-4-5-20251001"],
|
|
139
157
|
expect: "pass",
|
|
140
158
|
},
|
|
141
159
|
{
|
|
142
|
-
// Phase 4 slice η: --json-schema accepts an inline JSON Schema literal
|
|
143
|
-
// (per `claude --help` example), not a path. Codex parity for
|
|
144
|
-
// structured-output validation in one slice.
|
|
145
160
|
id: "claude-json-schema",
|
|
146
161
|
description: "Phase 4 slice η: --json-schema accepts inline JSON literal",
|
|
147
162
|
args: [
|
|
@@ -155,18 +170,29 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
155
170
|
expect: "pass",
|
|
156
171
|
},
|
|
157
172
|
{
|
|
158
|
-
// Phase 4 slice ζ: --add-dir wired through prepareClaudeHighImpactFlags.
|
|
159
|
-
// Repeated once per directory; each instance has arity:"one".
|
|
160
173
|
id: "claude-add-dir",
|
|
161
174
|
description: "Phase 4 slice ζ: repeated --add-dir is accepted",
|
|
162
175
|
args: ["-p", "hello", "--add-dir", "/tmp/a", "--add-dir", "/tmp/b"],
|
|
163
176
|
expect: "pass",
|
|
164
177
|
},
|
|
165
178
|
{
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
179
|
+
id: "claude-session-settings-tools",
|
|
180
|
+
description: "Claude 2.x: --no-session-persistence, --setting-sources, --settings, and --tools (variadic) are accepted",
|
|
181
|
+
args: [
|
|
182
|
+
"-p",
|
|
183
|
+
"hello",
|
|
184
|
+
"--no-session-persistence",
|
|
185
|
+
"--setting-sources",
|
|
186
|
+
"project,local",
|
|
187
|
+
"--settings",
|
|
188
|
+
"{}",
|
|
189
|
+
"--tools",
|
|
190
|
+
"Read",
|
|
191
|
+
"Edit",
|
|
192
|
+
],
|
|
193
|
+
expect: "pass",
|
|
194
|
+
},
|
|
195
|
+
{
|
|
170
196
|
id: "claude-stream-json-requires-verbose",
|
|
171
197
|
description: "Claude CLI 2.x: --output-format stream-json + --include-partial-messages + --verbose accepted together",
|
|
172
198
|
args: [
|
|
@@ -180,12 +206,6 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
180
206
|
expect: "pass",
|
|
181
207
|
},
|
|
182
208
|
{
|
|
183
|
-
// Slice κ: when caller marks promptParts with cache_control, the
|
|
184
|
-
// gateway emits `-p` as a standalone flag and pipes the JSON
|
|
185
|
-
// content-blocks payload over stdin via `--input-format
|
|
186
|
-
// stream-json`. The fixture pins the exact argv combination so
|
|
187
|
-
// a future regression (re-emitting a positional prompt, dropping
|
|
188
|
-
// `--input-format`, etc.) trips loudly here.
|
|
189
209
|
id: "claude-input-format-stream-json",
|
|
190
210
|
description: "Slice κ: `-p` standalone + --input-format stream-json + --output-format stream-json + --include-partial-messages + --verbose",
|
|
191
211
|
args: [
|
|
@@ -252,15 +272,10 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
252
272
|
"images",
|
|
253
273
|
"ignoreUserConfig",
|
|
254
274
|
"ignoreRules",
|
|
255
|
-
// Phase 4 slice ζ
|
|
256
275
|
"workingDir",
|
|
257
276
|
"addDir",
|
|
258
277
|
],
|
|
259
278
|
resumeOnlyFlags: ["--last", "--all"],
|
|
260
|
-
// Phase 4 slice α (v1.8.0) verified that `codex exec resume` accepts
|
|
261
|
-
// `--output-schema` and `-c` (codex-cli 0.133.0 `exec resume --help`),
|
|
262
|
-
// so they're no longer forbidden. Current resume help does not accept
|
|
263
|
-
// session-profile or working-directory policy flags.
|
|
264
279
|
resumeForbiddenFlags: ["--sandbox", "-C", "--cd", "--add-dir", "--profile"],
|
|
265
280
|
flags: {
|
|
266
281
|
"--last": { arity: "none", description: "Resume latest session" },
|
|
@@ -323,8 +338,6 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
323
338
|
arity: "none",
|
|
324
339
|
description: "Resume picker: show all sessions without cwd filtering",
|
|
325
340
|
},
|
|
326
|
-
// The gateway emits the short form `-C`, and the advisory contract also
|
|
327
|
-
// tracks the long `--cd` alias advertised by current Codex exec help.
|
|
328
341
|
"-C": {
|
|
329
342
|
arity: "one",
|
|
330
343
|
description: "Working root for the session (Phase 4 slice ζ; new sessions only)",
|
|
@@ -365,9 +378,6 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
365
378
|
expect: "fail",
|
|
366
379
|
},
|
|
367
380
|
{
|
|
368
|
-
// Phase 4 slice α: --output-schema IS accepted on resume per
|
|
369
|
-
// codex-cli 0.133.0; this fixture pins the new behaviour so future
|
|
370
|
-
// contract changes can't silently regress.
|
|
371
381
|
id: "codex-resume-output-schema",
|
|
372
382
|
description: "Phase 4 slice α: --output-schema accepted on resume (codex-cli 0.133.0)",
|
|
373
383
|
args: ["exec", "resume", "--output-schema", "/tmp/schema.json", "session-id", "hello"],
|
|
@@ -476,8 +486,8 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
476
486
|
"policyFiles",
|
|
477
487
|
"adminPolicyFiles",
|
|
478
488
|
"attachments",
|
|
479
|
-
// Phase 4 slice γ
|
|
480
489
|
"skipTrust",
|
|
490
|
+
"yolo",
|
|
481
491
|
],
|
|
482
492
|
flags: {
|
|
483
493
|
"-p": { arity: "one", description: "Prompt text" },
|
|
@@ -503,6 +513,10 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
503
513
|
arity: "none",
|
|
504
514
|
description: "Trust workspace for this session (Phase 4 slice γ)",
|
|
505
515
|
},
|
|
516
|
+
"--yolo": {
|
|
517
|
+
arity: "none",
|
|
518
|
+
description: "Auto-approve all actions (gemini -y/--yolo). Functionally equivalent to --approval-mode yolo; the gateway emits at most one of the two.",
|
|
519
|
+
},
|
|
506
520
|
},
|
|
507
521
|
env: {},
|
|
508
522
|
conformanceFixtures: [
|
|
@@ -524,6 +538,12 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
524
538
|
args: ["-p", "hello", "--skip-trust"],
|
|
525
539
|
expect: "pass",
|
|
526
540
|
},
|
|
541
|
+
{
|
|
542
|
+
id: "gemini-yolo",
|
|
543
|
+
description: "--yolo (auto-approve all) is accepted",
|
|
544
|
+
args: ["-p", "hello", "--yolo"],
|
|
545
|
+
expect: "pass",
|
|
546
|
+
},
|
|
527
547
|
{
|
|
528
548
|
id: "gemini-stream-json",
|
|
529
549
|
description: "Phase 4 slice ε: -o stream-json is accepted",
|
|
@@ -566,16 +586,15 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
566
586
|
"mcpServers",
|
|
567
587
|
"allowedTools",
|
|
568
588
|
"disallowedTools",
|
|
569
|
-
// Phase 4 slice δ
|
|
570
589
|
"maxTurns",
|
|
571
|
-
// Phase 4 slice ζ
|
|
572
590
|
"workingDir",
|
|
573
|
-
// Phase 4 slice θ — Grok HIGH parity
|
|
574
591
|
"sandbox",
|
|
575
592
|
"rules",
|
|
576
593
|
"systemPromptOverride",
|
|
577
594
|
"allow",
|
|
578
595
|
"deny",
|
|
596
|
+
"compactionMode",
|
|
597
|
+
"compactionDetail",
|
|
579
598
|
],
|
|
580
599
|
flags: {
|
|
581
600
|
"-p": { arity: "one", description: "Prompt text" },
|
|
@@ -609,10 +628,6 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
609
628
|
arity: "one",
|
|
610
629
|
description: "Working directory for the invocation (Phase 4 slice ζ)",
|
|
611
630
|
},
|
|
612
|
-
// Phase 4 slice θ — Grok HIGH parity. `--sandbox` is freeform per
|
|
613
|
-
// `grok --help` on 0.1.210 (no `[possible values: …]` list, unlike
|
|
614
|
-
// --effort / --permission-mode / --output-format), so we register
|
|
615
|
-
// it without a `values` constraint.
|
|
616
631
|
"--sandbox": {
|
|
617
632
|
arity: "one",
|
|
618
633
|
description: "Sandbox profile for filesystem + network access (Phase 4 slice θ; freeform passthrough; env: GROK_SANDBOX)",
|
|
@@ -665,6 +680,16 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
665
680
|
arity: "optional",
|
|
666
681
|
description: "Start the session in a new git worktree, optionally named",
|
|
667
682
|
},
|
|
683
|
+
"--compaction-mode": {
|
|
684
|
+
arity: "one",
|
|
685
|
+
values: ["summary", "transcript", "segments"],
|
|
686
|
+
description: "Compaction mode (default summary; sets GROK_COMPACTION_MODE). `segments` persists per-segment markdown.",
|
|
687
|
+
},
|
|
688
|
+
"--compaction-detail": {
|
|
689
|
+
arity: "one",
|
|
690
|
+
values: ["none", "minimal", "balanced", "verbose"],
|
|
691
|
+
description: "Segment verbatim detail (default verbose; sets GROK_COMPACTION_DETAIL). Only affects `--compaction-mode segments`.",
|
|
692
|
+
},
|
|
668
693
|
},
|
|
669
694
|
env: {},
|
|
670
695
|
conformanceFixtures: [
|
|
@@ -762,6 +787,18 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
762
787
|
],
|
|
763
788
|
expect: "pass",
|
|
764
789
|
},
|
|
790
|
+
{
|
|
791
|
+
id: "grok-compaction",
|
|
792
|
+
description: "Grok 0.2.x: --compaction-mode and --compaction-detail accepted with valid enum values",
|
|
793
|
+
args: ["-p", "hello", "--compaction-mode", "segments", "--compaction-detail", "balanced"],
|
|
794
|
+
expect: "pass",
|
|
795
|
+
},
|
|
796
|
+
{
|
|
797
|
+
id: "grok-compaction-mode-invalid",
|
|
798
|
+
description: "Grok --compaction-mode rejects a value outside the contract enum",
|
|
799
|
+
args: ["-p", "hello", "--compaction-mode", "aggressive"],
|
|
800
|
+
expect: "fail",
|
|
801
|
+
},
|
|
765
802
|
],
|
|
766
803
|
},
|
|
767
804
|
mistral: {
|
|
@@ -787,19 +824,14 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
787
824
|
"resumeLatest",
|
|
788
825
|
"createNewSession",
|
|
789
826
|
"permissionMode",
|
|
790
|
-
"effort",
|
|
791
|
-
"reasoningEffort",
|
|
792
827
|
"approvalStrategy",
|
|
793
828
|
"mcpServers",
|
|
794
829
|
"allowedTools",
|
|
795
830
|
"disallowedTools",
|
|
796
|
-
// Phase 4 slice γ
|
|
797
831
|
"trust",
|
|
798
|
-
// Phase 4 slice δ
|
|
799
832
|
"maxTurns",
|
|
800
833
|
"maxPrice",
|
|
801
834
|
"maxTokens",
|
|
802
|
-
// Phase 4 slice ζ
|
|
803
835
|
"workingDir",
|
|
804
836
|
"addDir",
|
|
805
837
|
],
|
|
@@ -815,8 +847,6 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
815
847
|
values: ["default", "plan", "accept-edits", "auto-approve", "chat", "explore", "lean"],
|
|
816
848
|
description: "Agent/permission mode",
|
|
817
849
|
},
|
|
818
|
-
"--effort": { arity: "one", description: "Reasoning effort" },
|
|
819
|
-
"--reasoning-effort": { arity: "one", description: "Reasoning effort override" },
|
|
820
850
|
"--enabled-tools": { arity: "one", description: "Enabled tool" },
|
|
821
851
|
"--resume": { arity: "one", description: "Resume session" },
|
|
822
852
|
"--continue": { arity: "none", description: "Continue latest session" },
|
|
@@ -831,8 +861,6 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
831
861
|
},
|
|
832
862
|
"--max-price": {
|
|
833
863
|
arity: "one",
|
|
834
|
-
// Decimal-only: matches the MAX_PRICE_SCHEMA min(1e-6) lower bound
|
|
835
|
-
// that keeps String(N) in decimal form (no scientific notation).
|
|
836
864
|
pattern: /^(0|[1-9][0-9]*)(\.[0-9]+)?$/,
|
|
837
865
|
description: "Cumulative cost cap in USD (Phase 4 slice δ, programmatic mode only)",
|
|
838
866
|
},
|
|
@@ -932,6 +960,20 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
932
960
|
env: { VIBE_ACTIVE_MODEL: "mistral-medium-3.5" },
|
|
933
961
|
expect: "pass",
|
|
934
962
|
},
|
|
963
|
+
{
|
|
964
|
+
id: "mistral-effort-rejected",
|
|
965
|
+
description: "vibe 2.x advertises no reasoning-effort surface: a raw --effort arg is rejected by the contract (mirrors the CLI's own 'unrecognized arguments' failure)",
|
|
966
|
+
args: ["-p", "hello", "--agent", "auto-approve", "--effort", "high"],
|
|
967
|
+
env: { VIBE_ACTIVE_MODEL: "mistral-medium-3.5" },
|
|
968
|
+
expect: "fail",
|
|
969
|
+
},
|
|
970
|
+
{
|
|
971
|
+
id: "mistral-reasoning-effort-rejected",
|
|
972
|
+
description: "vibe 2.x: a raw --reasoning-effort arg is rejected by the contract",
|
|
973
|
+
args: ["-p", "hello", "--agent", "auto-approve", "--reasoning-effort", "medium"],
|
|
974
|
+
env: { VIBE_ACTIVE_MODEL: "mistral-medium-3.5" },
|
|
975
|
+
expect: "fail",
|
|
976
|
+
},
|
|
935
977
|
],
|
|
936
978
|
},
|
|
937
979
|
};
|
|
@@ -1093,24 +1135,8 @@ function validateFlagValue(cli, arg, flag, value, index, violations) {
|
|
|
1093
1135
|
});
|
|
1094
1136
|
}
|
|
1095
1137
|
}
|
|
1096
|
-
/**
|
|
1097
|
-
* Best-effort, advisory-only extraction of long-form flags from raw --help text.
|
|
1098
|
-
* Returns a sorted array of unique `--foo-bar` style flags discovered in the output.
|
|
1099
|
-
*
|
|
1100
|
-
* Heuristics:
|
|
1101
|
-
* - Matches common option declaration lines emitted by clap, yargs, commander, custom TUIs, etc.
|
|
1102
|
-
* - Lowercases for stable comparison against our contract keys.
|
|
1103
|
-
* - Intentionally conservative: ignores obvious noise (URLs, prose in descriptions).
|
|
1104
|
-
*
|
|
1105
|
-
* This powers the bidirectional drift detector (extra flags the installed binary
|
|
1106
|
-
* advertises that our contract does not yet allow). It is NEVER used for argv
|
|
1107
|
-
* validation — only for the upstream scanner and `upstream_contracts` probe reports.
|
|
1108
|
-
*/
|
|
1109
1138
|
export function extractDiscoveredFlags(helpText) {
|
|
1110
1139
|
const discovered = new Set();
|
|
1111
|
-
// Long flags: --foo, --foo-bar, --foo_bar (some CLIs normalize _ to - in display).
|
|
1112
|
-
// Only inspect option declaration lines so prose such as
|
|
1113
|
-
// "(Claude Code: --allowedTools)" does not create false drift.
|
|
1114
1140
|
const longRe = /--([a-z0-9][a-z0-9_-]{1,}[a-z0-9]?)/g;
|
|
1115
1141
|
for (const line of helpText.split(/\r?\n/)) {
|
|
1116
1142
|
const trimmed = line.trimStart();
|
|
@@ -1175,7 +1201,6 @@ export function probeInstalledCliContract(cli, timeoutMs = 5_000) {
|
|
|
1175
1201
|
const discoveredFlags = extractDiscoveredFlags(helpText);
|
|
1176
1202
|
const contractFlagSet = new Set(Object.keys(contract.flags));
|
|
1177
1203
|
const extraFlags = discoveredFlags.filter(f => !contractFlagSet.has(f));
|
|
1178
|
-
// Cheap version hint: first line that looks like a version banner
|
|
1179
1204
|
const versionMatch = helpText.match(/^\s*(?:[A-Za-z][\w .-]+)?v?\d+\.\d+\S*/m);
|
|
1180
1205
|
const versionHint = versionMatch ? versionMatch[0].trim().slice(0, 80) : undefined;
|
|
1181
1206
|
const helpHash = createHash("sha256").update(helpText).digest("hex");
|
|
@@ -1204,9 +1229,6 @@ export function buildUpstreamContractReport(options = {}) {
|
|
|
1204
1229
|
{
|
|
1205
1230
|
executable: contract.executable,
|
|
1206
1231
|
upstream: contract.upstream,
|
|
1207
|
-
// Pure metadata pointers (changelog URLs, package name, watch
|
|
1208
|
-
// categories). Enriched from the CliContract — the single source of
|
|
1209
|
-
// truth — so report consumers and the scanner read the same values.
|
|
1210
1232
|
upstreamMetadata: contract.upstreamMetadata
|
|
1211
1233
|
? {
|
|
1212
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",
|