()
| 110 | val = val.slice(1, -1); |
| 111 | } |
| 112 | // Handle multiline description (>-) |
| 113 | if (val === '>-' || val === '>') { |
| 114 | continue; |
| 115 | } |
| 116 | if (key && val) fm[key] = val; |
| 117 | } |
| 118 | // Handle multiline description by regex |
| 119 | const descMatch = normalized.match(/description:\s*>-?\n([\s\S]*?)(?=\n[a-zA-Z][\w-]*:|\n---)/); |
| 120 | if (descMatch) { |
| 121 | fm.description = descMatch[1].replace(/\n\s*/g, ' ').trim(); |
| 122 | } |
| 123 | return fm; |
| 124 | } |
| 125 | |
| 126 | // ---- 1. Generate .codex/config.toml ----------------------------------------- |
| 127 | |
| 128 | function generateConfigToml() { |
| 129 | console.log('Generating .codex/config.toml...'); |
| 130 | |
| 131 | // Read .mcp.json for MCP server entries |
| 132 | let mcpSection = ''; |
| 133 | const mcpPath = path.join(PROJECT_ROOT, '.mcp.json'); |
| 134 | const mcpData = readJSON(mcpPath); |
| 135 | const entries = [mcpServerToToml('citadel-state', { |
| 136 | command: 'node', |
| 137 | args: [path.join(CITADEL_ROOT, 'mcp-servers', 'citadel-state', 'index.js')], |
| 138 | env: { |
| 139 | CITADEL_PROJECT_ROOT: PROJECT_ROOT, |
| 140 | CITADEL_ROOT, |
| 141 | }, |
| 142 | _codex: { |
| 143 | startup_timeout_sec: 10, |
| 144 | tool_timeout_sec: 30, |
| 145 | required: false, |
| 146 | instructions: 'Use citadel_status to orient on campaign, fleet, telemetry, and artifact state before invoking Citadel workflows.', |
| 147 | }, |
| 148 | })]; |
| 149 | if (mcpData && mcpData.mcpServers) { |
| 150 | for (const [name, config] of Object.entries(mcpData.mcpServers)) { |
| 151 | // Skip comments and disabled entries (prefixed with _) |
| 152 | if (name.startsWith('_')) continue; |
| 153 | if (name === 'citadel-state') continue; |
| 154 | entries.push(mcpServerToToml(name, config)); |
| 155 | } |
| 156 | } |
| 157 | if (entries.length > 0) { |
| 158 | mcpSection = '\n' + entries.join('\n'); |
| 159 | } |
| 160 | |
| 161 | // On Windows, PowerShell 5 fails to load its managed runtime in some environments |
| 162 | // (error 8009001d). Emit the [windows] agent_shell override and set SHELL in the |
| 163 | // env policy so both the Codex shell selector and any sub-invocations use Git Bash. |
| 164 | let shellEnvVars = 'CITADEL_RUNTIME = "codex"'; |
| 165 | let windowsSection = ''; |
| 166 | if (process.platform === 'win32') { |
| 167 | const gitBash = 'C:/Program Files/Git/bin/bash.exe'; |
| 168 | if (fs.existsSync(gitBash)) { |
| 169 | shellEnvVars += `, SHELL = "${gitBash}"`; |
no test coverage detected