llm-cli-gateway 2.15.0 → 2.16.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +50 -1
  2. package/dist/acp/process-manager.js +2 -1
  3. package/dist/acp/provider-registry.js +8 -8
  4. package/dist/async-job-manager.d.ts +4 -1
  5. package/dist/async-job-manager.js +15 -6
  6. package/dist/compressor/estimate.d.ts +5 -0
  7. package/dist/compressor/estimate.js +21 -0
  8. package/dist/compressor/index.d.ts +23 -0
  9. package/dist/compressor/index.js +77 -0
  10. package/dist/compressor/router.d.ts +2 -0
  11. package/dist/compressor/router.js +57 -0
  12. package/dist/compressor/transforms/ansi.d.ts +3 -0
  13. package/dist/compressor/transforms/ansi.js +89 -0
  14. package/dist/compressor/transforms/json.d.ts +1 -0
  15. package/dist/compressor/transforms/json.js +156 -0
  16. package/dist/compressor/transforms/log.d.ts +12 -0
  17. package/dist/compressor/transforms/log.js +55 -0
  18. package/dist/compressor/transforms/whitespace.d.ts +8 -0
  19. package/dist/compressor/transforms/whitespace.js +79 -0
  20. package/dist/config.d.ts +8 -0
  21. package/dist/config.js +25 -0
  22. package/dist/executor.d.ts +1 -0
  23. package/dist/executor.js +5 -2
  24. package/dist/flight-recorder.d.ts +9 -0
  25. package/dist/flight-recorder.js +42 -0
  26. package/dist/index.d.ts +18 -2
  27. package/dist/index.js +273 -66
  28. package/dist/job-store.d.ts +4 -0
  29. package/dist/job-store.js +16 -0
  30. package/dist/provider-definitions.d.ts +1 -0
  31. package/dist/provider-definitions.js +28 -10
  32. package/dist/provider-tool-capabilities.js +3 -3
  33. package/dist/request-helpers.js +1 -1
  34. package/dist/spawn-env-isolation.d.ts +10 -0
  35. package/dist/spawn-env-isolation.js +55 -0
  36. package/dist/upstream-contracts.js +47 -27
  37. package/npm-shrinkwrap.json +2 -2
  38. package/package.json +7 -3
