fix(codex): add array coercion and typed arguments for CLI-backed routes
- Coerce mcp/plugins/marketplaces GET responses to arrays (CLI may emit object), degrading to empty list rather than crash on unexpected shape - Add typed interfaces: CodexMcpAddArgs, CodexPluginActionArgs, CodexMarketplaceActionArgs with validated action literals - Mirrors ccConfig's type safety across the namespace
This commit is contained in:
+43
-9
@@ -1700,25 +1700,37 @@ export const api = {
|
|||||||
requestCodexBackupsHelper(params),
|
requestCodexBackupsHelper(params),
|
||||||
/**
|
/**
|
||||||
* GET /api/codex-config/mcp - configured MCP servers from the codex CLI.
|
* GET /api/codex-config/mcp - configured MCP servers from the codex CLI.
|
||||||
|
* Coerces the CLI's JSON output (which may be an object) to an array.
|
||||||
* @returns `{ mcp }` — {@link CodexMcpServer} items.
|
* @returns `{ mcp }` — {@link CodexMcpServer} items.
|
||||||
*/
|
*/
|
||||||
mcp: () => request<{ mcp: CodexMcpServer[] }>("/codex-config/mcp"),
|
mcp: async () => {
|
||||||
|
const res = await request<{ mcp: unknown }>("/codex-config/mcp");
|
||||||
|
return { mcp: Array.isArray(res.mcp) ? res.mcp : [] };
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* GET /api/codex-config/plugins - installed plugins from the codex CLI.
|
* GET /api/codex-config/plugins - installed plugins from the codex CLI.
|
||||||
|
* Coerces the CLI's JSON output (which may be an object) to an array.
|
||||||
* @returns `{ plugins }` — {@link CodexPlugin} items.
|
* @returns `{ plugins }` — {@link CodexPlugin} items.
|
||||||
*/
|
*/
|
||||||
plugins: () => request<{ plugins: CodexPlugin[] }>("/codex-config/plugins"),
|
plugins: async () => {
|
||||||
|
const res = await request<{ plugins: unknown }>("/codex-config/plugins");
|
||||||
|
return { plugins: Array.isArray(res.plugins) ? res.plugins : [] };
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* GET /api/codex-config/marketplaces - registered marketplaces from the codex CLI.
|
* GET /api/codex-config/marketplaces - registered marketplaces from the codex CLI.
|
||||||
|
* Coerces the CLI's JSON output (which may be an object) to an array.
|
||||||
* @returns `{ marketplaces }` — {@link CodexMarketplace} items.
|
* @returns `{ marketplaces }` — {@link CodexMarketplace} items.
|
||||||
*/
|
*/
|
||||||
marketplaces: () => request<{ marketplaces: CodexMarketplace[] }>("/codex-config/marketplaces"),
|
marketplaces: async () => {
|
||||||
|
const res = await request<{ marketplaces: unknown }>("/codex-config/marketplaces");
|
||||||
|
return { marketplaces: Array.isArray(res.marketplaces) ? res.marketplaces : [] };
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* POST /api/codex-config/mcp/add - add an MCP server via the `codex` CLI.
|
* POST /api/codex-config/mcp/add - add an MCP server via the `codex` CLI.
|
||||||
* @param args Arguments for `codex mcp add`.
|
* @param args {@link CodexMcpAddArgs} for `codex mcp add`.
|
||||||
* @returns `{ ok, stdout, stderr }` — success and CLI output.
|
* @returns `{ ok, stdout, stderr }` — success and CLI output.
|
||||||
*/
|
*/
|
||||||
mcpAdd: (args: unknown) =>
|
mcpAdd: (args: CodexMcpAddArgs) =>
|
||||||
request<{ ok: true; stdout: string; stderr: string }>("/codex-config/mcp/add", {
|
request<{ ok: true; stdout: string; stderr: string }>("/codex-config/mcp/add", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify(args),
|
body: JSON.stringify(args),
|
||||||
@@ -1735,10 +1747,10 @@ export const api = {
|
|||||||
}),
|
}),
|
||||||
/**
|
/**
|
||||||
* POST /api/codex-config/plugins/action - add or remove a plugin via the `codex` CLI.
|
* POST /api/codex-config/plugins/action - add or remove a plugin via the `codex` CLI.
|
||||||
* @param args Arguments with `spec` and `action` fields.
|
* @param args {@link CodexPluginActionArgs} with `spec` and `action` fields.
|
||||||
* @returns `{ ok, stdout, stderr }` — success and CLI output.
|
* @returns `{ ok, stdout, stderr }` — success and CLI output.
|
||||||
*/
|
*/
|
||||||
pluginAction: (args: unknown) =>
|
pluginAction: (args: CodexPluginActionArgs) =>
|
||||||
request<{ ok: true; stdout: string; stderr: string }>("/codex-config/plugins/action", {
|
request<{ ok: true; stdout: string; stderr: string }>("/codex-config/plugins/action", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify(args),
|
body: JSON.stringify(args),
|
||||||
@@ -1755,10 +1767,10 @@ export const api = {
|
|||||||
}),
|
}),
|
||||||
/**
|
/**
|
||||||
* POST /api/codex-config/marketplaces/action - update or remove a marketplace via the `codex` CLI.
|
* POST /api/codex-config/marketplaces/action - update or remove a marketplace via the `codex` CLI.
|
||||||
* @param args Arguments with `name` and `action` fields.
|
* @param args {@link CodexMarketplaceActionArgs} with `name` and `action` fields.
|
||||||
* @returns `{ ok, stdout, stderr }` — success and CLI output.
|
* @returns `{ ok, stdout, stderr }` — success and CLI output.
|
||||||
*/
|
*/
|
||||||
marketplaceAction: (args: unknown) =>
|
marketplaceAction: (args: CodexMarketplaceActionArgs) =>
|
||||||
request<{ ok: true; stdout: string; stderr: string }>("/codex-config/marketplaces/action", {
|
request<{ ok: true; stdout: string; stderr: string }>("/codex-config/marketplaces/action", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify(args),
|
body: JSON.stringify(args),
|
||||||
@@ -2994,6 +3006,28 @@ export interface CodexMarketplace {
|
|||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Arguments for POST /api/codex-config/mcp/add. */
|
||||||
|
export interface CodexMcpAddArgs {
|
||||||
|
name: string;
|
||||||
|
url?: string;
|
||||||
|
bearerTokenEnvVar?: string;
|
||||||
|
command?: string;
|
||||||
|
args?: string[];
|
||||||
|
env?: Record<string, string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Arguments for POST /api/codex-config/plugins/action. */
|
||||||
|
export interface CodexPluginActionArgs {
|
||||||
|
spec: string;
|
||||||
|
action: "add" | "remove";
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Arguments for POST /api/codex-config/marketplaces/action. */
|
||||||
|
export interface CodexMarketplaceActionArgs {
|
||||||
|
name: string;
|
||||||
|
action: "remove";
|
||||||
|
}
|
||||||
|
|
||||||
// ─────────────────────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────────────────────
|
||||||
// Run types — request/response shapes for the Run page's `claude` process
|
// Run types — request/response shapes for the Run page's `claude` process
|
||||||
// spawning/management. `RunMode`/`RunStatus`/`PermissionMode`/`EffortLevel`
|
// spawning/management. `RunMode`/`RunStatus`/`PermissionMode`/`EffortLevel`
|
||||||
|
|||||||
Reference in New Issue
Block a user