llm-cli-gateway 1.16.2 → 1.17.1

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 CHANGED
@@ -4,6 +4,48 @@ All notable changes to the llm-cli-gateway project.
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## [1.17.1] - 2026-05-30 — Socket shell-access suppression
8
+
9
+ Patch release updating the package's Socket policy for the reviewed gateway
10
+ process-launching capability.
11
+
12
+ ### Changed
13
+
14
+ - Suppressed Socket's `shellAccess` alert in `socket.yml` now that the
15
+ child-process surface is documented and release-audited.
16
+ - Updated README Socket-alert wording so reviewers still get the bounded
17
+ shell-access rationale without seeing the same package alert on every release.
18
+
19
+ ## [1.17.0] - 2026-05-30 — upstream provider tracking
20
+
21
+ Feature release adding repeatable upstream-provider contract tracking for the
22
+ gateway's supported CLIs.
23
+
24
+ ### Added
25
+
26
+ - Added provider-specific maintenance skills for Claude Code, Codex, Gemini,
27
+ Grok, and Mistral Vibe.
28
+ - Added upstream source metadata to the CLI contract table and mirrored it into
29
+ `docs/upstream/provider-sources.dag.toml`.
30
+ - Added `scripts/upstream-scan.mjs` plus `npm run upstream:contracts` and
31
+ `npm run upstream:scan` for offline contract checks and advisory live source
32
+ scans.
33
+ - Added upstream source tests covering contract/TOML synchronization.
34
+
35
+ ### Changed
36
+
37
+ - Pointed Claude Code tracking at the markdown changelog, Codex tracking at the
38
+ GitHub releases feed plus product changelog, Gemini tracking at the Gemini CLI
39
+ changelog plus GitHub releases, and Grok tracking at the markdown xAI release
40
+ notes.
41
+ - Ignored local-only agent/worktree artifacts that should not enter source
42
+ control.
43
+
44
+ ### Fixed
45
+
46
+ - Fixed the `maxTokens` request schema so token budgets no longer reuse the
47
+ `maxTurns` limit.
48
+
7
49
  ## [1.16.2] - 2026-05-29 — release formatting follow-up
8
50
 
9
51
  Patch release that keeps the Mistral Vibe CLI contract fixes from `1.16.1`
package/README.md CHANGED
@@ -1176,7 +1176,7 @@ The gateway supports concurrent requests across different CLIs. Each request spa
1176
1176
 
1177
1177
  ### Socket alerts — context for reviewers
1178
1178
 
1179
- If you're vetting `llm-cli-gateway` through [Socket](https://socket.dev/npm/package/llm-cli-gateway) or a similar supply-chain scanner, you'll see three behavioural alerts and some dependency-ownership alerts. They are accurate descriptions of what the package does and what it depends on; we've left them visible (not silenced in `socket.yml`) so you don't have to take our word for it. Here's the context for each:
1179
+ If you're vetting `llm-cli-gateway` through [Socket](https://socket.dev/npm/package/llm-cli-gateway) or a similar supply-chain scanner, you'll see behavioural alerts and some dependency-ownership alerts. They are accurate descriptions of what the package does and what it depends on. The reviewed `shellAccess` capability is suppressed in `socket.yml` to avoid a repeat finding on every release; the rationale remains documented here and in the package.
1180
1180
 
1181
1181
  | Alert | Where | Why it's bounded |
1182
1182
  | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
package/dist/index.d.ts CHANGED
@@ -66,6 +66,7 @@ type GatewayLogger = typeof logger;
66
66
  * upper bound — no plausible single agent loop exceeds 10k turns or 10k USD.
67
67
  */
68
68
  export declare const MAX_TURNS_SCHEMA: z.ZodNumber;
69
+ export declare const MAX_TOKENS_SCHEMA: z.ZodNumber;
69
70
  export declare const MAX_PRICE_SCHEMA: z.ZodNumber;
70
71
  /**
71
72
  * Slice λ: shared worktree directive for all 10 `*_request` / `*_request_async`
package/dist/index.js CHANGED
@@ -242,6 +242,10 @@ const MCP_SERVER_ENUM = z.enum(CLAUDE_MCP_SERVER_NAMES);
242
242
  * upper bound — no plausible single agent loop exceeds 10k turns or 10k USD.
243
243
  */
244
244
  export const MAX_TURNS_SCHEMA = z.number().int().positive().safe().max(10_000);