@@ -10,6 +10,7 @@ export interface JobRecord {
10
10
  cli: string;
11
11
  argsJson: string;
12
12
  outputFormat?: string | null;
13
+ compressResponse?: boolean | null;
13
14
  status: JobStoreStatus;
14
15
  exitCode: number | null;
15
16
  stdout: string;
@@ -52,6 +53,7 @@ export interface JobStore {
52
53
  cli: string;
53
54
  args: string[];
54
55
  outputFormat?: string;
56
+ compressResponse?: boolean;
55
57
  startedAt: string;
56
58
  pid: number | null;
57
59
  ownerPrincipal?: string | null;
@@ -173,6 +175,7 @@ export declare class SqliteJobStore implements JobStore, ValidationRunStore {
173
175
  cli: string;
174
176
  args: string[];
175
177
  outputFormat?: string;
178
+ compressResponse?: boolean;
176
179
  startedAt: string;
177
180
  pid: number | null;
178
181
  ownerPrincipal?: string | null;
@@ -236,6 +239,7 @@ export declare class MemoryJobStore implements JobStore {
236
239
  cli: string;
237
240
  args: string[];
238
241
  outputFormat?: string;
242
+ compressResponse?: boolean;
239
243
  startedAt: string;
240
244
  pid: number | null;
241
245
  ownerPrincipal?: string | null;
package/dist/job-store.js CHANGED
@@ -51,6 +51,9 @@ function rowToRecord(row) {
51
51
  cli: row.cli,
52
52
  argsJson: row.args_json,
53
53
  outputFormat: row.output_format ?? null,
54
+ compressResponse: row.compress_response === null || row.compress_response === undefined
55
+ ? null
56
+ : Boolean(row.compress_response),
54
57
  status: row.status,
55
58
  exitCode: row.exit_code,
56
59
  stdout: row.stdout ?? "",
@@ -99,6 +102,13 @@ function ensureJobsLeaseColumns(db) {
99
102
  db.exec("ALTER TABLE jobs ADD COLUMN lease_deadline INTEGER");
100
103
  }
101
104
  }
105
+ function ensureJobsCompressResponseColumn(db) {
106
+ const cols = db.prepare("PRAGMA table_info(jobs)").all();
107
+ const names = new Set(cols.map(col => col?.name));
108
+ if (!names.has("compress_response")) {
109
+ db.exec("ALTER TABLE jobs ADD COLUMN compress_response INTEGER");
110
+ }
111
+ }
102
112
  export function isValidationRunStore(store) {
103
113
  return (typeof store === "object" &&
104
114
  store !== null &&
@@ -143,6 +153,7 @@ export class SqliteJobStore {
143
153
  cli TEXT NOT NULL,
144
154
  args_json TEXT NOT NULL,
145
155
  output_format TEXT,
156
+ compress_response INTEGER,
146
157
  status TEXT NOT NULL,
147
158
  exit_code INTEGER,
148
159
  stdout TEXT,
@@ -216,6 +227,7 @@ export class SqliteJobStore {
216
227
  ensureJobsTransportColumns(this.db);
217
228
  ensureJobsLeaseColumns(this.db);
218
229
  this.db.exec("CREATE INDEX IF NOT EXISTS idx_jobs_owner_status ON jobs(owner_instance, status)");
230
+ ensureJobsCompressResponseColumn(this.db);
219
231
  if (process.platform !== "win32") {
220
232
  try {
221
233
  chmodSync(dbPath, 0o600);
@@ -228,10 +240,12 @@ export class SqliteJobStore {
228
240
  this.leaseTtlMs = options.leaseTtlMs ?? DEFAULT_INSTANCE_LEASE_TTL_MS;
229
241
  this.insertStmt = this.db.prepare(`
230
242
  INSERT INTO jobs (id, correlation_id, request_key, cli, args_json, output_format,
243
+ compress_response,
231
244
  status, exit_code, stdout, stderr, output_truncated, error,
232
245
  started_at, finished_at, pid, expires_at, owner_principal,
233
246
  transport, http_status, payload_json, owner_instance, lease_deadline)
234
247
  VALUES (@id, @correlation_id, @request_key, @cli, @args_json, @output_format,
248
+ @compress_response,
235
249
  'queued', @exit_code, @stdout, @stderr, @output_truncated, @error,
236
250
  @started_at, @finished_at, @pid, @expires_at, @owner_principal,
237
251
  @transport, @http_status, @payload_json, @owner_instance,
@@ -332,6 +346,7 @@ export class SqliteJobStore {
332
346
  cli: input.cli,
333
347
  args_json: JSON.stringify(input.args),
334
348
  output_format: input.outputFormat ?? null,
349
+ compress_response: input.compressResponse === undefined ? null : input.compressResponse ? 1 : 0,
335
350
  exit_code: null,
336
351
  stdout: "",
337
352
  stderr: "",
@@ -624,6 +639,7 @@ export class MemoryJobStore {
624
639
  cli: input.cli,
625
640
  argsJson: JSON.stringify(input.args),
626
641
  outputFormat: input.outputFormat ?? null,
642
+ compressResponse: input.compressResponse ?? null,
627
643
  status: "queued",
628
644
  exitCode: null,
629
645
  stdout: "",
@@ -119,6 +119,7 @@ export interface ProviderDefinition {
119
119
  readonly upstreamContract: ProviderUpstreamLinkage;
120
120
  readonly capabilityScope: CapabilityScope;
121
121
  }
122
+ export declare const PROVIDER_TARGET_VERSIONS: Record<CliType, string>;
122
123
  export declare const PROVIDER_DEFINITIONS_BY_ID: Readonly<Record<CliType, ProviderDefinition>>;
123
124
  export declare function getAllProviderDefinitions(): readonly ProviderDefinition[];
124
125
  export declare function getProviderDefinition(id: CliType): ProviderDefinition;
@@ -4,6 +4,15 @@ export function adminSurfaceKind(family) {
4
4
  return family.kind ?? "cli-subcommand";
5
5
  }
6
6
  export const DEVIN_ACP_AGENT_TYPES = ["summarizer", "review"];
7
+ export const PROVIDER_TARGET_VERSIONS = {
8
+ claude: "claude 2.1.206",
9
+ codex: "codex-cli 0.144.1",
10
+ gemini: "agy 1.1.0",
11
+ grok: "grok 0.2.93 (f00f96316d)",
12
+ mistral: "vibe 2.19.1",
13
+ devin: "devin 3000.1.27 (0d4bf12e)",
14
+ cursor: "cursor-agent 2026.07.09-c59fd9a",
15
+ };
7
16
  const PROVIDER_DEFINITIONS = {
8
17
  claude: {
9
18
  id: "claude",
@@ -86,7 +95,7 @@ const PROVIDER_DEFINITIONS = {
86
95
  nativeEntrypoint: null,
87
96
  entrypoint: null,
88
97
  probeArgv: [],
89
- evidence: "No native Claude Code ACP subcommand or flag in installed help (claude 2.1.198) or the official CLI reference. Coverage is CLI-first; ACP reporting says no native entrypoint is advertised.",
98
+ evidence: `No native Claude Code ACP subcommand or flag in installed help (${PROVIDER_TARGET_VERSIONS.claude}) or the official CLI reference. Coverage is CLI-first; ACP reporting says no native entrypoint is advertised.`,
90
99
  },
91
100
  safetyModes: {
92
101
  sandbox: false,
@@ -98,7 +107,10 @@ const PROVIDER_DEFINITIONS = {
98
107
  outputFormats: ["text", "json", "stream-json"],
99
108
  streamingFormats: ["stream-json"],
100
109
  resourcePolicy: { exposesModelsResource: true, exposesSessionsResource: true },
101
- upstreamContract: { targetVersion: "Claude Code 2.1.198", helpChecksumRef: "claude--help.txt" },
110
+ upstreamContract: {
111
+ targetVersion: PROVIDER_TARGET_VERSIONS.claude,
112
+ helpChecksumRef: "claude--help.txt",
113
+ },
102
114
  capabilityScope: "full",
103
115
  },
104
116
  codex: {
@@ -215,7 +227,7 @@ const PROVIDER_DEFINITIONS = {
215
227
  nativeEntrypoint: null,
216
228
  entrypoint: null,
217
229
  probeArgv: [],
218
- evidence: "codex-cli 0.142.4 advertises mcp-server and app-server transports, not a native ACP agent entrypoint. Third-party adapters exist but are documentation only and are never treated as native gateway ACP.",
230
+ evidence: `${PROVIDER_TARGET_VERSIONS.codex} advertises mcp-server and app-server transports, not a native ACP agent entrypoint. Third-party adapters exist but are documentation only and are never treated as native gateway ACP.`,
219
231
  },
220
232
  safetyModes: {
221
233
  sandbox: true,
@@ -233,7 +245,7 @@ const PROVIDER_DEFINITIONS = {
233
245
  streamingFormats: ["jsonl"],
234
246
  resourcePolicy: { exposesModelsResource: true, exposesSessionsResource: true },
235
247
  upstreamContract: {
236
- targetVersion: "codex-cli 0.142.4",
248
+ targetVersion: PROVIDER_TARGET_VERSIONS.codex,
237
249
  helpChecksumRef: "codex-exec--help.txt",
238
250
  },
239
251
  capabilityScope: "full",
@@ -319,7 +331,7 @@ const PROVIDER_DEFINITIONS = {
319
331
  nativeEntrypoint: null,
320
332
  entrypoint: null,
321
333
  probeArgv: [],
322
- evidence: "agy 1.0.14 has no ACP flag or subcommand in installed help or the Antigravity CLI docs. Legacy Gemini CLI ACP evidence does not transfer. No native entrypoint advertised.",
334
+ evidence: `${PROVIDER_TARGET_VERSIONS.gemini} has no ACP flag or subcommand in installed help or the Antigravity CLI docs. Legacy Gemini CLI ACP evidence does not transfer. No native entrypoint advertised.`,
323
335
  },
324
336
  safetyModes: {
325
337
  sandbox: true,
@@ -331,7 +343,10 @@ const PROVIDER_DEFINITIONS = {
331
343
  outputFormats: ["text"],
332
344
  streamingFormats: [],
333
345
  resourcePolicy: { exposesModelsResource: true, exposesSessionsResource: true },
334
- upstreamContract: { targetVersion: "agy 1.0.14", helpChecksumRef: "agy--help.txt" },
346
+ upstreamContract: {
347
+ targetVersion: PROVIDER_TARGET_VERSIONS.gemini,
348
+ helpChecksumRef: "agy--help.txt",
349
+ },
335
350
  capabilityScope: "full",
336
351
  },
337
352
  grok: {
@@ -436,7 +451,7 @@ const PROVIDER_DEFINITIONS = {
436
451
  streamingFormats: ["json"],
437
452
  resourcePolicy: { exposesModelsResource: true, exposesSessionsResource: true },
438
453
  upstreamContract: {
439
- targetVersion: "grok 0.2.77 (44e77bec3a)",
454
+ targetVersion: PROVIDER_TARGET_VERSIONS.grok,
440
455
  helpChecksumRef: "grok--help.txt",
441
456
  },
442
457
  capabilityScope: "full",
@@ -551,7 +566,10 @@ const PROVIDER_DEFINITIONS = {
551
566
  outputFormats: ["text", "json"],
552
567
  streamingFormats: [],
553
568
  resourcePolicy: { exposesModelsResource: true, exposesSessionsResource: true },
554
- upstreamContract: { targetVersion: "vibe 2.18.3", helpChecksumRef: "vibe--help.txt" },
569
+ upstreamContract: {
570
+ targetVersion: PROVIDER_TARGET_VERSIONS.mistral,
571
+ helpChecksumRef: "vibe--help.txt",
572
+ },
555
573
  capabilityScope: "full",
556
574
  },
557
575
  devin: {
@@ -660,7 +678,7 @@ const PROVIDER_DEFINITIONS = {
660
678
  streamingFormats: [],
661
679
  resourcePolicy: { exposesModelsResource: true, exposesSessionsResource: true },
662
680
  upstreamContract: {
663
- targetVersion: "devin 2026.8.18 (16737566)",
681
+ targetVersion: PROVIDER_TARGET_VERSIONS.devin,
664
682
  helpChecksumRef: "devin--help.txt",
665
683
  },
666
684
  capabilityScope: "full",
@@ -734,7 +752,7 @@ const PROVIDER_DEFINITIONS = {
734
752
  streamingFormats: ["stream-json"],
735
753
  resourcePolicy: { exposesModelsResource: true, exposesSessionsResource: true },
736
754
  upstreamContract: {
737
- targetVersion: "cursor-agent 2026.06.29-2ad2186",
755
+ targetVersion: PROVIDER_TARGET_VERSIONS.cursor,
738
756
  helpChecksumRef: "cursor-agent--help.txt",
739
757
  },
740
758
  capabilityScope: "maintain-only",
@@ -4,7 +4,7 @@ import path from "path";
4
4
  import { parse as parseToml } from "smol-toml";
5
5
  import { CLAUDE_MCP_SERVER_NAMES } from "./claude-mcp-config.js";
6
6
  import { getAvailableCliInfo } from "./model-registry.js";
7
- import { CLI_TYPES, getProviderDefinition } from "./provider-definitions.js";
7
+ import { CLI_TYPES, getProviderDefinition, PROVIDER_TARGET_VERSIONS, } from "./provider-definitions.js";
8
8
  import { enabledApiProviders, isXaiProviderEnabled, loadProvidersConfig, } from "./config.js";
9
9
  import { apiContinuityForKind } from "./api-provider.js";
10
10
  const MAX_SKILLS_PER_DIR = 100;
@@ -50,7 +50,7 @@ export const ACP_CONTRACT = {
50
50
  },
51
51
  gemini: {
52
52
  classification: "absent_watchlist",
53
- summary: "Google Antigravity agy 1.0.14 has no ACP surface; watchlist item only.",
53
+ summary: `Google Antigravity ${PROVIDER_TARGET_VERSIONS.gemini} has no ACP surface; watchlist item only.`,
54
54
  },
55
55
  grok_api: {
56
56
  classification: "absent_watchlist",
@@ -110,7 +110,7 @@ const ACP_RESIDUAL = {
110
110
  smokeSupported: false,
111
111
  smokeStatus: "unsupported",
112
112
  caveats: [
113
- "Antigravity agy 1.0.14 has no ACP flag or subcommand.",
113
+ `Antigravity ${PROVIDER_TARGET_VERSIONS.gemini} has no ACP flag or subcommand.`,
114
114
  "Legacy Gemini CLI ACP evidence does not transfer to agy; kept on the upstream drift watchlist.",
115
115
  ],
116
116
  },
@@ -99,7 +99,7 @@ export const MISTRAL_BUILTIN_AGENT_MODES = [
99
99
  "accept-edits",
100
100
  "auto-approve",
101
101
  ];
102
- export const MISTRAL_DEFAULT_AGENT_MODE = "auto-approve";
102
+ export const MISTRAL_DEFAULT_AGENT_MODE = "accept-edits";
103
103
  export function prepareMistralRequest(input) {
104
104
  const args = ["-p", input.prompt];
105
105
  const env = {};
@@ -0,0 +1,10 @@
1
+ import type { Logger } from "./logger.js";
2
+ export declare function isRedirectionEnvKey(key: string): boolean;
3
+ export declare function isSpawnEnvIsolationEnabled(env?: NodeJS.ProcessEnv): boolean;
4
+ export interface SpawnEnvSanitizeResult {
5
+ env: NodeJS.ProcessEnv;
6
+ stripped: string[];
7
+ }
8
+ export declare function sanitizeSpawnEnv(baseEnv: NodeJS.ProcessEnv): SpawnEnvSanitizeResult;
9
+ export declare function resetSpawnEnvIsolationWarning(): void;
10
+ export declare function applySpawnEnvIsolation(finalEnv: NodeJS.ProcessEnv, logger?: Logger, env?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
@@ -0,0 +1,55 @@
1
+ import { logWarn } from "./logger.js";
2
+ const REDIRECTION_SUFFIXES = [
3
+ /_BASE_URL$/,
4
+ /_API_URL$/,
5
+ /_API_BASE$/,
6
+ /_ENDPOINT$/,
7
+ /_ENDPOINT_URL$/,
8
+ /_SERVER_URL$/,
9
+ ];
10
+ const REDIRECTION_EXACT = new Set([
11
+ "ANTHROPIC_UNIX_SOCKET",
12
+ "GROK_LEADER_SOCKET",
13
+ ]);
14
+ export function isRedirectionEnvKey(key) {
15
+ const upper = key.toUpperCase();
16
+ if (upper === "NO_PROXY")
17
+ return false;
18
+ if (upper.endsWith("_PROXY"))
19
+ return true;
20
+ if (REDIRECTION_EXACT.has(upper))
21
+ return true;
22
+ return REDIRECTION_SUFFIXES.some(re => re.test(upper));
23
+ }
24
+ export function isSpawnEnvIsolationEnabled(env = process.env) {
25
+ const raw = (env.LLM_GATEWAY_ISOLATE_SPAWN_ENV ?? "").trim().toLowerCase();
26
+ return raw === "1" || raw === "true" || raw === "on" || raw === "yes";
27
+ }
28
+ export function sanitizeSpawnEnv(baseEnv) {
29
+ const env = {};
30
+ const stripped = [];
31
+ for (const key of Object.keys(baseEnv)) {
32
+ if (isRedirectionEnvKey(key)) {
33
+ stripped.push(key);
34
+ continue;
35
+ }
36
+ env[key] = baseEnv[key];
37
+ }
38
+ return { env, stripped };
39
+ }
40
+ let warnedOnce = false;
41
+ export function resetSpawnEnvIsolationWarning() {
42
+ warnedOnce = false;
43
+ }
44
+ export function applySpawnEnvIsolation(finalEnv, logger, env = process.env) {
45
+ if (!isSpawnEnvIsolationEnabled(env))
46
+ return finalEnv;
47
+ const { env: sanitized, stripped } = sanitizeSpawnEnv(finalEnv);
48
+ if (stripped.length > 0 && logger && !warnedOnce) {
49
+ warnedOnce = true;
50
+ logWarn(logger, `spawn-env isolation: withheld ${stripped.length} endpoint/proxy redirection variable(s) ` +
51
+ `from provider child processes (${stripped.join(", ")}). ` +
52
+ `Unset LLM_GATEWAY_ISOLATE_SPAWN_ENV to disable.`);
53
+ }
54
+ return sanitized;
55
+ }
@@ -1,6 +1,6 @@
1
1
  import { spawnSync } from "node:child_process";
2
2
  import { createHash } from "node:crypto";
3
- import { getProviderDefinition } from "./provider-definitions.js";
3
+ import { getProviderDefinition, PROVIDER_TARGET_VERSIONS, } from "./provider-definitions.js";
4
4
  import { envWithExtendedPath, getExtendedPath, resolveCommandForSpawn } from "./executor.js";
5
5
  export const ACP_ENTRYPOINT_CONTRACTS = {
6
6
  mistral: {
@@ -9,7 +9,7 @@ export const ACP_ENTRYPOINT_CONTRACTS = {
9
9
  status: "native",
10
10
  executable: "vibe-acp",
11
11
  entrypointArgs: [],
12
- targetVersion: "vibe 2.18.3",
12
+ targetVersion: PROVIDER_TARGET_VERSIONS.mistral,
13
13
  probeArgs: [["--version"], ["--help"]],
14
14
  evidence: "Native ACP executable vibe-acp; manual initialize + session/new smoke passed. First runtime pilot.",
15
15
  docsRef: "docs/plans/first-class-acp-gateway-extension.dag.toml#provider_matrix.mistral",
@@ -20,9 +20,9 @@ export const ACP_ENTRYPOINT_CONTRACTS = {
20
20
  status: "native",
21
21
  executable: "grok",
22
22
  entrypointArgs: ["agent", "stdio"],
23
- targetVersion: "grok 0.2.77 (44e77bec3a)",
23
+ targetVersion: PROVIDER_TARGET_VERSIONS.grok,
24
24
  probeArgs: [["agent", "stdio", "--help"]],
25
- evidence: "Native ACP via `grok agent stdio`; initialize + session/new smoke passed with isolated leader socket. Second runtime pilot. Entrypoint re-probed clean at 0.2.77.",
25
+ evidence: `Native ACP via \`grok agent stdio\`; initialize + session/new smoke passed with isolated leader socket. Second runtime pilot. Entrypoint re-probed clean at ${PROVIDER_TARGET_VERSIONS.grok}.`,
26
26
  docsRef: "docs/plans/first-class-acp-gateway-extension.dag.toml#provider_matrix.grok",
27
27
  },
28
28
  codex: {
@@ -31,10 +31,10 @@ export const ACP_ENTRYPOINT_CONTRACTS = {
31
31
  status: "adapter_mediated_deferred",
32
32
  executable: "codex",
33
33
  entrypointArgs: [],
34
- targetVersion: "codex-cli 0.142.4",
34
+ targetVersion: PROVIDER_TARGET_VERSIONS.codex,
35
35
  probeArgs: [],
36
36
  adapterCandidates: ["zed-industries/codex-acp", "agentclientprotocol/codex-acp"],
37
- evidence: "No native ACP entrypoint at codex-cli 0.142.4. Adapter evidence tracked as documentation only; not native gateway ACP support.",
37
+ evidence: `No native ACP entrypoint at ${PROVIDER_TARGET_VERSIONS.codex}. Adapter evidence tracked as documentation only; not native gateway ACP support.`,
38
38
  docsRef: "docs/plans/first-class-acp-gateway-extension.dag.toml#provider_matrix.codex",
39
39
  },
40
40
  claude: {
@@ -43,10 +43,10 @@ export const ACP_ENTRYPOINT_CONTRACTS = {
43
43
  status: "adapter_mediated_deferred",
44
44
  executable: "claude",
45
45
  entrypointArgs: [],
46
- targetVersion: "claude 2.1.198",
46
+ targetVersion: PROVIDER_TARGET_VERSIONS.claude,
47
47
  probeArgs: [],
48
48
  adapterCandidates: ["Claude Agent SDK ACP adapter"],
49
- evidence: "No native Claude Code CLI ACP entrypoint at claude 2.1.198. Adapter ownership/permission bridging unresolved; deferred.",
49
+ evidence: `No native Claude Code CLI ACP entrypoint at ${PROVIDER_TARGET_VERSIONS.claude}. Adapter ownership/permission bridging unresolved; deferred.`,
50
50
  docsRef: "docs/plans/first-class-acp-gateway-extension.dag.toml#provider_matrix.claude",
51
51
  },
52
52
  gemini: {
@@ -55,9 +55,9 @@ export const ACP_ENTRYPOINT_CONTRACTS = {
55
55
  status: "absent_watchlist",
56
56
  executable: "agy",
57
57
  entrypointArgs: [],
58
- targetVersion: "agy 1.0.14",
58
+ targetVersion: PROVIDER_TARGET_VERSIONS.gemini,
59
59
  probeArgs: [],
60
- evidence: "agy 1.0.14 has no ACP flag or subcommand. Legacy Gemini CLI ACP evidence does not transfer. Watchlist item.",
60
+ evidence: `${PROVIDER_TARGET_VERSIONS.gemini} has no ACP flag or subcommand. Legacy Gemini CLI ACP evidence does not transfer. Watchlist item.`,
61
61
  docsRef: "docs/plans/first-class-acp-gateway-extension.dag.toml#provider_matrix.gemini",
62
62
  },
63
63
  devin: {
@@ -66,7 +66,7 @@ export const ACP_ENTRYPOINT_CONTRACTS = {
66
66
  status: "native",
67
67
  executable: "devin",
68
68
  entrypointArgs: ["acp"],
69
- targetVersion: "devin 2026.8.18 (16737566)",
69
+ targetVersion: PROVIDER_TARGET_VERSIONS.devin,
70
70
  probeArgs: [["--version"]],
71
71
  evidence: 'Native ACP entrypoint `devin acp` (stdio JSON-RPC). Slice D1 manual initialize + session/new smoke passed (protocolVersion 1, agent "Affogato", session created). Third native runtime pilot; routing stays config-gated.',
72
72
  docsRef: "docs/plans/first-class-acp-gateway-extension.dag.toml#provider_matrix.devin",
@@ -77,7 +77,7 @@ export const ACP_ENTRYPOINT_CONTRACTS = {
77
77
  status: "native",
78
78
  executable: "cursor-agent",
79
79
  entrypointArgs: ["acp"],
80
- targetVersion: "cursor-agent 2026.06.29-2ad2186",
80
+ targetVersion: PROVIDER_TARGET_VERSIONS.cursor,
81
81
  probeArgs: [["acp", "--help"]],
82
82
  evidence: "Native hidden ACP entrypoint `cursor-agent acp` (stdio JSON-RPC). `cursor-agent acp --help` was verified locally; manual initialize + session/new smoke passed locally (protocolVersion 1, session created; no agentInfo returned). Runtime routing stays config-gated.",
83
83
  docsRef: "docs/plans/first-class-acp-gateway-extension.dag.toml#provider_matrix.cursor",
@@ -326,10 +326,12 @@ export const UPSTREAM_CLI_CONTRACTS = {
326
326
  "--system-prompt-file": {
327
327
  arity: "one",
328
328
  description: "Replacement system prompt read from a file path",
329
+ hiddenFromHelp: true,
329
330
  },
330
331
  "--append-system-prompt-file": {
331
332
  arity: "one",
332
333
  description: "Appended system prompt read from a file path",
334
+ hiddenFromHelp: true,
333
335
  },
334
336
  "--name": { arity: "one", description: "Session name label" },
335
337
  "--plugin-dir": {
@@ -494,7 +496,7 @@ export const UPSTREAM_CLI_CONTRACTS = {
494
496
  },
495
497
  {
496
498
  id: "claude-background-acknowledged-not-emitted",
497
- description: "Claude 2.1.198 advertises --bg/--background (background agent), but the gateway acknowledges them without emitting; caller argv is rejected",
499
+ description: "Claude 2.1.204 advertises --bg/--background (background agent), but the gateway acknowledges them without emitting; caller argv is rejected",
498
500
  args: ["-p", "hello", "--background"],
499
501
  expect: "fail",
500
502
  },
@@ -658,8 +660,11 @@ export const UPSTREAM_CLI_CONTRACTS = {
658
660
  "--disable",
659
661
  "--enable",
660
662
  "--include-managed-config",
661
- "--permissions-profile",
663
+ "--permission-profile",
662
664
  "--profile",
665
+ "--sandbox-state-disable-network",
666
+ "--sandbox-state-json",
667
+ "--sandbox-state-readable-root",
663
668
  ], { exposure: "not_exposed" }),
664
669
  debug: subcommand(["debug"], "Run Codex debugging utilities.", "read_only", ["--config", "--disable", "--enable"], { tier: "diagnostic" }),
665
670
  apply: subcommand(["apply"], "Apply a Codex patch to the workspace.", "destructive", ["--config", "--disable", "--enable"], { exposure: "not_exposed" }),
@@ -1028,7 +1033,7 @@ export const UPSTREAM_CLI_CONTRACTS = {
1028
1033
  description: "Print-mode wait timeout as a Go duration string (e.g. 5m0s)",
1029
1034
  },
1030
1035
  },
1031
- acknowledgedUpstreamFlags: ["--log-file", "--prompt-interactive"],
1036
+ acknowledgedUpstreamFlags: ["--log-file", "--mode", "--prompt-interactive"],
1032
1037
  env: {},
1033
1038
  conformanceFixtures: [
1034
1039
  {
@@ -1109,6 +1114,7 @@ export const UPSTREAM_CLI_CONTRACTS = {
1109
1114
  "--leader-socket",
1110
1115
  "--model",
1111
1116
  "--no-leader",
1117
+ "--plugin-dir",
1112
1118
  "--reasoning-effort",
1113
1119
  "--reauth",
1114
1120
  "--xai-api-base-url",
@@ -1189,11 +1195,11 @@ export const UPSTREAM_CLI_CONTRACTS = {
1189
1195
  "--deny",
1190
1196
  "--disable-web-search",
1191
1197
  "--disallowed-tools",
1192
- "--effort",
1193
1198
  "--experimental-memory",
1194
1199
  "--fork-session",
1195
1200
  "--json-schema",
1196
1201
  "--max-turns",
1202
+ "--minimal",
1197
1203
  "--model",
1198
1204
  "--no-alt-screen",
1199
1205
  "--no-memory",
@@ -1233,7 +1239,7 @@ export const UPSTREAM_CLI_CONTRACTS = {
1233
1239
  worktree: subcommand(["worktree"], "Manage Grok worktree sessions.", "writes_local_config", ["--leader-socket"]),
1234
1240
  }, GROK_DEBUG_HELP_FLAGS),
1235
1241
  maxPositionals: 0,
1236
- acknowledgedUpstreamFlags: [...GROK_DEBUG_HELP_FLAGS, "--session-id"],
1242
+ acknowledgedUpstreamFlags: [...GROK_DEBUG_HELP_FLAGS, "--minimal", "--session-id"],
1237
1243
  mcpTools: ["grok_request", "grok_request_async"],
1238
1244
  mcpParameters: [
1239
1245
  "prompt",
@@ -1675,7 +1681,13 @@ export const UPSTREAM_CLI_CONTRACTS = {
1675
1681
  description: "Additional writable workspace directory (Phase 4 slice ζ; repeat once per directory)",
1676
1682
  },
1677
1683
  },
1678
- acknowledgedUpstreamFlags: ["--auto-approve", "--check-upgrade", "--yolo"],
1684
+ acknowledgedUpstreamFlags: [
1685
+ "--auto-approve",
1686
+ "--check-upgrade",
1687
+ "--disabled-tools",
1688
+ "--worktree",
1689
+ "--yolo",
1690
+ ],
1679
1691
  env: {
1680
1692
  VIBE_ACTIVE_MODEL: {
1681
1693
  arity: "one",
@@ -1774,25 +1786,39 @@ export const UPSTREAM_CLI_CONTRACTS = {
1774
1786
  },
1775
1787
  {
1776
1788
  id: "mistral-current-help-surface",
1777
- description: "Vibe 2.18.3 request-time help surface: --prompt, -v, --version, --setup accepted",
1789
+ description: "Vibe 2.19.1 request-time help surface: --prompt, -v, --version, --setup accepted",
1778
1790
  args: ["--prompt", "hello", "--agent", "auto-approve", "-v", "--version", "--setup"],
1779
1791
  env: { VIBE_ACTIVE_MODEL: "mistral-medium-3.5" },
1780
1792
  expect: "pass",
1781
1793
  },
1782
1794
  {
1783
1795
  id: "mistral-yolo-shortcut-rejected",
1784
- description: "Vibe 2.18.3 advertises --yolo as a shortcut, but the gateway keeps using explicit --agent auto-approve",
1796
+ description: "Vibe 2.19.0 advertises --yolo as a shortcut, but the gateway keeps using explicit --agent auto-approve",
1785
1797
  args: ["-p", "hello", "--yolo"],
1786
1798
  env: { VIBE_ACTIVE_MODEL: "mistral-medium-3.5" },
1787
1799
  expect: "fail",
1788
1800
  },
1789
1801
  {
1790
1802
  id: "mistral-check-upgrade-rejected",
1791
- description: "Vibe 2.18.3 advertises --check-upgrade, but gateway request validation rejects update-prompt flags",
1803
+ description: "Vibe 2.19.0 advertises --check-upgrade, but gateway request validation rejects update-prompt flags",
1792
1804
  args: ["--check-upgrade"],
1793
1805
  env: { VIBE_ACTIVE_MODEL: "mistral-medium-3.5" },
1794
1806
  expect: "fail",
1795
1807
  },
1808
+ {
1809
+ id: "mistral-worktree-rejected",
1810
+ description: "Vibe 2.19.0 advertises --worktree (native worktree); the gateway uses slice-λ worktree (spawns with cwd) and rejects raw --worktree as caller argv",
1811
+ args: ["-p", "hello", "--worktree", "feature"],
1812
+ env: { VIBE_ACTIVE_MODEL: "mistral-medium-3.5" },
1813
+ expect: "fail",
1814
+ },
1815
+ {
1816
+ id: "mistral-disabled-tools-rejected",
1817
+ description: "Vibe 2.19.1 adds --disabled-tools (denylist counterpart to --enabled-tools); the gateway does not emit it (disallowedTools is accepted but ignored) and rejects raw --disabled-tools as caller argv",
1818
+ args: ["-p", "hello", "--disabled-tools", "shell"],
1819
+ env: { VIBE_ACTIVE_MODEL: "mistral-medium-3.5" },
1820
+ expect: "fail",
1821
+ },
1796
1822
  {
1797
1823
  id: "mistral-resume-bare",
1798
1824
  description: "Vibe --resume without session ID is accepted (optional arity)",
@@ -2031,22 +2057,16 @@ export const UPSTREAM_CLI_CONTRACTS = {
2031
2057
  acknowledgedUpstreamFlags: [
2032
2058
  "--api-key",
2033
2059
  "--header",
2034
- "-H",
2035
- "-p",
2036
2060
  "--plan",
2037
2061
  "--yolo",
2038
2062
  "--approve-mcps",
2039
2063
  "--plugin-dir",
2040
2064
  "--worktree",
2041
- "-w",
2042
2065
  "--worktree-base",
2043
2066
  "--skip-worktree-setup",
2044
2067
  "--stream-partial-output",
2045
2068
  "--list-models",
2046
2069
  "--version",
2047
- "-v",
2048
- "--help",
2049
- "-h",
2050
2070
  ],
2051
2071
  env: {
2052
2072
  CURSOR_API_KEY: {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "llm-cli-gateway",
3
- "version": "2.15.0",
3
+ "version": "2.16.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "llm-cli-gateway",
9
- "version": "2.15.0",
9
+ "version": "2.16.0",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@modelcontextprotocol/sdk": "^1.29.0",
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "llm-cli-gateway",
3
- "version": "2.15.0",
3
+ "version": "2.16.0",
4
4
  "mcpName": "io.github.verivus-oss/llm-cli-gateway",
5
- "description": "Local-first MCP gateway for cross-model review across native coding-agent CLIs and API-token LLMs with sessions, durable jobs, and validation receipts.",
5
+ "description": "Secure local control plane for AI coding agents across supported MCP clients, with workspace-scoped remote access, approval gates, durable jobs, sessions, and audit receipts.",
6
6
  "license": "MIT",
7
7
  "author": "VerivusAI Labs (https://github.com/verivus-oss)",
8
8
  "repository": {
@@ -20,6 +20,7 @@
20
20
  "codex",
21
21
  "gemini",
22
22
  "orchestration",
23
+ "control-plane",
23
24
  "model-context-protocol",
24
25
  "ai",
25
26
  "cli-gateway"
@@ -84,6 +85,9 @@
84
85
  "upstream:contracts": "node scripts/upstream-scan.mjs --contracts-check",
85
86
  "upstream:scan": "node scripts/upstream-scan.mjs",
86
87
  "provider:surfaces:check": "node scripts/provider-surfaces-check.mjs",
88
+ "site:generate": "node scripts/generate-site-discovery.mjs",
89
+ "site:generate:check": "node scripts/generate-site-discovery.mjs --check",
90
+ "site:validate": "node scripts/validate-site-discovery.mjs",
87
91
  "lint": "eslint src/**/*.ts",
88
92
  "lint:fix": "eslint src/**/*.ts --fix",
89
93
  "format": "prettier --write 'src/**/*.ts'",
@@ -93,7 +97,7 @@
93
97
  "search:google:submit:dry-run": "node scripts/submit-google-search-console.mjs --dry-run",
94
98
  "search:submit": "node scripts/submit-indexnow.mjs",
95
99
  "search:submit:dry-run": "node scripts/submit-indexnow.mjs --dry-run",
96
- "check": "npm run build && npm run lint && npm run format:check && npm run provider:surfaces:check && npm test && npm run security:audit",
100
+ "check": "npm run build && npm run lint && npm run format:check && npm run provider:surfaces:check && npm run site:generate:check && npm run site:validate && npm test && npm run security:audit",
97
101
  "release:build": "bash installer/build-release.sh",
98
102
  "release:checksums": "cd installer/dist && sha256sum --check SHA256SUMS",
99
103
  "release:docker": "docker compose -f docker/personal.compose.yml build"