refactor: use --json flag alias instead of --format json throughout CLI
This commit is contained in:
@@ -4,6 +4,44 @@ export type AgentProvider = string;
|
||||
|
||||
export type AgentMetadata = { [key: string]: unknown };
|
||||
|
||||
/**
|
||||
* Stdio-based MCP server (spawns a subprocess).
|
||||
*/
|
||||
export interface McpStdioServerConfig {
|
||||
type: "stdio";
|
||||
command: string;
|
||||
args?: string[];
|
||||
env?: Record<string, string>;
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP-based MCP server.
|
||||
*/
|
||||
export interface McpHttpServerConfig {
|
||||
type: "http";
|
||||
url: string;
|
||||
headers?: Record<string, string>;
|
||||
}
|
||||
|
||||
/**
|
||||
* SSE-based MCP server (Server-Sent Events over HTTP).
|
||||
*/
|
||||
export interface McpSseServerConfig {
|
||||
type: "sse";
|
||||
url: string;
|
||||
headers?: Record<string, string>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Canonical MCP server configuration.
|
||||
* Discriminated union by `type` field.
|
||||
* Each provider normalizes this to their expected format.
|
||||
*/
|
||||
export type McpServerConfig =
|
||||
| McpStdioServerConfig
|
||||
| McpHttpServerConfig
|
||||
| McpSseServerConfig;
|
||||
|
||||
export type AgentMode = {
|
||||
id: string;
|
||||
label: string;
|
||||
@@ -208,7 +246,7 @@ export type AgentSessionConfig = {
|
||||
codex?: AgentMetadata;
|
||||
claude?: Partial<ClaudeAgentOptions>;
|
||||
};
|
||||
mcpServers?: AgentMetadata;
|
||||
mcpServers?: Record<string, McpServerConfig>;
|
||||
/**
|
||||
* Internal agents are hidden from listings and don't trigger notifications.
|
||||
* They are used for ephemeral system tasks like commit/PR generation.
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
query,
|
||||
type AgentDefinition,
|
||||
type CanUseTool,
|
||||
type McpServerConfig,
|
||||
type McpServerConfig as ClaudeSdkMcpServerConfig,
|
||||
type ModelInfo,
|
||||
type Options,
|
||||
type PermissionMode,
|
||||
@@ -45,6 +45,7 @@ import type {
|
||||
AgentRuntimeInfo,
|
||||
ListModelsOptions,
|
||||
ListPersistedAgentsOptions,
|
||||
McpServerConfig,
|
||||
PersistedAgentDescriptor,
|
||||
} from "../agent-sdk-types.js";
|
||||
import { getOrchestratorModeInstructions } from "../orchestrator-instructions.js";
|
||||
@@ -102,7 +103,6 @@ type ClaudeAgentConfig = AgentSessionConfig & { provider: "claude" };
|
||||
|
||||
export type ClaudeContentChunk = { type: string; [key: string]: any };
|
||||
|
||||
type ClaudeMcpServerConfig = McpServerConfig;
|
||||
type ClaudeOptions = Options;
|
||||
|
||||
type ClaudeAgentClientOptions = {
|
||||
@@ -178,6 +178,32 @@ function isMetadata(value: unknown): value is AgentMetadata {
|
||||
return typeof value === "object" && value !== null;
|
||||
}
|
||||
|
||||
function isMcpServerConfig(value: unknown): value is McpServerConfig {
|
||||
if (!isMetadata(value)) {
|
||||
return false;
|
||||
}
|
||||
const type = value.type;
|
||||
if (type === "stdio") {
|
||||
return typeof value.command === "string";
|
||||
}
|
||||
if (type === "http" || type === "sse") {
|
||||
return typeof value.url === "string";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isMcpServersRecord(value: unknown): value is Record<string, McpServerConfig> {
|
||||
if (!isMetadata(value)) {
|
||||
return false;
|
||||
}
|
||||
for (const config of Object.values(value)) {
|
||||
if (!isMcpServerConfig(config)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function isPermissionMode(value: string | undefined): value is PermissionMode {
|
||||
return typeof value === "string" && VALID_CLAUDE_MODES.has(value);
|
||||
}
|
||||
@@ -230,18 +256,37 @@ function coerceSessionMetadata(metadata: AgentMetadata | undefined): Partial<Age
|
||||
result.extra = extra;
|
||||
}
|
||||
}
|
||||
if (isMetadata(metadata.mcpServers)) {
|
||||
if (isMcpServersRecord(metadata.mcpServers)) {
|
||||
result.mcpServers = metadata.mcpServers;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function isClaudeMcpServerConfig(value: unknown): value is ClaudeMcpServerConfig {
|
||||
if (!isMetadata(value)) {
|
||||
return false;
|
||||
function toClaudeSdkMcpConfig(
|
||||
config: McpServerConfig
|
||||
): ClaudeSdkMcpServerConfig {
|
||||
switch (config.type) {
|
||||
case "stdio":
|
||||
return {
|
||||
type: "stdio",
|
||||
command: config.command,
|
||||
args: config.args,
|
||||
env: config.env,
|
||||
};
|
||||
case "http":
|
||||
return {
|
||||
type: "http",
|
||||
url: config.url,
|
||||
headers: config.headers,
|
||||
};
|
||||
case "sse":
|
||||
return {
|
||||
type: "sse",
|
||||
url: config.url,
|
||||
headers: config.headers,
|
||||
};
|
||||
}
|
||||
return typeof value.type === "string" || typeof value.command === "string" || typeof value.url === "string";
|
||||
}
|
||||
|
||||
function isClaudeContentChunk(value: unknown): value is ClaudeContentChunk {
|
||||
@@ -783,10 +828,7 @@ class ClaudeAgentSession implements AgentSession {
|
||||
};
|
||||
|
||||
if (this.config.mcpServers) {
|
||||
const normalizedUserServers = this.normalizeMcpServers(this.config.mcpServers);
|
||||
if (normalizedUserServers) {
|
||||
base.mcpServers = normalizedUserServers;
|
||||
}
|
||||
base.mcpServers = this.normalizeMcpServers(this.config.mcpServers);
|
||||
}
|
||||
|
||||
if (this.config.model) {
|
||||
@@ -800,18 +842,13 @@ class ClaudeAgentSession implements AgentSession {
|
||||
}
|
||||
|
||||
private normalizeMcpServers(
|
||||
servers: ClaudeAgentConfig["mcpServers"]
|
||||
): Record<string, ClaudeMcpServerConfig> | undefined {
|
||||
if (!servers) {
|
||||
return undefined;
|
||||
}
|
||||
const result: Record<string, ClaudeMcpServerConfig> = {};
|
||||
servers: Record<string, McpServerConfig>
|
||||
): Record<string, ClaudeSdkMcpServerConfig> {
|
||||
const result: Record<string, ClaudeSdkMcpServerConfig> = {};
|
||||
for (const [name, config] of Object.entries(servers)) {
|
||||
if (isClaudeMcpServerConfig(config)) {
|
||||
result[name] = config;
|
||||
}
|
||||
result[name] = toClaudeSdkMcpConfig(config);
|
||||
}
|
||||
return Object.keys(result).length ? result : undefined;
|
||||
return result;
|
||||
}
|
||||
|
||||
private toSdkUserMessage(prompt: AgentPromptInput): SDKUserMessage {
|
||||
|
||||
@@ -37,6 +37,7 @@ import type {
|
||||
AgentRuntimeInfo,
|
||||
ListModelsOptions,
|
||||
ListPersistedAgentsOptions,
|
||||
McpServerConfig,
|
||||
PersistedAgentDescriptor,
|
||||
} from "../agent-sdk-types.js";
|
||||
import { curateAgentActivity } from "../activity-curator.js";
|
||||
@@ -1866,6 +1867,31 @@ const AgentSessionExtraSchema = z.object({
|
||||
claude: z.custom<AgentSessionExtra["claude"]>().optional(),
|
||||
});
|
||||
|
||||
const McpStdioServerConfigSchema = z.object({
|
||||
type: z.literal("stdio"),
|
||||
command: z.string(),
|
||||
args: z.array(z.string()).optional(),
|
||||
env: z.record(z.string()).optional(),
|
||||
});
|
||||
|
||||
const McpHttpServerConfigSchema = z.object({
|
||||
type: z.literal("http"),
|
||||
url: z.string(),
|
||||
headers: z.record(z.string()).optional(),
|
||||
});
|
||||
|
||||
const McpSseServerConfigSchema = z.object({
|
||||
type: z.literal("sse"),
|
||||
url: z.string(),
|
||||
headers: z.record(z.string()).optional(),
|
||||
});
|
||||
|
||||
const McpServerConfigSchema = z.discriminatedUnion("type", [
|
||||
McpStdioServerConfigSchema,
|
||||
McpHttpServerConfigSchema,
|
||||
McpSseServerConfigSchema,
|
||||
]);
|
||||
|
||||
const AgentSessionConfigSchema = z
|
||||
.object({
|
||||
provider: z.string(),
|
||||
@@ -1879,7 +1905,7 @@ const AgentSessionConfigSchema = z
|
||||
webSearch: z.boolean().optional(),
|
||||
reasoningEffort: z.string().optional(),
|
||||
extra: AgentSessionExtraSchema.optional(),
|
||||
mcpServers: z.record(z.unknown()).optional(),
|
||||
mcpServers: z.record(McpServerConfigSchema).optional(),
|
||||
})
|
||||
.passthrough();
|
||||
|
||||
@@ -2693,14 +2719,35 @@ function getCodexMcpCommand(): string {
|
||||
}
|
||||
}
|
||||
|
||||
type CodexMcpServerConfig = {
|
||||
interface CodexMcpServerConfig {
|
||||
url?: string;
|
||||
http_headers?: Record<string, string>; // Static HTTP headers for HTTP servers
|
||||
http_headers?: Record<string, string>;
|
||||
command?: string;
|
||||
args?: string[];
|
||||
env?: Record<string, string>;
|
||||
tool_timeout_sec?: number; // Override the default 60s per-tool timeout
|
||||
};
|
||||
tool_timeout_sec?: number;
|
||||
}
|
||||
|
||||
function toCodexMcpConfig(config: McpServerConfig): CodexMcpServerConfig {
|
||||
switch (config.type) {
|
||||
case "stdio":
|
||||
return {
|
||||
command: config.command,
|
||||
args: config.args,
|
||||
env: config.env,
|
||||
};
|
||||
case "http":
|
||||
return {
|
||||
url: config.url,
|
||||
http_headers: config.headers,
|
||||
};
|
||||
case "sse":
|
||||
return {
|
||||
url: config.url,
|
||||
http_headers: config.headers,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
type CodexConfigPayload = {
|
||||
mcp_servers?: Record<string, CodexMcpServerConfig>;
|
||||
@@ -2754,22 +2801,10 @@ function buildCodexMcpConfig(
|
||||
// Build MCP servers configuration
|
||||
const mcpServers: Record<string, CodexMcpServerConfig> = {};
|
||||
|
||||
// Merge MCP servers from extra.codex.mcp_servers (legacy location)
|
||||
const extraCodex = config.extra?.codex as Record<string, unknown> | undefined;
|
||||
if (extraCodex?.mcp_servers && typeof extraCodex.mcp_servers === "object") {
|
||||
for (const [name, serverConfig] of Object.entries(extraCodex.mcp_servers as Record<string, unknown>)) {
|
||||
if (typeof serverConfig === "object" && serverConfig !== null) {
|
||||
mcpServers[name] = serverConfig as CodexMcpServerConfig;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Merge user-provided MCP servers (they take highest precedence)
|
||||
// Merge user-provided MCP servers
|
||||
if (config.mcpServers) {
|
||||
for (const [name, serverConfig] of Object.entries(config.mcpServers)) {
|
||||
if (typeof serverConfig === "object" && serverConfig !== null) {
|
||||
mcpServers[name] = serverConfig as CodexMcpServerConfig;
|
||||
}
|
||||
mcpServers[name] = toCodexMcpConfig(serverConfig);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,31 @@ const AgentUsageSchema: z.ZodType<AgentUsage> = z.object({
|
||||
totalCostUsd: z.number().optional(),
|
||||
});
|
||||
|
||||
const McpStdioServerConfigSchema = z.object({
|
||||
type: z.literal("stdio"),
|
||||
command: z.string(),
|
||||
args: z.array(z.string()).optional(),
|
||||
env: z.record(z.string()).optional(),
|
||||
});
|
||||
|
||||
const McpHttpServerConfigSchema = z.object({
|
||||
type: z.literal("http"),
|
||||
url: z.string(),
|
||||
headers: z.record(z.string()).optional(),
|
||||
});
|
||||
|
||||
const McpSseServerConfigSchema = z.object({
|
||||
type: z.literal("sse"),
|
||||
url: z.string(),
|
||||
headers: z.record(z.string()).optional(),
|
||||
});
|
||||
|
||||
const McpServerConfigSchema = z.discriminatedUnion("type", [
|
||||
McpStdioServerConfigSchema,
|
||||
McpHttpServerConfigSchema,
|
||||
McpSseServerConfigSchema,
|
||||
]);
|
||||
|
||||
const AgentSessionConfigSchema = z.object({
|
||||
provider: AgentProviderSchema,
|
||||
cwd: z.string(),
|
||||
@@ -70,7 +95,7 @@ const AgentSessionConfigSchema = z.object({
|
||||
})
|
||||
.partial()
|
||||
.optional(),
|
||||
mcpServers: z.record(z.unknown()).optional(),
|
||||
mcpServers: z.record(McpServerConfigSchema).optional(),
|
||||
});
|
||||
|
||||
const AgentPermissionUpdateSchema = z.record(z.unknown());
|
||||
|
||||
Reference in New Issue
Block a user