245
+ // Token budgets can legitimately exceed the agent-turn cap by orders of
246
+ // magnitude. Keep a finite operational guardrail while avoiding the 10k turn
247
+ // ceiling that would make large-context Vibe sessions unusable.
248
+ export const MAX_TOKENS_SCHEMA = z.number().int().positive().safe().max(100_000_000);
245
249
  // `.min(1e-6)` keeps the value in JS's decimal-stringify range:
246
250
  // String(1e-6) === "0.000001" but String(1e-7) === "1e-7", which both
247
251
  // upstream CLIs would reject. 1µUSD per request is fine-grained enough
@@ -3826,7 +3830,7 @@ export function createGatewayServer(deps = {}) {
3826
3830
  .describe("Emit `--trust` so Vibe trusts the cwd for this invocation only (not persisted to trusted_folders.toml) and skips the interactive trust prompt (Phase 4 slice γ)."),
3827
3831
  maxTurns: MAX_TURNS_SCHEMA.optional().describe("Vibe `--max-turns N`: cap the agent-loop iteration count (programmatic mode only, Phase 4 slice δ). Bounded to safe integers ≤ 10000."),
3828
3832
  maxPrice: MAX_PRICE_SCHEMA.optional().describe("Vibe `--max-price DOLLARS`: interrupt the session when cumulative cost crosses this cap (programmatic mode only, Phase 4 slice δ). Bounded to finite values ≤ 10000 USD."),
3829
- maxTokens: MAX_TURNS_SCHEMA.optional().describe("Vibe `--max-tokens N`: cap cumulative prompt + completion tokens for the session (programmatic mode only). Bounded to safe integers ≤ 10000."),
3833
+ maxTokens: MAX_TOKENS_SCHEMA.optional().describe("Vibe `--max-tokens N`: cap cumulative prompt + completion tokens for the session (programmatic mode only). Bounded to safe integers ≤ 100000000."),
3830
3834
  // Phase 4 slice ζ — Vibe working-directory + additional-dirs parity.
3831
3835
  workingDir: z
3832
3836
  .string()
@@ -4548,7 +4552,7 @@ export function createGatewayServer(deps = {}) {
4548
4552
  .describe("Emit `--trust` so Vibe trusts the cwd for this invocation only (not persisted to trusted_folders.toml) and skips the interactive trust prompt (Phase 4 slice γ)."),
4549
4553
  maxTurns: MAX_TURNS_SCHEMA.optional().describe("Vibe `--max-turns N`: cap the agent-loop iteration count (programmatic mode only, Phase 4 slice δ). Bounded to safe integers ≤ 10000."),
4550
4554
  maxPrice: MAX_PRICE_SCHEMA.optional().describe("Vibe `--max-price DOLLARS`: interrupt the session when cumulative cost crosses this cap (programmatic mode only, Phase 4 slice δ). Bounded to finite values ≤ 10000 USD."),
4551
- maxTokens: MAX_TURNS_SCHEMA.optional().describe("Vibe `--max-tokens N`: cap cumulative prompt + completion tokens for the session (programmatic mode only). Bounded to safe integers ≤ 10000."),
4555
+ maxTokens: MAX_TOKENS_SCHEMA.optional().describe("Vibe `--max-tokens N`: cap cumulative prompt + completion tokens for the session (programmatic mode only). Bounded to safe integers ≤ 100000000."),
4552
4556
  // Phase 4 slice ζ — Vibe working-directory + additional-dirs parity.
4553
4557
  workingDir: z
4554
4558
  .string()
@@ -13,6 +13,43 @@ export interface CliFlagContract {
13
13
  pattern?: RegExp;
14
14
  description: string;
15
15
  }
16
+ /**
17
+ * Pure upstream-tracking metadata for a provider CLI.
18
+ *
19
+ * IMPORTANT — non-duplication invariant: nothing here encodes mechanical
20
+ * behaviour. Flags, output modes, session/resume rules, permission modes,
21
+ * forbidden flags, env contracts, and positional limits live ONLY in the
22
+ * surrounding {@link CliContract} and are validated ONLY by
23
+ * {@link validateUpstreamCliArgs} / {@link validateUpstreamCliEnv}. The fields
24
+ * below are descriptive pointers used by the upstream changelog scanner
25
+ * (`scripts/upstream-scan.mjs`) and surfaced in the contract report — they
26
+ * never drive argv/env enforcement.
27
+ *
28
+ * `docs/upstream/provider-sources.dag.toml` mirrors `sourceUrls` and
29
+ * `watchCategories` for the scanner's offline scan plan; a unit test
30
+ * (`upstream-sources.test.ts`) asserts the TOML stays in sync with these
31
+ * fields so the two cannot drift. The TypeScript values here are authoritative;
32
+ * the TOML is scanner input only and is never consulted for contract
33
+ * enforcement.
34
+ */
35
+ export interface CliUpstreamMetadata {
36
+ /** Canonical changelog / release-notes URLs the scanner fetches with --live. */
37
+ sourceUrls: readonly string[];
38
+ /** Distribution package identifier (npm package name, PyPI project, …). */
39
+ packageName?: string;
40
+ /** Source repository URL, when distinct from the changelog source. */
41
+ repo?: string;
42
+ /** Human-facing install / getting-started docs. */
43
+ installDocsUrl?: string;
44
+ /** Distribution channel the gateway expects the CLI to ship through. */
45
+ releaseChannel?: "npm" | "pypi" | "github-release" | "vendor";
46
+ /**
47
+ * Contract surfaces worth watching in upstream release notes (e.g. "flags",
48
+ * "output-formats", "session-resume"). Descriptive labels for the scanner and
49
+ * report ONLY — never a validation input.
50
+ */
51
+ watchCategories: readonly string[];
52
+ }
16
53
  export interface CliContract {
17
54
  cli: CliType;
18
55
  executable: string;
@@ -31,6 +68,8 @@ export interface CliContract {
31
68
  resumeMaxPositionals?: number;
32
69
  resumeOnlyFlags?: readonly string[];
33
70
  resumeForbiddenFlags?: readonly string[];
71
+ /** Non-mechanical upstream-tracking metadata. See {@link CliUpstreamMetadata}. */
72
+ upstreamMetadata?: CliUpstreamMetadata;
34
73
  }
35
74
  export interface CliContractFixture {
36
75
  id: string;
@@ -14,6 +14,13 @@ export const UPSTREAM_CLI_CONTRACTS = {
14
14
  cli: "claude",
15
15
  executable: "claude",
16
16
  upstream: "Claude Code CLI",
17
+ upstreamMetadata: {
18
+ sourceUrls: ["https://code.claude.com/docs/en/changelog.md"],
19
+ packageName: "@anthropic-ai/claude-code",
20
+ installDocsUrl: "https://code.claude.com/docs/en/overview",
21
+ releaseChannel: "npm",
22
+ watchCategories: ["flags", "output-formats", "permission-modes", "session-resume", "models"],
23
+ },
17
24
  helpArgs: [["--help"]],
18
25
  maxPositionals: 0,
19
26
  mcpTools: ["claude_request", "claude_request_async"],
@@ -197,6 +204,23 @@ export const UPSTREAM_CLI_CONTRACTS = {
197
204
  cli: "codex",
198
205
  executable: "codex",
199
206
  upstream: "OpenAI Codex CLI",
207
+ upstreamMetadata: {
208
+ sourceUrls: [
209
+ "https://github.com/openai/codex/releases",
210
+ "https://developers.openai.com/codex/changelog",
211
+ ],
212
+ packageName: "@openai/codex",
213
+ repo: "https://github.com/openai/codex",
214
+ installDocsUrl: "https://developers.openai.com/codex/cli",
215
+ releaseChannel: "npm",
216
+ watchCategories: [
217
+ "flags",
218
+ "sandbox-modes",
219
+ "approval-modes",
220
+ "session-resume",
221
+ "output-schema",
222
+ ],
223
+ },
200
224
  helpArgs: [
201
225
  ["exec", "--help"],
202
226
  ["exec", "resume", "--help"],
@@ -343,6 +367,17 @@ export const UPSTREAM_CLI_CONTRACTS = {
343
367
  cli: "gemini",
344
368
  executable: "gemini",
345
369
  upstream: "Google Gemini CLI",
370
+ upstreamMetadata: {
371
+ sourceUrls: [
372
+ "https://geminicli.com/docs/changelogs/",
373
+ "https://github.com/google-gemini/gemini-cli/releases",
374
+ ],
375
+ packageName: "@google/gemini-cli",
376
+ repo: "https://github.com/google-gemini/gemini-cli",
377
+ installDocsUrl: "https://geminicli.com/docs/",
378
+ releaseChannel: "npm",
379
+ watchCategories: ["flags", "approval-modes", "output-formats", "session-resume"],
380
+ },
346
381
  helpArgs: [["--help"]],
347
382
  maxPositionals: 0,
348
383
  mcpTools: ["gemini_request", "gemini_request_async"],
@@ -428,6 +463,12 @@ export const UPSTREAM_CLI_CONTRACTS = {
428
463
  cli: "grok",
429
464
  executable: "grok",
430
465
  upstream: "xAI Grok CLI",
466
+ upstreamMetadata: {
467
+ sourceUrls: ["https://docs.x.ai/developers/release-notes.md"],
468
+ installDocsUrl: "https://docs.x.ai/build/overview",
469
+ releaseChannel: "vendor",
470
+ watchCategories: ["flags", "permission-modes", "session-resume", "sandbox", "output-formats"],
471
+ },
431
472
  helpArgs: [["--help"]],
432
473
  maxPositionals: 0,
433
474
  mcpTools: ["grok_request", "grok_request_async"],
@@ -582,6 +623,14 @@ export const UPSTREAM_CLI_CONTRACTS = {
582
623
  cli: "mistral",
583
624
  executable: "vibe",
584
625
  upstream: "Mistral Vibe CLI",
626
+ upstreamMetadata: {
627
+ sourceUrls: ["https://github.com/mistralai/mistral-vibe/releases"],
628
+ packageName: "mistral-vibe",
629
+ repo: "https://github.com/mistralai/mistral-vibe",
630
+ installDocsUrl: "https://github.com/mistralai/mistral-vibe#installation",
631
+ releaseChannel: "pypi",
632
+ watchCategories: ["flags", "agent-modes", "session-logging", "output-formats", "env-model"],
633
+ },
585
634
  helpArgs: [["--help"]],
586
635
  maxPositionals: 0,
587
636
  mcpTools: ["mistral_request", "mistral_request_async"],
@@ -960,6 +1009,19 @@ export function buildUpstreamContractReport(options = {}) {
960
1009
  {
961
1010
  executable: contract.executable,
962
1011
  upstream: contract.upstream,
1012
+ // Pure metadata pointers (changelog URLs, package name, watch
1013
+ // categories). Enriched from the CliContract — the single source of
1014
+ // truth — so report consumers and the scanner read the same values.
1015
+ upstreamMetadata: contract.upstreamMetadata
1016
+ ? {
1017
+ sourceUrls: contract.upstreamMetadata.sourceUrls,
1018
+ packageName: contract.upstreamMetadata.packageName ?? null,
1019
+ repo: contract.upstreamMetadata.repo ?? null,
1020
+ installDocsUrl: contract.upstreamMetadata.installDocsUrl ?? null,
1021
+ releaseChannel: contract.upstreamMetadata.releaseChannel ?? null,
1022
+ watchCategories: contract.upstreamMetadata.watchCategories,
1023
+ }
1024
+ : null,
963
1025
  command: contract.command ?? null,
964
1026
  helpArgs: contract.helpArgs,
965
1027
  mcpTools: contract.mcpTools,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "llm-cli-gateway",
3
- "version": "1.16.2",
3
+ "version": "1.17.1",
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",
@@ -71,6 +71,8 @@
71
71
  "test:pg": "bash ./scripts/test-pg.sh",
72
72
  "test:all": "npm run test && npm run test:pg",
73
73
  "smoke:cache-control": "node docs/plans/slice-kappa-smoke-test.mjs",
74
+ "upstream:contracts": "node scripts/upstream-scan.mjs --contracts-check",
75
+ "upstream:scan": "node scripts/upstream-scan.mjs",
74
76
  "lint": "eslint src/**/*.ts",
75
77
  "lint:fix": "eslint src/**/*.ts --fix",
76
78
  "format": "prettier --write 'src/**/*.ts'",
package/socket.yml CHANGED
@@ -2,11 +2,9 @@ version: 2
2
2
 
3
3
  # Socket alerts on llm-cli-gateway
4
4
  # ---------------------------------
5
- # This package intentionally triggers three of Socket's behavioural alerts.
6
- # We do NOT disable them they are accurate descriptions of what the package
7
- # does, and silencing them would hide useful signal from anyone evaluating
8
- # this dependency. The rationale for each is documented inline below and in
9
- # detail under "Security Considerations" in README.md.
5
+ # This package intentionally triggers behavioural alerts. They are accurate
6
+ # descriptions of what the package does; the rationale for each is documented
7
+ # inline below and in detail under "Security Considerations" in README.md.
10
8
  #
11
9
  # networkAccess
12
10
  # src/http-transport.ts opens an HTTP MCP transport (createServer/listen).
@@ -22,11 +20,37 @@ version: 2
22
20
  # (SQLite, sessions.json) or explicit local CLI process I/O.
23
21
  #
24
22
  # shellAccess
25
- # src/executor.ts uses child_process.spawn(cmd, args, { ... }) with a
26
- # fixed allow-list of CLI binaries (claude / codex / gemini / grok /
27
- # vibe). shell:true is never set; arguments are passed as an array, so
28
- # there is no shell interpolation path for user input. Spawning these
29
- # CLIs is the entire purpose of the package.
23
+ # This alert fires on every module that imports node:child_process, and
24
+ # because spawning provider CLIs and git is the entire purpose of the package
25
+ # it is a reviewed capability description, not a finding. As of v1.17.1 this
26
+ # specific reviewed alert is suppressed via `issueRules.shellAccess: false`
27
+ # to avoid noisy repeat findings on every release.
28
+ #
29
+ # INVARIANT enforced across ALL sites below: arguments are always passed
30
+ # as an array and `shell: true` is NEVER set, so there is no shell
31
+ # interpolation path for user input. `scripts/release-security-audit.sh`
32
+ # guards the dynamic-execution surface. When you add a new module that
33
+ # imports child_process, add it to this list so the alert location set
34
+ # stays documented instead of reading like a regression.
35
+ #
36
+ # Current production child_process sites (dist/*.js mirrors of src/*.ts):
37
+ # - src/executor.ts spawn(cmd, args) — provider CLI allow-list
38
+ # (claude / codex / gemini / grok / vibe).
39
+ # - src/worktree-manager.ts spawn("git", args) — gateway-owned git
40
+ # worktree lifecycle (add / list / prune /
41
+ # remove / branch -D).
42
+ # - src/cli-updater.ts spawnSync(cmd, args) — provider CLI version
43
+ # + upgrade checks.
44
+ # - src/provider-status.ts spawnSync(cmd, args) — provider login-status
45
+ # probe.
46
+ # - src/upstream-contracts.ts spawnSync(cmd, ["--help"]) — optional
47
+ # installed-CLI contract probe.
48
+ # - src/endpoint-exposure.ts spawnSync(process.execPath, ["-e", …]) —
49
+ # out-of-process HEAD reachability probe
50
+ # (opt-in via the start:http path only).
51
+ # - src/async-job-manager.ts imports the ChildProcess *type* only for
52
+ # job lifecycle tracking; it spawns via
53
+ # executor.ts (spawnCliProcess), not directly.
30
54
  #
31
55
  # usesEval
32
56
  # Not in our source. Transitive via @modelcontextprotocol/sdk → ajv@8,
@@ -40,16 +64,6 @@ version: 2
40
64
  # gateway does not call db.pragma() from production code; SQLite setup
41
65
  # uses fixed literal db.exec("PRAGMA ...") statements, and the release
42
66
  # security audit fails future production `.pragma()` calls.
43
- #
44
- # ioredis obfuscated code / base64 strings
45
- # Socket may flag ioredis@5.10.1 built/constants/TLSProfiles.js because it
46
- # contains base64-looking strings. This is a reviewed false positive: the
47
- # strings are PEM-encoded Redis Cloud TLS CA certificates. The file exports
48
- # static TLS profile data only; it contains no decoder loop, dynamic eval,
49
- # network call, or hidden execution path. The same file is byte-for-byte
50
- # identical in ioredis@5.9.2. ioredis is not installed by the default
51
- # production dependency tree; it is an optional peer for PostgreSQL/Redis
52
- # session storage and a pinned dev dependency for tests.
53
67
 
54
68
  issueRules:
55
69
  # Defaults from Socket. Listed explicitly so future contributors see what
@@ -60,6 +74,7 @@ issueRules:
60
74
  installScripts: true
61
75
  telemetry: true
62
76
  hasNativeCode: true # better-sqlite3 — known and expected
77
+ shellAccess: false # reviewed gateway capability; see rationale above
63
78
  shellScriptOverride: true
64
79
  gitDependency: true
65
80
  httpDependency: true