@jjdenhertog/ai-driven-development
Version:
AI-driven development workflow with learning capabilities for Claude
128 lines (127 loc) • 6.25 kB
JavaScript
;
/* eslint-disable @typescript-eslint/restrict-template-expressions */
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.executePlanCommand = executePlanCommand;
const fs_extra_1 = require("fs-extra");
const claude_wrapper_1 = require("../../claude-wrapper");
const checkGitInitialized_1 = require("../utils/git/checkGitInitialized");
const isInWorktree_1 = require("../utils/git/isInWorktree");
const logger_1 = require("../utils/logger");
const node_path_1 = require("node:path");
const PHASES = [
{
file: 'aidev-plan-phase0-analyze.md',
name: 'Phase 0: Concept Analysis',
completionMarker: '.aidev-storage/planning/PHASE0_COMPLETE'
},
{
file: 'aidev-plan-phase1-architect.md',
name: 'Phase 1: Architecture Planning',
requiredFiles: ['.aidev-storage/planning/PHASE0_COMPLETE'],
completionMarker: '.aidev-storage/planning/PHASE1_COMPLETE'
},
{
file: 'aidev-plan-phase2-generate.md',
name: 'Phase 2: Task Generation',
requiredFiles: ['.aidev-storage/planning/PHASE1_COMPLETE'],
completionMarker: '.aidev-storage/planning/PHASE2_COMPLETE'
},
{
file: 'aidev-plan-phase3-validate.md',
name: 'Phase 3: Validation & Refinement',
requiredFiles: [
'.aidev-storage/planning/PHASE0_COMPLETE',
'.aidev-storage/planning/PHASE1_COMPLETE',
'.aidev-storage/planning/PHASE2_COMPLETE'
],
completionMarker: '.aidev-storage/planning/READY'
}
];
function validatePhasePrerequisites(phase) {
(0, logger_1.log)(`Validating prerequisites for ${phase.name}...`, 'info');
// Check if phase was already completed
if (phase.completionMarker && (0, fs_extra_1.existsSync)(phase.completionMarker)) {
if (phase.completionMarker === '.aidev-storage/planning/READY') {
(0, logger_1.log)('Planning was already completed and finalized. Tasks are ready for implementation.', 'warn');
return false;
}
(0, logger_1.log)(`${phase.name} was already completed. To re-run, delete: ${phase.completionMarker}`, 'warn');
return false;
}
// Check required files
if (phase.requiredFiles) {
for (const file of phase.requiredFiles) {
if (!(0, fs_extra_1.existsSync)(file)) {
(0, logger_1.log)(`ERROR: Missing required file from previous phase: ${file}`, 'error');
(0, logger_1.log)(`You must complete the previous phase first.`, 'error');
return false;
}
}
}
(0, logger_1.log)(`✅ All prerequisites validated for ${phase.name}`, 'success');
return true;
}
function executePlanCommand(options) {
return __awaiter(this, void 0, void 0, function* () {
const { dangerouslySkipPermission, phase, reset } = 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.');
// @TODO: Remove .aidev-storage/planning/ directory
if (reset) {
const planningPath = (0, node_path_1.join)(process.cwd(), '.aidev-storage', 'planning');
if ((0, fs_extra_1.existsSync)(planningPath))
(0, fs_extra_1.rmSync)(planningPath, { force: true, recursive: true });
}
// Step 3: Execute Claude
(0, logger_1.log)('Starting Claude with aidev-plan commands...', 'success');
if (phase > 1)
(0, logger_1.log)(`Starting from phase ${phase}`, 'warn');
if (dangerouslySkipPermission)
(0, logger_1.log)('Dangerously skipping permission checks of Claude Code', 'warn');
const claudeCommand = (prompt) => __awaiter(this, void 0, void 0, function* () {
const args = [];
if (dangerouslySkipPermission)
args.push('--dangerously-skip-permissions');
// Execute Claude and wait for completion
yield (0, claude_wrapper_1.executeClaudeCommand)({
cwd: process.cwd(),
command: `Please complete the following steps IN ORDER:
1. First, use the Read tool to read the entire contents of the file: .aidev-storage/prompts/${prompt}
2. After reading the file, list the key constraints and outputs for this phase.
3. Then execute the instructions from that file
4. Show me progress as you work through the phase.
`,
args,
preventAutoExit: true,
});
});
for (let i = phase - 1; i < PHASES.length; i++) {
const currentPhase = PHASES[i];
(0, logger_1.log)(`\n=== Starting ${currentPhase.name} ===`, 'info');
// Validate prerequisites before starting phase
const isValid = validatePhasePrerequisites(currentPhase);
if (!isValid) {
(0, logger_1.log)(`Stopping execution due to prerequisite validation failure.`, 'error');
break;
}
// Execute the phase
yield claudeCommand(currentPhase.file);
(0, logger_1.log)(`✅ ${currentPhase.name} completed`, 'success');
}
(0, logger_1.log)(`Claude commands success...`, 'success');
});
}
//# sourceMappingURL=executePlanCommands.js.map