llm-cli-gateway 2.10.0 → 2.11.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.
Files changed (64) hide show
  1. package/CHANGELOG.md +75 -1
  2. package/README.md +46 -14
  3. package/dist/acp/event-normalizer.d.ts +42 -0
  4. package/dist/acp/event-normalizer.js +71 -0
  5. package/dist/acp/flight-redaction.d.ts +25 -0
  6. package/dist/acp/flight-redaction.js +40 -0
  7. package/dist/acp/host-services.d.ts +16 -0
  8. package/dist/acp/host-services.js +29 -0
  9. package/dist/acp/permission-bridge.d.ts +15 -0
  10. package/dist/acp/permission-bridge.js +90 -0
  11. package/dist/acp/process-manager.js +7 -1
  12. package/dist/acp/provider-registry.d.ts +1 -1
  13. package/dist/acp/provider-registry.js +18 -5
  14. package/dist/acp/runtime.d.ts +35 -0
  15. package/dist/acp/runtime.js +125 -0
  16. package/dist/acp/session-map.d.ts +42 -0
  17. package/dist/acp/session-map.js +67 -0
  18. package/dist/acp/smoke-harness.d.ts +28 -0
  19. package/dist/acp/smoke-harness.js +90 -0
  20. package/dist/api-http.d.ts +18 -0
  21. package/dist/api-http.js +122 -0
  22. package/dist/api-provider.d.ts +83 -0
  23. package/dist/api-provider.js +258 -0
  24. package/dist/api-request.d.ts +30 -0
  25. package/dist/api-request.js +51 -0
  26. package/dist/approval-manager.d.ts +1 -1
  27. package/dist/approval-manager.js +6 -7
  28. package/dist/async-job-manager.d.ts +19 -4
  29. package/dist/async-job-manager.js +211 -35
  30. package/dist/claude-mcp-config.d.ts +2 -2
  31. package/dist/claude-mcp-config.js +42 -52
  32. package/dist/cli-updater.js +16 -1
  33. package/dist/config.d.ts +20 -0
  34. package/dist/config.js +93 -35
  35. package/dist/doctor.d.ts +1 -1
  36. package/dist/flight-recorder.d.ts +1 -0
  37. package/dist/flight-recorder.js +11 -0
  38. package/dist/index.d.ts +56 -5
  39. package/dist/index.js +639 -38
  40. package/dist/job-store.d.ts +15 -0
  41. package/dist/job-store.js +39 -5
  42. package/dist/mcp-registry.d.ts +17 -0
  43. package/dist/mcp-registry.js +5 -0
  44. package/dist/metrics.js +7 -2
  45. package/dist/model-registry.js +11 -0
  46. package/dist/prompt-parts.d.ts +6 -6
  47. package/dist/provider-login-guidance.js +21 -0
  48. package/dist/provider-status.js +4 -1
  49. package/dist/provider-tool-capabilities.d.ts +8 -3
  50. package/dist/provider-tool-capabilities.js +107 -17
  51. package/dist/request-helpers.d.ts +6 -6
  52. package/dist/request-helpers.js +1 -4
  53. package/dist/session-manager-pg.js +2 -9
  54. package/dist/session-manager.d.ts +9 -4
  55. package/dist/session-manager.js +13 -4
  56. package/dist/upstream-contracts.js +184 -24
  57. package/dist/validation-normalizer.d.ts +2 -2
  58. package/dist/validation-orchestrator.d.ts +2 -0
  59. package/dist/validation-orchestrator.js +28 -7
  60. package/dist/validation-tools.d.ts +61 -0
  61. package/dist/validation-tools.js +36 -21
  62. package/migrations/005_provider_type_open_api_names.sql +28 -0
  63. package/npm-shrinkwrap.json +6 -5
  64. package/package.json +12 -9
@@ -1,7 +1,68 @@
1
+ import { z } from "zod/v3";
1
2
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
3
  import type { AsyncJobManager } from "./async-job-manager.js";
3
4
  import { type ValidationOrchestratorDeps } from "./validation-orchestrator.js";
4
5
  export interface ValidationToolDeps extends ValidationOrchestratorDeps {
5
6
  asyncJobManager: AsyncJobManager;
6
7
  }
