2026-02-02 21:52:40 +09:00

83 lines
2.2 KiB
TypeScript

/**
* /watch command implementation
*
* Watches .takt/tasks/ for new task files and executes them automatically.
* Stays resident until Ctrl+C (SIGINT).
*/
import { TaskRunner, type TaskInfo, TaskWatcher } from '../../../infra/task/index.js';
import { getCurrentWorkflow } from '../../../infra/config/index.js';
import {
header,
info,
success,
status,
blankLine,
} from '../../../shared/ui/index.js';
import { executeAndCompleteTask } from '../execute/taskExecution.js';
import { DEFAULT_WORKFLOW_NAME } from '../../../shared/constants.js';
import type { TaskExecutionOptions } from '../execute/types.js';
/**
* Watch for tasks and execute them as they appear.
* Runs until Ctrl+C.
*/
export async function watchTasks(cwd: string, options?: TaskExecutionOptions): Promise<void> {
const workflowName = getCurrentWorkflow(cwd) || DEFAULT_WORKFLOW_NAME;
const taskRunner = new TaskRunner(cwd);
const watcher = new TaskWatcher(cwd);
let taskCount = 0;
let successCount = 0;
let failCount = 0;
header('TAKT Watch Mode');
info(`Workflow: ${workflowName}`);
info(`Watching: ${taskRunner.getTasksDir()}`);
info('Waiting for tasks... (Ctrl+C to stop)');
blankLine();
// Graceful shutdown on SIGINT
const onSigInt = () => {
blankLine();
info('Stopping watch...');
watcher.stop();
};
process.on('SIGINT', onSigInt);
try {
await watcher.watch(async (task: TaskInfo) => {
taskCount++;
blankLine();
info(`=== Task ${taskCount}: ${task.name} ===`);
blankLine();
const taskSuccess = await executeAndCompleteTask(task, taskRunner, cwd, workflowName, options);
if (taskSuccess) {
successCount++;
} else {
failCount++;
}
blankLine();
info('Waiting for tasks... (Ctrl+C to stop)');
});
} finally {
process.removeListener('SIGINT', onSigInt);
}
// Summary on exit
if (taskCount > 0) {
blankLine();
header('Watch Summary');
status('Total', String(taskCount));
status('Success', String(successCount), successCount === taskCount ? 'green' : undefined);
if (failCount > 0) {
status('Failed', String(failCount), 'red');
}
}
success('Watch stopped.');
}