diff --git a/client/src/lib/api.ts b/client/src/lib/api.ts index ad6c5844..592ab231 100644 --- a/client/src/lib/api.ts +++ b/client/src/lib/api.ts @@ -1700,25 +1700,37 @@ export const api = { requestCodexBackupsHelper(params), /** * 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. */ - 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. + * Coerces the CLI's JSON output (which may be an object) to an array. * @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. + * Coerces the CLI's JSON output (which may be an object) to an array. * @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. - * @param args Arguments for `codex mcp add`. + * @param args {@link CodexMcpAddArgs} for `codex mcp add`. * @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", { method: "POST", 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. - * @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. */ - pluginAction: (args: unknown) => + pluginAction: (args: CodexPluginActionArgs) => request<{ ok: true; stdout: string; stderr: string }>("/codex-config/plugins/action", { method: "POST", 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. - * @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. */ - marketplaceAction: (args: unknown) => + marketplaceAction: (args: CodexMarketplaceActionArgs) => request<{ ok: true; stdout: string; stderr: string }>("/codex-config/marketplaces/action", { method: "POST", body: JSON.stringify(args), @@ -2994,6 +3006,28 @@ export interface CodexMarketplace { [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; +} + +/** 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 // spawning/management. `RunMode`/`RunStatus`/`PermissionMode`/`EffortLevel`