import { describe, expect, it } from 'vitest' import { latestSessionTodos, parseTodos } from './todos' describe('parseTodos', () => { it('parses todo arrays with valid ids, content, and statuses', () => { expect( parseTodos([ { content: 'Gather ingredients', id: 'prep', status: 'completed' }, { content: 'Boil water', id: 'boil', status: 'in_progress' }, { content: 'Serve', id: 'serve', status: 'pending' } ]) ).toEqual([ { content: 'Gather ingredients', id: 'prep', status: 'completed' }, { content: 'Boil water', id: 'boil', status: 'in_progress' }, { content: 'Serve', id: 'serve', status: 'pending' } ]) }) it('parses nested todo payloads from wrapped objects and JSON strings', () => { expect(parseTodos({ todos: [{ content: 'Plate', id: 'plate', status: 'pending' }] })).toEqual([ { content: 'Plate', id: 'plate', status: 'pending' } ]) expect(parseTodos('{"todos":[{"id":"plate","content":"Plate","status":"pending"}]}')).toEqual([ { content: 'Plate', id: 'plate', status: 'pending' } ]) }) it('returns null for non-todo payloads', () => { expect(parseTodos(undefined)).toBeNull() expect(parseTodos('not json')).toBeNull() expect(parseTodos({ message: 'no todos here' })).toBeNull() }) }) describe('latestSessionTodos', () => { const todoPart = (todos: unknown, extra: Record = {}) => ({ type: 'tool-call', toolCallId: 't1', toolName: 'todo', args: { todos }, ...extra }) it('returns the last todo list across the transcript (result beats args)', () => { const messages = [ { parts: [todoPart([{ content: 'Old', id: 'a', status: 'pending' }])] }, { parts: [{ type: 'text', text: 'hi' }] }, { parts: [ todoPart([{ content: 'Stale', id: 'a', status: 'pending' }], { result: { todos: [{ content: 'Fresh', id: 'a', status: 'completed' }] } }) ] } ] expect(latestSessionTodos(messages)).toEqual([{ content: 'Fresh', id: 'a', status: 'completed' }]) }) it('prefers the live carried `todos` field over args', () => { const messages = [ { parts: [ todoPart([{ content: 'Args', id: 'a', status: 'pending' }], { todos: [{ content: 'Live', id: 'a', status: 'in_progress' }] }) ] } ] expect(latestSessionTodos(messages)).toEqual([{ content: 'Live', id: 'a', status: 'in_progress' }]) }) it('returns null when no todo tool calls exist', () => { expect(latestSessionTodos([{ parts: [{ type: 'text', text: 'hi' }] }])).toBeNull() expect(latestSessionTodos([])).toBeNull() }) })