fix(headless): match "completed" status from RPC v2 in exit code mapper
mapStatusToExitCode only handled "complete" but RPC v2 emits "completed", causing all headless sessions to falsely timeout and restart. Also emits milestone-ready notification in checkAutoStartAfterDiscuss so headless parent can detect and chain into auto-mode. Closes #2914 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b5715c20bb
commit
8870d84012
3 changed files with 40 additions and 0 deletions
|
|
@ -20,6 +20,8 @@ export const EXIT_CANCELLED = 11
|
|||
* Map a headless session status string to its standardized exit code.
|
||||
*
|
||||
* success → 0
|
||||
* complete → 0
|
||||
* completed → 0
|
||||
* error → 1
|
||||
* timeout → 1
|
||||
* blocked → 10
|
||||
|
|
@ -31,6 +33,7 @@ export function mapStatusToExitCode(status: string): number {
|
|||
switch (status) {
|
||||
case 'success':
|
||||
case 'complete':
|
||||
case 'completed':
|
||||
return EXIT_SUCCESS
|
||||
case 'error':
|
||||
case 'timeout':
|
||||
|
|
|
|||
|
|
@ -178,6 +178,7 @@ export function checkAutoStartAfterDiscuss(): boolean {
|
|||
try { unlinkSync(manifestPath); } catch { /* may not exist for single-milestone */ }
|
||||
|
||||
pendingAutoStart = null;
|
||||
ctx.ui.notify(`Milestone ${milestoneId} ready.`, "info");
|
||||
startAuto(ctx, pi, basePath, false, { step }).catch((err) => {
|
||||
ctx.ui.notify(`Auto-start failed: ${getErrorMessage(err)}`, "error");
|
||||
if (process.env.GSD_DEBUG) console.error('[gsd] auto start error:', err);
|
||||
|
|
|
|||
|
|
@ -149,3 +149,39 @@ test('empty filter blocks all events', () => {
|
|||
assert.ok(!shouldEmit('agent_end'))
|
||||
assert.ok(!shouldEmit('message_update'))
|
||||
})
|
||||
|
||||
import { mapStatusToExitCode, EXIT_SUCCESS, EXIT_ERROR, EXIT_BLOCKED, EXIT_CANCELLED } from '../headless-events.js'
|
||||
|
||||
// ─── mapStatusToExitCode ─────────────────────────────────────────────────
|
||||
|
||||
test('mapStatusToExitCode: "complete" returns EXIT_SUCCESS', () => {
|
||||
assert.equal(mapStatusToExitCode('complete'), EXIT_SUCCESS)
|
||||
})
|
||||
|
||||
test('mapStatusToExitCode: "completed" returns EXIT_SUCCESS', () => {
|
||||
assert.equal(mapStatusToExitCode('completed'), EXIT_SUCCESS)
|
||||
})
|
||||
|
||||
test('mapStatusToExitCode: "success" returns EXIT_SUCCESS', () => {
|
||||
assert.equal(mapStatusToExitCode('success'), EXIT_SUCCESS)
|
||||
})
|
||||
|
||||
test('mapStatusToExitCode: "error" returns EXIT_ERROR', () => {
|
||||
assert.equal(mapStatusToExitCode('error'), EXIT_ERROR)
|
||||
})
|
||||
|
||||
test('mapStatusToExitCode: "timeout" returns EXIT_ERROR', () => {
|
||||
assert.equal(mapStatusToExitCode('timeout'), EXIT_ERROR)
|
||||
})
|
||||
|
||||
test('mapStatusToExitCode: "blocked" returns EXIT_BLOCKED', () => {
|
||||
assert.equal(mapStatusToExitCode('blocked'), EXIT_BLOCKED)
|
||||
})
|
||||
|
||||
test('mapStatusToExitCode: "cancelled" returns EXIT_CANCELLED', () => {
|
||||
assert.equal(mapStatusToExitCode('cancelled'), EXIT_CANCELLED)
|
||||
})
|
||||
|
||||
test('mapStatusToExitCode: unknown status returns EXIT_ERROR', () => {
|
||||
assert.equal(mapStatusToExitCode('unknown'), EXIT_ERROR)
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue