llm-cli-gateway 1.4.0 → 1.5.13
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 +135 -1
- package/README.md +358 -15
- package/dist/approval-manager.d.ts +1 -1
- package/dist/async-job-manager.d.ts +32 -2
- package/dist/async-job-manager.js +101 -16
- package/dist/auth.d.ts +15 -0
- package/dist/auth.js +46 -0
- package/dist/cli-updater.d.ts +19 -2
- package/dist/cli-updater.js +110 -7
- package/dist/codex-json-parser.d.ts +34 -0
- package/dist/codex-json-parser.js +105 -0
- package/dist/config.d.ts +30 -0
- package/dist/config.js +167 -0
- package/dist/doctor.d.ts +110 -0
- package/dist/doctor.js +280 -0
- package/dist/endpoint-exposure.d.ts +22 -0
- package/dist/endpoint-exposure.js +231 -0
- package/dist/entrypoint-url.d.ts +1 -0
- package/dist/entrypoint-url.js +5 -0
- package/dist/executor.d.ts +9 -1
- package/dist/executor.js +52 -17
- package/dist/flight-recorder.d.ts +3 -1
- package/dist/flight-recorder.js +31 -2
- package/dist/gateway-server.d.ts +2 -0
- package/dist/gateway-server.js +1 -0
- package/dist/gemini-json-parser.d.ts +21 -0
- package/dist/gemini-json-parser.js +47 -0
- package/dist/health.d.ts +7 -0
- package/dist/health.js +22 -0
- package/dist/http-transport.d.ts +22 -0
- package/dist/http-transport.js +164 -0
- package/dist/index.d.ts +186 -2
- package/dist/index.js +2761 -1454
- package/dist/job-store.d.ts +118 -2
- package/dist/job-store.js +176 -5
- package/dist/logger.d.ts +9 -0
- package/dist/logger.js +14 -0
- package/dist/model-registry.js +40 -6
- package/dist/provider-login-guidance.d.ts +21 -0
- package/dist/provider-login-guidance.js +98 -0
- package/dist/provider-status.d.ts +41 -0
- package/dist/provider-status.js +203 -0
- package/dist/request-helpers.d.ts +484 -4
- package/dist/request-helpers.js +613 -0
- package/dist/resources.js +44 -0
- package/dist/session-manager-pg.js +1 -0
- package/dist/session-manager.d.ts +1 -1
- package/dist/session-manager.js +2 -1
- package/dist/upstream-contracts.d.ts +62 -0
- package/dist/upstream-contracts.js +620 -0
- package/dist/validation-normalizer.d.ts +23 -0
- package/dist/validation-normalizer.js +79 -0
- package/dist/validation-orchestrator.d.ts +47 -0
- package/dist/validation-orchestrator.js +145 -0
- package/dist/validation-prompts.d.ts +15 -0
- package/dist/validation-prompts.js +52 -0
- package/dist/validation-report.d.ts +57 -0
- package/dist/validation-report.js +129 -0
- package/dist/validation-tools.d.ts +7 -0
- package/dist/validation-tools.js +198 -0
- package/package.json +25 -10
- package/setup/status.schema.json +271 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { getCliInfo } from "./model-registry.js";
|
|
3
|
+
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
|
+
});
|
|
24
|
+
function textResponse(body) {
|
|
25
|
+
const text = responseText(body);
|
|
26
|
+
return {
|
|
27
|
+
content: [{ type: "text", text }],
|
|
28
|
+
structuredContent: body,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function responseText(body) {
|
|
32
|
+
const report = findHumanReadableReport(body);
|
|
33
|
+
if (report)
|
|
34
|
+
return report;
|
|
35
|
+
return JSON.stringify(body, null, 2);
|
|
36
|
+
}
|
|
37
|
+
function findHumanReadableReport(value) {
|
|
38
|
+
if (typeof value !== "object" || value === null)
|
|
39
|
+
return null;
|
|
40
|
+
if ("humanReadable" in value &&
|
|
41
|
+
typeof value.humanReadable === "string") {
|
|
42
|
+
return value.humanReadable;
|
|
43
|
+
}
|
|
44
|
+
if ("report" in value) {
|
|
45
|
+
return findHumanReadableReport(value.report);
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
export function registerValidationTools(server, deps) {
|
|
50
|
+
server.tool("validate_with_models", {
|
|
51
|
+
question: z.string().min(1).describe("Question or content to validate."),
|
|
52
|
+
models: providerListSchema.describe("Providers to ask. Defaults to Claude and Codex."),
|
|
53
|
+
focus: z
|
|
54
|
+
.string()
|
|
55
|
+
.default("correctness, missing assumptions, and practical next steps")
|
|
56
|
+
.describe("What reviewers should pay attention to."),
|
|
57
|
+
judgeModel: providerSchema
|
|
58
|
+
.optional()
|
|
59
|
+
.describe("Optional provider to run an explicit judge synthesis job."),
|
|
60
|
+
}, async ({ question, models, focus, judgeModel }) => textResponse({
|
|
61
|
+
success: true,
|
|
62
|
+
tool: "validate_with_models",
|
|
63
|
+
readMostly: true,
|
|
64
|
+
report: startValidationRun(deps, {
|
|
65
|
+
intent: "validate",
|
|
66
|
+
question,
|
|
67
|
+
providers: models,
|
|
68
|
+
focus,
|
|
69
|
+
judgeProvider: judgeModel,
|
|
70
|
+
}),
|
|
71
|
+
}));
|
|
72
|
+
server.tool("second_opinion", {
|
|
73
|
+
answer: z.string().min(1).describe("Answer to review."),
|
|
74
|
+
question: z.string().optional().describe("Original question, if available."),
|
|
75
|
+
model: providerSchema.default("codex").describe("Provider to ask for the second opinion."),
|
|
76
|
+
}, async ({ answer, question, model }) => textResponse({
|
|
77
|
+
success: true,
|
|
78
|
+
tool: "second_opinion",
|
|
79
|
+
readMostly: true,
|
|
80
|
+
report: startValidationRun(deps, {
|
|
81
|
+
intent: "second_opinion",
|
|
82
|
+
question,
|
|
83
|
+
content: answer,
|
|
84
|
+
providers: [model],
|
|
85
|
+
}),
|
|
86
|
+
}));
|
|
87
|
+
server.tool("compare_answers", {
|
|
88
|
+
question: z.string().min(1).describe("Question the answers respond to."),
|
|
89
|
+
answers: z.array(z.string().min(1)).min(2).describe("Two or more answers to compare."),
|
|
90
|
+
}, async ({ question, answers }) => textResponse({
|
|
91
|
+
success: true,
|
|
92
|
+
tool: "compare_answers",
|
|
93
|
+
readMostly: true,
|
|
94
|
+
comparison: {
|
|
95
|
+
question,
|
|
96
|
+
answerCount: answers.length,
|
|
97
|
+
checks: ["agreement", "contradictions", "missing evidence", "actionable recommendation"],
|
|
98
|
+
status: "local_summary_only",
|
|
99
|
+
note: "Use validate_with_models when independent provider review is needed.",
|
|
100
|
+
},
|
|
101
|
+
}));
|
|
102
|
+
server.tool("red_team_review", {
|
|
103
|
+
content: z.string().min(1).describe("Plan, answer, or document to challenge."),
|
|
104
|
+
riskLevel: z
|
|
105
|
+
.enum(["normal", "high"])
|
|
106
|
+
.default("normal")
|
|
107
|
+
.describe("How aggressively to review."),
|
|
108
|
+
models: providerListSchema.describe("Providers to ask for adversarial review."),
|
|
109
|
+
}, async ({ content, riskLevel, models }) => textResponse({
|
|
110
|
+
success: true,
|
|
111
|
+
tool: "red_team_review",
|
|
112
|
+
readMostly: true,
|
|
113
|
+
report: startValidationRun(deps, {
|
|
114
|
+
intent: "red_team",
|
|
115
|
+
content,
|
|
116
|
+
providers: models,
|
|
117
|
+
riskLevel,
|
|
118
|
+
}),
|
|
119
|
+
}));
|
|
120
|
+
server.tool("consensus_check", {
|
|
121
|
+
claim: z.string().min(1).describe("Claim to check across providers."),
|
|
122
|
+
models: providerListSchema.describe("Providers to ask for agreement or disagreement."),
|
|
123
|
+
}, async ({ claim, models }) => textResponse({
|
|
124
|
+
success: true,
|
|
125
|
+
tool: "consensus_check",
|
|
126
|
+
readMostly: true,
|
|
127
|
+
report: startValidationRun(deps, {
|
|
128
|
+
intent: "consensus",
|
|
129
|
+
content: claim,
|
|
130
|
+
providers: models,
|
|
131
|
+
}),
|
|
132
|
+
}));
|
|
133
|
+
server.tool("ask_model", {
|
|
134
|
+
question: z.string().min(1).describe("Question for one provider."),
|
|
135
|
+
model: providerSchema.default("claude").describe("Provider to ask."),
|
|
136
|
+
}, async ({ question, model }) => textResponse({
|
|
137
|
+
success: true,
|
|
138
|
+
tool: "ask_model",
|
|
139
|
+
readMostly: true,
|
|
140
|
+
report: startValidationRun(deps, {
|
|
141
|
+
intent: "ask_model",
|
|
142
|
+
question,
|
|
143
|
+
providers: [model],
|
|
144
|
+
}),
|
|
145
|
+
}));
|
|
146
|
+
server.tool("synthesize_validation", {
|
|
147
|
+
question: z.string().min(1).describe("Original request that was validated."),
|
|
148
|
+
providerResults: z
|
|
149
|
+
.array(normalizedProviderResultSchema)
|
|
150
|
+
.min(1)
|
|
151
|
+
.describe("Terminal normalized provider results from job_result."),
|
|
152
|
+
judgeModel: providerSchema.default("codex").describe("Provider to run the judge synthesis."),
|
|
153
|
+
}, async ({ question, providerResults, judgeModel }) => textResponse({
|
|
154
|
+
success: true,
|
|
155
|
+
tool: "synthesize_validation",
|
|
156
|
+
readMostly: true,
|
|
157
|
+
synthesis: startJudgeSynthesis(deps, {
|
|
158
|
+
question,
|
|
159
|
+
providerResults,
|
|
160
|
+
judgeProvider: judgeModel,
|
|
161
|
+
}),
|
|
162
|
+
}));
|
|
163
|
+
server.tool("list_available_models", {}, async () => textResponse({ success: true, models: getCliInfo() }));
|
|
164
|
+
server.tool("job_status", {
|
|
165
|
+
jobId: z.string().min(1).describe("Validation job ID."),
|
|
166
|
+
}, async ({ jobId }) => {
|
|
167
|
+
const job = deps.asyncJobManager.getJobSnapshot(jobId);
|
|
168
|
+
if (!job) {
|
|
169
|
+
return textResponse({ success: false, error: "Job not found", jobId });
|
|
170
|
+
}
|
|
171
|
+
return textResponse({ success: true, job });
|
|
172
|
+
});
|
|
173
|
+
server.tool("job_result", {
|
|
174
|
+
jobId: z.string().min(1).describe("Validation job ID."),
|
|
175
|
+
provider: providerSchema
|
|
176
|
+
.optional()
|
|
177
|
+
.describe("Provider that produced the job, used for normalized validation output."),
|
|
178
|
+
maxChars: z
|
|
179
|
+
.number()
|
|
180
|
+
.int()
|
|
181
|
+
.min(1000)
|
|
182
|
+
.max(2000000)
|
|
183
|
+
.default(200000)
|
|
184
|
+
.describe("Maximum result size."),
|
|
185
|
+
}, async ({ jobId, provider, maxChars }) => {
|
|
186
|
+
const result = deps.asyncJobManager.getJobResult(jobId, maxChars);
|
|
187
|
+
if (!result) {
|
|
188
|
+
return textResponse({ success: false, error: "Job not found", jobId });
|
|
189
|
+
}
|
|
190
|
+
return textResponse({
|
|
191
|
+
success: true,
|
|
192
|
+
result,
|
|
193
|
+
normalized: provider !== undefined
|
|
194
|
+
? collectValidationJobResult(deps, provider, jobId, null, maxChars)
|
|
195
|
+
: null,
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "llm-cli-gateway",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.13",
|
|
4
4
|
"mcpName": "io.github.verivus-oss/llm-cli-gateway",
|
|
5
|
-
"description": "MCP server providing unified access to Claude Code, Codex, Gemini, and
|
|
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",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "VerivusAI Labs",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
13
|
-
"url": "https://github.com/verivus-oss/llm-cli-gateway.git"
|
|
13
|
+
"url": "git+https://github.com/verivus-oss/llm-cli-gateway.git"
|
|
14
14
|
},
|
|
15
15
|
"homepage": "https://github.com/verivus-oss/llm-cli-gateway#readme",
|
|
16
16
|
"bugs": {
|
|
@@ -33,10 +33,14 @@
|
|
|
33
33
|
".": {
|
|
34
34
|
"types": "./dist/index.d.ts",
|
|
35
35
|
"default": "./dist/index.js"
|
|
36
|
+
},
|
|
37
|
+
"./gateway-server": {
|
|
38
|
+
"types": "./dist/gateway-server.d.ts",
|
|
39
|
+
"default": "./dist/gateway-server.js"
|
|
36
40
|
}
|
|
37
41
|
},
|
|
38
42
|
"bin": {
|
|
39
|
-
"llm-cli-gateway": "
|
|
43
|
+
"llm-cli-gateway": "dist/index.js"
|
|
40
44
|
},
|
|
41
45
|
"engines": {
|
|
42
46
|
"node": ">=20.0.0"
|
|
@@ -45,6 +49,7 @@
|
|
|
45
49
|
"dist/**/*.js",
|
|
46
50
|
"dist/**/*.d.ts",
|
|
47
51
|
"!dist/__tests__/**",
|
|
52
|
+
"setup/status.schema.json",
|
|
48
53
|
"README.md",
|
|
49
54
|
"CHANGELOG.md",
|
|
50
55
|
"LICENSE"
|
|
@@ -54,8 +59,11 @@
|
|
|
54
59
|
"build:all": "tsc",
|
|
55
60
|
"prepublishOnly": "npm run build && npm test",
|
|
56
61
|
"start": "node dist/index.js",
|
|
62
|
+
"start:http": "node dist/index.js --transport=http",
|
|
63
|
+
"doctor": "node dist/index.js doctor --json",
|
|
57
64
|
"migrate": "node dist/migrate.js",
|
|
58
65
|
"test": "vitest run",
|
|
66
|
+
"test:ci": "vitest run --pool=forks --maxWorkers=1",
|
|
59
67
|
"test:coverage": "vitest run --coverage",
|
|
60
68
|
"test:watch": "vitest",
|
|
61
69
|
"test:unit": "vitest run src/__tests__/executor.test.ts",
|
|
@@ -68,11 +76,14 @@
|
|
|
68
76
|
"lint:fix": "eslint src/**/*.ts --fix",
|
|
69
77
|
"format": "prettier --write 'src/**/*.ts'",
|
|
70
78
|
"format:check": "prettier --check 'src/**/*.ts'",
|
|
71
|
-
"check": "npm run build && npm run lint && npm test"
|
|
79
|
+
"check": "npm run build && npm run lint && npm test",
|
|
80
|
+
"release:build": "bash installer/build-release.sh",
|
|
81
|
+
"release:checksums": "cd installer/dist && sha256sum --check SHA256SUMS",
|
|
82
|
+
"release:docker": "docker compose -f docker-compose.personal.yml build"
|
|
72
83
|
},
|
|
73
84
|
"dependencies": {
|
|
74
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
75
|
-
"better-sqlite3": "^12.
|
|
85
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
86
|
+
"better-sqlite3": "^12.10.0",
|
|
76
87
|
"ioredis": "^5.4.1",
|
|
77
88
|
"pg": "^8.12.0",
|
|
78
89
|
"toml": "^3.0.0",
|
|
@@ -82,13 +93,17 @@
|
|
|
82
93
|
"@types/better-sqlite3": "^7.6.0",
|
|
83
94
|
"@types/node": "^20.19.30",
|
|
84
95
|
"@types/pg": "^8.11.10",
|
|
85
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
86
|
-
"@typescript-eslint/parser": "^
|
|
96
|
+
"@typescript-eslint/eslint-plugin": "^8.59.4",
|
|
97
|
+
"@typescript-eslint/parser": "^8.59.4",
|
|
87
98
|
"@vitest/coverage-v8": "^4.1.2",
|
|
88
|
-
"eslint": "^8.
|
|
99
|
+
"eslint": "^8.57.1",
|
|
89
100
|
"eslint-config-prettier": "^9.0.0",
|
|
90
101
|
"prettier": "^3.0.0",
|
|
91
102
|
"typescript": "^5.0.0",
|
|
92
103
|
"vitest": "^4.0.18"
|
|
104
|
+
},
|
|
105
|
+
"overrides": {
|
|
106
|
+
"type-is": "2.0.1",
|
|
107
|
+
"content-type": "1.0.5"
|
|
93
108
|
}
|
|
94
109
|
}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://verivus.ai/schemas/llm-cli-gateway/status.schema.json",
|
|
4
|
+
"title": "llm-cli-gateway doctor status",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": [
|
|
7
|
+
"schema_version",
|
|
8
|
+
"ok",
|
|
9
|
+
"generated_at",
|
|
10
|
+
"system",
|
|
11
|
+
"gateway",
|
|
12
|
+
"transport",
|
|
13
|
+
"auth",
|
|
14
|
+
"providers",
|
|
15
|
+
"endpoint_exposure",
|
|
16
|
+
"client_config",
|
|
17
|
+
"next_actions"
|
|
18
|
+
],
|
|
19
|
+
"properties": {
|
|
20
|
+
"schema_version": { "const": "1.0" },
|
|
21
|
+
"ok": { "type": "boolean" },
|
|
22
|
+
"generated_at": { "type": "string", "format": "date-time" },
|
|
23
|
+
"system": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"required": ["os", "arch", "release", "node_version"],
|
|
26
|
+
"properties": {
|
|
27
|
+
"os": { "type": "string" },
|
|
28
|
+
"arch": { "type": "string" },
|
|
29
|
+
"release": { "type": "string" },
|
|
30
|
+
"node_version": { "type": "string" }
|
|
31
|
+
},
|
|
32
|
+
"additionalProperties": false
|
|
33
|
+
},
|
|
34
|
+
"gateway": {
|
|
35
|
+
"type": "object",
|
|
36
|
+
"required": ["name", "version"],
|
|
37
|
+
"properties": {
|
|
38
|
+
"name": { "const": "llm-cli-gateway" },
|
|
39
|
+
"version": { "type": "string" }
|
|
40
|
+
},
|
|
41
|
+
"additionalProperties": false
|
|
42
|
+
},
|
|
43
|
+
"transport": {
|
|
44
|
+
"type": "object",
|
|
45
|
+
"required": ["default", "http"],
|
|
46
|
+
"properties": {
|
|
47
|
+
"default": { "enum": ["stdio", "http"] },
|
|
48
|
+
"http": {
|
|
49
|
+
"type": "object",
|
|
50
|
+
"required": ["enabled", "host", "port", "path", "public_url_configured", "public_url"],
|
|
51
|
+
"properties": {
|
|
52
|
+
"enabled": { "type": "boolean" },
|
|
53
|
+
"host": { "type": "string" },
|
|
54
|
+
"port": { "type": "integer", "minimum": 1, "maximum": 65535 },
|
|
55
|
+
"path": { "type": "string" },
|
|
56
|
+
"public_url_configured": { "type": "boolean" },
|
|
57
|
+
"public_url": { "type": ["string", "null"] }
|
|
58
|
+
},
|
|
59
|
+
"additionalProperties": false
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"additionalProperties": false
|
|
63
|
+
},
|
|
64
|
+
"auth": {
|
|
65
|
+
"type": "object",
|
|
66
|
+
"required": ["required", "token_configured", "source"],
|
|
67
|
+
"properties": {
|
|
68
|
+
"required": { "type": "boolean" },
|
|
69
|
+
"token_configured": { "type": "boolean" },
|
|
70
|
+
"source": { "enum": ["env", "disabled"] }
|
|
71
|
+
},
|
|
72
|
+
"additionalProperties": false
|
|
73
|
+
},
|
|
74
|
+
"providers": {
|
|
75
|
+
"type": "object",
|
|
76
|
+
"required": ["claude", "codex", "gemini", "grok", "mistral"],
|
|
77
|
+
"additionalProperties": {
|
|
78
|
+
"type": "object",
|
|
79
|
+
"required": [
|
|
80
|
+
"cli_available",
|
|
81
|
+
"version",
|
|
82
|
+
"login_status",
|
|
83
|
+
"version_command",
|
|
84
|
+
"login_check",
|
|
85
|
+
"install_guidance",
|
|
86
|
+
"login_guidance"
|
|
87
|
+
],
|
|
88
|
+
"properties": {
|
|
89
|
+
"cli_available": { "type": "boolean" },
|
|
90
|
+
"version": { "type": ["string", "null"] },
|
|
91
|
+
"login_status": {
|
|
92
|
+
"enum": ["authenticated", "not_authenticated", "unknown", "not_checked"]
|
|
93
|
+
},
|
|
94
|
+
"version_command": {
|
|
95
|
+
"type": "array",
|
|
96
|
+
"items": { "type": "string" }
|
|
97
|
+
},
|
|
98
|
+
"login_check": {
|
|
99
|
+
"type": "object",
|
|
100
|
+
"required": ["method", "command", "credential_store", "detail"],
|
|
101
|
+
"properties": {
|
|
102
|
+
"method": { "enum": ["cli", "credential_store", "not_checked"] },
|
|
103
|
+
"command": {
|
|
104
|
+
"type": ["array", "null"],
|
|
105
|
+
"items": { "type": "string" }
|
|
106
|
+
},
|
|
107
|
+
"credential_store": { "enum": ["present", "not_found", "not_checked"] },
|
|
108
|
+
"detail": { "type": "string" }
|
|
109
|
+
},
|
|
110
|
+
"additionalProperties": false
|
|
111
|
+
},
|
|
112
|
+
"install_guidance": {
|
|
113
|
+
"type": "object",
|
|
114
|
+
"required": ["summary", "commands"],
|
|
115
|
+
"properties": {
|
|
116
|
+
"summary": { "type": "string" },
|
|
117
|
+
"commands": {
|
|
118
|
+
"type": "array",
|
|
119
|
+
"items": { "type": "string" }
|
|
120
|
+
},
|
|
121
|
+
"documentation_url": { "type": "string" }
|
|
122
|
+
},
|
|
123
|
+
"additionalProperties": false
|
|
124
|
+
},
|
|
125
|
+
"login_guidance": {
|
|
126
|
+
"type": "object",
|
|
127
|
+
"required": ["summary", "commands", "credential_handling"],
|
|
128
|
+
"properties": {
|
|
129
|
+
"summary": { "type": "string" },
|
|
130
|
+
"commands": {
|
|
131
|
+
"type": "array",
|
|
132
|
+
"items": { "type": "string" }
|
|
133
|
+
},
|
|
134
|
+
"credential_handling": { "type": "string" }
|
|
135
|
+
},
|
|
136
|
+
"additionalProperties": false
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
"additionalProperties": false
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
"endpoint_exposure": {
|
|
143
|
+
"type": "object",
|
|
144
|
+
"required": [
|
|
145
|
+
"mode",
|
|
146
|
+
"local_url",
|
|
147
|
+
"public_url_configured",
|
|
148
|
+
"public_url",
|
|
149
|
+
"https_required_for_web",
|
|
150
|
+
"https_configured",
|
|
151
|
+
"web_clients_supported",
|
|
152
|
+
"tunnel_provider",
|
|
153
|
+
"reachable_from_web",
|
|
154
|
+
"verification",
|
|
155
|
+
"next_actions"
|
|
156
|
+
],
|
|
157
|
+
"properties": {
|
|
158
|
+
"mode": {
|
|
159
|
+
"enum": ["local_only", "lan", "tunnel", "byo_reverse_proxy", "misconfigured"]
|
|
160
|
+
},
|
|
161
|
+
"local_url": { "type": "string" },
|
|
162
|
+
"public_url_configured": { "type": "boolean" },
|
|
163
|
+
"public_url": { "type": ["string", "null"] },
|
|
164
|
+
"https_required_for_web": { "type": "boolean" },
|
|
165
|
+
"https_configured": { "type": "boolean" },
|
|
166
|
+
"web_clients_supported": { "type": "boolean" },
|
|
167
|
+
"tunnel_provider": { "type": ["string", "null"] },
|
|
168
|
+
"reachable_from_web": { "enum": ["not_checked", "reachable", "unreachable"] },
|
|
169
|
+
"verification": {
|
|
170
|
+
"type": "object",
|
|
171
|
+
"required": ["method", "checked_url", "status_code", "error"],
|
|
172
|
+
"properties": {
|
|
173
|
+
"method": { "enum": ["not_checked", "http_head"] },
|
|
174
|
+
"checked_url": { "type": ["string", "null"] },
|
|
175
|
+
"status_code": { "type": ["integer", "null"] },
|
|
176
|
+
"error": { "type": ["string", "null"] }
|
|
177
|
+
},
|
|
178
|
+
"additionalProperties": false
|
|
179
|
+
},
|
|
180
|
+
"next_actions": {
|
|
181
|
+
"type": "array",
|
|
182
|
+
"items": { "type": "string" }
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
"additionalProperties": false
|
|
186
|
+
},
|
|
187
|
+
"client_config": {
|
|
188
|
+
"type": "object",
|
|
189
|
+
"required": [
|
|
190
|
+
"claude_desktop_config_present",
|
|
191
|
+
"codex_config_present",
|
|
192
|
+
"gemini_settings_present",
|
|
193
|
+
"gemini_config",
|
|
194
|
+
"vibe_session_logging"
|
|
195
|
+
],
|
|
196
|
+
"properties": {
|
|
197
|
+
"claude_desktop_config_present": { "type": "boolean" },
|
|
198
|
+
"codex_config_present": { "type": "boolean" },
|
|
199
|
+
"gemini_settings_present": { "type": "boolean" },
|
|
200
|
+
"gemini_config": {
|
|
201
|
+
"type": "object",
|
|
202
|
+
"required": [
|
|
203
|
+
"project_gemini_md_present",
|
|
204
|
+
"project_gemini_md_path",
|
|
205
|
+
"user_gemini_md_present",
|
|
206
|
+
"user_gemini_md_path",
|
|
207
|
+
"settings_json_present",
|
|
208
|
+
"settings_json_path",
|
|
209
|
+
"mcp_servers_registered",
|
|
210
|
+
"mcp_reconciliation",
|
|
211
|
+
"next_actions"
|
|
212
|
+
],
|
|
213
|
+
"properties": {
|
|
214
|
+
"project_gemini_md_present": { "type": "boolean" },
|
|
215
|
+
"project_gemini_md_path": { "type": "string" },
|
|
216
|
+
"user_gemini_md_present": { "type": "boolean" },
|
|
217
|
+
"user_gemini_md_path": { "type": "string" },
|
|
218
|
+
"settings_json_present": { "type": "boolean" },
|
|
219
|
+
"settings_json_path": { "type": "string" },
|
|
220
|
+
"mcp_servers_registered": {
|
|
221
|
+
"type": "array",
|
|
222
|
+
"items": { "type": "string" }
|
|
223
|
+
},
|
|
224
|
+
"mcp_reconciliation": {
|
|
225
|
+
"type": "object",
|
|
226
|
+
"required": ["whitelisted", "missing_from_settings"],
|
|
227
|
+
"properties": {
|
|
228
|
+
"whitelisted": {
|
|
229
|
+
"type": "array",
|
|
230
|
+
"items": { "type": "string" }
|
|
231
|
+
},
|
|
232
|
+
"missing_from_settings": {
|
|
233
|
+
"type": "array",
|
|
234
|
+
"items": { "type": "string" }
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
"additionalProperties": false
|
|
238
|
+
},
|
|
239
|
+
"next_actions": {
|
|
240
|
+
"type": "array",
|
|
241
|
+
"items": { "type": "string" }
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
"additionalProperties": false
|
|
245
|
+
},
|
|
246
|
+
"vibe_session_logging": {
|
|
247
|
+
"type": "object",
|
|
248
|
+
"required": [
|
|
249
|
+
"config_path",
|
|
250
|
+
"config_present",
|
|
251
|
+
"session_logging_enabled",
|
|
252
|
+
"note"
|
|
253
|
+
],
|
|
254
|
+
"properties": {
|
|
255
|
+
"config_path": { "type": "string" },
|
|
256
|
+
"config_present": { "type": "boolean" },
|
|
257
|
+
"session_logging_enabled": { "type": "boolean" },
|
|
258
|
+
"note": { "type": "string" }
|
|
259
|
+
},
|
|
260
|
+
"additionalProperties": false
|
|
261
|
+
}
|
|
262
|
+
},
|
|
263
|
+
"additionalProperties": false
|
|
264
|
+
},
|
|
265
|
+
"next_actions": {
|
|
266
|
+
"type": "array",
|
|
267
|
+
"items": { "type": "string" }
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
"additionalProperties": false
|
|
271
|
+
}
|