Skip to content

Commit 2034052

Browse files
committed
Guard final todo reminder injection
1 parent 8f68e0d commit 2034052

2 files changed

Lines changed: 28 additions & 1 deletion

File tree

src/hooks/todo-continuation/todo-hygiene.test.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,28 @@ describe('todo hygiene', () => {
246246
expect(output.output).not.toContain(TODO_HYGIENE_REMINDER);
247247
});
248248

249+
test('shouldInject rejection prevents immediate final-active reminder', async () => {
250+
const hook = createTodoHygiene({
251+
getTodoState: async () =>
252+
createState({
253+
openCount: 1,
254+
inProgressCount: 1,
255+
pendingCount: 0,
256+
}),
257+
shouldInject: () => false,
258+
});
259+
const output = createToolOutput();
260+
261+
hook.handleRequestStart({ sessionID: 's1' });
262+
await hook.handleToolExecuteAfter(
263+
{ tool: 'todowrite', sessionID: 's1' },
264+
output,
265+
);
266+
267+
expect(output.output).toBe('tool result');
268+
expect(output.output).not.toContain(TODO_FINAL_ACTIVE_REMINDER);
269+
});
270+
249271
test('final-active reminder wins when only one active todo remains', async () => {
250272
const hook = createTodoHygiene({
251273
getTodoState: async () =>
@@ -376,7 +398,7 @@ describe('todo hygiene', () => {
376398
);
377399
await hook.handleToolExecuteAfter({ tool: 'grep', sessionID: 's1' });
378400

379-
expect(calls).toBe(1);
401+
expect(calls).toBe(0);
380402
expect(output.output).toBe('tool result');
381403
expect(output.output).not.toContain(TODO_HYGIENE_REMINDER);
382404
});

src/hooks/todo-continuation/todo-hygiene.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ export function createTodoHygiene(options: Options) {
122122

123123
try {
124124
if (RESET.has(tool)) {
125+
if (options.shouldInject && !options.shouldInject(input.sessionID)) {
126+
clear(input.sessionID);
127+
return;
128+
}
129+
125130
active.add(input.sessionID);
126131
clearCycle(input.sessionID);
127132
const state = await options.getTodoState(input.sessionID);

0 commit comments

Comments
 (0)