MetaCraft/scripts/bootstrap.js

176 lines
4.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env node
/**
* bootstrap.js - MetaCraft 自举循环入口
*
* 1. 读取待办任务列表
* 2. 显示可选任务
* 3. 执行选中的任务调用对应prompt
* 4. 验证结果并更新任务状态
*/
const fs = require('fs');
const path = require('path');
const readline = require('readline');
const TODO_FILE = path.join(__dirname, '../meta/todo.md');
const PROMPTS_DIR = path.join(__dirname, '../prompts');
// 解析待办任务文件
function parseTodo(content) {
const lines = content.split('\n');
const tasks = [];
let currentCategory = '';
for (const line of lines) {
const categoryMatch = line.match(/^##\s+(.+)/);
if (categoryMatch) {
currentCategory = categoryMatch[1].trim();
continue;
}
const taskMatch = line.match(/^- \[( |x)\]\s+(.+)/);
if (taskMatch) {
const checked = taskMatch[1] === 'x';
const description = taskMatch[2].trim();
tasks.push({
category: currentCategory,
description,
checked,
raw: line
});
}
}
return tasks;
}
// 更新待办任务文件
function updateTodo(tasks, updatedTask) {
// 简化的实现:找到对应行并替换
const content = fs.readFileSync(TODO_FILE, 'utf-8');
const lines = content.split('\n');
for (let i = 0; i < lines.length; i++) {
if (lines[i].includes(updatedTask.description)) {
const newLine = lines[i].replace('- [ ]', '- [x]');
lines[i] = newLine;
break;
}
}
fs.writeFileSync(TODO_FILE, lines.join('\n'), 'utf-8');
}
// 查找对应prompt文件
function findPromptForTask(task) {
// 简单映射:将任务描述转换为文件名
const name = task.description
.toLowerCase()
.replace(/[^\w\s]/g, '')
.replace(/\s+/g, '-');
const possiblePaths = [
path.join(PROMPTS_DIR, `${name}.md`),
path.join(PROMPTS_DIR, `implement-${name}.md`),
path.join(PROMPTS_DIR, `task-${name}.md`)
];
for (const p of possiblePaths) {
if (fs.existsSync(p)) {
return p;
}
}
return null;
}
async function main() {
console.log('🚀 MetaCraft 自举循环启动\n');
if (!fs.existsSync(TODO_FILE)) {
console.error('❌ 待办任务文件不存在:', TODO_FILE);
process.exit(1);
}
const todoContent = fs.readFileSync(TODO_FILE, 'utf-8');
const tasks = parseTodo(todoContent);
const pendingTasks = tasks.filter(t => !t.checked);
if (pendingTasks.length === 0) {
console.log('🎉 所有任务已完成!');
return;
}
console.log('📋 待办任务列表:');
pendingTasks.forEach((task, index) => {
console.log(` ${index + 1}. [${task.category}] ${task.description}`);
});
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
function askQuestion(query) {
return new Promise(resolve => {
rl.question(query, answer => {
resolve(answer);
});
});
}
const answer = await askQuestion('\n请输入要执行的任务编号或按回车跳过');
rl.close();
if (!answer.trim()) {
console.log('⏭️ 跳过任务选择');
return;
}
const taskIndex = parseInt(answer) - 1;
if (isNaN(taskIndex) || taskIndex < 0 || taskIndex >= pendingTasks.length) {
console.error('❌ 无效的选择');
process.exit(1);
}
const selectedTask = pendingTasks[taskIndex];
console.log(`\n🎯 选中任务:${selectedTask.description}`);
const promptPath = findPromptForTask(selectedTask);
if (!promptPath) {
console.error(`❌ 未找到对应prompt文件请在 ${PROMPTS_DIR} 中创建。`);
console.log('提示prompt文件名应与任务描述相关如 "implement-prompt-engine.md"');
return;
}
console.log(`📄 找到prompt文件${promptPath}`);
// 执行prompt
const { main: runPrompt } = require('./run-prompt');
await runPrompt([promptPath]);
// 询问是否标记为完成
const confirm = await new Promise(resolve => {
const confirmRl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
confirmRl.question('\n✅ 任务是否已完成?(y/n) ', answer => {
confirmRl.close();
resolve(answer.toLowerCase() === 'y');
});
});
if (confirm) {
updateTodo(tasks, selectedTask);
console.log('📝 已更新待办任务状态');
} else {
console.log('⚠️ 任务状态未更新,请手动处理');
}
}
if (require.main === module) {
main().catch(err => {
console.error('自举循环错误:', err);
process.exit(1);
});
}
module.exports = { parseTodo, findPromptForTask };