feat(HAI-065): add file-scope overlap detection with blockedBy tracking

- Add blockedBy field to Task type and core store
- Update scheduler to set blockedBy when deferring tasks due to file-scope overlap
- Render file-scope overlap badge on TaskCard in dashboard
- Add tests for blockedBy store logic, scheduler deferral, and TaskCard badge
- Simplify and refactor existing executor, triage, and CLI command code
This commit is contained in:
Dustin Byrne
2026-03-26 00:09:42 -04:00
parent cac3bad367
commit cdb0ae5d41
8 changed files with 137 additions and 8 deletions

View File

@@ -267,6 +267,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
if (toColumn === "done") {
task.status = undefined;
task.worktree = undefined;
task.blockedBy = undefined;
}
await this.atomicWriteTaskJson(dir, task);
@@ -281,7 +282,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
async updateTask(
id: string,
updates: { title?: string; description?: string; prompt?: string; worktree?: string; status?: string | null },
updates: { title?: string; description?: string; prompt?: string; worktree?: string; status?: string | null; blockedBy?: string | null },
): Promise<Task> {
return this.withTaskLock(id, async () => {
const dir = this.taskDir(id);
@@ -295,6 +296,11 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
} else if (updates.status !== undefined) {
task.status = updates.status;
}
if (updates.blockedBy === null) {
task.blockedBy = undefined;
} else if (updates.blockedBy !== undefined) {
task.blockedBy = updates.blockedBy;
}
task.updatedAt = new Date().toISOString();
await this.atomicWriteTaskJson(dir, task);
@@ -564,6 +570,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
task.column = "done";
task.worktree = undefined;
task.status = undefined;
task.blockedBy = undefined;
task.updatedAt = new Date().toISOString();
await this.atomicWriteTaskJson(dir, task);