fix(hub): Check-in adressiert wie der Work-Loop (Titel-Präfix + Handoff)
Der Check-in prüfte nur `assignedTo`, `findAddressedOpenTask` dagegen Titel-Präfix `<name>:`, Handoff-Empfänger UND `assignedTo`. Folge: `agenthub start codex` meldete "AKTUELL: nichts offen", während TSK-0268 mit `codex:`-Präfix offen lag — der Work-Loop hätte sie unmittelbar danach geclaimt. Zwei Wahrheiten über dieselbe Frage. Jetzt nutzt der Check-in dieselbe Adressierungslogik. Tests: 293 → 295. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4be0826a6f
commit
1250359e6d
@ -1,6 +1,7 @@
|
|||||||
import { listTasks } from './taskService.js';
|
import { listTasks } from './taskService.js';
|
||||||
import { listMessages } from './messageService.js';
|
import { listMessages } from './messageService.js';
|
||||||
import { listAsks } from './askService.js';
|
import { listAsks } from './askService.js';
|
||||||
|
import { listHandoffs } from './handoffService.js';
|
||||||
import { agentIdentity } from './identityService.js';
|
import { agentIdentity } from './identityService.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,8 +109,28 @@ export function resolvePending(
|
|||||||
pending.answeredAsks.push({ id: ask.id, answer: previewOf(ask.answer) });
|
pending.answeredAsks.push({ id: ask.id, answer: previewOf(ask.answer) });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Adressierung EXAKT wie in findAddressedOpenTask (start.ts): Titel-Präfix
|
||||||
|
// `<name>:`, Handoff-Empfänger ODER assignedTo. Prüfte der Check-in nur
|
||||||
|
// assignedTo, meldete der Session-Start "nichts offen" — und der Work-Loop
|
||||||
|
// claimte unmittelbar danach eine Task, die er über das Titel-Präfix findet.
|
||||||
|
// Zwei Wahrheiten über dieselbe Frage sind genau das, was hier nicht passieren darf.
|
||||||
|
let addressedByHandoff = new Set<string>();
|
||||||
|
try {
|
||||||
|
addressedByHandoff = new Set(
|
||||||
|
listHandoffs(cwd)
|
||||||
|
.filter((h) => h.toAgent && isMine(h.toAgent) && h.taskId)
|
||||||
|
.map((h) => String(h.taskId)),
|
||||||
|
);
|
||||||
|
} catch {
|
||||||
|
// Handoffs nicht lesbar — Präfix/assignedTo tragen weiterhin.
|
||||||
|
}
|
||||||
|
const addressedToMe = (task: { id: string; title?: string; assignedTo?: string }) =>
|
||||||
|
[...names].some((n) => (task.title ?? '').toLowerCase().startsWith(`${n}:`)) ||
|
||||||
|
addressedByHandoff.has(task.id) ||
|
||||||
|
isMine(task.assignedTo);
|
||||||
|
|
||||||
for (const task of tasks) {
|
for (const task of tasks) {
|
||||||
if (task.status === 'open' && isMine(task.assignedTo)) pending.waitingTasks.push(task.id);
|
if (task.status === 'open' && addressedToMe(task)) pending.waitingTasks.push(task.id);
|
||||||
else if (task.status === 'review' && isMine(task.claimedBy ?? task.assignedTo)) pending.awaitingReview.push(task.id);
|
else if (task.status === 'review' && isMine(task.claimedBy ?? task.assignedTo)) pending.awaitingReview.push(task.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -170,3 +170,21 @@ describe('resolvePending — `delivered` zaehlt weiter', () => {
|
|||||||
expect(hasPending(pending)).toBe(true);
|
expect(hasPending(pending)).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('resolvePending — Adressierung wie im Work-Loop', () => {
|
||||||
|
it('erkennt eine Task am Titel-Praefix, auch ohne assignedTo', () => {
|
||||||
|
// Genau der Fall, der den Session-Start luegen liess: Task traegt das
|
||||||
|
// Praefix, aber kein assignedTo — der Work-Loop haette sie sofort geclaimt.
|
||||||
|
const task = createTask(cwd, { title: 'codex: Blocker-Redesign', role: 'implementer' });
|
||||||
|
|
||||||
|
const pending = resolvePending(cwd, 'codex');
|
||||||
|
|
||||||
|
expect(pending.waitingTasks).toContain(task.id);
|
||||||
|
expect(hasPending(pending)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('beansprucht keine fremd adressierte Task', () => {
|
||||||
|
createTask(cwd, { title: 'kimi: nicht meins', role: 'implementer' });
|
||||||
|
expect(resolvePending(cwd, 'codex').waitingTasks).toHaveLength(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user