import { test } from 'node:test'; import assert from 'node:assert/strict'; import { deriveState } from '../src/scan.mjs'; const state = (text, overrides = {}) => deriveState({ alive: true, session: { lastMessage: { role: 'assistant', stopReason: 'stop', content: [{ type: 'text', text }], ...overrides }, } }); test('completed smoke replies and ordinary questions are idle, not human blockers', () => { for (const text of ['BOARD_REPLY_OK', 'RESEARCHER_NATIVE_SMOKE_OK', 'Done.', 'Shall I continue?']) { assert.equal(state(text), 'idle', text); } }); test('only an explicit first-line input request makes a finished reply waiting', () => { assert.equal(state('Input needed: Choose the release target.\nDetails follow.'), 'waiting'); for (const text of ['Input needed:', 'Input needed: ', 'Example:\nInput needed: Choose A.', '```\nInput needed: Choose A.\n```']) { assert.equal(state(text), 'idle', text); } }); test('tool activity, user text, errors and unfinished turns override attention text', () => { const text = 'Input needed: Choose A.'; assert.equal(state(text, { content: [{ type: 'text', text }, { type: 'toolCall', name: 'read' }] }), 'working'); assert.equal(state(text, { role: 'user' }), 'working'); assert.equal(state(text, { role: 'toolResult' }), 'working'); assert.equal(state(text, { stopReason: 'error' }), 'error'); assert.equal(state(text, { stopReason: undefined }), 'working'); });