(tmpPrefix: string, skillName: 'plan-ceo-review' | 'plan-eng-review')
| 125 | `; |
| 126 | |
| 127 | function setupCodexSkillDir(tmpPrefix: string, skillName: 'plan-ceo-review' | 'plan-eng-review'): { skillDir: string; planDir: string; outFile: string } { |
| 128 | const planDir = fs.mkdtempSync(path.join(os.tmpdir(), tmpPrefix)); |
| 129 | const run = (cmd: string, args: string[]) => |
| 130 | spawnSync(cmd, args, { cwd: planDir, stdio: 'pipe', timeout: 5000 }); |
| 131 | |
| 132 | run('git', ['init', '-b', 'main']); |
| 133 | run('git', ['config', 'user.email', 'test@test.com']); |
| 134 | run('git', ['config', 'user.name', 'Test']); |
| 135 | |
| 136 | fs.writeFileSync(path.join(planDir, 'plan.md'), SAMPLE_PLAN); |
| 137 | run('git', ['add', '.']); |
| 138 | run('git', ['commit', '-m', 'add plan']); |
| 139 | |
| 140 | // Codex skill lives in .agents/skills/gstack-{name}/ per the gstack host convention. |
| 141 | const codexSkillSource = path.join(ROOT, '.agents', 'skills', `gstack-${skillName}`); |
| 142 | const skillDir = path.join(planDir, '.agents', 'skills', `gstack-${skillName}`); |
| 143 | fs.mkdirSync(skillDir, { recursive: true }); |
| 144 | fs.cpSync(codexSkillSource, skillDir, { recursive: true }); |
| 145 | |
| 146 | const outFile = path.join(planDir, 'ask-capture.md'); |
| 147 | return { skillDir, planDir, outFile }; |
| 148 | } |
| 149 | |
| 150 | // Capture instruction — same shape as the Claude version. Codex may ignore tool calls, |
| 151 | // so we tell it to write prose to the file directly. |
no test coverage detected