fix(cli): shrink cliTools.ts/cliRuntime.ts under the file-size ratchet + fix stale catalog counts

The grok-build registry/runtime entries pushed cliTools.ts (916->932) and
cliRuntime.ts (1128->1137) past their frozen file-size caps. Extract the
grok-build entries into cliToolsGrokBuild.ts (registry, typed) and
cliRuntimeGrokBuild.ts (runtime metadata, deliberately untyped/no
cliCatalog import so it doesn't drag that schema file into the
typecheck:core curated allowlist's transitive graph). The amp runtime
entry rides along in the same runtime file for the extra headroom needed
to clear cliRuntime.ts's cap with zero slack.

Also update the two catalog-cardinality canaries (cli-tools-schema.test.ts,
cli-catalog-counts.test.ts) and EXPECTED_CODE_COUNT to include grok-build:
20->21 visible code entries, 24->25 total code entries, 32->33 grand total.

Fixes CI reds on #7241 surviving a release/v3.8.49 merge: Fast Quality
Gates (check:file-size) and Unit Tests fast-path (1/4, 2/4).
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-07-15 11:58:54 -03:00
parent 32d1700407
commit e1da792dea
7 changed files with 61 additions and 41 deletions

View File

@@ -1,6 +1,7 @@
// CLI Tools configuration
import { getClaudeCodeDefaultModels } from "@omniroute/open-sse/config/providerRegistry";
import type { CliCatalogEntry } from "@/shared/schemas/cliCatalog";
import { GROK_BUILD_CLI_TOOL } from "@/shared/constants/cliToolsGrokBuild";
const _cc = getClaudeCodeDefaultModels();
@@ -540,7 +541,6 @@ export const CLI_TOOLS: Record<string, CliCatalogEntry> = {
acpSpawnable: false,
baseUrlSupport: "full",
},
// ── Code entries — aider ──────────────────────────────────────────────────
aider: {
id: "aider",
@@ -567,7 +567,6 @@ export const CLI_TOOLS: Record<string, CliCatalogEntry> = {
aider --openai-api-base "{{baseUrl}}" --model "{{model}}"`,
},
},
// ── Code entries — forge ──────────────────────────────────────────────────
forge: {
id: "forge",
@@ -584,22 +583,7 @@ aider --openai-api-base "{{baseUrl}}" --model "{{model}}"`,
defaultCommand: "forge",
},
// ── Code entries — grok-build ─────────────────────────────────────────────
"grok-build": {
id: "grok-build",
name: "Grok Build",
icon: "terminal",
color: "#1DA1F2",
description: "xAI Grok Build TUI coding agent — custom provider via ~/.grok/config.toml",
docsUrl: "https://x.ai/cli",
configType: "custom",
category: "code",
vendor: "xAI",
acpSpawnable: false,
baseUrlSupport: "full",
defaultCommand: "grok",
},
"grok-build": GROK_BUILD_CLI_TOOL,
// ── Code entries — cursor-cli ─────────────────────────────────────────────
"cursor-cli": {
id: "cursor-cli",

View File

@@ -0,0 +1,19 @@
// Grok Build CLI tool registry entry — extracted from cliTools.ts to keep the
// frozen registry file under its file-size ratchet cap (config/quality/file-size-baseline.json).
import type { CliCatalogEntry } from "@/shared/schemas/cliCatalog";
/** xAI Grok Build TUI coding agent — custom provider via ~/.grok/config.toml */
export const GROK_BUILD_CLI_TOOL: CliCatalogEntry = {
id: "grok-build",
name: "Grok Build",
icon: "terminal",
color: "#1DA1F2",
description: "xAI Grok Build TUI coding agent — custom provider via ~/.grok/config.toml",
docsUrl: "https://x.ai/cli",
configType: "custom",
category: "code",
vendor: "xAI",
acpSpawnable: false,
baseUrlSupport: "full",
defaultCommand: "grok",
};

View File

@@ -62,7 +62,8 @@ export const CliCatalogSchema = z.record(CliCatalogEntrySchema);
/** Cardinalidade obrigatória (Plano §3.1/§3.2 + D15). +1 (crush, decolua/9router#1233). */
// +1 (2026-07-02): "codewhale" added as a dual entry alongside "deepseek-tui"
// (CodeWhale is the actively-maintained successor to DeepSeek TUI).
export const EXPECTED_CODE_COUNT = 20;
// +1 (grok-build, decolua/9router#2571): xAI Grok Build TUI coding agent.
export const EXPECTED_CODE_COUNT = 21;
// +2 (#6318): "omp" (Oh My Pi) and "letta" (Letta CLI) added as agent entries.
// Note: #6318 originally also shipped duplicate "pi"/"jcode"/"codewhale" entries —
// those tools were already delivered by a separate PR, so only omp+letta landed here.

View File

@@ -6,6 +6,7 @@ import { spawn, execFileSync } from "child_process";
import { getHermesHome } from "@/lib/cli-helper/config-generator/hermesHome";
import { getCachedLoginShellPath, mergeShellPath } from "./loginShellPath";
import { withSettingsFallback } from "./cliInstallFallback";
import { GROK_BUILD_RUNTIME_ENTRY, AMP_RUNTIME_ENTRY } from "./cliRuntimeGrokBuild";
const VALID_RUNTIME_MODES = new Set(["auto", "host", "container"]);
const FALSE_VALUES = new Set(["0", "false", "no", "off"]);
@@ -155,13 +156,7 @@ const CLI_TOOLS: Record<string, any> = {
config: "config.yaml",
},
},
amp: {
defaultCommand: "amp",
envBinKey: "CLI_AMP_BIN",
requiresBinary: true,
healthcheckTimeoutMs: 12000,
paths: {},
},
amp: AMP_RUNTIME_ENTRY,
qoder: {
defaultCommand: "qodercli",
envBinKey: "CLI_QODER_BIN",
@@ -201,15 +196,7 @@ const CLI_TOOLS: Record<string, any> = {
config: ".jcode/config.json",
},
},
"grok-build": {
defaultCommand: "grok",
envBinKey: "CLI_GROK_BUILD_BIN",
requiresBinary: true,
healthcheckTimeoutMs: 8000,
paths: {
config: ".grok/config.toml",
},
},
"grok-build": GROK_BUILD_RUNTIME_ENTRY,
"deepseek-tui": {
defaultCommand: "deepseek-tui",
envBinKey: "CLI_DEEPSEEK_TUI_BIN",

View File

@@ -0,0 +1,26 @@
// Runtime-detection metadata entries extracted from cliRuntime.ts to keep that
// frozen file under its file-size ratchet cap (config/quality/file-size-baseline.json).
// Deliberately untyped (matches cliRuntime.ts's own `Record<string, any>` CLI_TOOLS
// shape) and has NO import of the CliCatalogEntry schema — keep it that way, so this
// module never drags src/shared/schemas/cliCatalog.ts into the typecheck-core
// transitive graph (that file is not on typecheck:core's curated allowlist).
/** Grok Build runtime-detection metadata (binary lookup + healthcheck). */
export const GROK_BUILD_RUNTIME_ENTRY = {
defaultCommand: "grok",
envBinKey: "CLI_GROK_BUILD_BIN",
requiresBinary: true,
healthcheckTimeoutMs: 8000,
paths: {
config: ".grok/config.toml",
},
};
/** Amp runtime-detection metadata (extracted alongside grok-build for file-size headroom). */
export const AMP_RUNTIME_ENTRY = {
defaultCommand: "amp",
envBinKey: "CLI_AMP_BIN",
requiresBinary: true,
healthcheckTimeoutMs: 12000,
paths: {},
};

View File

@@ -30,7 +30,7 @@ test(`CLI_TOOLS has exactly ${EXPECTED_AGENT_COUNT} agent entries`, () => {
);
});
test("CLI_TOOLS total code entries (including none) equals 24 (20 visible + 4 none)", () => {
test("CLI_TOOLS total code entries (including none) equals 25 (21 visible + 4 none)", () => {
// code-none entries: antigravity, kiro, cursor (app), hermes (simple guide)
const codeNone = codeAll.filter((t) => t.baseUrlSupport === "none");
assert.equal(
@@ -38,11 +38,11 @@ test("CLI_TOOLS total code entries (including none) equals 24 (20 visible + 4 no
4,
`Expected 4 code entries with baseUrlSupport='none', got ${codeNone.length}: ${codeNone.map((t) => t.id).join(", ")}`
);
assert.equal(codeAll.length, 24, `Expected 24 total code entries, got ${codeAll.length}`);
assert.equal(codeAll.length, 25, `Expected 25 total code entries, got ${codeAll.length}`);
});
test("CLI_TOOLS total (code + agent) = 32", () => {
assert.equal(all.length, 32, `Expected 32 total entries, got ${all.length}`);
test("CLI_TOOLS total (code + agent) = 33", () => {
assert.equal(all.length, 33, `Expected 33 total entries, got ${all.length}`);
});
test("All code-none entries have configType mitm OR are legacy excluded entries", () => {
@@ -66,7 +66,7 @@ test("All agent entries have baseUrlSupport 'full' or 'partial' (no agent is 'no
}
});
test("The 20 visible code entries match D15 list exactly (+ crush + codewhale)", () => {
test("The 21 visible code entries match D15 list exactly (+ crush + codewhale + grok-build)", () => {
const d15List = new Set([
"claude",
"codex",
@@ -88,6 +88,7 @@ test("The 20 visible code entries match D15 list exactly (+ crush + codewhale)",
"pi",
"custom",
"crush",
"grok-build",
]);
const visibleIds = new Set(codeVisible.map((t) => t.id));
for (const id of d15List) {

View File

@@ -1,7 +1,7 @@
import test from "node:test";
import assert from "node:assert/strict";
test("CLI_TOOLS registry contains all expected tools (plan 14 — 32 total + crush + codewhale + omp + letta)", async () => {
test("CLI_TOOLS registry contains all expected tools (plan 14 — 33 total + crush + codewhale + omp + letta + grok-build)", async () => {
const { CLI_TOOLS } = await import("../../src/shared/constants/cliTools.ts");
// windsurf and amp removed per plan 14 D17 (MITM backlog plan 11)
// New entries added: roo, jcode, deepseek-tui, smelt, pi, aider, forge,
@@ -10,6 +10,7 @@ test("CLI_TOOLS registry contains all expected tools (plan 14 — 32 total + cru
// codewhale added 2026-07-02 as a dual entry alongside deepseek-tui
// (CodeWhale is the actively-maintained successor to DeepSeek TUI).
// omp + letta added by #6318 (agent-category CLI integrations).
// grok-build added — xAI Grok Build TUI coding agent (ported from upstream decolua/9router#2571).
const expected = [
"claude",
"codex",
@@ -43,6 +44,7 @@ test("CLI_TOOLS registry contains all expected tools (plan 14 — 32 total + cru
"letta",
"agent-deck",
"crush",
"grok-build",
];
for (const id of expected) {
assert.ok(id in CLI_TOOLS, `Missing tool: ${id}`);