| 85 | } |
| 86 | |
| 87 | async function observeOutcome(task, cwd, runError) { |
| 88 | const existingFiles = []; |
| 89 | const fileContents = {}; |
| 90 | for (const p of task.check.filesExist ?? []) { |
| 91 | if (fsSync.existsSync(path.join(cwd, p))) existingFiles.push(p); |
| 92 | } |
| 93 | for (const fc of task.check.fileChecks ?? []) { |
| 94 | const abs = path.join(cwd, fc.path); |
| 95 | if (fsSync.existsSync(abs)) { |
| 96 | if (!existingFiles.includes(fc.path)) existingFiles.push(fc.path); |
| 97 | fileContents[fc.path] = await fs.readFile(abs, 'utf-8'); |
| 98 | } |
| 99 | } |
| 100 | let commandExitCode; |
| 101 | if (task.check.command) { |
| 102 | const res = spawnSync(task.check.command.command, { cwd, shell: true, timeout: 60_000, env: { ...process.env, FORCE_COLOR: '0' } }); |
| 103 | commandExitCode = res.status; |
| 104 | } |
| 105 | return { existingFiles, fileContents, commandExitCode, error: runError }; |
| 106 | } |
| 107 | |
| 108 | async function runTask(task) { |
| 109 | const work = await fs.mkdtemp(path.join(os.tmpdir(), `qodex-eval-${task.id}-`)); |