mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
feat(cli): consolidar CLI_TOOLS — listCliTools/getCliTool + setup --list (Fase 1.6)
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { dirname, resolve } from "node:path";
|
||||
import { createPrompt, printHeading, printInfo, printSuccess } from "../io.mjs";
|
||||
import { openOmniRouteDb } from "../sqlite.mjs";
|
||||
import { getSettings, hashManagementPassword, updateSettings } from "../settings-store.mjs";
|
||||
@@ -10,6 +12,13 @@ import {
|
||||
} from "../provider-catalog.mjs";
|
||||
import { t } from "../i18n.mjs";
|
||||
|
||||
const PROJECT_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "../../..");
|
||||
|
||||
async function getListCliTools() {
|
||||
const { listCliTools } = await import(`${PROJECT_ROOT}/src/shared/constants/cliTools.ts`);
|
||||
return listCliTools;
|
||||
}
|
||||
|
||||
function wantsProviderSetup(opts) {
|
||||
return opts.addProvider || Boolean(opts.provider) || Boolean(opts.apiKey);
|
||||
}
|
||||
@@ -135,6 +144,7 @@ export function registerSetup(program) {
|
||||
.option("--provider-base-url <url>", "Optional OpenAI-compatible base URL override")
|
||||
.option("--test-provider", "Test the provider after saving it")
|
||||
.option("--non-interactive", "Read all inputs from flags/env and do not prompt")
|
||||
.option("--list", "List all supported CLI tools")
|
||||
.action(async (opts, cmd) => {
|
||||
const globalOpts = cmd.optsWithGlobals();
|
||||
const exitCode = await runSetupCommand({ ...opts, output: globalOpts.output });
|
||||
@@ -143,6 +153,22 @@ export function registerSetup(program) {
|
||||
}
|
||||
|
||||
export async function runSetupCommand(opts = {}) {
|
||||
if (opts.list) {
|
||||
const listCliTools = await getListCliTools();
|
||||
const tools = listCliTools();
|
||||
if (opts.json || opts.output === "json") {
|
||||
console.log(JSON.stringify(tools, null, 2));
|
||||
} else {
|
||||
printHeading("Supported CLI Tools");
|
||||
for (const tool of tools) {
|
||||
const cmd = tool.defaultCommand || tool.defaultCommands?.[0] || "";
|
||||
const cmdStr = cmd ? ` \x1b[2m(${cmd})\x1b[0m` : "";
|
||||
console.log(` • ${tool.name}${cmdStr}`);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const nonInteractive = opts.nonInteractive ?? false;
|
||||
const prompt = createPrompt();
|
||||
|
||||
|
||||
@@ -526,6 +526,22 @@ amp --model "{{model}}"
|
||||
},
|
||||
};
|
||||
|
||||
// ─── Registry helpers ────────────────────────────────────────────────────────
|
||||
|
||||
export type CliToolEntry = (typeof CLI_TOOLS)[keyof typeof CLI_TOOLS];
|
||||
|
||||
/** Returns an ordered list of all registered CLI tools. */
|
||||
export function listCliTools(): CliToolEntry[] {
|
||||
return Object.values(CLI_TOOLS) as CliToolEntry[];
|
||||
}
|
||||
|
||||
/** Returns a single tool by id, or undefined if not found. */
|
||||
export function getCliTool(id: string): CliToolEntry | undefined {
|
||||
return (CLI_TOOLS as Record<string, CliToolEntry>)[id];
|
||||
}
|
||||
|
||||
// ─── Provider model mapping helper ───────────────────────────────────────────
|
||||
|
||||
// Get all provider models for mapping dropdown
|
||||
export const getProviderModelsForMapping = (providers) => {
|
||||
const result = [];
|
||||
|
||||
62
tests/unit/cli-tools-schema.test.ts
Normal file
62
tests/unit/cli-tools-schema.test.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
test("CLI_TOOLS registry contains all 17 expected tools", async () => {
|
||||
const { CLI_TOOLS } = await import("../../src/shared/constants/cliTools.ts");
|
||||
const expected = [
|
||||
"claude",
|
||||
"codex",
|
||||
"opencode",
|
||||
"cline",
|
||||
"kilo",
|
||||
"continue",
|
||||
"qwen",
|
||||
"windsurf",
|
||||
"hermes",
|
||||
"amp",
|
||||
"kiro",
|
||||
"cursor",
|
||||
"droid",
|
||||
"antigravity",
|
||||
"copilot",
|
||||
"openclaw",
|
||||
"custom",
|
||||
];
|
||||
for (const id of expected) {
|
||||
assert.ok(id in CLI_TOOLS, `Missing tool: ${id}`);
|
||||
}
|
||||
assert.equal(Object.keys(CLI_TOOLS).length, expected.length);
|
||||
});
|
||||
|
||||
test("Every tool has required fields: id, name, description, configType", async () => {
|
||||
const { CLI_TOOLS } = await import("../../src/shared/constants/cliTools.ts");
|
||||
for (const [key, tool] of Object.entries(CLI_TOOLS)) {
|
||||
assert.equal(typeof tool.id, "string", `${key}.id must be string`);
|
||||
assert.equal(tool.id, key, `${key}.id must match its registry key`);
|
||||
assert.equal(typeof tool.name, "string", `${key}.name must be string`);
|
||||
assert.ok(tool.name.length > 0, `${key}.name must be non-empty`);
|
||||
assert.equal(typeof tool.description, "string", `${key}.description must be string`);
|
||||
assert.equal(typeof tool.configType, "string", `${key}.configType must be string`);
|
||||
}
|
||||
});
|
||||
|
||||
test("listCliTools returns all tools as an array", async () => {
|
||||
const { listCliTools, CLI_TOOLS } = await import("../../src/shared/constants/cliTools.ts");
|
||||
const tools = listCliTools();
|
||||
assert.ok(Array.isArray(tools));
|
||||
assert.equal(tools.length, Object.keys(CLI_TOOLS).length);
|
||||
for (const tool of tools) {
|
||||
assert.equal(typeof tool.id, "string");
|
||||
}
|
||||
});
|
||||
|
||||
test("getCliTool returns correct tool by id", async () => {
|
||||
const { getCliTool } = await import("../../src/shared/constants/cliTools.ts");
|
||||
const claude = getCliTool("claude");
|
||||
assert.ok(claude);
|
||||
assert.equal(claude.id, "claude");
|
||||
assert.equal(claude.name, "Claude Code");
|
||||
|
||||
const missing = getCliTool("nonexistent");
|
||||
assert.equal(missing, undefined);
|
||||
});
|
||||
Reference in New Issue
Block a user