refactor: drop discover command, agents create new tasks instead
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
import { runDashboard } from "./commands/dashboard.js";
|
import { runDashboard } from "./commands/dashboard.js";
|
||||||
import { runTaskCreate, runTaskList, runTaskMove, runTaskMerge, runTaskUpdate, runTaskLog, runTaskDiscover, runTaskShow } from "./commands/task.js";
|
import { runTaskCreate, runTaskList, runTaskMove, runTaskMerge, runTaskUpdate, runTaskLog, runTaskShow } from "./commands/task.js";
|
||||||
|
|
||||||
const HELP = `
|
const HELP = `
|
||||||
hai — AI-orchestrated task board
|
hai — AI-orchestrated task board
|
||||||
@@ -14,7 +14,6 @@ Usage:
|
|||||||
hai task move <id> <col> Move a task to a column
|
hai task move <id> <col> Move a task to a column
|
||||||
hai task update <id> <step> <status> Update step status (pending|in-progress|done|skipped)
|
hai task update <id> <step> <status> Update step status (pending|in-progress|done|skipped)
|
||||||
hai task log <id> <message> Add a log entry
|
hai task log <id> <message> Add a log entry
|
||||||
hai task discover <id> <what> <disp> Record a discovery
|
|
||||||
hai task merge <id> Merge an in-review task and close it
|
hai task merge <id> Merge an in-review task and close it
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
@@ -95,15 +94,6 @@ async function main() {
|
|||||||
await runTaskLog(id, message);
|
await runTaskLog(id, message);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "discover": {
|
|
||||||
const id = args[2], what = args[3], disp = args[4], loc = args[5];
|
|
||||||
if (!id || !what || !disp) {
|
|
||||||
console.error("Usage: hai task discover <id> <discovery> <disposition> [location]");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
await runTaskDiscover(id, what, disp, loc);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "merge": {
|
case "merge": {
|
||||||
const id = args[2];
|
const id = args[2];
|
||||||
if (!id) { console.error("Usage: hai task merge <id>"); process.exit(1); }
|
if (!id) { console.error("Usage: hai task merge <id>"); process.exit(1); }
|
||||||
|
|||||||
@@ -101,17 +101,6 @@ export async function runTaskLog(id: string, message: string, outcome?: string)
|
|||||||
console.log();
|
console.log();
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function runTaskDiscover(id: string, discovery: string, disposition: string, location?: string) {
|
|
||||||
const store = await getStore();
|
|
||||||
await store.addDiscovery(id, discovery, disposition, location);
|
|
||||||
|
|
||||||
console.log();
|
|
||||||
console.log(` ✓ ${id}: discovery recorded`);
|
|
||||||
console.log(` ${discovery}`);
|
|
||||||
console.log(` → ${disposition}`);
|
|
||||||
console.log();
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function runTaskShow(id: string) {
|
export async function runTaskShow(id: string) {
|
||||||
const store = await getStore();
|
const store = await getStore();
|
||||||
const task = await store.getTask(id);
|
const task = await store.getTask(id);
|
||||||
@@ -139,15 +128,6 @@ export async function runTaskShow(id: string) {
|
|||||||
console.log();
|
console.log();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Discoveries
|
|
||||||
if (task.discoveries.length > 0) {
|
|
||||||
console.log(` Discoveries:`);
|
|
||||||
for (const d of task.discoveries) {
|
|
||||||
console.log(` • ${d.discovery} → ${d.disposition}${d.location ? ` (${d.location})` : ""}`);
|
|
||||||
}
|
|
||||||
console.log();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recent log
|
// Recent log
|
||||||
if (task.log.length > 0) {
|
if (task.log.length > 0) {
|
||||||
const recent = task.log.slice(-5);
|
const recent = task.log.slice(-5);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export { COLUMNS, COLUMN_LABELS, COLUMN_DESCRIPTIONS, VALID_TRANSITIONS, DEFAULT_SETTINGS } from "./types.js";
|
export { COLUMNS, COLUMN_LABELS, COLUMN_DESCRIPTIONS, VALID_TRANSITIONS, DEFAULT_SETTINGS } from "./types.js";
|
||||||
export type { Column, Task, TaskCreateInput, TaskDetail, BoardConfig, MergeResult, Settings, TaskStep, StepStatus, TaskLogEntry, TaskDiscovery, TaskReview } from "./types.js";
|
export type { Column, Task, TaskCreateInput, TaskDetail, BoardConfig, MergeResult, Settings, TaskStep, StepStatus, TaskLogEntry } from "./types.js";
|
||||||
export { TaskStore } from "./store.js";
|
export { TaskStore } from "./store.js";
|
||||||
export { canTransition, getValidTransitions, resolveDependencyOrder } from "./board.js";
|
export { canTransition, getValidTransitions, resolveDependencyOrder } from "./board.js";
|
||||||
|
|||||||
@@ -94,8 +94,6 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
|||||||
dependencies: input.dependencies || [],
|
dependencies: input.dependencies || [],
|
||||||
steps: [],
|
steps: [],
|
||||||
currentStep: 0,
|
currentStep: 0,
|
||||||
reviews: [],
|
|
||||||
discoveries: [],
|
|
||||||
log: [{ timestamp: now, action: "Task created" }],
|
log: [{ timestamp: now, action: "Task created" }],
|
||||||
createdAt: now,
|
createdAt: now,
|
||||||
updatedAt: now,
|
updatedAt: now,
|
||||||
@@ -301,37 +299,6 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
|||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Record a discovery (things found during execution that may affect future tasks).
|
|
||||||
*/
|
|
||||||
async addDiscovery(
|
|
||||||
id: string,
|
|
||||||
discovery: string,
|
|
||||||
disposition: string,
|
|
||||||
location?: string,
|
|
||||||
): Promise<Task> {
|
|
||||||
const dir = this.taskDir(id);
|
|
||||||
const data = await readFile(join(dir, "task.json"), "utf-8");
|
|
||||||
const task = JSON.parse(data) as Task;
|
|
||||||
|
|
||||||
task.discoveries.push({ discovery, disposition, location });
|
|
||||||
task.updatedAt = new Date().toISOString();
|
|
||||||
|
|
||||||
task.log.push({
|
|
||||||
timestamp: task.updatedAt,
|
|
||||||
action: `Discovery: ${discovery}`,
|
|
||||||
outcome: disposition,
|
|
||||||
});
|
|
||||||
|
|
||||||
const taskJsonPath = join(dir, "task.json");
|
|
||||||
this.suppressWatcher(taskJsonPath);
|
|
||||||
await writeFile(taskJsonPath, JSON.stringify(task, null, 2));
|
|
||||||
if (this.watcher) this.taskCache.set(id, { ...task });
|
|
||||||
|
|
||||||
this.emit("task:updated", task);
|
|
||||||
return task;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sync steps from PROMPT.md into task.json (called when steps are empty).
|
* Sync steps from PROMPT.md into task.json (called when steps are empty).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -14,20 +14,6 @@ export interface TaskLogEntry {
|
|||||||
outcome?: string;
|
outcome?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TaskDiscovery {
|
|
||||||
discovery: string;
|
|
||||||
disposition: string;
|
|
||||||
location?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface TaskReview {
|
|
||||||
id: number;
|
|
||||||
type: string;
|
|
||||||
step: number;
|
|
||||||
verdict: string;
|
|
||||||
notes?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Task {
|
export interface Task {
|
||||||
id: string;
|
id: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
@@ -37,8 +23,6 @@ export interface Task {
|
|||||||
worktree?: string;
|
worktree?: string;
|
||||||
steps: TaskStep[];
|
steps: TaskStep[];
|
||||||
currentStep: number;
|
currentStep: number;
|
||||||
reviews: TaskReview[];
|
|
||||||
discoveries: TaskDiscovery[];
|
|
||||||
log: TaskLogEntry[];
|
log: TaskLogEntry[];
|
||||||
size?: "S" | "M" | "L";
|
size?: "S" | "M" | "L";
|
||||||
reviewLevel?: number;
|
reviewLevel?: number;
|
||||||
|
|||||||
@@ -41,10 +41,10 @@ Log important actions, decisions, or issues:
|
|||||||
hai task log {TASK_ID} "description of what happened"
|
hai task log {TASK_ID} "description of what happened"
|
||||||
\`\`\`
|
\`\`\`
|
||||||
|
|
||||||
### Discoveries
|
### Out-of-scope work
|
||||||
When you find something unexpected that may affect future tasks:
|
If you find something that needs doing but is outside this task's scope, create a new task:
|
||||||
\`\`\`bash
|
\`\`\`bash
|
||||||
hai task discover {TASK_ID} "what you found" "what to do about it" "optional/file/location"
|
hai task create "description of the new work needed"
|
||||||
\`\`\`
|
\`\`\`
|
||||||
|
|
||||||
## Git discipline
|
## Git discipline
|
||||||
@@ -65,7 +65,7 @@ hai task discover {TASK_ID} "what you found" "what to do about it" "optional/fil
|
|||||||
- Stay within the file scope defined in PROMPT.md
|
- Stay within the file scope defined in PROMPT.md
|
||||||
- Read "Context to Read First" files before starting
|
- Read "Context to Read First" files before starting
|
||||||
- Follow the "Do NOT" section strictly
|
- Follow the "Do NOT" section strictly
|
||||||
- If you discover work outside the task's scope, log it with \`hai task discover\` but don't do it
|
- If you find work outside the task's scope, create a new task with \`hai task create "description"\`
|
||||||
- Update documentation listed in "Must Update" and check "Check If Affected"
|
- Update documentation listed in "Must Update" and check "Check If Affected"
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
@@ -243,7 +243,7 @@ ${task.prompt}
|
|||||||
- \`hai task update ${task.id} 0 in-progress\` — when starting Step 0
|
- \`hai task update ${task.id} 0 in-progress\` — when starting Step 0
|
||||||
- \`hai task update ${task.id} 0 done\` — when Step 0 is complete
|
- \`hai task update ${task.id} 0 done\` — when Step 0 is complete
|
||||||
- \`hai task log ${task.id} "what you did"\` — for important actions
|
- \`hai task log ${task.id} "what you did"\` — for important actions
|
||||||
- \`hai task discover ${task.id} "finding" "disposition"\` — for discoveries
|
- \`hai task create "description"\` — for out-of-scope work found during execution
|
||||||
3. Implement each step in order, committing at step boundaries:
|
3. Implement each step in order, committing at step boundaries:
|
||||||
\`git commit -m "feat(${task.id}): complete Step N — description"\`
|
\`git commit -m "feat(${task.id}): complete Step N — description"\`
|
||||||
4. Follow the review level guidance in the spec
|
4. Follow the review level guidance in the spec
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ Follow this structure exactly:
|
|||||||
### Step {N}: Documentation & Delivery
|
### Step {N}: Documentation & Delivery
|
||||||
|
|
||||||
- [ ] Update relevant documentation
|
- [ ] Update relevant documentation
|
||||||
- [ ] Discoveries logged via \`hai task discover\`
|
- [ ] Out-of-scope findings created as new tasks via \`hai task create\`
|
||||||
|
|
||||||
## Documentation Requirements
|
## Documentation Requirements
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user