8
+ export declare function buildValidationSchemas(deps: ValidationToolDeps): {
9
+ providerSchema: z.ZodEnum<[string, ...string[]]>;
10
+ providerListSchema: z.ZodDefault<z.ZodArray<z.ZodEnum<[string, ...string[]]>, "many">>;
11
+ normalizedProviderResultSchema: z.ZodObject<{
12
+ provider: z.ZodEnum<[string, ...string[]]>;
13
+ model: z.ZodNullable<z.ZodString>;
14
+ status: z.ZodEnum<["running", "completed", "failed", "canceled", "orphaned", "skipped"]>;
15
+ verdict: z.ZodNullable<z.ZodString>;
16
+ rationale: z.ZodNullable<z.ZodString>;
17
+ risks: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
18
+ rawJobReference: z.ZodNullable<z.ZodObject<{
19
+ jobId: z.ZodString;
20
+ correlationId: z.ZodString;
21
+ statusTool: z.ZodLiteral<"job_status">;
22
+ resultTool: z.ZodLiteral<"job_result">;
23
+ }, "strip", z.ZodTypeAny, {
24
+ correlationId: string;
25
+ jobId: string;
26
+ statusTool: "job_status";
27
+ resultTool: "job_result";
28
+ }, {
29
+ correlationId: string;
30
+ jobId: string;
31
+ statusTool: "job_status";
32
+ resultTool: "job_result";
33
+ }>>;
34
+ error: z.ZodNullable<z.ZodString>;
35
+ warning: z.ZodOptional<z.ZodString>;
36
+ }, "strip", z.ZodTypeAny, {
37
+ error: string | null;
38
+ status: "running" | "completed" | "failed" | "canceled" | "orphaned" | "skipped";
39
+ model: string | null;
40
+ provider: string;
41
+ rawJobReference: {
42
+ correlationId: string;
43
+ jobId: string;
44
+ statusTool: "job_status";
45
+ resultTool: "job_result";
46
+ } | null;
47
+ verdict: string | null;
48
+ rationale: string | null;
49
+ risks: string[];
50
+ warning?: string | undefined;
51
+ }, {
52
+ error: string | null;
53
+ status: "running" | "completed" | "failed" | "canceled" | "orphaned" | "skipped";
54
+ model: string | null;
55
+ provider: string;
56
+ rawJobReference: {
57
+ correlationId: string;
58
+ jobId: string;
59
+ statusTool: "job_status";
60
+ resultTool: "job_result";
61
+ } | null;
62
+ verdict: string | null;
63
+ rationale: string | null;
64
+ risks?: string[] | undefined;
65
+ warning?: string | undefined;
66
+ }>;
67
+ };
7
68
  export declare function registerValidationTools(server: McpServer, deps: ValidationToolDeps): void;
@@ -1,26 +1,33 @@
1
1
  import { z } from "zod/v3";
2
+ import { CLI_TYPES } from "./session-manager.js";
2
3
  import { getAvailableCliInfo } from "./model-registry.js";
4
+ import { apiProviderCatalogEntry } from "./api-request.js";
3
5
  import { collectValidationJobResult, startJudgeSynthesis, startValidationRun, } from "./validation-orchestrator.js";
