llm-cli-gateway 2.16.0 → 2.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/least-cost-routing/SKILL.md +123 -0
- package/CHANGELOG.md +37 -0
- package/README.md +12 -12
- package/dist/acp/client.js +5 -0
- package/dist/acp/flight-redaction.d.ts +2 -0
- package/dist/acp/flight-redaction.js +2 -0
- package/dist/acp/runtime.d.ts +1 -0
- package/dist/acp/runtime.js +20 -0
- package/dist/acp/types.d.ts +52 -0
- package/dist/acp/types.js +8 -0
- package/dist/api-provider.d.ts +1 -0
- package/dist/api-provider.js +1 -0
- package/dist/async-job-manager.d.ts +16 -0
- package/dist/async-job-manager.js +70 -22
- package/dist/claude-mcp-config.js +1 -1
- package/dist/compressor/transforms/ansi.js +12 -2
- package/dist/config.d.ts +31 -0
- package/dist/config.js +142 -7
- package/dist/db.js +4 -4
- package/dist/doctor.d.ts +34 -1
- package/dist/doctor.js +85 -3
- package/dist/executor.d.ts +5 -0
- package/dist/executor.js +11 -1
- package/dist/flight-recorder.d.ts +10 -0
- package/dist/flight-recorder.js +68 -2
- package/dist/http-transport.js +19 -21
- package/dist/index.d.ts +42 -3
- package/dist/index.js +666 -41
- package/dist/job-store.d.ts +10 -2
- package/dist/job-store.js +154 -43
- package/dist/lcr-priors.d.ts +60 -0
- package/dist/lcr-priors.js +190 -0
- package/dist/lcr-router-env.d.ts +20 -0
- package/dist/lcr-router-env.js +133 -0
- package/dist/lcr-telemetry.d.ts +2 -0
- package/dist/lcr-telemetry.js +17 -0
- package/dist/least-cost-router.d.ts +86 -0
- package/dist/least-cost-router.js +296 -0
- package/dist/least-cost-types.d.ts +34 -0
- package/dist/least-cost-types.js +1 -0
- package/dist/migrate-sessions.js +1 -1
- package/dist/migrate.js +1 -1
- package/dist/model-registry.js +1 -1
- package/dist/postgres-job-store-worker.js +56 -13
- package/dist/pricing.d.ts +17 -0
- package/dist/pricing.js +167 -0
- package/dist/provider-admin-tools.js +12 -4
- package/dist/provider-definitions.d.ts +4 -0
- package/dist/provider-definitions.js +33 -5
- package/dist/provider-tool-capabilities.js +6 -9
- package/dist/request-helpers.d.ts +3 -4
- package/dist/request-helpers.js +9 -10
- package/dist/resources.d.ts +37 -2
- package/dist/resources.js +96 -1
- package/dist/retry.d.ts +1 -0
- package/dist/retry.js +1 -1
- package/dist/token-estimator.d.ts +6 -0
- package/dist/token-estimator.js +59 -0
- package/dist/upstream-contracts.d.ts +4 -1
- package/dist/upstream-contracts.js +255 -71
- package/dist/validation-receipt.js +1 -1
- package/dist/validation-tools.d.ts +6 -0
- package/dist/validation-tools.js +174 -54
- package/npm-shrinkwrap.json +2 -2
- package/package.json +14 -5
- package/setup/status.schema.json +68 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const CJK_RE = /[\u3000-\u303f\u3040-\u309f\u30a0-\u30ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff\uff00-\uffef\uac00-\ud7af]/g;
|
|
2
|
+
const CODE_SYMBOL_RE = /[{}[\]()<>;=+\-*/\\|&%$#@`~]/g;
|
|
3
|
+
const CODE_KEYWORD_RE = /\b(function|const|let|var|return|import|export|class|def|public|private|static|void|for|while|switch|case)\b/;
|
|
4
|
+
const DIVISOR_BY_TYPE = new Map([
|
|
5
|
+
["prose", 4],
|
|
6
|
+
["code", 3],
|
|
7
|
+
["cjk", 1.5],
|
|
8
|
+
]);
|
|
9
|
+
const FAMILY_MULTIPLIERS = new Map([
|
|
10
|
+
["openai", 1.0],
|
|
11
|
+
["o200k", 1.0],
|
|
12
|
+
["cl100k", 1.02],
|
|
13
|
+
["claude", 1.08],
|
|
14
|
+
["gemini", 0.98],
|
|
15
|
+
["sentencepiece", 0.98],
|
|
16
|
+
["grok", 1.0],
|
|
17
|
+
["mistral", 1.05],
|
|
18
|
+
]);
|
|
19
|
+
export function classifyContent(text) {
|
|
20
|
+
if (!text)
|
|
21
|
+
return "prose";
|
|
22
|
+
const nonSpace = text.replace(/\s+/g, "").length;
|
|
23
|
+
if (nonSpace === 0)
|
|
24
|
+
return "prose";
|
|
25
|
+
const cjkMatches = text.match(CJK_RE);
|
|
26
|
+
const cjkCount = cjkMatches ? cjkMatches.length : 0;
|
|
27
|
+
if (cjkCount / nonSpace >= 0.2)
|
|
28
|
+
return "cjk";
|
|
29
|
+
const trimmed = text.trim();
|
|
30
|
+
const looksJson = /^[[{]/.test(trimmed) && /[}\]]/.test(trimmed) && /[:,]/.test(trimmed);
|
|
31
|
+
const symbolMatches = trimmed.match(CODE_SYMBOL_RE);
|
|
32
|
+
const symbolCount = symbolMatches ? symbolMatches.length : 0;
|
|
33
|
+
const symbolRatio = symbolCount / nonSpace;
|
|
34
|
+
const hasKeyword = CODE_KEYWORD_RE.test(trimmed);
|
|
35
|
+
if (looksJson || symbolRatio >= 0.08 || (hasKeyword && symbolRatio >= 0.03)) {
|
|
36
|
+
return "code";
|
|
37
|
+
}
|
|
38
|
+
return "prose";
|
|
39
|
+
}
|
|
40
|
+
function familyMultiplier(family) {
|
|
41
|
+
if (!family)
|
|
42
|
+
return 1;
|
|
43
|
+
const f = family.toLowerCase();
|
|
44
|
+
for (const [key, multiplier] of FAMILY_MULTIPLIERS) {
|
|
45
|
+
if (f === key || f.includes(key))
|
|
46
|
+
return multiplier;
|
|
47
|
+
}
|
|
48
|
+
return 1;
|
|
49
|
+
}
|
|
50
|
+
export function estimateInputTokens(text, opts) {
|
|
51
|
+
if (!text)
|
|
52
|
+
return 0;
|
|
53
|
+
const type = classifyContent(text);
|
|
54
|
+
const divisor = DIVISOR_BY_TYPE.get(type) ?? 4;
|
|
55
|
+
const base = text.length / divisor;
|
|
56
|
+
const familyMult = familyMultiplier(opts?.family);
|
|
57
|
+
const k = opts?.calibrationK ?? 1;
|
|
58
|
+
return Math.ceil(base * familyMult * k);
|
|
59
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type CliType } from "./provider-definitions.js";
|
|
2
2
|
export type CliFlagArity = "none" | "one" | "optional" | "variadic";
|
|
3
|
+
export type CliPositionalLimit = number | "variadic";
|
|
3
4
|
export interface CliFlagContract {
|
|
4
5
|
arity: CliFlagArity;
|
|
5
6
|
values?: readonly string[];
|
|
@@ -52,12 +53,13 @@ export interface CliSubcommandContract {
|
|
|
52
53
|
commandPath: readonly string[];
|
|
53
54
|
helpArgs: readonly string[][];
|
|
54
55
|
flags: Record<string, CliFlagContract>;
|
|
55
|
-
maxPositionals:
|
|
56
|
+
maxPositionals: CliPositionalLimit;
|
|
56
57
|
acknowledgedUpstreamFlags?: readonly string[];
|
|
57
58
|
aliases?: readonly string[];
|
|
58
59
|
children?: Record<string, CliSubcommandContract>;
|
|
59
60
|
risk: CliSubcommandRisk;
|
|
60
61
|
exposure: CliSubcommandExposure;
|
|
62
|
+
adminProjection?: "not_exposed";
|
|
61
63
|
tier: CliSubcommandTier;
|
|
62
64
|
tokenCost: CliSubcommandTokenCost;
|
|
63
65
|
summary: string;
|
|
@@ -122,6 +124,7 @@ export interface AcpEntrypointContract {
|
|
|
122
124
|
docsRef: string;
|
|
123
125
|
}
|
|
124
126
|
export declare const ACP_ENTRYPOINT_CONTRACTS: Record<CliType, AcpEntrypointContract>;
|
|
127
|
+
export declare const CLAUDE_WIRE_PERMISSION_MODES: readonly ["acceptEdits", "auto", "bypassPermissions", "manual", "dontAsk", "plan"];
|
|
125
128
|
export declare const UPSTREAM_CLI_CONTRACTS: Record<CliType, CliContract>;
|
|
126
129
|
export declare function validateUpstreamCliArgs(cli: CliType, args: readonly string[]): ContractValidationResult;
|
|
127
130
|
export declare function assertUpstreamCliArgs(cli: CliType, args: readonly string[]): void;
|
|
@@ -67,7 +67,7 @@ export const ACP_ENTRYPOINT_CONTRACTS = {
|
|
|
67
67
|
executable: "devin",
|
|
68
68
|
entrypointArgs: ["acp"],
|
|
69
69
|
targetVersion: PROVIDER_TARGET_VERSIONS.devin,
|
|
70
|
-
probeArgs: [["--
|
|
70
|
+
probeArgs: [["acp", "--help"]],
|
|
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",
|
|
73
73
|
},
|
|
@@ -83,13 +83,21 @@ export const ACP_ENTRYPOINT_CONTRACTS = {
|
|
|
83
83
|
docsRef: "docs/plans/first-class-acp-gateway-extension.dag.toml#provider_matrix.cursor",
|
|
84
84
|
},
|
|
85
85
|
};
|
|
86
|
-
const
|
|
87
|
-
"default",
|
|
86
|
+
export const CLAUDE_WIRE_PERMISSION_MODES = [
|
|
88
87
|
"acceptEdits",
|
|
88
|
+
"auto",
|
|
89
|
+
"bypassPermissions",
|
|
90
|
+
"manual",
|
|
91
|
+
"dontAsk",
|
|
89
92
|
"plan",
|
|
93
|
+
];
|
|
94
|
+
const GROK_PERMISSION_MODES = [
|
|
95
|
+
"default",
|
|
96
|
+
"acceptEdits",
|
|
90
97
|
"auto",
|
|
91
98
|
"dontAsk",
|
|
92
99
|
"bypassPermissions",
|
|
100
|
+
"plan",
|
|
93
101
|
];
|
|
94
102
|
const EFFORT_LEVELS = ["low", "medium", "high", "xhigh", "max"];
|
|
95
103
|
function scFlag(name, arity = "optional") {
|
|
@@ -114,6 +122,7 @@ function subcommand(commandPath, summary, risk, flags = [], options = {}) {
|
|
|
114
122
|
children: options.children ?? {},
|
|
115
123
|
risk,
|
|
116
124
|
exposure: options.exposure ?? "tracked_only",
|
|
125
|
+
...(options.adminProjection ? { adminProjection: options.adminProjection } : {}),
|
|
117
126
|
tier: options.tier ?? "catalog",
|
|
118
127
|
tokenCost: options.tokenCost ?? "small",
|
|
119
128
|
summary,
|
|
@@ -150,6 +159,10 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
150
159
|
doctor: subcommand(["doctor"], "Run Claude Code diagnostic checks.", "read_only", [], {
|
|
151
160
|
tier: "diagnostic",
|
|
152
161
|
}),
|
|
162
|
+
gateway: subcommand(["gateway"], "Run Claude enterprise auth and telemetry gateway mode.", "starts_server", ["--config"], {
|
|
163
|
+
exposure: "not_exposed",
|
|
164
|
+
flagArities: { "--config": "one" },
|
|
165
|
+
}),
|
|
153
166
|
mcp: subcommand(["mcp"], "Manage Claude MCP server configuration.", "writes_local_config"),
|
|
154
167
|
plugin: subcommand(["plugin"], "Manage Claude plugins.", "writes_local_config", [], {
|
|
155
168
|
aliases: ["plugins"],
|
|
@@ -244,7 +257,7 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
244
257
|
},
|
|
245
258
|
"--output-format": {
|
|
246
259
|
arity: "one",
|
|
247
|
-
values: ["json", "stream-json"],
|
|
260
|
+
values: ["text", "json", "stream-json"],
|
|
248
261
|
description: "Machine-readable output format",
|
|
249
262
|
},
|
|
250
263
|
"--include-partial-messages": {
|
|
@@ -259,7 +272,7 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
259
272
|
"--disallowed-tools": { arity: "variadic", description: "Disallowed tool names/patterns" },
|
|
260
273
|
"--permission-mode": {
|
|
261
274
|
arity: "one",
|
|
262
|
-
values:
|
|
275
|
+
values: CLAUDE_WIRE_PERMISSION_MODES,
|
|
263
276
|
description: "Claude permission mode",
|
|
264
277
|
},
|
|
265
278
|
"--mcp-config": { arity: "one", description: "MCP config path" },
|
|
@@ -392,6 +405,18 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
392
405
|
args: ["-p", "hello"],
|
|
393
406
|
expect: "pass",
|
|
394
407
|
},
|
|
408
|
+
{
|
|
409
|
+
id: "claude-permission-mode-manual",
|
|
410
|
+
description: "Claude 2.1.207 accepts the manual permission mode literal",
|
|
411
|
+
args: ["-p", "hello", "--permission-mode", "manual"],
|
|
412
|
+
expect: "pass",
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
id: "claude-permission-mode-default-gateway-only",
|
|
416
|
+
description: "Gateway default is represented by omitting the upstream flag",
|
|
417
|
+
args: ["-p", "hello", "--permission-mode", "default"],
|
|
418
|
+
expect: "fail",
|
|
419
|
+
},
|
|
395
420
|
{
|
|
396
421
|
id: "claude-unsupported-flag",
|
|
397
422
|
description: "Unsupported flag is rejected before spawn",
|
|
@@ -404,6 +429,12 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
404
429
|
args: ["-p", "hello", "--fallback-model", "claude-haiku-4-5-20251001"],
|
|
405
430
|
expect: "pass",
|
|
406
431
|
},
|
|
432
|
+
{
|
|
433
|
+
id: "claude-output-format-text",
|
|
434
|
+
description: "Claude 2.1.207 accepts explicit text output format",
|
|
435
|
+
args: ["-p", "hello", "--output-format", "text"],
|
|
436
|
+
expect: "pass",
|
|
437
|
+
},
|
|
407
438
|
{
|
|
408
439
|
id: "claude-json-schema",
|
|
409
440
|
description: "Phase 4 slice η: --json-schema accepts inline JSON literal",
|
|
@@ -508,8 +539,8 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
508
539
|
upstream: "OpenAI Codex CLI",
|
|
509
540
|
upstreamMetadata: {
|
|
510
541
|
sourceUrls: [
|
|
511
|
-
"https://github.com/openai/codex/releases",
|
|
512
|
-
"https://
|
|
542
|
+
"https://api.github.com/repos/openai/codex/releases/latest",
|
|
543
|
+
"https://learn.chatgpt.com/docs/changelog/rss.xml",
|
|
513
544
|
],
|
|
514
545
|
packageName: "@openai/codex",
|
|
515
546
|
repo: "https://github.com/openai/codex",
|
|
@@ -668,6 +699,76 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
668
699
|
], { exposure: "not_exposed" }),
|
|
669
700
|
debug: subcommand(["debug"], "Run Codex debugging utilities.", "read_only", ["--config", "--disable", "--enable"], { tier: "diagnostic" }),
|
|
670
701
|
apply: subcommand(["apply"], "Apply a Codex patch to the workspace.", "destructive", ["--config", "--disable", "--enable"], { exposure: "not_exposed" }),
|
|
702
|
+
resume: subcommand(["resume"], "Resume a saved interactive Codex session.", "executes_agent", [
|
|
703
|
+
"--add-dir",
|
|
704
|
+
"--all",
|
|
705
|
+
"--ask-for-approval",
|
|
706
|
+
"--cd",
|
|
707
|
+
"--config",
|
|
708
|
+
"--dangerously-bypass-approvals-and-sandbox",
|
|
709
|
+
"--dangerously-bypass-hook-trust",
|
|
710
|
+
"--disable",
|
|
711
|
+
"--enable",
|
|
712
|
+
"--image",
|
|
713
|
+
"--include-non-interactive",
|
|
714
|
+
"--last",
|
|
715
|
+
"--local-provider",
|
|
716
|
+
"--model",
|
|
717
|
+
"--no-alt-screen",
|
|
718
|
+
"--oss",
|
|
719
|
+
"--profile",
|
|
720
|
+
"--remote",
|
|
721
|
+
"--remote-auth-token-env",
|
|
722
|
+
"--sandbox",
|
|
723
|
+
"--search",
|
|
724
|
+
"--strict-config",
|
|
725
|
+
"--version",
|
|
726
|
+
], {
|
|
727
|
+
exposure: "not_exposed",
|
|
728
|
+
maxPositionals: 2,
|
|
729
|
+
flagArities: {
|
|
730
|
+
"--all": "none",
|
|
731
|
+
"--dangerously-bypass-approvals-and-sandbox": "none",
|
|
732
|
+
"--dangerously-bypass-hook-trust": "none",
|
|
733
|
+
"--include-non-interactive": "none",
|
|
734
|
+
"--last": "none",
|
|
735
|
+
"--no-alt-screen": "none",
|
|
736
|
+
"--oss": "none",
|
|
737
|
+
"--search": "none",
|
|
738
|
+
"--strict-config": "none",
|
|
739
|
+
"--version": "none",
|
|
740
|
+
},
|
|
741
|
+
}),
|
|
742
|
+
delete: subcommand(["delete"], "Permanently delete a saved Codex session.", "destructive", [
|
|
743
|
+
"--add-dir",
|
|
744
|
+
"--cd",
|
|
745
|
+
"--config",
|
|
746
|
+
"--dangerously-bypass-approvals-and-sandbox",
|
|
747
|
+
"--dangerously-bypass-hook-trust",
|
|
748
|
+
"--disable",
|
|
749
|
+
"--enable",
|
|
750
|
+
"--force",
|
|
751
|
+
"--image",
|
|
752
|
+
"--local-provider",
|
|
753
|
+
"--model",
|
|
754
|
+
"--oss",
|
|
755
|
+
"--profile",
|
|
756
|
+
"--remote",
|
|
757
|
+
"--remote-auth-token-env",
|
|
758
|
+
"--sandbox",
|
|
759
|
+
"--strict-config",
|
|
760
|
+
], {
|
|
761
|
+
exposure: "not_exposed",
|
|
762
|
+
adminProjection: "not_exposed",
|
|
763
|
+
maxPositionals: 1,
|
|
764
|
+
flagArities: {
|
|
765
|
+
"--dangerously-bypass-approvals-and-sandbox": "none",
|
|
766
|
+
"--dangerously-bypass-hook-trust": "none",
|
|
767
|
+
"--force": "none",
|
|
768
|
+
"--oss": "none",
|
|
769
|
+
"--strict-config": "none",
|
|
770
|
+
},
|
|
771
|
+
}),
|
|
671
772
|
archive: subcommand(["archive"], "Archive Codex session state.", "writes_local_config", [
|
|
672
773
|
"--add-dir",
|
|
673
774
|
"--cd",
|
|
@@ -960,7 +1061,7 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
960
1061
|
upstreamMetadata: {
|
|
961
1062
|
sourceUrls: [
|
|
962
1063
|
"https://antigravity.google/docs/cli-overview",
|
|
963
|
-
"https://github.com/google-antigravity/antigravity-cli/releases",
|
|
1064
|
+
"https://api.github.com/repos/google-antigravity/antigravity-cli/releases/latest",
|
|
964
1065
|
],
|
|
965
1066
|
repo: "https://github.com/google-antigravity/antigravity-cli",
|
|
966
1067
|
installDocsUrl: "https://antigravity.google/docs/cli-getting-started",
|
|
@@ -969,6 +1070,11 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
969
1070
|
},
|
|
970
1071
|
helpArgs: [["--help"]],
|
|
971
1072
|
subcommands: {
|
|
1073
|
+
agent: subcommand(["agent"], "List available Antigravity agents.", "read_only", [], {
|
|
1074
|
+
aliases: ["agents"],
|
|
1075
|
+
tier: "inspect",
|
|
1076
|
+
tokenCost: "tiny",
|
|
1077
|
+
}),
|
|
972
1078
|
changelog: subcommand(["changelog"], "Show Antigravity CLI changelog and release notes.", "read_only", [], { tokenCost: "small" }),
|
|
973
1079
|
install: subcommand(["install"], "Configure Antigravity CLI environment paths and shell settings.", "writes_local_config", ["--dir", "--skip-aliases", "--skip-path"], {
|
|
974
1080
|
flagArities: { "--dir": "one", "--skip-aliases": "none", "--skip-path": "none" },
|
|
@@ -1033,7 +1139,7 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
1033
1139
|
description: "Print-mode wait timeout as a Go duration string (e.g. 5m0s)",
|
|
1034
1140
|
},
|
|
1035
1141
|
},
|
|
1036
|
-
acknowledgedUpstreamFlags: ["--log-file", "--mode", "--prompt-interactive"],
|
|
1142
|
+
acknowledgedUpstreamFlags: ["--agent", "--log-file", "--mode", "--prompt-interactive"],
|
|
1037
1143
|
env: {},
|
|
1038
1144
|
conformanceFixtures: [
|
|
1039
1145
|
{
|
|
@@ -1048,6 +1154,12 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
1048
1154
|
args: ["--print", "hello", "--not-a-gemini-flag"],
|
|
1049
1155
|
expect: "fail",
|
|
1050
1156
|
},
|
|
1157
|
+
{
|
|
1158
|
+
id: "gemini-agent-selection-acknowledged-not-emitted",
|
|
1159
|
+
description: "Antigravity 1.1.1 advertises --agent, but gateway request argv stays closed until its security model is explicitly wired",
|
|
1160
|
+
args: ["--print", "hello", "--agent", "reviewer"],
|
|
1161
|
+
expect: "fail",
|
|
1162
|
+
},
|
|
1051
1163
|
{
|
|
1052
1164
|
id: "gemini-antigravity-workspace-flags",
|
|
1053
1165
|
description: "Antigravity workspace and sandbox flags are accepted",
|
|
@@ -1181,49 +1293,9 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
1181
1293
|
sessions: subcommand(["sessions"], "Inspect Grok sessions.", "read_only", ["--leader-socket"], {
|
|
1182
1294
|
tier: "inspect",
|
|
1183
1295
|
}),
|
|
1184
|
-
setup: subcommand(["setup"], "Configure Grok CLI local setup.", "writes_local_config", ["--leader-socket"], {
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
"--agent",
|
|
1188
|
-
"--agents",
|
|
1189
|
-
"--allow",
|
|
1190
|
-
"--always-approve",
|
|
1191
|
-
"--best-of-n",
|
|
1192
|
-
"--check",
|
|
1193
|
-
"--continue",
|
|
1194
|
-
"--cwd",
|
|
1195
|
-
"--deny",
|
|
1196
|
-
"--disable-web-search",
|
|
1197
|
-
"--disallowed-tools",
|
|
1198
|
-
"--experimental-memory",
|
|
1199
|
-
"--fork-session",
|
|
1200
|
-
"--json-schema",
|
|
1201
|
-
"--max-turns",
|
|
1202
|
-
"--minimal",
|
|
1203
|
-
"--model",
|
|
1204
|
-
"--no-alt-screen",
|
|
1205
|
-
"--no-memory",
|
|
1206
|
-
"--no-plan",
|
|
1207
|
-
"--no-subagents",
|
|
1208
|
-
"--oauth",
|
|
1209
|
-
"--output-format",
|
|
1210
|
-
"--permission-mode",
|
|
1211
|
-
"--prompt-file",
|
|
1212
|
-
"--prompt-json",
|
|
1213
|
-
"--reasoning-effort",
|
|
1214
|
-
"--restore-code",
|
|
1215
|
-
"--resume",
|
|
1216
|
-
"--rules",
|
|
1217
|
-
"--sandbox",
|
|
1218
|
-
"--session-id",
|
|
1219
|
-
"--single",
|
|
1220
|
-
"--system-prompt-override",
|
|
1221
|
-
"--tools",
|
|
1222
|
-
"--verbatim",
|
|
1223
|
-
"--version",
|
|
1224
|
-
"--worktree",
|
|
1225
|
-
"--worktree-ref",
|
|
1226
|
-
],
|
|
1296
|
+
setup: subcommand(["setup"], "Configure Grok CLI local setup.", "writes_local_config", ["--json", "--leader-socket"], {
|
|
1297
|
+
exposure: "not_exposed",
|
|
1298
|
+
flagArities: { "--json": "none", "--leader-socket": "one" },
|
|
1227
1299
|
}),
|
|
1228
1300
|
trace: subcommand(["trace"], "Inspect Grok trace data.", "read_only", ["--json", "--leader-socket", "--local", "--output"], { tier: "diagnostic" }),
|
|
1229
1301
|
update: subcommand(["update"], "Update the Grok CLI binary.", "updates_binary", [
|
|
@@ -1237,9 +1309,20 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
1237
1309
|
], { exposure: "not_exposed" }),
|
|
1238
1310
|
version: subcommand(["version"], "Print Grok version information.", "read_only", ["--json", "--leader-socket"], { tier: "diagnostic" }),
|
|
1239
1311
|
worktree: subcommand(["worktree"], "Manage Grok worktree sessions.", "writes_local_config", ["--leader-socket"]),
|
|
1312
|
+
wrap: subcommand(["wrap"], "Run an arbitrary command inside a local clipboard-forwarding PTY.", "destructive", ["--leader-socket"], {
|
|
1313
|
+
exposure: "not_exposed",
|
|
1314
|
+
tier: "execute_candidate",
|
|
1315
|
+
maxPositionals: "variadic",
|
|
1316
|
+
flagArities: { "--leader-socket": "one" },
|
|
1317
|
+
}),
|
|
1240
1318
|
}, GROK_DEBUG_HELP_FLAGS),
|
|
1241
1319
|
maxPositionals: 0,
|
|
1242
|
-
acknowledgedUpstreamFlags: [
|
|
1320
|
+
acknowledgedUpstreamFlags: [
|
|
1321
|
+
...GROK_DEBUG_HELP_FLAGS,
|
|
1322
|
+
"--fullscreen",
|
|
1323
|
+
"--minimal",
|
|
1324
|
+
"--session-id",
|
|
1325
|
+
],
|
|
1243
1326
|
mcpTools: ["grok_request", "grok_request_async"],
|
|
1244
1327
|
mcpParameters: [
|
|
1245
1328
|
"prompt",
|
|
@@ -1299,7 +1382,7 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
1299
1382
|
"--always-approve": { arity: "none", description: "Approve tool use automatically" },
|
|
1300
1383
|
"--permission-mode": {
|
|
1301
1384
|
arity: "one",
|
|
1302
|
-
values:
|
|
1385
|
+
values: GROK_PERMISSION_MODES,
|
|
1303
1386
|
description: "Permission mode",
|
|
1304
1387
|
},
|
|
1305
1388
|
"--effort": { arity: "one", values: EFFORT_LEVELS, description: "Reasoning effort" },
|
|
@@ -1648,6 +1731,7 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
1648
1731
|
description: "Agent/permission mode (builtin, install-gated, or custom agent name)",
|
|
1649
1732
|
},
|
|
1650
1733
|
"--enabled-tools": { arity: "one", description: "Enabled tool" },
|
|
1734
|
+
"--disabled-tools": { arity: "one", description: "Disabled tool" },
|
|
1651
1735
|
"--resume": {
|
|
1652
1736
|
arity: "optional",
|
|
1653
1737
|
description: "Resume session by ID, or interactive picker when omitted",
|
|
@@ -1681,17 +1765,11 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
1681
1765
|
description: "Additional writable workspace directory (Phase 4 slice ζ; repeat once per directory)",
|
|
1682
1766
|
},
|
|
1683
1767
|
},
|
|
1684
|
-
acknowledgedUpstreamFlags: [
|
|
1685
|
-
"--auto-approve",
|
|
1686
|
-
"--check-upgrade",
|
|
1687
|
-
"--disabled-tools",
|
|
1688
|
-
"--worktree",
|
|
1689
|
-
"--yolo",
|
|
1690
|
-
],
|
|
1768
|
+
acknowledgedUpstreamFlags: ["--auto-approve", "--check-upgrade", "--worktree", "--yolo"],
|
|
1691
1769
|
env: {
|
|
1692
1770
|
VIBE_ACTIVE_MODEL: {
|
|
1693
1771
|
arity: "one",
|
|
1694
|
-
pattern: /^[^\s\
|
|
1772
|
+
pattern: /^[^\s\p{Cc}]+$/u,
|
|
1695
1773
|
description: "Active model selector; Vibe uses env instead of a --model flag",
|
|
1696
1774
|
},
|
|
1697
1775
|
},
|
|
@@ -1813,11 +1891,11 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
1813
1891
|
expect: "fail",
|
|
1814
1892
|
},
|
|
1815
1893
|
{
|
|
1816
|
-
id: "mistral-disabled-tools
|
|
1817
|
-
description: "Vibe 2.19.1
|
|
1894
|
+
id: "mistral-disabled-tools",
|
|
1895
|
+
description: "Vibe 2.19.1 --disabled-tools denylist is accepted once per tool",
|
|
1818
1896
|
args: ["-p", "hello", "--disabled-tools", "shell"],
|
|
1819
1897
|
env: { VIBE_ACTIVE_MODEL: "mistral-medium-3.5" },
|
|
1820
|
-
expect: "
|
|
1898
|
+
expect: "pass",
|
|
1821
1899
|
},
|
|
1822
1900
|
{
|
|
1823
1901
|
id: "mistral-resume-bare",
|
|
@@ -1833,14 +1911,63 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
1833
1911
|
executable: "devin",
|
|
1834
1912
|
upstream: "Cognition Devin CLI",
|
|
1835
1913
|
upstreamMetadata: {
|
|
1836
|
-
sourceUrls: [
|
|
1914
|
+
sourceUrls: [
|
|
1915
|
+
"https://cli.devin.ai/docs/reference/commands",
|
|
1916
|
+
"https://docs.devin.ai/cli",
|
|
1917
|
+
"https://docs.devin.ai/cli/changelog/stable",
|
|
1918
|
+
],
|
|
1837
1919
|
packageName: "devin",
|
|
1838
1920
|
installDocsUrl: "https://docs.devin.ai/cli",
|
|
1839
1921
|
releaseChannel: "vendor",
|
|
1840
1922
|
watchCategories: ["flags", "subcommands", "permission-modes", "acp-entrypoint"],
|
|
1841
1923
|
},
|
|
1842
1924
|
helpArgs: [["--help"]],
|
|
1843
|
-
subcommands: {
|
|
1925
|
+
subcommands: {
|
|
1926
|
+
acp: subcommand(["acp"], "Run the Devin Agent Client Protocol server over stdio.", "starts_server", ["--agent-type"], {
|
|
1927
|
+
exposure: "not_exposed",
|
|
1928
|
+
flagArities: { "--agent-type": "one" },
|
|
1929
|
+
}),
|
|
1930
|
+
auth: subcommand(["auth"], "Manage Devin authentication state.", "auth", [], {
|
|
1931
|
+
exposure: "not_exposed",
|
|
1932
|
+
maxPositionals: "variadic",
|
|
1933
|
+
}),
|
|
1934
|
+
cloud: subcommand(["cloud"], "Manage Devin Cloud environments, sandboxes, and builds.", "network", [], { exposure: "not_exposed", maxPositionals: "variadic" }),
|
|
1935
|
+
list: subcommand(["list"], "List Devin sessions in the current directory.", "read_only", ["--format"], {
|
|
1936
|
+
aliases: ["ls"],
|
|
1937
|
+
tier: "inspect",
|
|
1938
|
+
flagArities: { "--format": "one" },
|
|
1939
|
+
}),
|
|
1940
|
+
mcp: subcommand(["mcp"], "Manage Devin MCP server connections.", "writes_local_config", [], {
|
|
1941
|
+
exposure: "not_exposed",
|
|
1942
|
+
maxPositionals: "variadic",
|
|
1943
|
+
}),
|
|
1944
|
+
plugins: subcommand(["plugins"], "Manage Devin plugins.", "writes_local_config", [], {
|
|
1945
|
+
exposure: "not_exposed",
|
|
1946
|
+
maxPositionals: "variadic",
|
|
1947
|
+
}),
|
|
1948
|
+
rules: subcommand(["rules"], "Manage Devin always-on agent rules.", "writes_local_config", [], { exposure: "not_exposed", maxPositionals: "variadic" }),
|
|
1949
|
+
sandbox: subcommand(["sandbox"], "Manage Devin process sandboxing.", "writes_local_config", [], { exposure: "not_exposed", maxPositionals: "variadic" }),
|
|
1950
|
+
setup: subcommand(["setup"], "Run Devin interactive setup.", "writes_local_config", ["--force-manual-token-flow"], {
|
|
1951
|
+
exposure: "not_exposed",
|
|
1952
|
+
flagArities: { "--force-manual-token-flow": "none" },
|
|
1953
|
+
}),
|
|
1954
|
+
shell: subcommand(["shell"], "Integrate Devin with the local shell.", "writes_local_config", [], { exposure: "not_exposed", maxPositionals: "variadic" }),
|
|
1955
|
+
skills: subcommand(["skills"], "Manage Devin skills.", "writes_local_config", [], {
|
|
1956
|
+
exposure: "not_exposed",
|
|
1957
|
+
maxPositionals: "variadic",
|
|
1958
|
+
}),
|
|
1959
|
+
uninstall: subcommand(["uninstall"], "Uninstall Devin and remove local data.", "destructive", ["--clean", "--force"], {
|
|
1960
|
+
exposure: "not_exposed",
|
|
1961
|
+
flagArities: { "--clean": "none", "--force": "none" },
|
|
1962
|
+
}),
|
|
1963
|
+
update: subcommand(["update"], "Check for or install Devin CLI updates.", "updates_binary", ["--force"], {
|
|
1964
|
+
exposure: "not_exposed",
|
|
1965
|
+
flagArities: { "--force": "none" },
|
|
1966
|
+
}),
|
|
1967
|
+
version: subcommand(["version"], "Print Devin version information.", "read_only", [], {
|
|
1968
|
+
tier: "diagnostic",
|
|
1969
|
+
}),
|
|
1970
|
+
},
|
|
1844
1971
|
maxPositionals: 0,
|
|
1845
1972
|
mcpTools: ["devin_request", "devin_request_async"],
|
|
1846
1973
|
mcpParameters: [
|
|
@@ -1865,8 +1992,8 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
1865
1992
|
"--model": { arity: "one", description: "AI model for this session" },
|
|
1866
1993
|
"--permission-mode": {
|
|
1867
1994
|
arity: "one",
|
|
1868
|
-
values: ["auto", "smart", "dangerous"],
|
|
1869
|
-
description: "Permission mode (auto = read-only auto-approve; smart = additionally auto-runs safe actions per fast model; dangerous = approve all)",
|
|
1995
|
+
values: ["auto", "accept-edits", "smart", "dangerous"],
|
|
1996
|
+
description: "Permission mode (auto = read-only auto-approve; accept-edits = also auto-approve workspace edits; smart = additionally auto-runs safe actions per fast model; dangerous = approve all)",
|
|
1870
1997
|
},
|
|
1871
1998
|
"--prompt-file": { arity: "one", description: "Load the initial prompt from a file" },
|
|
1872
1999
|
"--config": { arity: "one", description: "Config file path" },
|
|
@@ -1917,6 +2044,12 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
1917
2044
|
args: ["-p", "hello", "--permission-mode", "auto"],
|
|
1918
2045
|
expect: "pass",
|
|
1919
2046
|
},
|
|
2047
|
+
{
|
|
2048
|
+
id: "devin-permission-mode-accept-edits",
|
|
2049
|
+
description: "Valid --permission-mode 'accept-edits' accepted",
|
|
2050
|
+
args: ["-p", "hello", "--permission-mode", "accept-edits"],
|
|
2051
|
+
expect: "pass",
|
|
2052
|
+
},
|
|
1920
2053
|
{
|
|
1921
2054
|
id: "devin-permission-mode-smart",
|
|
1922
2055
|
description: "Valid --permission-mode 'smart' accepted",
|
|
@@ -2007,7 +2140,57 @@ export const UPSTREAM_CLI_CONTRACTS = {
|
|
|
2007
2140
|
],
|
|
2008
2141
|
},
|
|
2009
2142
|
helpArgs: [["--help"]],
|
|
2010
|
-
subcommands: {
|
|
2143
|
+
subcommands: {
|
|
2144
|
+
about: subcommand(["about"], "Display Cursor Agent version, system, and account information.", "read_only", ["--format"], { tier: "diagnostic", flagArities: { "--format": "one" } }),
|
|
2145
|
+
agent: subcommand(["agent"], "Start an interactive Cursor Agent session.", "executes_agent", [], { exposure: "not_exposed", maxPositionals: "variadic" }),
|
|
2146
|
+
"create-chat": subcommand(["create-chat"], "Create a new Cursor chat and return its ID.", "network", [], { exposure: "not_exposed" }),
|
|
2147
|
+
"generate-rule": subcommand(["generate-rule"], "Generate a Cursor rule through interactive prompts.", "writes_local_config", [], { aliases: ["rule"], exposure: "not_exposed", maxPositionals: "variadic" }),
|
|
2148
|
+
"install-shell-integration": subcommand(["install-shell-integration"], "Install Cursor shell integration.", "writes_local_config", [], { exposure: "not_exposed" }),
|
|
2149
|
+
login: subcommand(["login"], "Authenticate with Cursor.", "auth", [], {
|
|
2150
|
+
exposure: "not_exposed",
|
|
2151
|
+
}),
|
|
2152
|
+
logout: subcommand(["logout"], "Clear Cursor authentication state.", "auth", [], {
|
|
2153
|
+
exposure: "not_exposed",
|
|
2154
|
+
}),
|
|
2155
|
+
ls: subcommand(["ls"], "Resume a Cursor chat session.", "executes_agent", [], {
|
|
2156
|
+
exposure: "not_exposed",
|
|
2157
|
+
maxPositionals: "variadic",
|
|
2158
|
+
}),
|
|
2159
|
+
mcp: subcommand(["mcp"], "Manage Cursor MCP server configuration.", "writes_local_config", [], { exposure: "not_exposed", maxPositionals: "variadic" }),
|
|
2160
|
+
models: subcommand(["models"], "List Cursor account models.", "read_only", [], {
|
|
2161
|
+
tier: "inspect",
|
|
2162
|
+
}),
|
|
2163
|
+
resume: subcommand(["resume"], "Resume the latest Cursor chat.", "executes_agent", [], {
|
|
2164
|
+
exposure: "not_exposed",
|
|
2165
|
+
maxPositionals: "variadic",
|
|
2166
|
+
}),
|
|
2167
|
+
status: subcommand(["status"], "View Cursor authentication status.", "read_only", ["--format"], {
|
|
2168
|
+
aliases: ["whoami"],
|
|
2169
|
+
tier: "inspect",
|
|
2170
|
+
flagArities: { "--format": "one" },
|
|
2171
|
+
}),
|
|
2172
|
+
"uninstall-shell-integration": subcommand(["uninstall-shell-integration"], "Remove Cursor shell integration.", "writes_local_config", [], { exposure: "not_exposed" }),
|
|
2173
|
+
update: subcommand(["update"], "Update Cursor Agent.", "updates_binary", [], {
|
|
2174
|
+
exposure: "not_exposed",
|
|
2175
|
+
}),
|
|
2176
|
+
worker: subcommand(["worker"], "Start a private Cursor cloud worker for local agent runs.", "starts_server", [
|
|
2177
|
+
"--auth-token-file",
|
|
2178
|
+
"--data-dir",
|
|
2179
|
+
"--debug",
|
|
2180
|
+
"--idle-release-timeout",
|
|
2181
|
+
"--label",
|
|
2182
|
+
"--labels-file",
|
|
2183
|
+
"--management-addr",
|
|
2184
|
+
"--name",
|
|
2185
|
+
"--pool",
|
|
2186
|
+
"--pool-name",
|
|
2187
|
+
"--single-use",
|
|
2188
|
+
"--worker-dir",
|
|
2189
|
+
], {
|
|
2190
|
+
exposure: "not_exposed",
|
|
2191
|
+
flagArities: { "--debug": "none", "--single-use": "none" },
|
|
2192
|
+
}),
|
|
2193
|
+
},
|
|
2011
2194
|
maxPositionals: 1,
|
|
2012
2195
|
mcpTools: ["cursor_request", "cursor_request_async"],
|
|
2013
2196
|
mcpParameters: [
|
|
@@ -2297,6 +2480,7 @@ export function serializeCliSubcommandContract(cli, contract) {
|
|
|
2297
2480
|
})),
|
|
2298
2481
|
risk: contract.risk,
|
|
2299
2482
|
exposure: contract.exposure,
|
|
2483
|
+
adminProjection: contract.adminProjection ?? null,
|
|
2300
2484
|
tier: contract.tier,
|
|
2301
2485
|
tokenCost: contract.tokenCost,
|
|
2302
2486
|
summary: contract.summary,
|
|
@@ -2441,7 +2625,7 @@ export function validateUpstreamCliSubcommandArgs(cli, commandPath, args) {
|
|
|
2441
2625
|
});
|
|
2442
2626
|
}
|
|
2443
2627
|
}
|
|
2444
|
-
if (positionals.length > contract.maxPositionals) {
|
|
2628
|
+
if (contract.maxPositionals !== "variadic" && positionals.length > contract.maxPositionals) {
|
|
2445
2629
|
violations.push({
|
|
2446
2630
|
cli,
|
|
2447
2631
|
message: `${cli} subcommand "${subcommandKey(commandPath)}" has ${positionals.length} positional values; upstream subcommand contract allows ${contract.maxPositionals}`,
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { z } from "zod/v3";
|
|
2
2
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
3
|
import type { AsyncJobManager } from "./async-job-manager.js";
|
|
4
|
+
import { PerformanceMetrics } from "./metrics.js";
|
|
5
|
+
import { type LeastCostConfig } from "./config.js";
|
|
6
|
+
import type { FlightRecorderQuery } from "./flight-recorder.js";
|
|
4
7
|
import { type ValidationOrchestratorDeps } from "./validation-orchestrator.js";
|
|
5
8
|
export interface ValidationToolDeps extends ValidationOrchestratorDeps {
|
|
6
9
|
asyncJobManager: AsyncJobManager;
|
|
10
|
+
leastCost?: LeastCostConfig;
|
|
11
|
+
performanceMetrics?: PerformanceMetrics;
|
|
12
|
+
flightRecorder?: FlightRecorderQuery;
|
|
7
13
|
}
|
|
8
14
|
export declare function buildValidationSchemas(deps: ValidationToolDeps): {
|
|
9
15
|
providerSchema: z.ZodEnum<[string, ...string[]]>;
|