feat(cli): add Grok Build CLI tool setup (~/.grok/config.toml) - #7241
Conversation
Registers xAI's Grok Build TUI coding agent as a configurable CLI tool in /dashboard/cli-code, so OmniRoute can write itself in as a custom model provider in ~/.grok/config.toml. Mechanism: Grok Build reads a TOML config that can hold several user-defined [model.*] sections plus a [models].default pointer. Unlike the sibling Forge handler (which owns its whole config file and can full-replace it), this one surgically upserts ONLY the [model.omniroute] section and rewrites [models].default, leaving every other section byte-intact. Apply records the previous default in an `# omniroute-prev-default` marker comment so Reset can restore the user's original default instead of guessing. Built on OmniRoute's existing CLI-tools infrastructure rather than replaying the upstream shape: getCliRuntimeStatus() for detection (no ad-hoc `which grok` exec), Zod validation via cliModelConfigSchema, the write guard, createBackup(), the cliToolState DB module, and sanitizeErrorMessage() for every error path (Hard Rule #12). Security: GET reaches getCliRuntimeStatus(), which spawns a child process to locate and healthcheck the `grok` binary. That is the same transitive-spawn surface that classified /api/skills/collect/, so the route is registered in LOCAL_ONLY_API_PREFIXES and loopback-enforced before any auth check (Hard Rules #15 + #17). Writing a local CLI's config file is inherently a local-machine operation, so this costs no real capability. Co-authored-by: rixzkiye <rizkiyemubarok05@gmail.com> Inspired-by: decolua/9router#2571
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
|
Revisado a fundo — implementação sólida e bem alinhada com o padrão já estabelecido (omp-settings/letta-settings). Pontos verificados especificamente: (1) classificação LOCAL_ONLY correta e comprovada por teste — GET realmente spawna processo via getCliRuntimeStatus (confirmei no cliRuntime.ts); (2) upsert cirúrgico da seção [model.omniroute] preserva outras seções [model.*] do usuário (testado com pre-seed de [model.custom-thing]); (3) Reset restaura o default anterior via o marcador de comentário, e é no-op seguro quando não há config. Revert-proof da regressão de segurança confirmado (teste cai sem a entrada em LOCAL_ONLY_API_PREFIXES). typecheck+eslint limpos. Pronto para merge. |
…pr-2571-grok-build-setup
…t + 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).
check:mutation-test-coverage --strict flagged tests/unit/route-guard-grok-build-settings-local-only.test.ts as a covering unit test for src/server/authz/routeGuard.ts missing from stryker.conf.json's tap.testFiles allowlist (only became reachable once the Fast Quality Gates job got past the file-size fix earlier in this branch).
Babysit summaryStale verdict refresh: PR was 45 commits behind Real defects found and fixed (survived the fresh run):
Verification: all touched files pass lint + Result: all CI checks green (Fast Quality Gates, Unit Tests fast-path 1-4, Vitest, Docs Gates, ESLint, dast-smoke, semgrep ×2, merge integrity, change classification). No review threads were open. No test assertion was weakened — the two count-based tests were updated to the new, correct cardinalities, and the mutation-coverage fix only registers an existing test in the allowlist. Ready for human review & merge. |
…souzapw#7241) * feat(cli): add Grok Build CLI tool setup (~/.grok/config.toml) Registers xAI's Grok Build TUI coding agent as a configurable CLI tool in /dashboard/cli-code, so OmniRoute can write itself in as a custom model provider in ~/.grok/config.toml. Mechanism: Grok Build reads a TOML config that can hold several user-defined [model.*] sections plus a [models].default pointer. Unlike the sibling Forge handler (which owns its whole config file and can full-replace it), this one surgically upserts ONLY the [model.omniroute] section and rewrites [models].default, leaving every other section byte-intact. Apply records the previous default in an `# omniroute-prev-default` marker comment so Reset can restore the user's original default instead of guessing. Built on OmniRoute's existing CLI-tools infrastructure rather than replaying the upstream shape: getCliRuntimeStatus() for detection (no ad-hoc `which grok` exec), Zod validation via cliModelConfigSchema, the write guard, createBackup(), the cliToolState DB module, and sanitizeErrorMessage() for every error path (Hard Rule diegosouzapw#12). Security: GET reaches getCliRuntimeStatus(), which spawns a child process to locate and healthcheck the `grok` binary. That is the same transitive-spawn surface that classified /api/skills/collect/, so the route is registered in LOCAL_ONLY_API_PREFIXES and loopback-enforced before any auth check (Hard Rules diegosouzapw#15 + diegosouzapw#17). Writing a local CLI's config file is inherently a local-machine operation, so this costs no real capability. Co-authored-by: rixzkiye <rizkiyemubarok05@gmail.com> Inspired-by: decolua/9router#2571 * chore(changelog): fragment for diegosouzapw#7241 * 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 diegosouzapw#7241 surviving a release/v3.8.49 merge: Fast Quality Gates (check:file-size) and Unit Tests fast-path (1/4, 2/4). * test(stryker): register grok-build route-guard test in tap.testFiles check:mutation-test-coverage --strict flagged tests/unit/route-guard-grok-build-settings-local-only.test.ts as a covering unit test for src/server/authz/routeGuard.ts missing from stryker.conf.json's tap.testFiles allowlist (only became reachable once the Fast Quality Gates job got past the file-size fix earlier in this branch). --------- Co-authored-by: rixzkiye <rizkiyemubarok05@gmail.com>
…souzapw#7241) * feat(cli): add Grok Build CLI tool setup (~/.grok/config.toml) Registers xAI's Grok Build TUI coding agent as a configurable CLI tool in /dashboard/cli-code, so OmniRoute can write itself in as a custom model provider in ~/.grok/config.toml. Mechanism: Grok Build reads a TOML config that can hold several user-defined [model.*] sections plus a [models].default pointer. Unlike the sibling Forge handler (which owns its whole config file and can full-replace it), this one surgically upserts ONLY the [model.omniroute] section and rewrites [models].default, leaving every other section byte-intact. Apply records the previous default in an `# omniroute-prev-default` marker comment so Reset can restore the user's original default instead of guessing. Built on OmniRoute's existing CLI-tools infrastructure rather than replaying the upstream shape: getCliRuntimeStatus() for detection (no ad-hoc `which grok` exec), Zod validation via cliModelConfigSchema, the write guard, createBackup(), the cliToolState DB module, and sanitizeErrorMessage() for every error path (Hard Rule diegosouzapw#12). Security: GET reaches getCliRuntimeStatus(), which spawns a child process to locate and healthcheck the `grok` binary. That is the same transitive-spawn surface that classified /api/skills/collect/, so the route is registered in LOCAL_ONLY_API_PREFIXES and loopback-enforced before any auth check (Hard Rules diegosouzapw#15 + diegosouzapw#17). Writing a local CLI's config file is inherently a local-machine operation, so this costs no real capability. Co-authored-by: rixzkiye <rizkiyemubarok05@gmail.com> Inspired-by: decolua/9router#2571 * chore(changelog): fragment for diegosouzapw#7241 * 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 diegosouzapw#7241 surviving a release/v3.8.49 merge: Fast Quality Gates (check:file-size) and Unit Tests fast-path (1/4, 2/4). * test(stryker): register grok-build route-guard test in tap.testFiles check:mutation-test-coverage --strict flagged tests/unit/route-guard-grok-build-settings-local-only.test.ts as a covering unit test for src/server/authz/routeGuard.ts missing from stryker.conf.json's tap.testFiles allowlist (only became reachable once the Fast Quality Gates job got past the file-size fix earlier in this branch). --------- Co-authored-by: rixzkiye <rizkiyemubarok05@gmail.com>
Summary
grokTUI coding agent) as a configurable CLI tool in/dashboard/cli-code, so OmniRoute can write itself into~/.grok/config.tomlas a custom model provider.[model.omniroute]section and points[models].defaultat it; Reset removes it and restores the default the user had before.Attribution
Thanks to @rixzkiye for the original implementation this port is based on.
Changes
src/app/api/cli-tools/grok-build-settings/route.ts(new) — GET/POST/DELETE handler.src/shared/constants/cliTools.ts—grok-buildentry (configType: "custom", categorycode).src/shared/services/cliRuntime.ts— runtime descriptor (grokbinary,.grok/config.toml,CLI_GROK_BUILD_BIN).src/server/authz/routeGuard.ts— classify the route local-only.docs/reference/CLI-TOOLS.md— tool table + settings-handler table rows.Implementation notes
Grok Build's config can hold several user-defined
[model.*]sections plus a[models].defaultpointer. Unlike the sibling Forge handler (which owns its whole config file and full-replaces it), this handler surgically upserts only the[model.omniroute]section, leaving every other section byte-intact — covered by an explicit test asserting a pre-existing[model.custom-thing]survives both Apply and Reset.Apply records the prior default in an
# omniroute-prev-default = "..."marker so Reset restores the user's original default rather than guessing.Rebuilt on OmniRoute's existing CLI-tools infrastructure instead of replaying the upstream shape:
getCliRuntimeStatus()for detection (no ad-hocwhich grokexec — Hard Rule #13),cliModelConfigSchemaZod validation, the write guard,createBackup(), thecliToolStateDB module, andsanitizeErrorMessage()on every error path (Hard Rule #12).Security
GETreachesgetCliRuntimeStatus(), which spawns a child process to locate and healthcheck thegrokbinary. That is the same transitive-spawn surface that classified/api/skills/collect/, and the same class as the already-gatedomp-settings/letta-settings. The route is therefore added toLOCAL_ONLY_API_PREFIXESso loopback enforcement runs before any auth check — a leaked JWT over a tunnel cannot trigger the spawn. Writing a local CLI's config file is inherently a local-machine operation, so loopback-only costs no real capability. A unit test assertsisLocalOnlyPath()returnstruefor it, and that the entry does not over-gate the rest of/api/cli-tools/.Test plan
tests/unit/route-guard-grok-build-settings-local-only.test.ts— 4/4 pass. Fails before the routeGuard entry (verified: 2 assertions✖), passes after.tests/integration/cli-settings-grok-build.test.ts— 9/9 pass (auth 401, Zod 400s, Apply preserves unrelated sections + records prev-default, Reset restores it, no-op DELETE, error sanitization, noexec()/spawn()).tests/unit/check-route-guard-membership.test.ts— 15/15 pass (new prefix does not break the gate).npm run typecheck:core— clean.npx eslint <changed files>— clean.