chore: apply requested changes

This commit is contained in:
Ralph Khreish
2025-10-09 14:53:33 +02:00
parent f0d1d5de89
commit ef4e2e425b

View File

@@ -8,7 +8,12 @@ import { Command } from 'commander';
import chalk from 'chalk'; import chalk from 'chalk';
import boxen from 'boxen'; import boxen from 'boxen';
import ora, { type Ora } from 'ora'; import ora, { type Ora } from 'ora';
import { createTaskMasterCore, type TaskMasterCore } from '@tm/core'; import {
createTaskMasterCore,
type TaskMasterCore,
type Task,
type Subtask
} from '@tm/core';
import * as ui from '../utils/ui.js'; import * as ui from '../utils/ui.js';
/** /**
@@ -20,13 +25,32 @@ export interface AutopilotCommandOptions {
dryRun?: boolean; dryRun?: boolean;
} }
/**
* Preflight check result for a single check
*/
export interface PreflightCheckResult {
success: boolean;
message?: string;
}
/**
* Overall preflight check results
*/
export interface PreflightResult {
success: boolean;
testCommand: PreflightCheckResult;
gitWorkingTree: PreflightCheckResult;
requiredTools: PreflightCheckResult;
defaultBranch: PreflightCheckResult;
}
/** /**
* CLI-specific result type from autopilot command * CLI-specific result type from autopilot command
*/ */
export interface AutopilotCommandResult { export interface AutopilotCommandResult {
success: boolean; success: boolean;
taskId: string; taskId: string;
task?: any; task?: Task;
error?: string; error?: string;
message?: string; message?: string;
} }
@@ -107,7 +131,7 @@ export class AutopilotCommand extends Command {
// Display results // Display results
this.displayResults(result, options); this.displayResults(result, options);
} catch (error: any) { } catch (error: unknown) {
if (spinner) { if (spinner) {
spinner.fail('Operation failed'); spinner.fail('Operation failed');
} }
@@ -151,7 +175,7 @@ export class AutopilotCommand extends Command {
/** /**
* Load task from tm-core * Load task from tm-core
*/ */
private async loadTask(taskId: string): Promise<any | null> { private async loadTask(taskId: string): Promise<Task | null> {
if (!this.tmCore) { if (!this.tmCore) {
throw new Error('TaskMasterCore not initialized'); throw new Error('TaskMasterCore not initialized');
} }
@@ -167,7 +191,7 @@ export class AutopilotCommand extends Command {
/** /**
* Display task information before execution * Display task information before execution
*/ */
private displayTaskInfo(task: any, isDryRun: boolean): void { private displayTaskInfo(task: Task, isDryRun: boolean): void {
const prefix = isDryRun ? '[DRY RUN] ' : ''; const prefix = isDryRun ? '[DRY RUN] ' : '';
console.log(); console.log();
console.log( console.log(
@@ -196,22 +220,11 @@ export class AutopilotCommand extends Command {
*/ */
private async performAutopilot( private async performAutopilot(
taskId: string, taskId: string,
task: any, task: Task,
options: AutopilotCommandOptions options: AutopilotCommandOptions
): Promise<AutopilotCommandResult> { ): Promise<AutopilotCommandResult> {
const { PreflightChecker, TaskLoaderService } = await import('@tm/core');
// Run preflight checks // Run preflight checks
console.log(); const preflightResult = await this.runPreflightChecks(options);
console.log(chalk.cyan.bold('Running preflight checks...'));
const preflightChecker = new PreflightChecker(
options.project || process.cwd()
);
const preflightResult = await preflightChecker.runAllChecks();
// Display preflight results
this.displayPreflightResults(preflightResult);
if (!preflightResult.success) { if (!preflightResult.success) {
return { return {
success: false, success: false,
@@ -222,9 +235,67 @@ export class AutopilotCommand extends Command {
}; };
} }
// Load and validate task // Validate task structure and get execution order
const validationResult = await this.validateTaskStructure(
taskId,
task,
options
);
if (!validationResult.success) {
return validationResult;
}
// Display execution plan
this.displayExecutionPlan(
validationResult.task!,
validationResult.orderedSubtasks!,
options
);
return {
success: true,
taskId,
task: validationResult.task,
message: options.dryRun
? 'Dry run completed successfully'
: 'Autopilot execution ready (actual execution not yet implemented)'
};
}
/**
* Run preflight checks and display results
*/
private async runPreflightChecks(
options: AutopilotCommandOptions
): Promise<PreflightResult> {
const { PreflightChecker } = await import('@tm/core');
console.log();
console.log(chalk.cyan.bold('Running preflight checks...'));
const preflightChecker = new PreflightChecker(
options.project || process.cwd()
);
const result = await preflightChecker.runAllChecks();
this.displayPreflightResults(result);
return result;
}
/**
* Validate task structure and get execution order
*/
private async validateTaskStructure(
taskId: string,
task: Task,
options: AutopilotCommandOptions
): Promise<AutopilotCommandResult & { orderedSubtasks?: Subtask[] }> {
const { TaskLoaderService } = await import('@tm/core');
console.log(); console.log();
console.log(chalk.cyan.bold('Validating task structure...')); console.log(chalk.cyan.bold('Validating task structure...'));
const taskLoader = new TaskLoaderService(options.project || process.cwd()); const taskLoader = new TaskLoaderService(options.project || process.cwd());
const validationResult = await taskLoader.loadAndValidateTask(taskId); const validationResult = await taskLoader.loadAndValidateTask(taskId);
@@ -239,19 +310,33 @@ export class AutopilotCommand extends Command {
}; };
} }
// Get execution order
const orderedSubtasks = taskLoader.getExecutionOrder( const orderedSubtasks = taskLoader.getExecutionOrder(
validationResult.task! validationResult.task!
); );
await taskLoader.cleanup(); await taskLoader.cleanup();
// Display execution plan return {
success: true,
taskId,
task: validationResult.task,
orderedSubtasks
};
}
/**
* Display execution plan with subtasks and TDD workflow
*/
private displayExecutionPlan(
task: Task,
orderedSubtasks: Subtask[],
options: AutopilotCommandOptions
): void {
console.log(); console.log();
console.log(chalk.green.bold('✓ All checks passed!')); console.log(chalk.green.bold('✓ All checks passed!'));
console.log(); console.log();
console.log(chalk.cyan.bold('Execution Plan:')); console.log(chalk.cyan.bold('Execution Plan:'));
console.log(chalk.white(`Task: ${validationResult.task!.title}`)); console.log(chalk.white(`Task: ${task.title}`));
console.log( console.log(
chalk.gray( chalk.gray(
`${orderedSubtasks.length} subtasks will be executed in dependency order` `${orderedSubtasks.length} subtasks will be executed in dependency order`
@@ -260,11 +345,9 @@ export class AutopilotCommand extends Command {
console.log(); console.log();
// Display subtasks // Display subtasks
orderedSubtasks.forEach((subtask: any, index: number) => { orderedSubtasks.forEach((subtask: Subtask, index: number) => {
console.log( console.log(
chalk.yellow( chalk.yellow(`${index + 1}. ${task.id}.${subtask.id}: ${subtask.title}`)
`${index + 1}. ${validationResult.task!.id}.${subtask.id}: ${subtask.title}`
)
); );
if (subtask.dependencies && subtask.dependencies.length > 0) { if (subtask.dependencies && subtask.dependencies.length > 0) {
console.log( console.log(
@@ -287,21 +370,12 @@ export class AutopilotCommand extends Command {
chalk.yellow('This was a dry run. Use without --dry-run to execute.') chalk.yellow('This was a dry run. Use without --dry-run to execute.')
); );
} }
return {
success: true,
taskId,
task: validationResult.task,
message: options.dryRun
? 'Dry run completed successfully'
: 'Autopilot execution ready (actual execution not yet implemented)'
};
} }
/** /**
* Display preflight check results * Display preflight check results
*/ */
private displayPreflightResults(result: any): void { private displayPreflightResults(result: PreflightResult): void {
const checks = [ const checks = [
{ name: 'Test command', result: result.testCommand }, { name: 'Test command', result: result.testCommand },
{ name: 'Git working tree', result: result.gitWorkingTree }, { name: 'Git working tree', result: result.gitWorkingTree },
@@ -387,16 +461,22 @@ export class AutopilotCommand extends Command {
/** /**
* Handle general errors * Handle general errors
*/ */
private handleError(error: any): void { private handleError(error: unknown): void {
const msg = error?.getSanitizedDetails?.() ?? { const errorObj = error as {
message: error?.message ?? String(error) getSanitizedDetails?: () => { message: string };
message?: string;
stack?: string;
};
const msg = errorObj?.getSanitizedDetails?.() ?? {
message: errorObj?.message ?? String(error)
}; };
console.error(chalk.red(`Error: ${msg.message || 'Unexpected error'}`)); console.error(chalk.red(`Error: ${msg.message || 'Unexpected error'}`));
// Show stack trace in development mode or when DEBUG is set // Show stack trace in development mode or when DEBUG is set
const isDevelopment = process.env.NODE_ENV !== 'production'; const isDevelopment = process.env.NODE_ENV !== 'production';
if ((isDevelopment || process.env.DEBUG) && error.stack) { if ((isDevelopment || process.env.DEBUG) && errorObj.stack) {
console.error(chalk.gray(error.stack)); console.error(chalk.gray(errorObj.stack));
} }
} }