feat(HAI-078): add configurable task prefix to settings

- Add taskPrefix field to Settings type and use it in allocateId
- Update store listTasks and handleFsChange to support any task prefix
- Update triage duplicate regex to match configurable prefix
- Add Task Prefix input to dashboard SettingsModal UI
- Add tests for prefix-aware task allocation and settings modal
This commit is contained in:
Dustin Byrne
2026-03-26 00:48:38 -04:00
parent 40099be89e
commit 5dea073d22
6 changed files with 143 additions and 10 deletions

View File

@@ -160,7 +160,8 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
private async allocateId(): Promise<string> {
return this.withConfigLock(async () => {
const config = await this.readConfig();
const id = `HAI-${String(config.nextId).padStart(3, "0")}`;
const prefix = config.settings?.taskPrefix || "HAI";
const id = `${prefix}-${String(config.nextId).padStart(3, "0")}`;
config.nextId++;
await this.writeConfig(config);
return id;
@@ -235,7 +236,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
const tasks: Task[] = [];
for (const entry of entries) {
if (entry.isDirectory() && entry.name.startsWith("HAI-")) {
if (entry.isDirectory() && /^[A-Z]+-\d+$/.test(entry.name)) {
try {
tasks.push(await this.readTaskJson(join(this.tasksDir, entry.name)));
} catch {
@@ -655,7 +656,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
const taskId = normalizedParts[0];
const file = normalizedParts[normalizedParts.length - 1];
if (file !== "task.json") return;
if (!taskId.startsWith("HAI-")) return;
if (!/^[A-Z]+-\d+$/.test(taskId)) return;
const fullPath = join(this.tasksDir, taskId, "task.json");