( session: Session, goal: HeadlessGoalCreate, model: string | undefined, outputFormat: PromptOutputFormat, stdout: PromptOutput, stderr: PromptOutput, )
| 204 | } |
| 205 | |
| 206 | async function runHeadlessGoal( |
| 207 | session: Session, |
| 208 | goal: HeadlessGoalCreate, |
| 209 | model: string | undefined, |
| 210 | outputFormat: PromptOutputFormat, |
| 211 | stdout: PromptOutput, |
| 212 | stderr: PromptOutput, |
| 213 | ): Promise<void> { |
| 214 | requireConfiguredModel(model); |
| 215 | await session.createGoal({ |
| 216 | objective: goal.objective, |
| 217 | replace: goal.replace, |
| 218 | }); |
| 219 | let completedSnapshot: GoalSnapshot | null = null; |
| 220 | const unsubscribeGoalEvents = session.onEvent((event) => { |
| 221 | if ( |
| 222 | event.type === 'goal.updated' && |
| 223 | event.agentId === 'main' && |
| 224 | event.change?.kind === 'completion' && |
| 225 | event.snapshot !== null |
| 226 | ) { |
| 227 | completedSnapshot = event.snapshot; |
| 228 | } |
| 229 | }); |
| 230 | try { |
| 231 | // The objective is sent as the normal prompt; goal continuation keeps the |
| 232 | // turn alive until a terminal state is reached. |
| 233 | await runPromptTurn(session, goal.objective, outputFormat, stdout, stderr); |
| 234 | } finally { |
| 235 | unsubscribeGoalEvents(); |
| 236 | const snapshot = completedSnapshot ?? (await session.getGoal()).goal; |
| 237 | if (outputFormat === 'stream-json') { |
| 238 | stdout.write(`${JSON.stringify(goalSummaryJson(snapshot))}\n`); |
| 239 | } else { |
| 240 | stderr.write(`${formatGoalSummaryText(snapshot)}\n`); |
| 241 | } |
| 242 | // Map the terminal goal status to a distinct, non-fatal exit code. A turn |
| 243 | // that threw (error / cancellation) already propagates its own exit path. |
| 244 | if (snapshot !== null && snapshot.status !== 'complete') { |
| 245 | process.exitCode = goalExitCode(snapshot.status); |
| 246 | } |
| 247 | } |
| 248 | } |
| 249 | |
| 250 | interface ResolvedPromptSession { |
| 251 | readonly session: Session; |
no test coverage detected