()
| 227 | } |
| 228 | |
| 229 | export async function up(): Promise<void> { |
| 230 | try { |
| 231 | const instructionFilePath = await findNearestInstructionFile(getCwd()) |
| 232 | if (!instructionFilePath) { |
| 233 | writeToStderr( |
| 234 | 'No AGENTS.md or NCODE.md instruction file was found in this directory or any parent directory.\n', |
| 235 | ) |
| 236 | await gracefulShutdown(1) |
| 237 | return |
| 238 | } |
| 239 | |
| 240 | const markdown = await readFile(instructionFilePath, 'utf8') |
| 241 | const section = extractUpSection(markdown) |
| 242 | if (!section) { |
| 243 | writeToStderr( |
| 244 | `No "# code up" or "# ncode up" section was found in ${instructionFilePath}.\n`, |
| 245 | ) |
| 246 | await gracefulShutdown(1) |
| 247 | return |
| 248 | } |
| 249 | |
| 250 | const blocks = extractExecutableBlocks(section) |
| 251 | if (blocks.length === 0) { |
| 252 | writeToStderr( |
| 253 | `The setup section in ${instructionFilePath} does not contain any executable shell code blocks.\n`, |
| 254 | ) |
| 255 | await gracefulShutdown(1) |
| 256 | return |
| 257 | } |
| 258 | |
| 259 | writeToStdout(`Using ${instructionFilePath}\n`) |
| 260 | for (const [index, block] of blocks.entries()) { |
| 261 | writeToStdout( |
| 262 | `\n[code up] Running block ${index + 1}/${blocks.length} (line ${block.startLine})\n`, |
| 263 | ) |
| 264 | const exitCode = await runBlock(block, dirname(instructionFilePath)) |
| 265 | if (exitCode !== 0) { |
| 266 | writeToStderr( |
| 267 | `[code up] Block ${index + 1} failed with exit code ${exitCode}.\n`, |
| 268 | ) |
| 269 | await gracefulShutdown(exitCode) |
| 270 | return |
| 271 | } |
| 272 | } |
| 273 | |
| 274 | writeToStdout(`\n[code up] Completed ${blocks.length} setup block(s).\n`) |
| 275 | await gracefulShutdown(0) |
| 276 | } catch (error) { |
| 277 | writeToStderr(`code up failed: ${error instanceof Error ? error.message : String(error)}\n`) |
| 278 | await gracefulShutdown(1) |
| 279 | } |
| 280 | } |
no test coverage detected