llm-cli-gateway 2.0.0 → 2.1.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 +39 -0
- package/README.md +138 -14
- package/dist/index.d.ts +2 -0
- package/dist/index.js +22 -5
- package/dist/upstream-contracts.d.ts +10 -0
- package/dist/upstream-contracts.js +116 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,45 @@ All notable changes to the llm-cli-gateway project.
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## [2.1.0] - 2026-06-07: Grok Build 0.2.32, probe drift acknowledgement, docs currency
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Grok Build 0.2.32 support: new `leaderSocket` parameter on `grok_request` /
|
|
12
|
+
`grok_request_async` maps to the new `--leader-socket <PATH>` flag (isolated
|
|
13
|
+
leader process for local/branch Grok builds; default `~/.grok/leader.sock`).
|
|
14
|
+
Contract declares the flag with arity-one validation plus conformance
|
|
15
|
+
fixtures. The release's other changes (plugin slash commands in all
|
|
16
|
+
conversations, ordered rapid prompt submissions, faster grep on large
|
|
17
|
+
repos) are CLI-internal and inherited automatically. Probe at 0.2.32:
|
|
18
|
+
missingFlags/warnings clean.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- Upstream-contract probe drift after the 2026-06 provider CLI upgrades
|
|
23
|
+
(gemini 0.45.2, grok 0.2.22, vibe 2.14.0): `CliFlagContract.hiddenFromHelp`
|
|
24
|
+
marks real flags hidden from a binary's `--help` (Claude `--max-turns`), and
|
|
25
|
+
`CliContract.acknowledgedUpstreamFlags` acknowledges upstream-only flags the
|
|
26
|
+
gateway never emits (29 Claude, 18 Gemini). Both are probe-only — the argv
|
|
27
|
+
allowlist is unchanged — with stale-marker warnings in both directions and a
|
|
28
|
+
new `acknowledgedExtraFlags` probe field. New pure `computeFlagDrift` plus
|
|
29
|
+
7 unit tests.
|
|
30
|
+
- MCP server version now reports the real package version (was hardcoded
|
|
31
|
+
`1.0.0`).
|
|
32
|
+
|
|
33
|
+
### Documentation
|
|
34
|
+
|
|
35
|
+
- Cross-LLM documentation currency review (Codex + Gemini + Grok + Mistral):
|
|
36
|
+
README tool reference gains `codex_fork_session`, `llm_request_result`,
|
|
37
|
+
`llm_process_health`, `upstream_contracts`, and `list_available_models`;
|
|
38
|
+
`claude_request` parameter list completed (`outputFormat` default is
|
|
39
|
+
`stream-json`); Codex `fullAuto` documented as deprecated in favour of
|
|
40
|
+
`sandboxMode`; Gemini approval modes include `plan`; grok/mistral upgrade
|
|
41
|
+
strategies documented; stale test counts, provider lists, and
|
|
42
|
+
`BEST_PRACTICES.md` path pointers corrected across README, AGENTS.md,
|
|
43
|
+
.cursorrules, CLAUDE.md, docs/guides, docs/personal-mcp (Mistral/Vibe row
|
|
44
|
+
added to the provider support matrix), and docs/upstream.
|
|
45
|
+
|
|
7
46
|
## [2.0.0] - 2026-06-04: node:sqlite migration — native module out of the prod graph
|
|
8
47
|
|
|
9
48
|
Major release. Persistence moves from the native `better-sqlite3` binding to
|
package/README.md
CHANGED
|
@@ -205,7 +205,7 @@ Opt-in flags (all default off) live under `[cache_awareness]` in `~/.llm-cli-gat
|
|
|
205
205
|
|
|
206
206
|
### Security & Quality
|
|
207
207
|
|
|
208
|
-
- **Comprehensive Testing**:
|
|
208
|
+
- **Comprehensive Testing**: 1,000+ tests covering unit, integration, and regression scenarios with real CLI execution
|
|
209
209
|
- **Input Validation**: Zod schemas prevent injection attacks
|
|
210
210
|
- **No Secret Leakage**: Generic session descriptions only (file permissions 0o600)
|
|
211
211
|
- **No ReDoS**: Bounded regex patterns prevent catastrophic backtracking
|
|
@@ -344,6 +344,7 @@ The personal-appliance surface exposes simplified validation tools for non-devel
|
|
|
344
344
|
- `consensus_check`: check whether providers agree with a claim.
|
|
345
345
|
- `ask_model`: ask one provider through the simplified surface.
|
|
346
346
|
- `synthesize_validation`: run an explicit judge model after provider results have been collected.
|
|
347
|
+
- `list_available_models`: list the models each provider CLI exposes through the simplified surface.
|
|
347
348
|
- `job_status` and `job_result`: poll and collect validation job outputs.
|
|
348
349
|
|
|
349
350
|
The validation report preserves per-provider disagreement. Optional judge synthesis is explicit about which provider produced the judge job.
|
|
@@ -356,15 +357,29 @@ Execute a Claude Code request with optional session management.
|
|
|
356
357
|
|
|
357
358
|
**Parameters:**
|
|
358
359
|
|
|
359
|
-
- `prompt` (string,
|
|
360
|
+
- `prompt` (string, optional*): The prompt to send (1-100,000 chars). *Exactly one of `prompt` or `promptParts` is required (mutually exclusive)
|
|
360
361
|
- `model` (string, optional): Model name or alias (use `list_models` for available values; supports `latest`)
|
|
361
|
-
- `outputFormat` (string, optional): Output format (
|
|
362
|
+
- `outputFormat` (string, optional): Output format (`text|json|stream-json`), default: `stream-json` — the gateway parses NDJSON usage events for token/cost observability; override to `text` only when you want unparsed stdout
|
|
362
363
|
- `sessionId` (string, optional): Specific session ID to use
|
|
363
364
|
- `continueSession` (boolean, optional): Continue the active session
|
|
364
365
|
- `createNewSession` (boolean, optional): Always create a new session
|
|
366
|
+
- `forkSession` (boolean, optional): Fork the resumed session instead of appending to it
|
|
365
367
|
- `allowedTools` (string[], optional): Restrict Claude tools to this allow-list
|
|
366
368
|
- `disallowedTools` (string[], optional): Explicitly deny listed Claude tools
|
|
367
|
-
- `
|
|
369
|
+
- `permissionMode` (string, optional): Claude permission mode (`default|acceptEdits|plan|auto|dontAsk|bypassPermissions`); preferred over `dangerouslySkipPermissions`
|
|
370
|
+
- `dangerouslySkipPermissions` (boolean, optional): Deprecated — maps to `permissionMode: "bypassPermissions"`; `permissionMode` wins when both are set
|
|
371
|
+
- `agent` (string, optional): Named sub-agent to run as
|
|
372
|
+
- `agents` (string, optional): Inline agent definitions JSON
|
|
373
|
+
- `systemPrompt` / `appendSystemPrompt` (string, optional): Replace or extend the system prompt
|
|
374
|
+
- `maxBudgetUsd` (number, optional): Budget cap in USD for the request
|
|
375
|
+
- `maxTurns` (integer, optional): Agent-loop turn cap
|
|
376
|
+
- `effort` (string, optional): Reasoning effort (`low|medium|high|xhigh|max`)
|
|
377
|
+
- `fallbackModel` (string, optional): Auto-fallback model when the default is overloaded
|
|
378
|
+
- `jsonSchema` (string, optional): JSON Schema literal constraining structured output
|
|
379
|
+
- `addDir` (string[], optional): Additional workspace directories
|
|
380
|
+
- `noSessionPersistence` (boolean, optional): Ephemeral session (not persisted to disk)
|
|
381
|
+
- `settingSources` / `settings` / `tools` (optional): Setting sources to load, settings JSON path/literal, built-in tool restriction
|
|
382
|
+
- `excludeDynamicSystemPromptSections` (boolean, optional): Trim dynamic system prompt sections
|
|
368
383
|
- `approvalStrategy` (string, optional): `"legacy"` (default) or `"mcp_managed"`
|
|
369
384
|
- `approvalPolicy` (string, optional): `"strict"`, `"balanced"`, or `"permissive"`
|
|
370
385
|
- `mcpServers` (string[], optional): Claude MCP servers to expose (default: `["sqry","exa","ref_tools"]`; `"trstr"` available as opt-in)
|
|
@@ -372,6 +387,10 @@ Execute a Claude Code request with optional session management.
|
|
|
372
387
|
- `optimizePrompt` (boolean, optional): Optimize prompt for token efficiency (44% reduction), default: false
|
|
373
388
|
- `optimizeResponse` (boolean, optional): Optimize response for token efficiency (37% reduction), default: false
|
|
374
389
|
- `correlationId` (string, optional): Request trace ID (auto-generated if omitted)
|
|
390
|
+
- `idleTimeoutMs` (integer, optional): Kill a stuck process after output inactivity; 30,000 to 3,600,000 ms
|
|
391
|
+
- `worktree` (boolean|object, optional): Run inside a gateway-owned git worktree (slice λ)
|
|
392
|
+
- `promptParts` (object, optional): Cache-aware structured prompt `{ system?, tools?, context?, task }`; mutually exclusive with `prompt`
|
|
393
|
+
- `forceRefresh` (boolean, optional): Bypass dedup and force a fresh CLI run, default: false
|
|
375
394
|
|
|
376
395
|
**Response extras:**
|
|
377
396
|
|
|
@@ -396,19 +415,33 @@ Execute a Codex request with optional session tracking.
|
|
|
396
415
|
|
|
397
416
|
**Parameters:**
|
|
398
417
|
|
|
399
|
-
- `prompt` (string,
|
|
400
|
-
- `model` (string, optional): Model name or alias (use `list_models` for available values; supports `latest`, recommended: `gpt-5.
|
|
401
|
-
- `fullAuto` (boolean, optional):
|
|
418
|
+
- `prompt` (string, optional*): The prompt to send (1-100,000 chars). *Exactly one of `prompt` or `promptParts` is required (mutually exclusive)
|
|
419
|
+
- `model` (string, optional): Model name or alias (use `list_models` for available values; supports `latest`, recommended: `gpt-5.5`)
|
|
420
|
+
- `fullAuto` (boolean, optional): Deprecated — expands to `--sandbox workspace-write` only (current Codex no longer accepts approval-policy flags); prefer `sandboxMode`
|
|
421
|
+
- `sandboxMode` (string, optional): Codex sandbox (`read-only|workspace-write|danger-full-access`)
|
|
402
422
|
- `dangerouslyBypassApprovalsAndSandbox` (boolean, optional): Request Codex bypass flags
|
|
403
423
|
- `approvalStrategy` (string, optional): `"legacy"` (default) or `"mcp_managed"`
|
|
404
424
|
- `approvalPolicy` (string, optional): `"strict"`, `"balanced"`, or `"permissive"`
|
|
405
425
|
- `mcpServers` (string[], optional): MCP servers expected for Codex execution context
|
|
406
426
|
- `sessionId` (string, optional): Session identifier for tracking
|
|
427
|
+
- `resumeLatest` (boolean, optional): Resume the most recent Codex session in the current cwd (`codex exec resume --last`); ignored if `sessionId` is set
|
|
407
428
|
- `createNewSession` (boolean, optional): Always create a new session
|
|
429
|
+
- `forceRefresh` (boolean, optional): Bypass dedup and force a fresh CLI run, default: false
|
|
430
|
+
- `outputFormat` (string, optional): `text` (default) or `json` (`--json` JSONL events for token usage extraction)
|
|
431
|
+
- `outputSchema` (string|object, optional): Codex `--output-schema` — path or inline JSON Schema
|
|
432
|
+
- `workingDir` (string, optional): Working root for this session (`-C`/`--cd`; new sessions only)
|
|
433
|
+
- `addDir` (string[], optional): Additional writable workspace directories (one `--add-dir` per entry; new sessions only)
|
|
434
|
+
- `ephemeral` (boolean, optional): Codex `--ephemeral` (no session persistence)
|
|
435
|
+
- `images` (string[], optional): Image attachments (one `-i <path>` per entry)
|
|
436
|
+
- `profile` (string, optional): Codex `--profile <name>` (new sessions only; ignored with a logged warning on resume)
|
|
437
|
+
- `configOverrides` (object, optional): Codex `-c key=value` overrides
|
|
438
|
+
- `ignoreRules` / `ignoreUserConfig` (boolean, optional): Codex `--ignore-rules` / `--ignore-user-config`
|
|
439
|
+
- `worktree` (boolean|object, optional): Run inside a gateway-owned git worktree (slice λ)
|
|
440
|
+
- `promptParts` (object, optional): Cache-aware structured prompt `{ system?, tools?, context?, task }`; mutually exclusive with `prompt`
|
|
408
441
|
- `optimizePrompt` (boolean, optional): Optimize prompt for token efficiency, default: false
|
|
409
442
|
- `optimizeResponse` (boolean, optional): Optimize response for token efficiency, default: false
|
|
410
443
|
- `correlationId` (string, optional): Request trace ID (auto-generated if omitted)
|
|
411
|
-
- `idleTimeoutMs` (
|
|
444
|
+
- `idleTimeoutMs` (integer, optional): Kill a stuck Codex process after output inactivity; 30,000 to 3,600,000 ms
|
|
412
445
|
|
|
413
446
|
**Response extras:**
|
|
414
447
|
|
|
@@ -420,32 +453,56 @@ Execute a Codex request with optional session tracking.
|
|
|
420
453
|
```json
|
|
421
454
|
{
|
|
422
455
|
"prompt": "Create a REST API endpoint",
|
|
423
|
-
"model": "gpt-5.
|
|
424
|
-
"
|
|
456
|
+
"model": "gpt-5.5",
|
|
457
|
+
"sandboxMode": "workspace-write",
|
|
425
458
|
"optimizePrompt": true
|
|
426
459
|
}
|
|
427
460
|
```
|
|
428
461
|
|
|
462
|
+
##### `codex_fork_session`
|
|
463
|
+
|
|
464
|
+
Fork an existing Codex session into a new branch (`codex fork <SESSION_ID|--last> <prompt>`), preserving the original session's history while the fork diverges.
|
|
465
|
+
|
|
466
|
+
**Parameters:**
|
|
467
|
+
|
|
468
|
+
- `prompt` (string, required): Prompt text for the forked session (1-100,000 chars)
|
|
469
|
+
- `sessionId` (string, optional): Codex session UUID to fork from (mutually exclusive with `forkLast`)
|
|
470
|
+
- `forkLast` (boolean, optional): Fork the most recent Codex session instead of naming one
|
|
471
|
+
- `model` (string, optional): Model name or alias (e.g. `gpt-5.5`, `latest`)
|
|
472
|
+
- `sandboxMode` (string, optional): Codex sandbox (`read-only|workspace-write|danger-full-access`)
|
|
473
|
+
- `correlationId` (string, optional): Request trace ID (auto-generated if omitted)
|
|
474
|
+
- `idleTimeoutMs` (number, optional): Idle timeout in ms (30s-1h, omit for CLI default)
|
|
475
|
+
|
|
429
476
|
##### `gemini_request`
|
|
430
477
|
|
|
431
478
|
Execute a Gemini CLI request with session support.
|
|
432
479
|
|
|
433
480
|
**Parameters:**
|
|
434
481
|
|
|
435
|
-
- `prompt` (string,
|
|
482
|
+
- `prompt` (string, optional*): The prompt to send (1-100,000 chars). *Exactly one of `prompt` or `promptParts` is required (mutually exclusive)
|
|
436
483
|
- `model` (string, optional): Model name or alias (use `list_models` for available values; supports `latest`, `pro`, `flash`)
|
|
437
484
|
- `sessionId` (string, optional): Session ID to resume
|
|
438
485
|
- `resumeLatest` (boolean, optional): Resume the latest session automatically
|
|
439
486
|
- `createNewSession` (boolean, optional): Always create a new session
|
|
440
|
-
- `approvalMode` (string, optional): Gemini approval mode (`default|auto_edit|yolo`) in legacy mode
|
|
487
|
+
- `approvalMode` (string, optional): Gemini approval mode (`default|auto_edit|yolo|plan`) in legacy mode
|
|
441
488
|
- `approvalStrategy` (string, optional): `"legacy"` (default) or `"mcp_managed"`
|
|
442
489
|
- `approvalPolicy` (string, optional): `"strict"`, `"balanced"`, or `"permissive"`
|
|
443
490
|
- `mcpServers` (string[], optional): Allowed Gemini MCP server names
|
|
444
491
|
- `allowedTools` (string[], optional): Restrict Gemini tools to this allow-list
|
|
445
492
|
- `includeDirs` (string[], optional): Additional workspace directories for Gemini
|
|
493
|
+
- `outputFormat` (string, optional): `text` (default), `json` (`-o json`), or `stream-json` (`-o stream-json`, NDJSON with usage extraction)
|
|
494
|
+
- `sandbox` (boolean, optional): Run Gemini in sandbox mode (`-s`)
|
|
495
|
+
- `policyFiles` / `adminPolicyFiles` (string[], optional): Policy / admin-policy file paths (one `--policy`/`--admin-policy` per file; paths must exist)
|
|
496
|
+
- `attachments` (string[], optional): Absolute file paths prepended as `@<path>` tokens to the prompt
|
|
497
|
+
- `skipTrust` (boolean, optional): Emit `--skip-trust` to trust the workspace for this session (required for headless runs in fresh workspaces)
|
|
498
|
+
- `yolo` (boolean, optional): Auto-approve all; equivalent to `approvalMode: "yolo"`. Emits `--yolo` only when `--approval-mode yolo` is not already being emitted (never both)
|
|
499
|
+
- `worktree` (boolean|object, optional): Run inside a gateway-owned git worktree (slice λ)
|
|
500
|
+
- `promptParts` (object, optional): Cache-aware structured prompt `{ system?, tools?, context?, task }`; mutually exclusive with `prompt`
|
|
446
501
|
- `optimizePrompt` (boolean, optional): Optimize prompt for token efficiency, default: false
|
|
447
502
|
- `optimizeResponse` (boolean, optional): Optimize response for token efficiency, default: false
|
|
448
503
|
- `correlationId` (string, optional): Request trace ID (auto-generated if omitted)
|
|
504
|
+
- `idleTimeoutMs` (integer, optional): Kill a stuck process after output inactivity; 30,000 to 3,600,000 ms
|
|
505
|
+
- `forceRefresh` (boolean, optional): Bypass dedup and force a fresh CLI run, default: false
|
|
449
506
|
|
|
450
507
|
**Response extras:**
|
|
451
508
|
|
|
@@ -469,7 +526,7 @@ Execute a Grok CLI (xAI) request with session support.
|
|
|
469
526
|
|
|
470
527
|
**Parameters:**
|
|
471
528
|
|
|
472
|
-
- `prompt` (string,
|
|
529
|
+
- `prompt` (string, optional*): The prompt to send (1-100,000 chars). *Exactly one of `prompt` or `promptParts` is required (mutually exclusive)
|
|
473
530
|
- `model` (string, optional): Model name or alias (e.g. `grok-build`, `latest`)
|
|
474
531
|
- `outputFormat` (string, optional): `"plain"` (default), `"json"`, or `"streaming-json"`
|
|
475
532
|
- `sessionId` (string, optional): Session ID to resume (`--resume <id>`)
|
|
@@ -484,9 +541,35 @@ Execute a Grok CLI (xAI) request with session support.
|
|
|
484
541
|
- `mcpServers` (string[], optional): MCP server names tracked for approvals (Grok manages its own MCP config via `grok mcp`)
|
|
485
542
|
- `allowedTools` (string[], optional): Allowed built-in tools (passed as `--tools` comma list)
|
|
486
543
|
- `disallowedTools` (string[], optional): Disallowed built-in tools (passed as `--disallowed-tools` comma list)
|
|
544
|
+
- `maxTurns` (integer, optional): Agent-loop iteration cap (`--max-turns`)
|
|
545
|
+
- `workingDir` (string, optional): Working directory for this invocation (`--cwd`)
|
|
546
|
+
- `sandbox` (string, optional): Sandbox profile for filesystem/network access (`--sandbox`, freeform; also via `GROK_SANDBOX`)
|
|
547
|
+
- `rules` (string, optional): Extra rules appended to the system prompt (`--rules`; supports `@file` prefix)
|
|
548
|
+
- `systemPromptOverride` (string, optional): Replace the agent's system prompt entirely
|
|
549
|
+
- `allow` / `deny` (string[], optional): Permission allow/deny rules (one `--allow`/`--deny` per entry)
|
|
550
|
+
- `compactionMode` (string, optional): `summary` (default) `|transcript|segments`
|
|
551
|
+
- `compactionDetail` (string, optional): `none|minimal|balanced|verbose` (segments mode only)
|
|
552
|
+
- `agent` (string, optional): Agent name or definition file path
|
|
553
|
+
- `agents` (string|object, optional): Inline subagent definitions JSON
|
|
554
|
+
- `bestOfN` (integer, optional): Run the task N ways in parallel and pick the best (headless only)
|
|
555
|
+
- `check` (boolean, optional): Append a self-verification loop (headless only)
|
|
556
|
+
- `disableWebSearch` (boolean, optional): Disable web search and remote retrieval tools
|
|
557
|
+
- `todoGate` (boolean, optional): Enable runtime turn-end TodoGate (session-scoped)
|
|
558
|
+
- `verbatim` (boolean, optional): Send the prompt exactly as given (also skips gateway prompt optimisation)
|
|
559
|
+
- `promptFile` / `promptJson` / `single` (optional): Single-turn prompt from a file / JSON blocks / literal
|
|
560
|
+
- `experimentalMemory` / `noMemory` (boolean, optional): Enable/disable cross-session memory
|
|
561
|
+
- `noAltScreen` / `noPlan` / `noSubagents` (boolean, optional): Disable alt screen / plan mode / subagent spawning
|
|
562
|
+
- `oauth` (boolean, optional): Use OAuth during authentication
|
|
563
|
+
- `restoreCode` (boolean, optional): Check out the original session commit when resuming
|
|
564
|
+
- `leaderSocket` (string, optional): Custom leader socket path (`--leader-socket`, Grok 0.2.32+; default `~/.grok/leader.sock`) — targets an isolated leader process, e.g. a local/branch Grok build
|
|
565
|
+
- `nativeWorktree` (boolean|string, optional): Grok's own `--worktree` flag (`true` → bare, string → named); distinct from the gateway `worktree` option
|
|
566
|
+
- `worktree` (boolean|object, optional): Run inside a gateway-owned git worktree (slice λ)
|
|
567
|
+
- `promptParts` (object, optional): Cache-aware structured prompt `{ system?, tools?, context?, task }`; mutually exclusive with `prompt`
|
|
487
568
|
- `optimizePrompt` (boolean, optional): Optimize prompt for token efficiency, default: false
|
|
488
569
|
- `optimizeResponse` (boolean, optional): Optimize response for token efficiency, default: false
|
|
489
570
|
- `correlationId` (string, optional): Request trace ID (auto-generated if omitted)
|
|
571
|
+
- `idleTimeoutMs` (integer, optional): Kill a stuck process after output inactivity; 30,000 to 3,600,000 ms
|
|
572
|
+
- `forceRefresh` (boolean, optional): Bypass dedup and force a fresh CLI run, default: false
|
|
490
573
|
|
|
491
574
|
**Example:**
|
|
492
575
|
|
|
@@ -740,6 +823,21 @@ Run a Mistral Vibe agentic coding request. Like `grok_request` in shape, but wit
|
|
|
740
823
|
- `disallowedTools` (string[], optional): Accepted for parity with the other providers; ignored at the CLI boundary with a logged warning.
|
|
741
824
|
- `outputFormat` (string, optional): Vibe 2.x values are `"text"`, `"json"`, or `"streaming"`; legacy aliases `"plain"` and `"stream-json"` are accepted and normalized before spawn.
|
|
742
825
|
- `sessionId` / `resumeLatest` / `createNewSession`: standard session controls. Current Vibe defaults session logging to enabled; if an older config has `[session_logging] enabled = false`, `doctor --json` surfaces an actionable next-action.
|
|
826
|
+
- `trust` (boolean, optional): Emit `--trust` so Vibe trusts the cwd for this invocation only (not persisted; skips the interactive trust prompt)
|
|
827
|
+
- `maxTurns` (integer, optional): Agent-loop iteration cap (`--max-turns`, programmatic mode only)
|
|
828
|
+
- `maxPrice` (number, optional): Interrupt when cumulative cost crosses this USD cap (`--max-price`, programmatic mode only)
|
|
829
|
+
- `maxTokens` (integer, optional): Cap cumulative prompt + completion tokens (`--max-tokens`, programmatic mode only)
|
|
830
|
+
- `workingDir` (string, optional): Change to this directory before running (`--workdir`)
|
|
831
|
+
- `addDir` (string[], optional): Additional writable workspace directories (one `--add-dir` per entry)
|
|
832
|
+
- `approvalStrategy` (string, optional): `"legacy"` (default) or `"mcp_managed"`
|
|
833
|
+
- `approvalPolicy` (string, optional): `"strict"`, `"balanced"`, or `"permissive"`
|
|
834
|
+
- `mcpServers` (string[], optional): MCP server names tracked for approvals (Vibe manages its own MCP config via `vibe mcp`)
|
|
835
|
+
- `worktree` (boolean|object, optional): Run inside a gateway-owned git worktree (slice λ)
|
|
836
|
+
- `promptParts` (object, optional): Cache-aware structured prompt `{ system?, tools?, context?, task }`; mutually exclusive with `prompt`
|
|
837
|
+
- `optimizePrompt` / `optimizeResponse` (boolean, optional): Token-efficiency optimisation, default: false
|
|
838
|
+
- `correlationId` (string, optional): Request trace ID (auto-generated if omitted)
|
|
839
|
+
- `idleTimeoutMs` (integer, optional): Kill a stuck process after output inactivity; 30,000 to 3,600,000 ms
|
|
840
|
+
- `forceRefresh` (boolean, optional): Bypass dedup and force a fresh CLI run, default: false
|
|
743
841
|
|
|
744
842
|
##### `claude_request_async` / `codex_request_async` / `gemini_request_async` / `grok_request_async` / `mistral_request_async`
|
|
745
843
|
|
|
@@ -778,10 +876,33 @@ List recent MCP-managed approval decisions recorded by the gateway.
|
|
|
778
876
|
**Parameters:**
|
|
779
877
|
|
|
780
878
|
- `limit` (number, optional): Max records (1-500), default: 50
|
|
781
|
-
- `cli` (string, optional): Filter by `"claude"`, `"codex"`, or `"
|
|
879
|
+
- `cli` (string, optional): Filter by `"claude"`, `"codex"`, `"gemini"`, `"grok"`, or `"mistral"`
|
|
782
880
|
|
|
783
881
|
Approval records are persisted to `~/.llm-cli-gateway/approvals.jsonl`.
|
|
784
882
|
|
|
883
|
+
##### `llm_request_result`
|
|
884
|
+
|
|
885
|
+
Read back any persisted request — sync or async — by its correlation ID. Every response echoes its ID in `structuredContent.correlationId`; pass it here to recover the persisted prompt/response after the inline result is gone. Reads the flight recorder, so it works independently of async-job persistence (returns "not found" when flight recording is disabled).
|
|
886
|
+
|
|
887
|
+
**Parameters:**
|
|
888
|
+
|
|
889
|
+
- `correlationId` (string, required): Correlation ID from a prior request
|
|
890
|
+
- `maxChars` (number, optional): Max chars of the persisted response to return (1,000-2,000,000)
|
|
891
|
+
- `includePrompt` (boolean, optional): Include the full persisted prompt text, default: false
|
|
892
|
+
|
|
893
|
+
##### `llm_process_health`
|
|
894
|
+
|
|
895
|
+
Report gateway process health: async-job manager state plus the resolved persistence block (`backend`, `dbPath`, config sources). Use it to confirm which config file and SQLite paths the gateway is actually running under.
|
|
896
|
+
|
|
897
|
+
##### `upstream_contracts`
|
|
898
|
+
|
|
899
|
+
Return the gateway's declared provider CLI contracts, optionally probing the installed binaries for drift.
|
|
900
|
+
|
|
901
|
+
**Parameters:**
|
|
902
|
+
|
|
903
|
+
- `cli` (string, optional): Filter (`claude|codex|gemini|grok|mistral`)
|
|
904
|
+
- `probeInstalled` (boolean, optional, default `false`): Run local `--help` probes and compare advertised flags against the declared contract — strongly recommended after any provider CLI upgrade. The probe reports `missingFlags`, `extraFlags`, `acknowledgedExtraFlags` (known upstream-only flags filtered from `extraFlags`), `discoveredFlags`, and stale-marker `warnings`.
|
|
905
|
+
|
|
785
906
|
#### Session Management Tools
|
|
786
907
|
|
|
787
908
|
##### `session_create`
|
|
@@ -924,6 +1045,9 @@ Plan or run an upgrade for one CLI.
|
|
|
924
1045
|
- Codex latest: `codex update`
|
|
925
1046
|
- Codex explicit target: `npm install -g @openai/codex@<target>`
|
|
926
1047
|
- Gemini: `npm install -g @google/gemini-cli@<target>`
|
|
1048
|
+
- Grok latest: `grok update`
|
|
1049
|
+
- Grok explicit target: `grok update --version <target>`
|
|
1050
|
+
- Mistral (Vibe): dispatches to the detected installer (`pip`/`uv`/`brew`); errors with guidance when none is detected (Vibe ships no self-update command)
|
|
927
1051
|
|
|
928
1052
|
**Example dry run:**
|
|
929
1053
|
|
package/dist/index.d.ts
CHANGED
|
@@ -251,6 +251,7 @@ export declare function prepareGrokRequest(params: {
|
|
|
251
251
|
noSubagents?: boolean;
|
|
252
252
|
oauth?: boolean;
|
|
253
253
|
restoreCode?: boolean;
|
|
254
|
+
leaderSocket?: string;
|
|
254
255
|
nativeWorktree?: boolean | string;
|
|
255
256
|
}, runtime?: GatewayServerRuntime): CliRequestPrep | ExtendedToolResponse;
|
|
256
257
|
export declare function prepareMistralRequest(params: {
|
|
@@ -376,6 +377,7 @@ export interface GrokRequestParams {
|
|
|
376
377
|
noSubagents?: boolean;
|
|
377
378
|
oauth?: boolean;
|
|
378
379
|
restoreCode?: boolean;
|
|
380
|
+
leaderSocket?: string;
|
|
379
381
|
nativeWorktree?: boolean | string;
|
|
380
382
|
worktree?: boolean | {
|
|
381
383
|
name?: string;
|
package/dist/index.js
CHANGED
|
@@ -143,8 +143,8 @@ function loadSkills() {
|
|
|
143
143
|
const loadedSkills = loadSkills();
|
|
144
144
|
const SERVER_INSTRUCTIONS = `llm-cli-gateway: Multi-LLM orchestration via MCP.
|
|
145
145
|
|
|
146
|
-
Tools: claude_request, codex_request, gemini_request, grok_request, mistral_request (sync) | *_request_async (async)
|
|
147
|
-
Validation: validate_with_models, second_opinion, compare_answers, red_team_review, consensus_check, ask_model, synthesize_validation
|
|
146
|
+
Tools: claude_request, codex_request, gemini_request, grok_request, mistral_request (sync) | *_request_async (async) | codex_fork_session (fork a Codex session into a new branch)
|
|
147
|
+
Validation: validate_with_models, second_opinion, compare_answers, red_team_review, consensus_check, ask_model, synthesize_validation, list_available_models | job_status/job_result (validation jobs)
|
|
148
148
|
Jobs: llm_job_status, llm_job_result, llm_job_cancel
|
|
149
149
|
Sessions: session_create, session_list, session_set_active, session_get, session_delete, session_clear_all
|
|
150
150
|
Other: list_models, cli_versions, upstream_contracts (use --probe-installed after CLI upgrades to detect drift), cli_upgrade, approval_list, llm_process_health, llm_request_result (read back any persisted request — sync or async — by correlationId)
|
|
@@ -159,7 +159,7 @@ Key behaviors:
|
|
|
159
159
|
Skills (full docs via MCP resources):
|
|
160
160
|
${loadedSkills.map(s => `- skills://${s.name} — ${s.description}`).join("\n")}`;
|
|
161
161
|
function newGatewayMcpServer() {
|
|
162
|
-
return new McpServer({ name: "llm-cli-gateway", version:
|
|
162
|
+
return new McpServer({ name: "llm-cli-gateway", version: packageVersion() }, { instructions: SERVER_INSTRUCTIONS });
|
|
163
163
|
}
|
|
164
164
|
let sessionManager;
|
|
165
165
|
let db = null;
|
|
@@ -1474,6 +1474,9 @@ export function prepareGrokRequest(params, runtime = resolveGatewayServerRuntime
|
|
|
1474
1474
|
if (params.restoreCode) {
|
|
1475
1475
|
args.push("--restore-code");
|
|
1476
1476
|
}
|
|
1477
|
+
if (params.leaderSocket) {
|
|
1478
|
+
args.push("--leader-socket", params.leaderSocket);
|
|
1479
|
+
}
|
|
1477
1480
|
if (params.nativeWorktree === true) {
|
|
1478
1481
|
args.push("--worktree");
|
|
1479
1482
|
}
|
|
@@ -1976,6 +1979,7 @@ export async function handleGrokRequest(deps, params) {
|
|
|
1976
1979
|
noSubagents: params.noSubagents,
|
|
1977
1980
|
oauth: params.oauth,
|
|
1978
1981
|
restoreCode: params.restoreCode,
|
|
1982
|
+
leaderSocket: params.leaderSocket,
|
|
1979
1983
|
nativeWorktree: params.nativeWorktree,
|
|
1980
1984
|
}, runtime);
|
|
1981
1985
|
if (!("args" in prep))
|
|
@@ -2133,6 +2137,7 @@ export async function handleGrokRequestAsync(deps, params) {
|
|
|
2133
2137
|
noSubagents: params.noSubagents,
|
|
2134
2138
|
oauth: params.oauth,
|
|
2135
2139
|
restoreCode: params.restoreCode,
|
|
2140
|
+
leaderSocket: params.leaderSocket,
|
|
2136
2141
|
nativeWorktree: params.nativeWorktree,
|
|
2137
2142
|
}, runtime);
|
|
2138
2143
|
if (!("args" in prep))
|
|
@@ -3488,12 +3493,17 @@ export function createGatewayServer(deps = {}) {
|
|
|
3488
3493
|
.boolean()
|
|
3489
3494
|
.optional()
|
|
3490
3495
|
.describe("Grok --restore-code: check out the original session commit when resuming."),
|
|
3496
|
+
leaderSocket: z
|
|
3497
|
+
.string()
|
|
3498
|
+
.min(1)
|
|
3499
|
+
.optional()
|
|
3500
|
+
.describe("Grok 0.2.32+ --leader-socket <PATH>: custom leader socket path (default ~/.grok/leader.sock). Targets an isolated leader process, e.g. a local/branch Grok build; name it ~/.grok/leader-*.sock to keep `grok leader list/kill` discovery working."),
|
|
3491
3501
|
nativeWorktree: z
|
|
3492
3502
|
.union([z.boolean(), z.string().min(1)])
|
|
3493
3503
|
.optional()
|
|
3494
3504
|
.describe("Grok -w/--worktree: native CLI worktree flag (`true` → bare `--worktree`, string → named). NOT gateway slice λ `worktree`."),
|
|
3495
3505
|
worktree: WORKTREE_SCHEMA.optional(),
|
|
3496
|
-
}, async ({ prompt, promptParts, model, outputFormat, sessionId, resumeLatest, createNewSession, alwaysApprove, permissionMode, effort, reasoningEffort, approvalStrategy, approvalPolicy, mcpServers, allowedTools, disallowedTools, correlationId, optimizePrompt, optimizeResponse, idleTimeoutMs, forceRefresh, maxTurns, workingDir, sandbox, rules, systemPromptOverride, allow, deny, compactionMode, compactionDetail, agent, bestOfN, check, disableWebSearch, todoGate, verbatim, agents, promptFile, promptJson, single, experimentalMemory, noAltScreen, noMemory, noPlan, noSubagents, oauth, restoreCode, nativeWorktree, worktree, }) => {
|
|
3506
|
+
}, async ({ prompt, promptParts, model, outputFormat, sessionId, resumeLatest, createNewSession, alwaysApprove, permissionMode, effort, reasoningEffort, approvalStrategy, approvalPolicy, mcpServers, allowedTools, disallowedTools, correlationId, optimizePrompt, optimizeResponse, idleTimeoutMs, forceRefresh, maxTurns, workingDir, sandbox, rules, systemPromptOverride, allow, deny, compactionMode, compactionDetail, agent, bestOfN, check, disableWebSearch, todoGate, verbatim, agents, promptFile, promptJson, single, experimentalMemory, noAltScreen, noMemory, noPlan, noSubagents, oauth, restoreCode, leaderSocket, nativeWorktree, worktree, }) => {
|
|
3497
3507
|
return handleGrokRequest({ sessionManager, logger, runtime }, {
|
|
3498
3508
|
prompt,
|
|
3499
3509
|
promptParts,
|
|
@@ -3542,6 +3552,7 @@ export function createGatewayServer(deps = {}) {
|
|
|
3542
3552
|
noSubagents,
|
|
3543
3553
|
oauth,
|
|
3544
3554
|
restoreCode,
|
|
3555
|
+
leaderSocket,
|
|
3545
3556
|
nativeWorktree,
|
|
3546
3557
|
worktree,
|
|
3547
3558
|
});
|
|
@@ -4298,12 +4309,17 @@ export function createGatewayServer(deps = {}) {
|
|
|
4298
4309
|
.boolean()
|
|
4299
4310
|
.optional()
|
|
4300
4311
|
.describe("Grok --restore-code: check out the original session commit when resuming."),
|
|
4312
|
+
leaderSocket: z
|
|
4313
|
+
.string()
|
|
4314
|
+
.min(1)
|
|
4315
|
+
.optional()
|
|
4316
|
+
.describe("Grok 0.2.32+ --leader-socket <PATH>: custom leader socket path (default ~/.grok/leader.sock). Targets an isolated leader process, e.g. a local/branch Grok build; name it ~/.grok/leader-*.sock to keep `grok leader list/kill` discovery working."),
|
|
4301
4317
|
nativeWorktree: z
|
|
4302
4318
|
.union([z.boolean(), z.string().min(1)])
|
|
4303
4319
|
.optional()
|
|
4304
4320
|
.describe("Grok -w/--worktree: native CLI worktree flag (`true` → bare `--worktree`, string → named). NOT gateway slice λ `worktree`."),
|
|
4305
4321
|
worktree: WORKTREE_SCHEMA.optional(),
|
|
4306
|
-
}, async ({ prompt, promptParts, model, outputFormat, sessionId, resumeLatest, createNewSession, alwaysApprove, permissionMode, effort, reasoningEffort, approvalStrategy, approvalPolicy, mcpServers, allowedTools, disallowedTools, correlationId, optimizePrompt, idleTimeoutMs, forceRefresh, maxTurns, workingDir, sandbox, rules, systemPromptOverride, allow, deny, compactionMode, compactionDetail, agent, bestOfN, check, disableWebSearch, todoGate, verbatim, agents, promptFile, promptJson, single, experimentalMemory, noAltScreen, noMemory, noPlan, noSubagents, oauth, restoreCode, nativeWorktree, worktree, }) => {
|
|
4322
|
+
}, async ({ prompt, promptParts, model, outputFormat, sessionId, resumeLatest, createNewSession, alwaysApprove, permissionMode, effort, reasoningEffort, approvalStrategy, approvalPolicy, mcpServers, allowedTools, disallowedTools, correlationId, optimizePrompt, idleTimeoutMs, forceRefresh, maxTurns, workingDir, sandbox, rules, systemPromptOverride, allow, deny, compactionMode, compactionDetail, agent, bestOfN, check, disableWebSearch, todoGate, verbatim, agents, promptFile, promptJson, single, experimentalMemory, noAltScreen, noMemory, noPlan, noSubagents, oauth, restoreCode, leaderSocket, nativeWorktree, worktree, }) => {
|
|
4307
4323
|
return handleGrokRequestAsync({ sessionManager, asyncJobManager, logger, runtime }, {
|
|
4308
4324
|
prompt,
|
|
4309
4325
|
promptParts,
|
|
@@ -4351,6 +4367,7 @@ export function createGatewayServer(deps = {}) {
|
|
|
4351
4367
|
noSubagents,
|
|
4352
4368
|
oauth,
|
|
4353
4369
|
restoreCode,
|
|
4370
|
+
leaderSocket,
|
|
4354
4371
|
nativeWorktree,
|
|
4355
4372
|
worktree,
|
|
4356
4373
|
});
|
|
@@ -5,6 +5,7 @@ export interface CliFlagContract {
|
|
|
5
5
|
values?: readonly string[];
|
|
6
6
|
pattern?: RegExp;
|
|
7
7
|
description: string;
|
|
8
|
+
hiddenFromHelp?: boolean;
|
|
8
9
|
}
|
|
9
10
|
export interface CliUpstreamMetadata {
|
|
10
11
|
sourceUrls: readonly string[];
|
|
@@ -32,6 +33,7 @@ export interface CliContract {
|
|
|
32
33
|
resumeMaxPositionals?: number;
|
|
33
34
|
resumeOnlyFlags?: readonly string[];
|
|
34
35
|
resumeForbiddenFlags?: readonly string[];
|
|
36
|
+
acknowledgedUpstreamFlags?: readonly string[];
|
|
35
37
|
upstreamMetadata?: CliUpstreamMetadata;
|
|
36
38
|
}
|
|
37
39
|
export interface CliContractFixture {
|
|
@@ -57,6 +59,13 @@ export declare function assertUpstreamCliArgs(cli: CliType, args: readonly strin
|
|
|
57
59
|
export declare function validateUpstreamCliEnv(cli: CliType, env: Record<string, string> | undefined): ContractValidationResult;
|
|
58
60
|
export declare function assertUpstreamCliEnv(cli: CliType, env: Record<string, string> | undefined): void;
|
|
59
61
|
export declare function extractDiscoveredFlags(helpText: string): readonly string[];
|
|
62
|
+
export interface FlagDriftResult {
|
|
63
|
+
missingFlags: string[];
|
|
64
|
+
extraFlags: readonly string[];
|
|
65
|
+
acknowledgedExtraFlags: readonly string[];
|
|
66
|
+
warnings: string[];
|
|
67
|
+
}
|
|
68
|
+
export declare function computeFlagDrift(contract: CliContract, helpText: string, discoveredFlags: readonly string[]): FlagDriftResult;
|
|
60
69
|
export interface InstalledCliContractProbe {
|
|
61
70
|
cli: CliType;
|
|
62
71
|
executable: string;
|
|
@@ -66,6 +75,7 @@ export interface InstalledCliContractProbe {
|
|
|
66
75
|
checkedHelpCommands: string[][];
|
|
67
76
|
missingFlags: string[];
|
|
68
77
|
extraFlags: readonly string[];
|
|
78
|
+
acknowledgedExtraFlags: readonly string[];
|
|
69
79
|
discoveredFlags: readonly string[];
|
|
70
80
|
helpHash?: string;
|
|
71
81
|
versionHint?: string;
|
|
@@ -99,7 +99,12 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
99
99
|
pattern: /^[0-9]+(?:\.[0-9]+)?$/,
|
|
100
100
|
description: "Budget cap in USD",
|
|
101
101
|
},
|
|
102
|
-
"--max-turns": {
|
|
102
|
+
"--max-turns": {
|
|
103
|
+
arity: "one",
|
|
104
|
+
pattern: /^[1-9][0-9]*$/,
|
|
105
|
+
description: "Turn cap",
|
|
106
|
+
hiddenFromHelp: true,
|
|
107
|
+
},
|
|
103
108
|
"--effort": { arity: "one", values: EFFORT_LEVELS, description: "Reasoning effort" },
|
|
104
109
|
"--exclude-dynamic-system-prompt-sections": {
|
|
105
110
|
arity: "none",
|
|
@@ -136,6 +141,37 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
136
141
|
description: 'Restrict the available built-in tool set ("" disables all)',
|
|
137
142
|
},
|
|
138
143
|
},
|
|
144
|
+
acknowledgedUpstreamFlags: [
|
|
145
|
+
"--allow-dangerously-skip-permissions",
|
|
146
|
+
"--allowed",
|
|
147
|
+
"--bare",
|
|
148
|
+
"--betas",
|
|
149
|
+
"--brief",
|
|
150
|
+
"--chrome",
|
|
151
|
+
"--dangerously-skip-permissions",
|
|
152
|
+
"--debug",
|
|
153
|
+
"--debug-file",
|
|
154
|
+
"--disable-slash-commands",
|
|
155
|
+
"--disallowed",
|
|
156
|
+
"--file",
|
|
157
|
+
"--from-pr",
|
|
158
|
+
"--ide",
|
|
159
|
+
"--include-hook-events",
|
|
160
|
+
"--mcp-debug",
|
|
161
|
+
"--name",
|
|
162
|
+
"--no-chrome",
|
|
163
|
+
"--plugin-dir",
|
|
164
|
+
"--plugin-url",
|
|
165
|
+
"--print",
|
|
166
|
+
"--prompt-suggestions",
|
|
167
|
+
"--remote-control",
|
|
168
|
+
"--remote-control-session-name-prefix",
|
|
169
|
+
"--replay-user-messages",
|
|
170
|
+
"--resume",
|
|
171
|
+
"--tmux",
|
|
172
|
+
"--version",
|
|
173
|
+
"--worktree",
|
|
174
|
+
],
|
|
139
175
|
env: {},
|
|
140
176
|
conformanceFixtures: [
|
|
141
177
|
{
|
|
@@ -518,6 +554,26 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
518
554
|
description: "Auto-approve all actions (gemini -y/--yolo). Functionally equivalent to --approval-mode yolo; the gateway emits at most one of the two.",
|
|
519
555
|
},
|
|
520
556
|
},
|
|
557
|
+
acknowledgedUpstreamFlags: [
|
|
558
|
+
"--accept-raw-output-risk",
|
|
559
|
+
"--acp",
|
|
560
|
+
"--debug",
|
|
561
|
+
"--delete-session",
|
|
562
|
+
"--experimental-acp",
|
|
563
|
+
"--extensions",
|
|
564
|
+
"--list-extensions",
|
|
565
|
+
"--list-sessions",
|
|
566
|
+
"--output-format",
|
|
567
|
+
"--prompt",
|
|
568
|
+
"--prompt-interactive",
|
|
569
|
+
"--raw-output",
|
|
570
|
+
"--sandbox",
|
|
571
|
+
"--screen-reader",
|
|
572
|
+
"--session-file",
|
|
573
|
+
"--session-id",
|
|
574
|
+
"--version",
|
|
575
|
+
"--worktree",
|
|
576
|
+
],
|
|
521
577
|
env: {},
|
|
522
578
|
conformanceFixtures: [
|
|
523
579
|
{
|
|
@@ -612,6 +668,7 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
612
668
|
"noSubagents",
|
|
613
669
|
"oauth",
|
|
614
670
|
"restoreCode",
|
|
671
|
+
"leaderSocket",
|
|
615
672
|
"nativeWorktree",
|
|
616
673
|
],
|
|
617
674
|
flags: {
|
|
@@ -693,6 +750,10 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
693
750
|
arity: "none",
|
|
694
751
|
description: "Check out the original session commit when resuming",
|
|
695
752
|
},
|
|
753
|
+
"--leader-socket": {
|
|
754
|
+
arity: "one",
|
|
755
|
+
description: "Custom leader socket path (isolated leader, Grok 0.2.32+)",
|
|
756
|
+
},
|
|
696
757
|
"--single": { arity: "one", description: "Single-turn prompt" },
|
|
697
758
|
"--todo-gate": { arity: "none", description: "Enable runtime turn-end TodoGate" },
|
|
698
759
|
"--verbatim": { arity: "none", description: "Send prompt exactly as given" },
|
|
@@ -843,6 +904,18 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
843
904
|
],
|
|
844
905
|
expect: "pass",
|
|
845
906
|
},
|
|
907
|
+
{
|
|
908
|
+
id: "grok-leader-socket",
|
|
909
|
+
description: "Grok 0.2.32: --leader-socket <PATH> is accepted",
|
|
910
|
+
args: ["-p", "hello", "--leader-socket", "/home/user/.grok/leader-branch.sock"],
|
|
911
|
+
expect: "pass",
|
|
912
|
+
},
|
|
913
|
+
{
|
|
914
|
+
id: "grok-leader-socket-missing-value",
|
|
915
|
+
description: "Grok 0.2.32: --leader-socket without a path is rejected (arity one)",
|
|
916
|
+
args: ["-p", "hello", "--leader-socket"],
|
|
917
|
+
expect: "fail",
|
|
918
|
+
},
|
|
846
919
|
],
|
|
847
920
|
},
|
|
848
921
|
mistral: {
|
|
@@ -1220,6 +1293,42 @@ export function extractDiscoveredFlags(helpText) {
|
|
|
1220
1293
|
}
|
|
1221
1294
|
return Array.from(discovered).sort();
|
|
1222
1295
|
}
|
|
1296
|
+
export function computeFlagDrift(contract, helpText, discoveredFlags) {
|
|
1297
|
+
const warnings = [];
|
|
1298
|
+
const missingFlags = [];
|
|
1299
|
+
for (const [flag, spec] of Object.entries(contract.flags)) {
|
|
1300
|
+
const inHelp = helpText.includes(flag);
|
|
1301
|
+
if (spec.hiddenFromHelp) {
|
|
1302
|
+
if (inHelp) {
|
|
1303
|
+
warnings.push(`${flag} is marked hiddenFromHelp but now appears in ${contract.executable} help output; remove the hiddenFromHelp marker from the contract`);
|
|
1304
|
+
}
|
|
1305
|
+
continue;
|
|
1306
|
+
}
|
|
1307
|
+
if (!inHelp)
|
|
1308
|
+
missingFlags.push(flag);
|
|
1309
|
+
}
|
|
1310
|
+
const contractFlagSet = new Set(Object.keys(contract.flags));
|
|
1311
|
+
const acknowledged = new Set(contract.acknowledgedUpstreamFlags ?? []);
|
|
1312
|
+
const extraFlags = [];
|
|
1313
|
+
const acknowledgedExtraFlags = [];
|
|
1314
|
+
for (const flag of discoveredFlags) {
|
|
1315
|
+
if (contractFlagSet.has(flag))
|
|
1316
|
+
continue;
|
|
1317
|
+
if (acknowledged.has(flag)) {
|
|
1318
|
+
acknowledgedExtraFlags.push(flag);
|
|
1319
|
+
}
|
|
1320
|
+
else {
|
|
1321
|
+
extraFlags.push(flag);
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
const discoveredSet = new Set(discoveredFlags);
|
|
1325
|
+
for (const flag of acknowledged) {
|
|
1326
|
+
if (!discoveredSet.has(flag)) {
|
|
1327
|
+
warnings.push(`acknowledged upstream flag ${flag} no longer appears in ${contract.executable} help output; remove it from acknowledgedUpstreamFlags`);
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
return { missingFlags, extraFlags, acknowledgedExtraFlags, warnings };
|
|
1331
|
+
}
|
|
1223
1332
|
export function probeInstalledCliContract(cli, timeoutMs = 5_000) {
|
|
1224
1333
|
const contract = UPSTREAM_CLI_CONTRACTS[cli];
|
|
1225
1334
|
const outputs = [];
|
|
@@ -1252,6 +1361,7 @@ export function probeInstalledCliContract(cli, timeoutMs = 5_000) {
|
|
|
1252
1361
|
checkedHelpCommands: contract.helpArgs,
|
|
1253
1362
|
missingFlags: [],
|
|
1254
1363
|
extraFlags: [],
|
|
1364
|
+
acknowledgedExtraFlags: [],
|
|
1255
1365
|
discoveredFlags: [],
|
|
1256
1366
|
helpHash: undefined,
|
|
1257
1367
|
versionHint: undefined,
|
|
@@ -1265,10 +1375,9 @@ export function probeInstalledCliContract(cli, timeoutMs = 5_000) {
|
|
|
1265
1375
|
}
|
|
1266
1376
|
}
|
|
1267
1377
|
const helpText = outputs.join("\n");
|
|
1268
|
-
const missingFlags = Object.keys(contract.flags).filter(flag => !helpText.includes(flag));
|
|
1269
1378
|
const discoveredFlags = extractDiscoveredFlags(helpText);
|
|
1270
|
-
const
|
|
1271
|
-
|
|
1379
|
+
const drift = computeFlagDrift(contract, helpText, discoveredFlags);
|
|
1380
|
+
warnings.push(...drift.warnings);
|
|
1272
1381
|
const versionMatch = helpText.match(/^\s*(?:[A-Za-z][\w .-]+)?v?\d+\.\d+\S*/m);
|
|
1273
1382
|
const versionHint = versionMatch ? versionMatch[0].trim().slice(0, 80) : undefined;
|
|
1274
1383
|
const helpHash = createHash("sha256").update(helpText).digest("hex");
|
|
@@ -1279,8 +1388,9 @@ export function probeInstalledCliContract(cli, timeoutMs = 5_000) {
|
|
|
1279
1388
|
resolvedArgs,
|
|
1280
1389
|
available: true,
|
|
1281
1390
|
checkedHelpCommands: contract.helpArgs,
|
|
1282
|
-
missingFlags,
|
|
1283
|
-
extraFlags,
|
|
1391
|
+
missingFlags: drift.missingFlags,
|
|
1392
|
+
extraFlags: drift.extraFlags,
|
|
1393
|
+
acknowledgedExtraFlags: drift.acknowledgedExtraFlags,
|
|
1284
1394
|
discoveredFlags,
|
|
1285
1395
|
helpHash,
|
|
1286
1396
|
versionHint,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "llm-cli-gateway",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
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",
|