@jjdenhertog/ai-driven-development
Version:
AI-driven development workflow with learning capabilities for Claude
113 lines • 6.83 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.executeNextTaskCommand = executeNextTaskCommand;
const branchExists_1 = require("../utils/git/branchExists");
const checkGitInitialized_1 = require("../utils/git/checkGitInitialized");
const isInWorktree_1 = require("../utils/git/isInWorktree");
const logger_1 = require("../utils/logger");
const getBranchName_1 = require("../utils/tasks/getBranchName");
const getTasks_1 = require("../utils/tasks/getTasks");
const hasUnresolvedDependencies_1 = require("../utils/tasks/hasUnresolvedDependencies");
const executeTaskCommand_1 = require("./executeTaskCommand");
const config_1 = require("../config");
function executeNextTaskCommand(options) {
return __awaiter(this, void 0, void 0, function* () {
const { dryRun, force, dangerouslySkipPermission } = options;
// Ensure git auth
if (!(yield (0, checkGitInitialized_1.checkGitInitialized)()))
throw new Error('Git is not initialized. Please run `git init` in the root of the repository.');
// Check if we are in a worktree
if (yield (0, isInWorktree_1.isInWorktree)())
throw new Error('This command must be run from the root of the repository.');
// Find all pending tasks (no need to switch branches - tasks are in worktree)
(0, logger_1.log)('─'.repeat(50), 'light');
(0, logger_1.log)('Looking for pending tasks...', 'info');
(0, logger_1.log)('─'.repeat(50), 'light');
const tasks = yield (0, getTasks_1.getTasks)();
const pendingTasks = tasks.filter(task => task.status === 'pending');
const inProgressTasks = tasks.filter(task => task.status === 'in-progress');
const failedTasks = tasks.filter(task => task.status === 'failed' || task.status === 'failed-completing');
if (inProgressTasks.length > 0) {
(0, logger_1.log)(`There are some tasks in progress. These need to finish before continuing`, 'info');
(0, logger_1.log)(`It is very likely that these tasks have crashed and require your attention.`, 'warn');
return { taskExecuted: false, noTasksFound: true };
}
if (failedTasks.length > 0) {
(0, logger_1.log)(`There are some tasks that failed. These need to be fixed before continuing`, 'info');
(0, logger_1.log)(`It is very likely that these tasks have crashed and require your attention.`, 'warn');
return { taskExecuted: false, noTasksFound: true };
}
const completedTasks = tasks.filter(task => task.status === 'completed');
const pendingScaffoldingTasks = tasks.filter(task => (task.status === 'pending' || task.status === 'completed') && task.type === 'scaffolding');
if (pendingTasks.length === 0) {
(0, logger_1.log)('No pending tasks found', 'warn');
return { taskExecuted: false, noTasksFound: true };
}
if (completedTasks.length > 0 && config_1.SEQUENTIAL) {
(0, logger_1.log)(`We are waiting for the completed task to be merged into main.`, 'info');
(0, logger_1.log)(`When merged into main, run 'aidev learn' to analyse the task and when that is successful, the next task can be executed again.`, 'info');
(0, logger_1.log)(`These tasks are waiting for analysis:`);
for (const task of completedTasks) {
(0, logger_1.log)(`- ${task.id}: ${task.name} (${task.status})`, 'info');
}
(0, logger_1.log)('─'.repeat(50), 'light');
return { taskExecuted: false, noTasksFound: true };
}
(0, logger_1.log)(`Found ${pendingTasks.length} pending tasks`, 'info');
// Find the next executable task
for (const task of pendingTasks) {
// log(`Checking task ${task.id}: ${task.name}`, 'info');
if (task.type != 'scaffolding' && pendingScaffoldingTasks.length > 0) {
(0, logger_1.log)(`Skipping ${task.id}: ${task.name} - we are waiting for scaffolding tasks to be merged into main`, 'warn');
continue;
}
if (task.hold) {
(0, logger_1.log)(`Skipping ${task.id}: ${task.name} - is on hold`, 'warn');
continue;
}
// Check dependencies
if (yield (0, hasUnresolvedDependencies_1.hasUnresolvedDependencies)(task)) {
(0, logger_1.log)(`Skipping ${task.id}: ${task.name} - has unresolved dependencies`, 'warn');
continue;
}
// Check if branch exists
const branchName = (0, getBranchName_1.getBranchName)(task);
const exists = yield (0, branchExists_1.branchExists)(branchName);
if (!exists) {
// Branch doesn't exist, we found our task!
(0, logger_1.log)(`Found executable task: ${task.id} - ${task.name}`, 'success');
yield (0, executeTaskCommand_1.executeTaskCommand)({
taskId: task.id,
dryRun,
force,
dangerouslySkipPermission
});
(0, logger_1.log)(`Task ${task.id} - ${task.name} executed`, 'success');
return { taskExecuted: true, noTasksFound: false };
}
// Found our task!
(0, logger_1.log)(`Found executable task: ${task.id} - ${task.name}`, 'success');
yield (0, executeTaskCommand_1.executeTaskCommand)({
taskId: task.id,
dangerouslySkipPermission,
dryRun,
force
});
(0, logger_1.log)(`Task ${task.id} - ${task.name} executed`, 'success');
return { taskExecuted: !dryRun, noTasksFound: false };
}
(0, logger_1.log)('No executable tasks found', 'warn');
(0, logger_1.log)('All pending tasks either have unresolved dependencies or are already in progress', 'info');
return { taskExecuted: false, noTasksFound: false };
});
}
//# sourceMappingURL=executeNextTaskCommand.js.map