feat(bf-60j): add currentBead field to WorkerInfo
Add currentBead field to WorkerInfo in src/types.ts and maintain it in src/store.ts: set it from bead.claim.succeeded (event.bead) and clear it (null) on bead.released. Foundation for the worker-card current-bead display. Update src/store.test.ts to cover claim->set and release->clear. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
93b3e9e038
commit
e0581f09cb
3 changed files with 69 additions and 7 deletions
|
|
@ -231,6 +231,55 @@ describe('InMemoryEventStore', () => {
|
|||
expect(worker?.beadsCompleted).toBe(0);
|
||||
});
|
||||
|
||||
it('should set currentBead from bead.claim.succeeded event', () => {
|
||||
store.add(createEvent({ worker: 'w-test', msg: 'bead.claim.succeeded', bead: 'bd-abc123' }));
|
||||
|
||||
const worker = store.getWorker('w-test');
|
||||
expect(worker?.currentBead).toBe('bd-abc123');
|
||||
});
|
||||
|
||||
it('should clear currentBead to null on bead.released event', () => {
|
||||
// First set currentBead
|
||||
store.add(createEvent({ worker: 'w-test', msg: 'bead.claim.succeeded', bead: 'bd-abc123' }));
|
||||
|
||||
const workerBefore = store.getWorker('w-test');
|
||||
expect(workerBefore?.currentBead).toBe('bd-abc123');
|
||||
|
||||
// Then release the bead
|
||||
store.add(createEvent({ worker: 'w-test', msg: 'bead.released', bead: 'bd-abc123' }));
|
||||
|
||||
const workerAfter = store.getWorker('w-test');
|
||||
expect(workerAfter?.currentBead).toBeNull();
|
||||
});
|
||||
|
||||
it('should clear currentBead on bead.released regardless of reason', () => {
|
||||
// Set currentBead
|
||||
store.add(createEvent({ worker: 'w-test', msg: 'bead.claim.succeeded', bead: 'bd-xyz' }));
|
||||
|
||||
// Release with non-success reason
|
||||
store.add(createEvent({ worker: 'w-test', msg: 'bead.released', reason: 'release_retry', bead: 'bd-xyz' }));
|
||||
|
||||
const worker = store.getWorker('w-test');
|
||||
expect(worker?.currentBead).toBeNull();
|
||||
});
|
||||
|
||||
it('should update currentBead when worker claims another bead', () => {
|
||||
// Claim first bead
|
||||
store.add(createEvent({ worker: 'w-test', msg: 'bead.claim.succeeded', bead: 'bd-first' }));
|
||||
expect(store.getWorker('w-test')?.currentBead).toBe('bd-first');
|
||||
|
||||
// Claim second bead
|
||||
store.add(createEvent({ worker: 'w-test', msg: 'bead.claim.succeeded', bead: 'bd-second' }));
|
||||
expect(store.getWorker('w-test')?.currentBead).toBe('bd-second');
|
||||
});
|
||||
|
||||
it('should initialize currentBead to null for new workers', () => {
|
||||
store.add(createEvent({ worker: 'w-newbie', msg: 'worker.started' }));
|
||||
|
||||
const worker = store.getWorker('w-newbie');
|
||||
expect(worker?.currentBead).toBeNull();
|
||||
});
|
||||
|
||||
it('should track firstSeen timestamp', () => {
|
||||
const earlyTs = 1000;
|
||||
const lateTs = 5000;
|
||||
|
|
|
|||
24
src/store.ts
24
src/store.ts
|
|
@ -622,6 +622,7 @@ export class InMemoryEventStore implements EventStore {
|
|||
activeFiles: [],
|
||||
hasCollision: false,
|
||||
activeBead: event.bead,
|
||||
currentBead: null,
|
||||
activeDirectories: [],
|
||||
collisionTypes: [],
|
||||
eventCount: 1,
|
||||
|
|
@ -687,14 +688,18 @@ export class InMemoryEventStore implements EventStore {
|
|||
worker.activeDirectories = [];
|
||||
worker.activeBead = undefined;
|
||||
}
|
||||
} else if (needleEvent === 'bead.released' && event['reason'] === 'release_success') {
|
||||
worker.status = 'idle';
|
||||
if (event.bead) {
|
||||
worker.beadsCompleted++;
|
||||
} else if (needleEvent === 'bead.released') {
|
||||
// Clear currentBead on any bead.released event (regardless of reason)
|
||||
worker.currentBead = null;
|
||||
if (event['reason'] === 'release_success') {
|
||||
worker.status = 'idle';
|
||||
if (event.bead) {
|
||||
worker.beadsCompleted++;
|
||||
}
|
||||
worker.activeFiles = [];
|
||||
worker.activeDirectories = [];
|
||||
worker.activeBead = undefined;
|
||||
}
|
||||
worker.activeFiles = [];
|
||||
worker.activeDirectories = [];
|
||||
worker.activeBead = undefined;
|
||||
} else if (
|
||||
needleEvent === 'worker.started' ||
|
||||
needleEvent === 'bead.claimed' ||
|
||||
|
|
@ -705,6 +710,11 @@ export class InMemoryEventStore implements EventStore {
|
|||
}
|
||||
}
|
||||
|
||||
// Set currentBead from bead.claim.succeeded event
|
||||
if (needleEvent === 'bead.claim.succeeded' && event.bead) {
|
||||
worker.currentBead = event.bead;
|
||||
}
|
||||
|
||||
// Update last event
|
||||
worker.lastEvent = event;
|
||||
|
||||
|
|
|
|||
|
|
@ -551,6 +551,9 @@ export interface WorkerInfo {
|
|||
/** Current bead/task being worked on */
|
||||
activeBead?: string;
|
||||
|
||||
/** Current bead from bead.claim.succeeded, cleared on bead.released */
|
||||
currentBead: string | null;
|
||||
|
||||
/** Directories this worker is active in */
|
||||
activeDirectories: string[];
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue