mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-18 21:22:28 +03:00
- canonical executable manifest (bin/cli/cli-manifest.mjs): run/configure/completion derive targets, aliases and --model wiring from one table; drift test cross-checks manifest x cliRuntime x UI catalog (tests/unit/cli/cli-manifest-drift.test.ts) - dashboard Codex generator converged to ~/.codex/config.toml (modern Codex v0.137+, verified against codex-cli 0.147.0): conservative merge, env_key auth (key never written), refuses invalid TOML, reports legacy config.yaml as migration note - omniroute run gemini: launcher over OmniRoute's /v1beta surface via GOOGLE_GEMINI_BASE_URL + isolated GEMINI_CLI_HOME forcing gemini-api-key auth (contract proven against @google/gemini-cli 0.50.0); ACP registration kept distinct - opt-in real smoke harness for upstream CLIs (RUN_CLI_SMOKE=1, credential by env NAME, redacted output): tests/integration/upstream-cli-smoke.int.test.ts - container-guard homologation for POST /api/cli-tools/apply (422 in container, dry-run preview allowed, host write passes) + docs; guard untouched - typecheck: omniglyphAdapter union narrowing, usageTracking typed signatures (UsageLike, no any), models.ts isValidModel params — typecheck:core and typecheck:noimplicit:core now clean - relay core (prior session of this effort): omniroute run for 6 CLIs, configure picker with per-context favorites/recents, contexts with optional keychain + 0600 fallback, provider CRUD with recursive redaction, completion updates, docs
139 lines
4.6 KiB
JavaScript
139 lines
4.6 KiB
JavaScript
/**
|
|
* Canonical executable manifest for the OmniRoute CLI command surfaces.
|
|
*
|
|
* One entry per canonical target id. `run.mjs`, `configure.mjs` and
|
|
* `completion.mjs` derive their target lists, alias resolution and model-flag
|
|
* wiring from this table instead of keeping private copies, so a new target
|
|
* (or a renamed alias) is declared exactly once.
|
|
*
|
|
* The server-side runtime catalog (`src/shared/services/cliRuntime.ts`) stays
|
|
* the source of truth for binaries, config paths and health checks; the drift
|
|
* test `tests/unit/cli/cli-manifest-drift.test.ts` asserts the two worlds and
|
|
* every consumer surface stay in sync.
|
|
*
|
|
* Capability semantics:
|
|
* - `run`: launchable through `omniroute run <target>`.
|
|
* - `configure`: supported by the `omniroute configure <target>` picker.
|
|
* - `runModel`: how `run` injects `--model` for the target (`null` when the
|
|
* model travels via env/provider args instead of a CLI flag).
|
|
*/
|
|
|
|
export const CLI_TARGET_MANIFEST = Object.freeze({
|
|
claude: Object.freeze({
|
|
description: "Claude Code",
|
|
aliases: Object.freeze(["claude-code", "cc", "anthropic"]),
|
|
run: true,
|
|
configure: true,
|
|
runModel: null, // injected via ANTHROPIC_MODEL env by the launcher
|
|
}),
|
|
codex: Object.freeze({
|
|
description: "OpenAI Codex CLI",
|
|
aliases: Object.freeze(["codex-cli", "openai-codex", "openai"]),
|
|
run: true,
|
|
configure: true,
|
|
runModel: null, // injected via -c model_providers.omniroute.* args
|
|
}),
|
|
aider: Object.freeze({
|
|
description: "Aider",
|
|
aliases: Object.freeze([]),
|
|
run: true,
|
|
configure: true,
|
|
runModel: Object.freeze({ flag: "--model", prefix: "openai/" }),
|
|
}),
|
|
goose: Object.freeze({
|
|
description: "Goose",
|
|
aliases: Object.freeze(["goose-cli"]),
|
|
run: true,
|
|
configure: true,
|
|
runModel: null, // injected via GOOSE_MODEL env
|
|
}),
|
|
opencode: Object.freeze({
|
|
description: "OpenCode",
|
|
aliases: Object.freeze(["open-code"]),
|
|
run: true,
|
|
configure: true,
|
|
runModel: Object.freeze({ flag: "--model", prefix: "omniroute/" }),
|
|
}),
|
|
qwen: Object.freeze({
|
|
description: "Qwen Code",
|
|
aliases: Object.freeze(["qwen-code"]),
|
|
run: true,
|
|
configure: true,
|
|
runModel: Object.freeze({ flag: "--model", prefix: "", required: true }),
|
|
}),
|
|
gemini: Object.freeze({
|
|
// Launch contract verified against @google/gemini-cli 0.50.0:
|
|
// GOOGLE_GEMINI_BASE_URL points the SDK at OmniRoute's /v1beta surface,
|
|
// GEMINI_API_KEY + isolated GEMINI_CLI_HOME (settings selectedType
|
|
// "gemini-api-key") force API-key auth over any stored OAuth session.
|
|
description: "Google Gemini CLI",
|
|
aliases: Object.freeze(["gemini-cli"]),
|
|
run: true,
|
|
configure: false,
|
|
runModel: Object.freeze({ flag: "--model", prefix: "" }),
|
|
}),
|
|
cline: Object.freeze({
|
|
description: "Cline",
|
|
aliases: Object.freeze([]),
|
|
run: false,
|
|
configure: true,
|
|
runModel: null,
|
|
}),
|
|
continue: Object.freeze({
|
|
description: "Continue",
|
|
aliases: Object.freeze(["cn"]),
|
|
run: false,
|
|
configure: true,
|
|
runModel: null,
|
|
}),
|
|
kilo: Object.freeze({
|
|
description: "Kilo Code",
|
|
aliases: Object.freeze(["kilocode", "kilo-code", "kilo_cli"]),
|
|
run: false,
|
|
configure: true,
|
|
runModel: null,
|
|
}),
|
|
});
|
|
|
|
/**
|
|
* List canonical target ids, optionally filtered by capability
|
|
* (`"run"` or `"configure"`). Order follows manifest declaration order.
|
|
*/
|
|
export function listManifestTargets(capability) {
|
|
return Object.entries(CLI_TARGET_MANIFEST)
|
|
.filter(([, entry]) => !capability || entry[capability])
|
|
.map(([id]) => id);
|
|
}
|
|
|
|
/**
|
|
* Resolve a user-supplied target (canonical id or alias) to its canonical id.
|
|
* Returns `undefined` when the target is unknown or lacks the capability.
|
|
*/
|
|
export function resolveManifestTarget(rawTarget, capability) {
|
|
const normalized = String(rawTarget || "")
|
|
.trim()
|
|
.toLowerCase();
|
|
if (!normalized) return undefined;
|
|
for (const [id, entry] of Object.entries(CLI_TARGET_MANIFEST)) {
|
|
if (id === normalized || entry.aliases.includes(normalized)) {
|
|
if (capability && !entry[capability]) return undefined;
|
|
return id;
|
|
}
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
/** Model CLI-flag arguments for a `run` target, derived from the manifest. */
|
|
export function manifestModelArgs(targetId, model) {
|
|
if (!model) return [];
|
|
const spec = CLI_TARGET_MANIFEST[targetId]?.runModel;
|
|
if (!spec) return [];
|
|
const value = spec.prefix && !model.startsWith(spec.prefix) ? `${spec.prefix}${model}` : model;
|
|
return [spec.flag, value];
|
|
}
|
|
|
|
/** Whether a `run` target refuses to launch without an explicit model. */
|
|
export function manifestRequiresModel(targetId) {
|
|
return Boolean(CLI_TARGET_MANIFEST[targetId]?.runModel?.required);
|
|
}
|