@sprouted/create-vibes
Version:
Create a new Vibes monorepo
86 lines • 3.29 kB
JavaScript
import * as path from 'path';
import * as fs from 'fs/promises';
import chalk from 'chalk';
import inquirer from 'inquirer';
export async function checkForSpec(featureName, projectRoot) {
const specPaths = [
path.join(projectRoot, 'specs/features', `${featureName}.md`),
path.join(projectRoot, 'specs', `${featureName}.md`),
path.join(projectRoot, 'features', featureName, 'SPEC.md')
];
for (const specPath of specPaths) {
try {
await fs.access(specPath);
console.log(chalk.green(`✓ Found spec: ${specPath}`));
return true;
}
catch {
// Continue checking other paths
}
}
return false;
}
export async function enforceSpecFirst(featureName, projectRoot) {
const hasSpec = await checkForSpec(featureName, projectRoot);
if (!hasSpec) {
console.log(chalk.yellow('\n⚠️ No specification found for this feature!'));
console.log(chalk.yellow('Spec-driven development requires a specification before implementation.\n'));
const { createSpec } = await inquirer.prompt([
{
type: 'confirm',
name: 'createSpec',
message: 'Would you like to create a specification first?',
default: true
}
]);
if (createSpec) {
console.log(chalk.cyan('\nGreat choice! Let\'s create a spec first.'));
console.log(chalk.cyan(`Run: vibe spec ${featureName}\n`));
process.exit(0);
}
else {
console.log(chalk.red('\n❌ Cannot proceed without a specification.'));
console.log(chalk.red('Spec-driven development is enforced in this project.\n'));
console.log('To create a spec:');
console.log(chalk.cyan(` vibe spec ${featureName}\n`));
process.exit(1);
}
}
}
export async function getSpecStatus(featureName, projectRoot) {
const specPaths = [
path.join(projectRoot, 'specs/features', `${featureName}.md`),
path.join(projectRoot, 'specs', `${featureName}.md`),
path.join(projectRoot, 'features', featureName, 'SPEC.md')
];
for (const specPath of specPaths) {
try {
const content = await fs.readFile(specPath, 'utf-8');
const statusMatch = content.match(/Status:\s*(\w+)/i);
return statusMatch ? statusMatch[1] : 'unknown';
}
catch {
// Continue checking other paths
}
}
return null;
}
export async function enforceApprovedSpec(featureName, projectRoot) {
const status = await getSpecStatus(featureName, projectRoot);
if (status !== 'approved') {
console.log(chalk.yellow(`\n⚠️ Spec status is '${status || 'unknown'}', not 'approved'.`));
const { proceed } = await inquirer.prompt([
{
type: 'confirm',
name: 'proceed',
message: 'Proceed with implementation anyway?',
default: false
}
]);
if (!proceed) {
console.log(chalk.cyan('\nGood decision! Get the spec approved first.'));
process.exit(0);
}
}
}
//# sourceMappingURL=spec-check.js.map