llm-cli-gateway 2.11.1 → 2.12.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/.agents/skills/async-job-orchestration/SKILL.md +288 -0
- package/.agents/skills/implement-review-fix/SKILL.md +154 -0
- package/.agents/skills/multi-llm-review/SKILL.md +174 -0
- package/.agents/skills/public-demo-session/SKILL.md +100 -0
- package/.agents/skills/secure-orchestration/SKILL.md +227 -0
- package/.agents/skills/session-workflow/SKILL.md +271 -0
- package/CHANGELOG.md +40 -0
- package/README.md +48 -19
- package/dist/acp/provider-registry.js +5 -5
- package/dist/api-provider.d.ts +7 -0
- package/dist/api-provider.js +7 -0
- package/dist/api-request.js +1 -0
- package/dist/async-job-manager.d.ts +11 -1
- package/dist/async-job-manager.js +44 -3
- package/dist/config.d.ts +2 -0
- package/dist/config.js +3 -0
- package/dist/index.d.ts +38 -2
- package/dist/index.js +609 -156
- package/dist/job-store.d.ts +48 -1
- package/dist/job-store.js +184 -0
- package/dist/provider-codegen.js +3 -0
- package/dist/provider-tool-capabilities.js +7 -7
- package/dist/upstream-contracts.d.ts +1 -0
- package/dist/upstream-contracts.js +128 -21
- package/dist/validation-orchestrator.d.ts +5 -2
- package/dist/validation-orchestrator.js +71 -5
- package/dist/validation-receipt.d.ts +68 -0
- package/dist/validation-receipt.js +245 -0
- package/dist/validation-report.d.ts +4 -2
- package/dist/validation-report.js +18 -1
- package/dist/validation-tools.js +58 -9
- package/npm-shrinkwrap.json +5 -5
- package/package.json +10 -4
- package/dist/xai-api-provider.d.ts +0 -43
- package/dist/xai-api-provider.js +0 -191
package/dist/job-store.d.ts
CHANGED
|
@@ -73,7 +73,46 @@ export interface OrphanedJobSnapshot {
|
|
|
73
73
|
transport: JobTransport;
|
|
74
74
|
httpStatus: number | null;
|
|
75
75
|
}
|
|
76
|
-
export
|
|
76
|
+
export interface ValidationRunLink {
|
|
77
|
+
provider: string;
|
|
78
|
+
jobId: string;
|
|
79
|
+
correlationId: string;
|
|
80
|
+
}
|
|
81
|
+
export interface ValidationRunRecord {
|
|
82
|
+
validationId: string;
|
|
83
|
+
ownerPrincipal: string;
|
|
84
|
+
intent: string;
|
|
85
|
+
createdAt: string;
|
|
86
|
+
requestJson: string;
|
|
87
|
+
providerLinks: ValidationRunLink[];
|
|
88
|
+
judgeLink: ValidationRunLink | null;
|
|
89
|
+
status: "running" | "finalized";
|
|
90
|
+
}
|
|
91
|
+
export interface ValidationReceiptRecord {
|
|
92
|
+
validationId: string;
|
|
93
|
+
ownerPrincipal: string;
|
|
94
|
+
mintedAt: string;
|
|
95
|
+
schemaVersion: string;
|
|
96
|
+
reportJson: string;
|
|
97
|
+
canonicalSha256: string;
|
|
98
|
+
prevSha256: string | null;
|
|
99
|
+
seq: number | null;
|
|
100
|
+
signature: string | null;
|
|
101
|
+
models: string[];
|
|
102
|
+
hasMaterialDisagreement: boolean;
|
|
103
|
+
confidence: string;
|
|
104
|
+
}
|
|
105
|
+
export interface ValidationRunStore {
|
|
106
|
+
recordValidationRun(run: ValidationRunRecord): void;
|
|
107
|
+
getValidationRun(validationId: string): ValidationRunRecord | null;
|
|
108
|
+
setValidationJudgeLink(validationId: string, judgeLink: ValidationRunLink): void;
|
|
109
|
+
setValidationRunStatus(validationId: string, status: ValidationRunRecord["status"]): void;
|
|
110
|
+
getValidationRunIdByJobId(jobId: string): string | null;
|
|
111
|
+
recordValidationReceipt(receipt: ValidationReceiptRecord): void;
|
|
112
|
+
getValidationReceipt(validationId: string): ValidationReceiptRecord | null;
|
|
113
|
+
}
|
|
114
|
+
export declare function isValidationRunStore(store: unknown): store is ValidationRunStore;
|
|
115
|
+
export declare class SqliteJobStore implements JobStore, ValidationRunStore {
|
|
77
116
|
private logger;
|
|
78
117
|
private db;
|
|
79
118
|
private retentionMs;
|
|
@@ -122,6 +161,14 @@ export declare class SqliteJobStore implements JobStore {
|
|
|
122
161
|
orphaned: Array<OrphanedJobSnapshot>;
|
|
123
162
|
};
|
|
124
163
|
evictExpired(): number;
|
|
164
|
+
recordValidationRun(run: ValidationRunRecord): void;
|
|
165
|
+
private linkRunJob;
|
|
166
|
+
getValidationRunIdByJobId(jobId: string): string | null;
|
|
167
|
+
getValidationRun(validationId: string): ValidationRunRecord | null;
|
|
168
|
+
setValidationJudgeLink(validationId: string, judgeLink: ValidationRunLink): void;
|
|
169
|
+
setValidationRunStatus(validationId: string, status: ValidationRunRecord["status"]): void;
|
|
170
|
+
recordValidationReceipt(receipt: ValidationReceiptRecord): void;
|
|
171
|
+
getValidationReceipt(validationId: string): ValidationReceiptRecord | null;
|
|
125
172
|
close(): void;
|
|
126
173
|
}
|
|
127
174
|
export declare const JobStoreClass: typeof SqliteJobStore;
|
package/dist/job-store.js
CHANGED
|
@@ -83,6 +83,13 @@ function ensureJobsTransportColumns(db) {
|
|
|
83
83
|
db.exec("ALTER TABLE jobs ADD COLUMN payload_json TEXT");
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
|
+
export function isValidationRunStore(store) {
|
|
87
|
+
return (typeof store === "object" &&
|
|
88
|
+
store !== null &&
|
|
89
|
+
typeof store.recordValidationRun === "function" &&
|
|
90
|
+
typeof store.getValidationRun === "function" &&
|
|
91
|
+
typeof store.recordValidationReceipt === "function");
|
|
92
|
+
}
|
|
86
93
|
export class SqliteJobStore {
|
|
87
94
|
logger;
|
|
88
95
|
db;
|
|
@@ -128,6 +135,42 @@ export class SqliteJobStore {
|
|
|
128
135
|
CREATE INDEX IF NOT EXISTS idx_jobs_status ON jobs(status);
|
|
129
136
|
CREATE INDEX IF NOT EXISTS idx_jobs_expires_at ON jobs(expires_at);
|
|
130
137
|
CREATE INDEX IF NOT EXISTS idx_jobs_request_key_finished ON jobs(request_key, finished_at);
|
|
138
|
+
`);
|
|
139
|
+
this.db.exec(`
|
|
140
|
+
CREATE TABLE IF NOT EXISTS validation_runs (
|
|
141
|
+
validation_id TEXT PRIMARY KEY,
|
|
142
|
+
owner_principal TEXT NOT NULL,
|
|
143
|
+
intent TEXT NOT NULL,
|
|
144
|
+
created_at TEXT NOT NULL,
|
|
145
|
+
request_json TEXT NOT NULL,
|
|
146
|
+
provider_links TEXT NOT NULL,
|
|
147
|
+
judge_link TEXT,
|
|
148
|
+
status TEXT NOT NULL
|
|
149
|
+
);
|
|
150
|
+
CREATE INDEX IF NOT EXISTS idx_validation_runs_owner ON validation_runs(owner_principal);
|
|
151
|
+
`);
|
|
152
|
+
this.db.exec(`
|
|
153
|
+
CREATE TABLE IF NOT EXISTS validation_run_jobs (
|
|
154
|
+
job_id TEXT PRIMARY KEY,
|
|
155
|
+
validation_id TEXT NOT NULL,
|
|
156
|
+
role TEXT NOT NULL
|
|
157
|
+
);
|
|
158
|
+
CREATE INDEX IF NOT EXISTS idx_validation_run_jobs_run ON validation_run_jobs(validation_id);
|
|
159
|
+
CREATE TABLE IF NOT EXISTS validation_receipts (
|
|
160
|
+
validation_id TEXT PRIMARY KEY,
|
|
161
|
+
owner_principal TEXT NOT NULL,
|
|
162
|
+
minted_at TEXT NOT NULL,
|
|
163
|
+
schema_version TEXT NOT NULL,
|
|
164
|
+
report_json TEXT NOT NULL,
|
|
165
|
+
canonical_sha256 TEXT NOT NULL,
|
|
166
|
+
prev_sha256 TEXT,
|
|
167
|
+
seq INTEGER,
|
|
168
|
+
signature TEXT,
|
|
169
|
+
models TEXT NOT NULL,
|
|
170
|
+
has_material_disagreement INTEGER NOT NULL,
|
|
171
|
+
confidence TEXT NOT NULL
|
|
172
|
+
);
|
|
173
|
+
CREATE INDEX IF NOT EXISTS idx_validation_receipts_owner ON validation_receipts(owner_principal);
|
|
131
174
|
`);
|
|
132
175
|
ensureJobsOwnerColumn(this.db);
|
|
133
176
|
ensureJobsTransportColumns(this.db);
|
|
@@ -262,6 +305,86 @@ export class SqliteJobStore {
|
|
|
262
305
|
const result = this.deleteExpiredStmt.run(now);
|
|
263
306
|
return Number(result.changes);
|
|
264
307
|
}
|
|
308
|
+
recordValidationRun(run) {
|
|
309
|
+
this.db
|
|
310
|
+
.prepare(`INSERT OR IGNORE INTO validation_runs
|
|
311
|
+
(validation_id, owner_principal, intent, created_at, request_json,
|
|
312
|
+
provider_links, judge_link, status)
|
|
313
|
+
VALUES (@validation_id, @owner_principal, @intent, @created_at, @request_json,
|
|
314
|
+
@provider_links, @judge_link, @status)`)
|
|
315
|
+
.run({
|
|
316
|
+
validation_id: run.validationId,
|
|
317
|
+
owner_principal: run.ownerPrincipal,
|
|
318
|
+
intent: run.intent,
|
|
319
|
+
created_at: run.createdAt,
|
|
320
|
+
request_json: run.requestJson,
|
|
321
|
+
provider_links: JSON.stringify(run.providerLinks),
|
|
322
|
+
judge_link: run.judgeLink ? JSON.stringify(run.judgeLink) : null,
|
|
323
|
+
status: run.status,
|
|
324
|
+
});
|
|
325
|
+
for (const link of run.providerLinks) {
|
|
326
|
+
this.linkRunJob(run.validationId, link.jobId, "provider");
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
linkRunJob(validationId, jobId, role) {
|
|
330
|
+
this.db
|
|
331
|
+
.prepare(`INSERT OR IGNORE INTO validation_run_jobs (job_id, validation_id, role)
|
|
332
|
+
VALUES (?, ?, ?)`)
|
|
333
|
+
.run(jobId, validationId, role);
|
|
334
|
+
}
|
|
335
|
+
getValidationRunIdByJobId(jobId) {
|
|
336
|
+
const row = this.db
|
|
337
|
+
.prepare(`SELECT validation_id FROM validation_run_jobs WHERE job_id = ?`)
|
|
338
|
+
.get(jobId);
|
|
339
|
+
return row?.validation_id ?? null;
|
|
340
|
+
}
|
|
341
|
+
getValidationRun(validationId) {
|
|
342
|
+
const row = this.db
|
|
343
|
+
.prepare(`SELECT * FROM validation_runs WHERE validation_id = ?`)
|
|
344
|
+
.get(validationId);
|
|
345
|
+
return row ? rowToValidationRunRecord(row) : null;
|
|
346
|
+
}
|
|
347
|
+
setValidationJudgeLink(validationId, judgeLink) {
|
|
348
|
+
this.db
|
|
349
|
+
.prepare(`UPDATE validation_runs SET judge_link = ? WHERE validation_id = ?`)
|
|
350
|
+
.run(JSON.stringify(judgeLink), validationId);
|
|
351
|
+
this.linkRunJob(validationId, judgeLink.jobId, "judge");
|
|
352
|
+
}
|
|
353
|
+
setValidationRunStatus(validationId, status) {
|
|
354
|
+
this.db
|
|
355
|
+
.prepare(`UPDATE validation_runs SET status = ? WHERE validation_id = ?`)
|
|
356
|
+
.run(status, validationId);
|
|
357
|
+
}
|
|
358
|
+
recordValidationReceipt(receipt) {
|
|
359
|
+
this.db
|
|
360
|
+
.prepare(`INSERT OR IGNORE INTO validation_receipts
|
|
361
|
+
(validation_id, owner_principal, minted_at, schema_version, report_json,
|
|
362
|
+
canonical_sha256, prev_sha256, seq, signature, models,
|
|
363
|
+
has_material_disagreement, confidence)
|
|
364
|
+
VALUES (@validation_id, @owner_principal, @minted_at, @schema_version, @report_json,
|
|
365
|
+
@canonical_sha256, @prev_sha256, @seq, @signature, @models,
|
|
366
|
+
@has_material_disagreement, @confidence)`)
|
|
367
|
+
.run({
|
|
368
|
+
validation_id: receipt.validationId,
|
|
369
|
+
owner_principal: receipt.ownerPrincipal,
|
|
370
|
+
minted_at: receipt.mintedAt,
|
|
371
|
+
schema_version: receipt.schemaVersion,
|
|
372
|
+
report_json: receipt.reportJson,
|
|
373
|
+
canonical_sha256: receipt.canonicalSha256,
|
|
374
|
+
prev_sha256: receipt.prevSha256,
|
|
375
|
+
seq: receipt.seq,
|
|
376
|
+
signature: receipt.signature,
|
|
377
|
+
models: JSON.stringify(receipt.models),
|
|
378
|
+
has_material_disagreement: receipt.hasMaterialDisagreement ? 1 : 0,
|
|
379
|
+
confidence: receipt.confidence,
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
getValidationReceipt(validationId) {
|
|
383
|
+
const row = this.db
|
|
384
|
+
.prepare(`SELECT * FROM validation_receipts WHERE validation_id = ?`)
|
|
385
|
+
.get(validationId);
|
|
386
|
+
return row ? rowToValidationReceiptRecord(row) : null;
|
|
387
|
+
}
|
|
265
388
|
close() {
|
|
266
389
|
try {
|
|
267
390
|
this.db.close();
|
|
@@ -271,6 +394,67 @@ export class SqliteJobStore {
|
|
|
271
394
|
}
|
|
272
395
|
}
|
|
273
396
|
}
|
|
397
|
+
function rowToValidationRunRecord(row) {
|
|
398
|
+
return {
|
|
399
|
+
validationId: row.validation_id,
|
|
400
|
+
ownerPrincipal: row.owner_principal,
|
|
401
|
+
intent: row.intent,
|
|
402
|
+
createdAt: row.created_at,
|
|
403
|
+
requestJson: row.request_json,
|
|
404
|
+
providerLinks: parseLinks(row.provider_links) ?? [],
|
|
405
|
+
judgeLink: parseLink(row.judge_link),
|
|
406
|
+
status: row.status,
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
function rowToValidationReceiptRecord(row) {
|
|
410
|
+
return {
|
|
411
|
+
validationId: row.validation_id,
|
|
412
|
+
ownerPrincipal: row.owner_principal,
|
|
413
|
+
mintedAt: row.minted_at,
|
|
414
|
+
schemaVersion: row.schema_version,
|
|
415
|
+
reportJson: row.report_json,
|
|
416
|
+
canonicalSha256: row.canonical_sha256,
|
|
417
|
+
prevSha256: row.prev_sha256 ?? null,
|
|
418
|
+
seq: row.seq ?? null,
|
|
419
|
+
signature: row.signature ?? null,
|
|
420
|
+
models: parseStringArray(row.models),
|
|
421
|
+
hasMaterialDisagreement: Boolean(row.has_material_disagreement),
|
|
422
|
+
confidence: row.confidence,
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
function parseLinks(value) {
|
|
426
|
+
if (typeof value !== "string" || value.length === 0)
|
|
427
|
+
return null;
|
|
428
|
+
try {
|
|
429
|
+
const parsed = JSON.parse(value);
|
|
430
|
+
return Array.isArray(parsed) ? parsed : null;
|
|
431
|
+
}
|
|
432
|
+
catch {
|
|
433
|
+
return null;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
function parseStringArray(value) {
|
|
437
|
+
if (typeof value !== "string" || value.length === 0)
|
|
438
|
+
return [];
|
|
439
|
+
try {
|
|
440
|
+
const parsed = JSON.parse(value);
|
|
441
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
442
|
+
}
|
|
443
|
+
catch {
|
|
444
|
+
return [];
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
function parseLink(value) {
|
|
448
|
+
if (typeof value !== "string" || value.length === 0)
|
|
449
|
+
return null;
|
|
450
|
+
try {
|
|
451
|
+
const parsed = JSON.parse(value);
|
|
452
|
+
return parsed && typeof parsed === "object" ? parsed : null;
|
|
453
|
+
}
|
|
454
|
+
catch {
|
|
455
|
+
return null;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
274
458
|
export const JobStoreClass = SqliteJobStore;
|
|
275
459
|
export class MemoryJobStore {
|
|
276
460
|
rows = new Map();
|
package/dist/provider-codegen.js
CHANGED
|
@@ -49,7 +49,7 @@ export const ACP_CONTRACT = {
|
|
|
49
49
|
},
|
|
50
50
|
gemini: {
|
|
51
51
|
classification: "absent_watchlist",
|
|
52
|
-
summary: "Google Antigravity agy 1.0.
|
|
52
|
+
summary: "Google Antigravity agy 1.0.13 has no ACP surface; watchlist item only.",
|
|
53
53
|
},
|
|
54
54
|
grok_api: {
|
|
55
55
|
classification: "absent_watchlist",
|
|
@@ -80,7 +80,7 @@ const ACP_CAPABILITIES = {
|
|
|
80
80
|
grok: {
|
|
81
81
|
status: "native_smoke_passed",
|
|
82
82
|
mediation: "native",
|
|
83
|
-
targetVersion: "grok 0.2.
|
|
83
|
+
targetVersion: "grok 0.2.73 (9ff14c43bb)",
|
|
84
84
|
entrypoint: { command: "grok", args: ["agent", "stdio"] },
|
|
85
85
|
runtimeEnabled: false,
|
|
86
86
|
smokeSupported: true,
|
|
@@ -95,7 +95,7 @@ const ACP_CAPABILITIES = {
|
|
|
95
95
|
codex: {
|
|
96
96
|
status: "adapter_mediated_deferred",
|
|
97
97
|
mediation: "adapter_mediated",
|
|
98
|
-
targetVersion: "codex-cli 0.
|
|
98
|
+
targetVersion: "codex-cli 0.142.4",
|
|
99
99
|
entrypoint: null,
|
|
100
100
|
runtimeEnabled: false,
|
|
101
101
|
smokeSupported: false,
|
|
@@ -109,7 +109,7 @@ const ACP_CAPABILITIES = {
|
|
|
109
109
|
claude: {
|
|
110
110
|
status: "adapter_mediated_deferred",
|
|
111
111
|
mediation: "adapter_mediated",
|
|
112
|
-
targetVersion: "claude 2.1.
|
|
112
|
+
targetVersion: "claude 2.1.195",
|
|
113
113
|
entrypoint: null,
|
|
114
114
|
runtimeEnabled: false,
|
|
115
115
|
smokeSupported: false,
|
|
@@ -123,13 +123,13 @@ const ACP_CAPABILITIES = {
|
|
|
123
123
|
gemini: {
|
|
124
124
|
status: "absent_watchlist",
|
|
125
125
|
mediation: "none",
|
|
126
|
-
targetVersion: "agy 1.0.
|
|
126
|
+
targetVersion: "agy 1.0.13",
|
|
127
127
|
entrypoint: null,
|
|
128
128
|
runtimeEnabled: false,
|
|
129
129
|
smokeSupported: false,
|
|
130
130
|
smokeStatus: "unsupported",
|
|
131
131
|
caveats: [
|
|
132
|
-
"Antigravity agy 1.0.
|
|
132
|
+
"Antigravity agy 1.0.13 has no ACP flag or subcommand.",
|
|
133
133
|
"Legacy Gemini CLI ACP evidence does not transfer to agy; kept on the upstream drift watchlist.",
|
|
134
134
|
],
|
|
135
135
|
docs: ACP_DOCS_REFERENCE,
|
|
@@ -148,7 +148,7 @@ const ACP_CAPABILITIES = {
|
|
|
148
148
|
devin: {
|
|
149
149
|
status: "native_smoke_passed",
|
|
150
150
|
mediation: "native",
|
|
151
|
-
targetVersion: "devin 2026.
|
|
151
|
+
targetVersion: "devin 2026.8.18 (16737566)",
|
|
152
152
|
entrypoint: { command: "devin", args: ["acp"] },
|
|
153
153
|
runtimeEnabled: false,
|
|
154
154
|
smokeSupported: true,
|
|
@@ -19,9 +19,9 @@ export const ACP_ENTRYPOINT_CONTRACTS = {
|
|
|
19
19
|
status: "native",
|
|
20
20
|
executable: "grok",
|
|
21
21
|
entrypointArgs: ["agent", "stdio"],
|
|
22
|
-
targetVersion: "grok 0.2.
|
|
22
|
+
targetVersion: "grok 0.2.73 (9ff14c43bb)",
|
|
23
23
|
probeArgs: [["agent", "stdio", "--help"]],
|
|
24
|
-
evidence: "Native ACP via `grok agent stdio`; initialize + session/new smoke passed with isolated leader socket. Second runtime pilot.
|
|
24
|
+
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.73.",
|
|
25
25
|
docsRef: "docs/plans/first-class-acp-gateway-extension.dag.toml#provider_matrix.grok",
|
|
26
26
|
},
|
|
27
27
|
codex: {
|
|
@@ -30,10 +30,10 @@ export const ACP_ENTRYPOINT_CONTRACTS = {
|
|
|
30
30
|
status: "adapter_mediated_deferred",
|
|
31
31
|
executable: "codex",
|
|
32
32
|
entrypointArgs: [],
|
|
33
|
-
targetVersion: "codex-cli 0.
|
|
33
|
+
targetVersion: "codex-cli 0.142.4",
|
|
34
34
|
probeArgs: [],
|
|
35
35
|
adapterCandidates: ["zed-industries/codex-acp", "agentclientprotocol/codex-acp"],
|
|
36
|
-
evidence: "No native ACP entrypoint at codex-cli 0.
|
|
36
|
+
evidence: "No native ACP entrypoint at codex-cli 0.142.4. Adapter evidence tracked as documentation only; not native gateway ACP support.",
|
|
37
37
|
docsRef: "docs/plans/first-class-acp-gateway-extension.dag.toml#provider_matrix.codex",
|
|
38
38
|
},
|
|
39
39
|
claude: {
|
|
@@ -42,10 +42,10 @@ export const ACP_ENTRYPOINT_CONTRACTS = {
|
|
|
42
42
|
status: "adapter_mediated_deferred",
|
|
43
43
|
executable: "claude",
|
|
44
44
|
entrypointArgs: [],
|
|
45
|
-
targetVersion: "claude 2.1.
|
|
45
|
+
targetVersion: "claude 2.1.195",
|
|
46
46
|
probeArgs: [],
|
|
47
47
|
adapterCandidates: ["Claude Agent SDK ACP adapter"],
|
|
48
|
-
evidence: "No native Claude Code CLI ACP entrypoint at claude 2.1.
|
|
48
|
+
evidence: "No native Claude Code CLI ACP entrypoint at claude 2.1.195. Adapter ownership/permission bridging unresolved; deferred.",
|
|
49
49
|
docsRef: "docs/plans/first-class-acp-gateway-extension.dag.toml#provider_matrix.claude",
|
|
50
50
|
},
|
|
51
51
|
gemini: {
|
|
@@ -54,9 +54,9 @@ export const ACP_ENTRYPOINT_CONTRACTS = {
|
|
|
54
54
|
status: "absent_watchlist",
|
|
55
55
|
executable: "agy",
|
|
56
56
|
entrypointArgs: [],
|
|
57
|
-
targetVersion: "agy 1.0.
|
|
57
|
+
targetVersion: "agy 1.0.13",
|
|
58
58
|
probeArgs: [],
|
|
59
|
-
evidence: "agy 1.0.
|
|
59
|
+
evidence: "agy 1.0.13 has no ACP flag or subcommand. Legacy Gemini CLI ACP evidence does not transfer. Watchlist item.",
|
|
60
60
|
docsRef: "docs/plans/first-class-acp-gateway-extension.dag.toml#provider_matrix.gemini",
|
|
61
61
|
},
|
|
62
62
|
devin: {
|
|
@@ -65,7 +65,7 @@ export const ACP_ENTRYPOINT_CONTRACTS = {
|
|
|
65
65
|
status: "native",
|
|
66
66
|
executable: "devin",
|
|
67
67
|
entrypointArgs: ["acp"],
|
|
68
|
-
targetVersion: "devin 2026.
|
|
68
|
+
targetVersion: "devin 2026.8.18 (16737566)",
|
|
69
69
|
probeArgs: [["--version"]],
|
|
70
70
|
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.',
|
|
71
71
|
docsRef: "docs/plans/first-class-acp-gateway-extension.dag.toml#provider_matrix.devin",
|
|
@@ -107,6 +107,7 @@ function subcommand(commandPath, summary, risk, flags = [], options = {}) {
|
|
|
107
107
|
summary,
|
|
108
108
|
conformanceFixtures: options.fixtures ?? [],
|
|
109
109
|
acknowledgedUpstreamFlags: options.acknowledgedUpstreamFlags ?? [],
|
|
110
|
+
...(options.helpProbeExitTolerant ? { helpProbeExitTolerant: true } : {}),
|
|
110
111
|
};
|
|
111
112
|
}
|
|
112
113
|
function acknowledgeSubcommandFlags(subcommands, flags) {
|
|
@@ -307,8 +308,10 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
307
308
|
"--allow-dangerously-skip-permissions",
|
|
308
309
|
"--allowed",
|
|
309
310
|
"--ax-screen-reader",
|
|
311
|
+
"--background",
|
|
310
312
|
"--bare",
|
|
311
313
|
"--betas",
|
|
314
|
+
"--bg",
|
|
312
315
|
"--brief",
|
|
313
316
|
"--chrome",
|
|
314
317
|
"--dangerously-skip-permissions",
|
|
@@ -320,7 +323,6 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
320
323
|
"--from-pr",
|
|
321
324
|
"--ide",
|
|
322
325
|
"--include-hook-events",
|
|
323
|
-
"--mcp-debug",
|
|
324
326
|
"--name",
|
|
325
327
|
"--no-chrome",
|
|
326
328
|
"--plugin-dir",
|
|
@@ -419,6 +421,12 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
419
421
|
],
|
|
420
422
|
expect: "pass",
|
|
421
423
|
},
|
|
424
|
+
{
|
|
425
|
+
id: "claude-background-acknowledged-not-emitted",
|
|
426
|
+
description: "Claude 2.1.195 advertises --bg/--background (background agent), but the gateway acknowledges them without emitting; caller argv is rejected",
|
|
427
|
+
args: ["-p", "hello", "--background"],
|
|
428
|
+
expect: "fail",
|
|
429
|
+
},
|
|
422
430
|
],
|
|
423
431
|
},
|
|
424
432
|
codex: {
|
|
@@ -899,7 +907,7 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
899
907
|
plugins: subcommand(["plugins"], "Alias for Antigravity plugin management.", "writes_local_config", [], {
|
|
900
908
|
aliases: ["plugin"],
|
|
901
909
|
}),
|
|
902
|
-
update: subcommand(["update"], "Update Antigravity CLI to the current release.", "writes_local_config", [], { tokenCost: "small" }),
|
|
910
|
+
update: subcommand(["update"], "Update Antigravity CLI to the current release.", "writes_local_config", [], { tokenCost: "small", helpProbeExitTolerant: true }),
|
|
903
911
|
},
|
|
904
912
|
maxPositionals: 1,
|
|
905
913
|
mcpTools: ["gemini_request", "gemini_request_async"],
|
|
@@ -921,6 +929,8 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
921
929
|
"attachments",
|
|
922
930
|
"skipTrust",
|
|
923
931
|
"yolo",
|
|
932
|
+
"project",
|
|
933
|
+
"newProject",
|
|
924
934
|
],
|
|
925
935
|
flags: {
|
|
926
936
|
"--print": { arity: "none", description: "Run a single prompt non-interactively" },
|
|
@@ -936,14 +946,13 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
936
946
|
"--conversation": { arity: "one", description: "Resume a previous conversation by ID" },
|
|
937
947
|
"--continue": { arity: "none", description: "Continue the most recent conversation" },
|
|
938
948
|
"-c": { arity: "none", description: "Short alias for --continue" },
|
|
949
|
+
"--project": { arity: "one", description: "Antigravity project ID for this session" },
|
|
950
|
+
"--new-project": {
|
|
951
|
+
arity: "none",
|
|
952
|
+
description: "Create a new Antigravity project for this session",
|
|
953
|
+
},
|
|
939
954
|
},
|
|
940
|
-
acknowledgedUpstreamFlags: [
|
|
941
|
-
"--prompt-interactive",
|
|
942
|
-
"-i",
|
|
943
|
-
"--print-timeout",
|
|
944
|
-
"--log-file",
|
|
945
|
-
"--version",
|
|
946
|
-
],
|
|
955
|
+
acknowledgedUpstreamFlags: ["--log-file", "--print-timeout", "--prompt-interactive"],
|
|
947
956
|
env: {},
|
|
948
957
|
conformanceFixtures: [
|
|
949
958
|
{
|
|
@@ -982,6 +991,18 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
982
991
|
args: ["--print", "hello", "-o", "json"],
|
|
983
992
|
expect: "fail",
|
|
984
993
|
},
|
|
994
|
+
{
|
|
995
|
+
id: "gemini-project-wired",
|
|
996
|
+
description: "Antigravity 1.0.13: --project <ID> is wired",
|
|
997
|
+
args: ["--print", "hello", "--project", "proj-123"],
|
|
998
|
+
expect: "pass",
|
|
999
|
+
},
|
|
1000
|
+
{
|
|
1001
|
+
id: "gemini-new-project-wired",
|
|
1002
|
+
description: "Antigravity 1.0.13: --new-project is wired",
|
|
1003
|
+
args: ["--print", "hello", "--new-project"],
|
|
1004
|
+
expect: "pass",
|
|
1005
|
+
},
|
|
985
1006
|
],
|
|
986
1007
|
},
|
|
987
1008
|
grok: {
|
|
@@ -1073,7 +1094,49 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
1073
1094
|
tier: "inspect",
|
|
1074
1095
|
}),
|
|
1075
1096
|
setup: subcommand(["setup"], "Configure Grok CLI local setup.", "writes_local_config", ["--leader-socket"], { exposure: "not_exposed" }),
|
|
1076
|
-
ssh: subcommand(["ssh"], "Manage Grok SSH integration.", "network", ["--leader-socket"]
|
|
1097
|
+
ssh: subcommand(["ssh"], "Manage Grok SSH integration.", "network", ["--leader-socket"], {
|
|
1098
|
+
acknowledgedUpstreamFlags: [
|
|
1099
|
+
"--agent",
|
|
1100
|
+
"--agents",
|
|
1101
|
+
"--allow",
|
|
1102
|
+
"--always-approve",
|
|
1103
|
+
"--best-of-n",
|
|
1104
|
+
"--check",
|
|
1105
|
+
"--continue",
|
|
1106
|
+
"--cwd",
|
|
1107
|
+
"--deny",
|
|
1108
|
+
"--disable-web-search",
|
|
1109
|
+
"--disallowed-tools",
|
|
1110
|
+
"--effort",
|
|
1111
|
+
"--experimental-memory",
|
|
1112
|
+
"--fork-session",
|
|
1113
|
+
"--json-schema",
|
|
1114
|
+
"--max-turns",
|
|
1115
|
+
"--model",
|
|
1116
|
+
"--no-alt-screen",
|
|
1117
|
+
"--no-memory",
|
|
1118
|
+
"--no-plan",
|
|
1119
|
+
"--no-subagents",
|
|
1120
|
+
"--oauth",
|
|
1121
|
+
"--output-format",
|
|
1122
|
+
"--permission-mode",
|
|
1123
|
+
"--prompt-file",
|
|
1124
|
+
"--prompt-json",
|
|
1125
|
+
"--reasoning-effort",
|
|
1126
|
+
"--restore-code",
|
|
1127
|
+
"--resume",
|
|
1128
|
+
"--rules",
|
|
1129
|
+
"--sandbox",
|
|
1130
|
+
"--session-id",
|
|
1131
|
+
"--single",
|
|
1132
|
+
"--system-prompt-override",
|
|
1133
|
+
"--tools",
|
|
1134
|
+
"--verbatim",
|
|
1135
|
+
"--version",
|
|
1136
|
+
"--worktree",
|
|
1137
|
+
"--worktree-ref",
|
|
1138
|
+
],
|
|
1139
|
+
}),
|
|
1077
1140
|
trace: subcommand(["trace"], "Inspect Grok trace data.", "read_only", ["--json", "--leader-socket", "--local", "--output"], { tier: "diagnostic" }),
|
|
1078
1141
|
update: subcommand(["update"], "Update the Grok CLI binary.", "updates_binary", [
|
|
1079
1142
|
"--alpha",
|
|
@@ -1088,7 +1151,7 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
1088
1151
|
worktree: subcommand(["worktree"], "Manage Grok worktree sessions.", "writes_local_config", ["--leader-socket"]),
|
|
1089
1152
|
}, GROK_DEBUG_HELP_FLAGS),
|
|
1090
1153
|
maxPositionals: 0,
|
|
1091
|
-
acknowledgedUpstreamFlags: GROK_DEBUG_HELP_FLAGS,
|
|
1154
|
+
acknowledgedUpstreamFlags: [...GROK_DEBUG_HELP_FLAGS, "--session-id"],
|
|
1092
1155
|
mcpTools: ["grok_request", "grok_request_async"],
|
|
1093
1156
|
mcpParameters: [
|
|
1094
1157
|
"prompt",
|
|
@@ -1133,6 +1196,9 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
1133
1196
|
"restoreCode",
|
|
1134
1197
|
"leaderSocket",
|
|
1135
1198
|
"nativeWorktree",
|
|
1199
|
+
"worktreeRef",
|
|
1200
|
+
"forkSession",
|
|
1201
|
+
"jsonSchema",
|
|
1136
1202
|
],
|
|
1137
1203
|
flags: {
|
|
1138
1204
|
"-p": { arity: "one", description: "Prompt text" },
|
|
@@ -1229,6 +1295,18 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
1229
1295
|
arity: "optional",
|
|
1230
1296
|
description: "Start the session in a new git worktree, optionally named",
|
|
1231
1297
|
},
|
|
1298
|
+
"--worktree-ref": {
|
|
1299
|
+
arity: "one",
|
|
1300
|
+
description: "Git ref to base the worktree on (requires --worktree)",
|
|
1301
|
+
},
|
|
1302
|
+
"--fork-session": {
|
|
1303
|
+
arity: "none",
|
|
1304
|
+
description: "Fork the resumed session into a new session ID",
|
|
1305
|
+
},
|
|
1306
|
+
"--json-schema": {
|
|
1307
|
+
arity: "one",
|
|
1308
|
+
description: "JSON Schema literal constraining structured output (implies json output)",
|
|
1309
|
+
},
|
|
1232
1310
|
"--compaction-mode": {
|
|
1233
1311
|
arity: "one",
|
|
1234
1312
|
values: ["summary", "transcript", "segments"],
|
|
@@ -1397,6 +1475,35 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
1397
1475
|
args: ["-p", "hello", "--agent", "reviewer", "--leader-socket", "/tmp/leader.sock"],
|
|
1398
1476
|
expect: "pass",
|
|
1399
1477
|
},
|
|
1478
|
+
{
|
|
1479
|
+
id: "grok-json-schema-wired",
|
|
1480
|
+
description: "Grok 0.2.73: --json-schema <SCHEMA> is wired (structured output, implies json)",
|
|
1481
|
+
args: [
|
|
1482
|
+
"-p",
|
|
1483
|
+
"hello",
|
|
1484
|
+
"--json-schema",
|
|
1485
|
+
'{"type":"object","properties":{"name":{"type":"string"}}}',
|
|
1486
|
+
],
|
|
1487
|
+
expect: "pass",
|
|
1488
|
+
},
|
|
1489
|
+
{
|
|
1490
|
+
id: "grok-fork-session-wired",
|
|
1491
|
+
description: "Grok 0.2.73: --fork-session is wired (fork resumed session into a new ID)",
|
|
1492
|
+
args: ["-p", "hello", "--resume", "sess-1", "--fork-session"],
|
|
1493
|
+
expect: "pass",
|
|
1494
|
+
},
|
|
1495
|
+
{
|
|
1496
|
+
id: "grok-worktree-ref-wired",
|
|
1497
|
+
description: "Grok 0.2.73: --worktree-ref <REF> is wired (with --worktree)",
|
|
1498
|
+
args: ["-p", "hello", "--worktree", "--worktree-ref", "main"],
|
|
1499
|
+
expect: "pass",
|
|
1500
|
+
},
|
|
1501
|
+
{
|
|
1502
|
+
id: "grok-session-id-acknowledged-not-emitted",
|
|
1503
|
+
description: "Grok 0.2.73 advertises --session-id, but the gateway owns session-id lifecycle and does not emit it; caller argv is rejected",
|
|
1504
|
+
args: ["-p", "hello", "--session-id", "11111111-1111-1111-1111-111111111111"],
|
|
1505
|
+
expect: "fail",
|
|
1506
|
+
},
|
|
1400
1507
|
],
|
|
1401
1508
|
},
|
|
1402
1509
|
mistral: {
|
|
@@ -2274,7 +2381,7 @@ function probeInstalledCliSubcommands(cli, timeoutMs) {
|
|
|
2274
2381
|
break;
|
|
2275
2382
|
}
|
|
2276
2383
|
outputs.push(`${result.stdout ?? ""}\n${result.stderr ?? ""}`);
|
|
2277
|
-
if (result.status !== 0) {
|
|
2384
|
+
if (result.status !== 0 && !sub.helpProbeExitTolerant) {
|
|
2278
2385
|
warnings.push(`${contract.executable} ${args.join(" ")} exited with status ${result.status}`);
|
|
2279
2386
|
}
|
|
2280
2387
|
}
|
|
@@ -3,11 +3,13 @@ import { type ProviderRuntimeStatus } from "./provider-status.js";
|
|
|
3
3
|
import type { ApiProviderRuntime } from "./config.js";
|
|
4
4
|
import { type NormalizedValidationResult, type ValidationProvider } from "./validation-normalizer.js";
|
|
5
5
|
import { type ValidationReport } from "./validation-report.js";
|
|
6
|
+
import type { ValidationRunStore } from "./job-store.js";
|
|
6
7
|
import { type ValidationIntent } from "./validation-prompts.js";
|
|
7
8
|
export interface ValidationOrchestratorDeps {
|
|
8
9
|
asyncJobManager: AsyncJobManager;
|
|
9
10
|
getProviderRuntimeStatus?: (provider: ValidationProvider) => ProviderRuntimeStatus;
|
|
10
11
|
apiProviders?: ApiProviderRuntime[];
|
|
12
|
+
validationRunStore?: ValidationRunStore | null;
|
|
11
13
|
}
|
|
12
14
|
export interface StartValidationInput {
|
|
13
15
|
intent: ValidationIntent;
|
|
@@ -21,7 +23,7 @@ export interface StartValidationInput {
|
|
|
21
23
|
export interface ValidationRunReport {
|
|
22
24
|
success: boolean;
|
|
23
25
|
validationId: string;
|
|
24
|
-
status: "running" | "partial" | "not_started";
|
|
26
|
+
status: "running" | "partial" | "not_started" | "completed";
|
|
25
27
|
startedAt: string;
|
|
26
28
|
intent: ValidationIntent;
|
|
27
29
|
originalRequest: {
|
|
@@ -32,7 +34,7 @@ export interface ValidationRunReport {
|
|
|
32
34
|
modelList: ValidationProvider[];
|
|
33
35
|
results: NormalizedValidationResult[];
|
|
34
36
|
synthesis: {
|
|
35
|
-
status: "not_requested" | "waiting_for_provider_results" | "running" | "skipped";
|
|
37
|
+
status: "not_requested" | "waiting_for_provider_results" | "running" | "skipped" | "completed";
|
|
36
38
|
judgeModel: ValidationProvider | null;
|
|
37
39
|
rawJobReference: NormalizedValidationResult["rawJobReference"];
|
|
38
40
|
note: string;
|
|
@@ -45,5 +47,6 @@ export declare function startJudgeSynthesis(deps: ValidationOrchestratorDeps, in
|
|
|
45
47
|
question: string;
|
|
46
48
|
providerResults: NormalizedValidationResult[];
|
|
47
49
|
judgeProvider: ValidationProvider;
|
|
50
|
+
validationId?: string;
|
|
48
51
|
}): ValidationRunReport["synthesis"];
|
|
49
52
|
export declare function collectValidationJobResult(deps: ValidationOrchestratorDeps, provider: ValidationProvider, jobId: string, model: string | null, maxChars?: number): NormalizedValidationResult | null;
|