(cwd, actionsTaken = [])
| 180 | } |
| 181 | |
| 182 | async function buildSetupReport(cwd, actionsTaken = []) { |
| 183 | const workspaceRoot = resolveWorkspaceRoot(cwd); |
| 184 | const nodeStatus = binaryAvailable("node", ["--version"], { cwd }); |
| 185 | const npmStatus = binaryAvailable("npm", ["--version"], { cwd }); |
| 186 | const codexStatus = getCodexAvailability(cwd); |
| 187 | const authStatus = await getCodexAuthStatus(cwd); |
| 188 | const config = getConfig(workspaceRoot); |
| 189 | |
| 190 | const nextSteps = []; |
| 191 | if (!codexStatus.available) { |
| 192 | nextSteps.push("Install Codex with `npm install -g @openai/codex`."); |
| 193 | } |
| 194 | if (codexStatus.available && !authStatus.loggedIn && authStatus.requiresOpenaiAuth) { |
| 195 | nextSteps.push("Run `!codex login`."); |
| 196 | nextSteps.push("If browser login is blocked, retry with `!codex login --device-auth` or `!codex login --with-api-key`."); |
| 197 | } |
| 198 | if (!config.stopReviewGate) { |
| 199 | nextSteps.push("Optional: run `/codex:setup --enable-review-gate` to require a fresh review before stop."); |
| 200 | } |
| 201 | |
| 202 | return { |
| 203 | ready: nodeStatus.available && codexStatus.available && authStatus.loggedIn, |
| 204 | node: nodeStatus, |
| 205 | npm: npmStatus, |
| 206 | codex: codexStatus, |
| 207 | auth: authStatus, |
| 208 | sessionRuntime: getSessionRuntimeStatus(process.env, workspaceRoot), |
| 209 | reviewGateEnabled: Boolean(config.stopReviewGate), |
| 210 | actionsTaken, |
| 211 | nextSteps |
| 212 | }; |
| 213 | } |
| 214 | |
| 215 | async function handleSetup(argv) { |
| 216 | const { options } = parseCommandInput(argv, { |
no test coverage detected