4
- const providerSchema = z.enum(["claude", "codex", "gemini", "grok", "mistral"]);
5
- const providerListSchema = z.array(providerSchema).min(1).default(["claude", "codex"]);
6
- const normalizedProviderResultSchema = z.object({
7
- provider: providerSchema,
8
- model: z.string().nullable(),
9
- status: z.enum(["running", "completed", "failed", "canceled", "orphaned", "skipped"]),
10
- verdict: z.string().nullable(),
11
- rationale: z.string().nullable(),
12
- risks: z.array(z.string()).default([]),
13
- rawJobReference: z
14
- .object({
15
- jobId: z.string(),
16
- correlationId: z.string(),
17
- statusTool: z.literal("job_status"),
18
- resultTool: z.literal("job_result"),
19
- })
20
- .nullable(),
21
- error: z.string().nullable(),
22
- warning: z.string().optional(),
23
- });
6
+ export function buildValidationSchemas(deps) {
7
+ const apiNames = (deps.apiProviders ?? []).map(p => p.name);
8
+ const allowed = [...CLI_TYPES, ...apiNames];
9
+ const providerSchema = z.enum(allowed);
10
+ const providerListSchema = z.array(providerSchema).min(1).default(["claude", "codex"]);
11
+ const normalizedProviderResultSchema = z.object({
12
+ provider: providerSchema,
13
+ model: z.string().nullable(),
14
+ status: z.enum(["running", "completed", "failed", "canceled", "orphaned", "skipped"]),
15
+ verdict: z.string().nullable(),
16
+ rationale: z.string().nullable(),
17
+ risks: z.array(z.string()).default([]),
18
+ rawJobReference: z
19
+ .object({
20
+ jobId: z.string(),
21
+ correlationId: z.string(),
22
+ statusTool: z.literal("job_status"),
23
+ resultTool: z.literal("job_result"),
24
+ })
25
+ .nullable(),
26
+ error: z.string().nullable(),
27
+ warning: z.string().optional(),
28
+ });
29
+ return { providerSchema, providerListSchema, normalizedProviderResultSchema };
30
+ }
24
31
  function textResponse(body) {
25
32
  const text = responseText(body);
26
33
  return {
@@ -47,6 +54,7 @@ function findHumanReadableReport(value) {
47
54
  return null;
48
55
  }
49
56
  export function registerValidationTools(server, deps) {
57
+ const { providerSchema, providerListSchema, normalizedProviderResultSchema } = buildValidationSchemas(deps);
50
58
  server.tool("validate_with_models", "Ask two or more provider CLIs to independently validate a question. Starts validation jobs — poll with job_status, collect with job_result (not llm_job_*).", {
51
59
  question: z.string().min(1).describe("Question or content to validate."),
52
60
  models: providerListSchema.describe("Providers to ask. Defaults to Claude and Codex."),
@@ -208,7 +216,14 @@ export function registerValidationTools(server, deps) {
208
216
  destructiveHint: false,
209
217
  idempotentHint: true,
210
218
  openWorldHint: false,
211
- }, async () => textResponse({ success: true, models: getAvailableCliInfo() }));
219
+ }, async () => {
220
+ const apiProviders = (deps.apiProviders ?? []).map(apiProviderCatalogEntry);
221
+ return textResponse({
222
+ success: true,
223
+ models: getAvailableCliInfo(),
224
+ ...(apiProviders.length > 0 ? { apiProviders } : {}),
225
+ });
226
+ });
212
227
  server.tool("job_status", "Check a VALIDATION job's status (jobs started by validate_with_models/ask_model/etc.) — distinct from llm_job_status, which tracks provider request jobs.", {
213
228
  jobId: z.string().min(1).describe("Validation job ID."),
214
229
  }, {
@@ -0,0 +1,28 @@
1
+ -- Slice 0.5 (API-endpoint routing, locked decision B: arbitrary provider names).
2
+ --
3
+ -- Relax the closed provider enum on the session tables so that any
4
+ -- `[providers.<name>]` config key (a kind:"api" provider id) is a valid
5
+ -- `cli` value. Migration 003 widened the constraint only as far as the
6
+ -- hard-coded set ('claude','codex','gemini','grok','mistral','grok-api');
7
+ -- arbitrary API provider names had no DB-level home.
8
+ --
9
+ -- Provider-set validation now lives in the application layer (config loading
10
+ -- plus `SESSION_PROVIDER_ENUM` for the registered set). The database keeps a
11
+ -- single *format* guard so empty strings / whitespace / control characters are
12
+ -- still rejected — it no longer enumerates a fixed provider list. The pattern
13
+ -- accepts the existing five CLIs and `grok-api`, and any well-formed provider
14
+ -- identifier (e.g. `ollama`, `openai`, `vllm`, `llama3.3`).
15
+
16
+ ALTER TABLE sessions DROP CONSTRAINT IF EXISTS sessions_cli_check;
17
+ ALTER TABLE sessions
18
+ ADD CONSTRAINT sessions_cli_check
19
+ CHECK (cli ~ '^[A-Za-z][A-Za-z0-9._-]*$');
20
+
21
+ ALTER TABLE active_sessions DROP CONSTRAINT IF EXISTS active_sessions_cli_check;
22
+ ALTER TABLE active_sessions
23
+ ADD CONSTRAINT active_sessions_cli_check
24
+ CHECK (cli ~ '^[A-Za-z][A-Za-z0-9._-]*$');
25
+
26
+ INSERT INTO schema_migrations (version, name)
27
+ VALUES (5, '005_provider_type_open_api_names')
28
+ ON CONFLICT (version) DO NOTHING;
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "llm-cli-gateway",
3
- "version": "2.10.0",
3
+ "version": "2.11.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "llm-cli-gateway",
9
- "version": "2.10.0",
9
+ "version": "2.11.1",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "@modelcontextprotocol/sdk": "^1.29.0",
13
+ "body-parser": "2.2.2",
13
14
  "content-type": "1.0.5",
14
15
  "smol-toml": "^1.6.1",
15
16
  "type-is": "2.0.1",
@@ -587,9 +588,9 @@
587
588
  }
588
589
  },
589
590
  "node_modules/hono": {
590
- "version": "4.12.22",
591
- "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.22.tgz",
592
- "integrity": "sha512-7fvVPbB92zNRsQke+uiRGwtTuef0tB2Dg4hWxYfFNvkQhIltWoyi0ONReM5LWA+jJWS3nfT5lTq+qbsIpX0IQw==",
591
+ "version": "4.12.25",
592
+ "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.25.tgz",
593
+ "integrity": "sha512-2NFaIyNVgJmBs/ecmtGzlmluTFs5cHEWGTdu0t1HBwYzoGXOL5nUQBRMXsXWla5i4KkG//QMzVP88m1+I3fdAQ==",
593
594
  "license": "MIT",
594
595
  "engines": {
595
596
  "node": ">=16.9.0"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "llm-cli-gateway",
3
- "version": "2.10.0",
3
+ "version": "2.11.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",
@@ -88,6 +88,7 @@
88
88
  },
89
89
  "dependencies": {
90
90
  "@modelcontextprotocol/sdk": "^1.29.0",
91
+ "body-parser": "2.2.2",
91
92
  "content-type": "1.0.5",
92
93
  "smol-toml": "^1.6.1",
93
94
  "type-is": "2.0.1",
@@ -104,24 +105,26 @@
104
105
  "devDependencies": {
105
106
  "@eslint/js": "^10.0.1",
106
107
  "@types/better-sqlite3": "^7.6.0",
107
- "better-sqlite3": "^12.10.0",
108
- "@types/node": "^25.9.1",
108
+ "@types/node": "^25.9.3",
109
109
  "@types/pg": "^8.11.10",
110
- "@typescript-eslint/eslint-plugin": "^8.59.4",
110
+ "@typescript-eslint/eslint-plugin": "^8.61.1",
111
111
  "@typescript-eslint/parser": "^8.59.4",
112
- "@vitest/coverage-v8": "^4.1.2",
113
- "eslint": "^10.4.1",
112
+ "@vitest/coverage-v8": "^4.1.9",
113
+ "better-sqlite3": "^12.11.1",
114
+ "eslint": "^10.5.0",
114
115
  "eslint-config-prettier": "^10.1.8",
115
- "eslint-plugin-security": "^4.0.0",
116
+ "eslint-plugin-security": "^4.0.1",
116
117
  "fast-check": "^4.8.0",
117
118
  "pg": "^8.12.0",
118
- "prettier": "^3.0.0",
119
+ "prettier": "^3.8.4",
119
120
  "typescript": "^6.0.3",
120
121
  "vitest": "^4.0.18"
121
122
  },
122
123
  "overrides": {
124
+ "body-parser": "2.2.2",
123
125
  "type-is": "2.0.1",
124
- "content-type": "1.0.5"
126
+ "content-type": "1.0.5",
127
+ "hono": "^4.12.25"
125
128
  },
126
129
  "directories": {
127
130
  "doc": "docs"