mirror of
https://github.com/wu736139669/hapi.git
synced 2026-10-14 20:26:05 +00:00
Windows global installs expose codex as codex.cmd; spawning 'codex' without shell hits ENOENT. Enable shell to align with Claude's Windows behavior and resolve PATH lookup. Shell spawn makes cmd.exe strip TOML double quotes in -c arrays, so args become a string. Switch mcp args to TOML literal (single-quoted) arrays to preserve types; update tests.
77 lines
2.5 KiB
TypeScript
77 lines
2.5 KiB
TypeScript
/**
|
|
* Utilities for building Codex CLI config arguments (-c) for MCP servers
|
|
* and developer instructions.
|
|
*
|
|
* Codex CLI accepts -c / --config flags with TOML-formatted key=value pairs.
|
|
* This module generates the appropriate arguments for passing MCP server
|
|
* configuration and developer instructions at runtime.
|
|
*/
|
|
|
|
/**
|
|
* Escape a string value for use in a TOML string literal.
|
|
* Handles double quotes, backslashes, and newlines.
|
|
*/
|
|
function escapeTomlString(value: string): string {
|
|
return value
|
|
.replace(/\\/g, '\\\\')
|
|
.replace(/"/g, '\\"')
|
|
.replace(/\n/g, '\\n')
|
|
.replace(/\r/g, '\\r')
|
|
.replace(/\t/g, '\\t');
|
|
}
|
|
|
|
/**
|
|
* Escape a string value for use in a TOML single-quoted literal string.
|
|
* Only single quotes need escaping (by doubling them).
|
|
*/
|
|
function escapeTomlLiteralString(value: string): string {
|
|
return value.replace(/'/g, "''");
|
|
}
|
|
|
|
function buildTomlLiteralArray(values: string[]): string {
|
|
const items = values.map((value) => `'${escapeTomlLiteralString(value)}'`);
|
|
return `[${items.join(',')}]`;
|
|
}
|
|
|
|
/**
|
|
* Build -c arguments for MCP server configuration.
|
|
*
|
|
* Generates arguments like:
|
|
* -c 'mcp_servers.hapi.command="hapi"'
|
|
* -c 'mcp_servers.hapi.args=['mcp', '--url', 'http://...']'
|
|
*
|
|
* @param mcpServers - Map of server name to server config
|
|
* @returns Array of CLI arguments to pass to codex
|
|
*/
|
|
export function buildMcpServerConfigArgs(
|
|
mcpServers: Record<string, { command: string; args: string[] }>
|
|
): string[] {
|
|
const configArgs: string[] = [];
|
|
|
|
for (const [name, server] of Object.entries(mcpServers)) {
|
|
// -c 'mcp_servers.<name>.command="<command>"'
|
|
configArgs.push('-c', `mcp_servers.${name}.command="${escapeTomlString(server.command)}"`);
|
|
|
|
// -c 'mcp_servers.<name>.args=['arg1','arg2']'
|
|
// Use TOML literal strings to avoid shell-quote mangling on Windows.
|
|
const argsToml = buildTomlLiteralArray(server.args);
|
|
configArgs.push('-c', `mcp_servers.${name}.args=${argsToml}`);
|
|
}
|
|
|
|
return configArgs;
|
|
}
|
|
|
|
/**
|
|
* Build -c argument for developer instructions.
|
|
*
|
|
* Generates argument like:
|
|
* -c 'developer_instructions="<escaped instructions>"'
|
|
*
|
|
* @param instructions - Developer instructions text
|
|
* @returns Array of CLI arguments to pass to codex
|
|
*/
|
|
export function buildDeveloperInstructionsArg(instructions: string): string[] {
|
|
const escaped = escapeTomlString(instructions);
|
|
return ['-c', `developer_instructions="${escaped}"`];
|
|
}
|