fix(cli): expose usable provider mode IDs in structured output

Provider listing discarded mode IDs and converted enabled state to display text before JSON and YAML rendering. Preserve those values in command data and format table columns through their existing accessors.

Co-authored-by: wilgon456 <54878785+wilgon456@users.noreply.github.com>
This commit is contained in:
paseo-bot[bot]
2026-10-09 19:19:55 +02:00
co-authored by wilgon456
parent a1da1b8f23
commit 24fd4f6922
2 changed files with 36 additions and 15 deletions
+10 -6
View File
@@ -7,9 +7,9 @@ export interface ProviderListItem {
provider: ProviderSnapshotEntry["provider"];
label: string;
status: string;
enabled: "Enabled" | "Disabled";
enabled: boolean;
defaultMode: string;
modes: string;
modes: Array<{ id: string; label: string }>;
}
/** Schema for provider ls output */
@@ -28,9 +28,13 @@ export const providerLsSchema: OutputSchema<ProviderListItem> = {
return undefined;
},
},
{ header: "ENABLED", field: "enabled", width: 10 },
{ header: "ENABLED", field: (item) => (item.enabled ? "Enabled" : "Disabled"), width: 10 },
{ header: "DEFAULT MODE", field: "defaultMode", width: 14 },
{ header: "MODES", field: "modes", width: 30 },
{
header: "MODES",
field: (item) => item.modes.map((mode) => mode.label).join(", "),
width: 30,
},
],
};
@@ -54,9 +58,9 @@ export async function runLsCommand(
provider: entry.provider,
label: entry.label ?? entry.provider,
status: entry.status === "ready" ? "available" : entry.status,
enabled: !entry.enabled ? "Disabled" : "Enabled",
enabled: entry.enabled,
defaultMode: entry.defaultModeId ?? "default",
modes: (entry.modes ?? []).map((mode) => mode.label).join(", "),
modes: (entry.modes ?? []).map(({ id, label }) => ({ id, label })),
})),
schema: providerLsSchema,
};
+26 -9
View File
@@ -22,6 +22,7 @@
*/
import assert from "node:assert";
import YAML from "yaml";
import { writeFile } from "node:fs/promises";
import { join } from "node:path";
import {
@@ -43,7 +44,8 @@ interface ProviderListRow {
provider: string;
label: string;
status: string;
enabled: string;
enabled: boolean;
modes: Array<{ id: string; label: string }>;
}
interface ProviderDiagnostic {
@@ -246,6 +248,7 @@ try {
// Test 3: provider ls --json outputs valid JSON
{
console.log("Test 3: provider ls --json outputs valid JSON");
await runProviderModelsJson("codex");
const result = await ctx.paseo(["provider", "ls", "--json"]);
assert.strictEqual(result.exitCode, 0, "should exit 0");
const data = JSON.parse(result.stdout.trim());
@@ -264,15 +267,33 @@ try {
"should include opencode",
);
const rows = data as ProviderListRow[];
const codex = rows.find((p) => p.provider === "codex");
assert(codex, "should include codex");
assert(Array.isArray(codex.modes), "mode choices should be structured, not display text");
assert(
codex.modes.some((mode) => mode.id === "full-access" && mode.label === "Full Access"),
"mode choices should include an ID usable with run --mode and its display label",
);
assert(
codex.modes.every((mode) => mode.label.length > 0),
"modes should keep display labels",
);
for (const provider of ["claude", "codex", "opencode"] as const) {
const row = rows.find((p) => p.provider === provider);
assert(row, `should include ${provider}`);
assert.strictEqual(row.enabled, "Enabled", `${provider} should report Enabled`);
assert.strictEqual(row.enabled, true, `${provider} should report enabled`);
}
const omp = rows.find((p) => p.provider === "omp");
assert(omp, "should include omp");
assert.strictEqual(omp.enabled, "Disabled", "omp should report Disabled by default");
assert.strictEqual(omp.enabled, false, "omp should report disabled by default");
const yamlResult = await ctx.paseo(["provider", "ls", "--format", "yaml"]);
assert.strictEqual(yamlResult.exitCode, 0, "YAML provider listing should exit 0");
const yamlRows = YAML.parse(yamlResult.stdout) as ProviderListRow[];
const yamlCodex = yamlRows.find((p) => p.provider === "codex");
assert(yamlCodex, "YAML should include codex");
assert.strictEqual(yamlCodex.enabled, true, "YAML should preserve boolean enabled state");
assert.deepStrictEqual(yamlCodex.modes, codex.modes, "YAML should preserve the same mode IDs");
console.log("✓ provider ls --json outputs valid JSON\n");
}
@@ -305,11 +326,11 @@ try {
const data = JSON.parse(result.stdout.trim()) as ProviderListRow[];
const claude = data.find((p) => p.provider === "claude");
assert(claude, "disabled claude provider should stay in provider ls");
assert.strictEqual(claude.enabled, "Disabled", "disabled provider should report Disabled");
assert.strictEqual(claude.enabled, false, "disabled provider should report false");
const opencode = data.find((p) => p.provider === "opencode");
assert(opencode, "enabled opencode provider should stay in provider ls");
assert.strictEqual(opencode.enabled, "Enabled", "enabled provider should report Enabled");
assert.strictEqual(opencode.enabled, true, "enabled provider should report true");
const modelsResult = await runPaseoCli(disabledCtx, ["provider", "models", "claude"]);
assert.notStrictEqual(
@@ -364,10 +385,6 @@ try {
ids.every((id) => id.startsWith("gpt-")),
"all codex model IDs should be from the gpt family",
);
assert(
ids.some((id) => id.includes("codex")),
"codex model list should include at least one codex-optimized model",
);
assert(
data.every((m) => m.model && m.id && m.description),
"every codex model should have model, id, and description fields",