faf-cli
Version:
😽 TURBO-CAT: The Rapid Catalytic Converter • Project DNA ✨ for ANY AI • Fully Integrated with React, Next.js, Svelte, TypeScript, Vite & n8n • FREE FOREVER • 10,000+ developers • Championship Edition
195 lines • 7.14 kB
JavaScript
;
/**
* Markdown to Context Extractor
* Converts ANY markdown to structured YAML and extracts relevant context
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.markdownToContext = markdownToContext;
exports.contextToFafData = contextToFafData;
exports.ingestReadme = ingestReadme;
const yaml_generator_1 = require("./yaml-generator");
/**
* Parse markdown and extract structured context
*/
function markdownToContext(markdown) {
const lines = markdown.split('\n');
const context = {
techStack: [],
goals: [],
features: [],
commands: {},
dependencies: [],
raw: {}
};
let currentSection = '';
let currentList = [];
for (const line of lines) {
// Extract title (first H1)
if (line.startsWith('# ') && !context.title) {
context.title = (0, yaml_generator_1.escapeForYaml)(line.substring(2).trim());
continue;
}
// Extract description (first paragraph after title)
if (!context.description && line.trim() && !line.startsWith('#') && !line.startsWith('-')) {
context.description = (0, yaml_generator_1.escapeForYaml)(line.trim());
continue;
}
// Track sections
if (line.startsWith('## ')) {
// Save previous list if any
if (currentList.length > 0) {
assignListToContext(context, currentSection, currentList);
currentList = [];
}
currentSection = line.substring(3).trim().toLowerCase();
continue;
}
// Extract lists
if (line.match(/^[\s]*[-*]\s+/)) {
const item = (0, yaml_generator_1.escapeForYaml)(line.replace(/^[\s]*[-*]\s+/, ''));
currentList.push(item);
continue;
}
// Extract code blocks with commands
if (line.includes('npm run') || line.includes('npm install')) {
const match = line.match(/(npm\s+\w+[\s\w-]*)/);
if (match) {
const cmd = match[1].trim();
if (context.commands) {
context.commands[cmd] = (0, yaml_generator_1.escapeForYaml)(line.trim());
}
}
}
// Look for tech indicators
if (line.match(/\b(React|Vue|Svelte|Angular|TypeScript|JavaScript|Python|Node|Express)\b/i)) {
const tech = line.match(/\b(React|Vue|Svelte|Angular|TypeScript|JavaScript|Python|Node|Express)\b/gi);
if (tech) {
tech.forEach(t => {
if (context.techStack && !context.techStack.includes(t)) {
context.techStack.push(t);
}
});
}
}
// Look for package.json dependencies
if (line.includes('"dependencies"') || line.includes('"devDependencies"')) {
// We're in a dependencies section
continue;
}
}
// Save final list
if (currentList.length > 0) {
assignListToContext(context, currentSection, currentList);
}
return context;
}
/**
* Assign list items to appropriate context field based on section name
*/
function assignListToContext(context, section, items) {
const sectionLower = section.toLowerCase();
if (sectionLower.includes('feature') || sectionLower.includes('capability')) {
context.features?.push(...items);
}
else if (sectionLower.includes('goal') || sectionLower.includes('objective')) {
context.goals?.push(...items);
}
else if (sectionLower.includes('tech') || sectionLower.includes('stack')) {
context.techStack?.push(...items);
}
else if (sectionLower.includes('depend')) {
context.dependencies?.push(...items);
}
else {
// Store in raw for other sections
if (context.raw) {
if (!context.raw[section]) {
context.raw[section] = [];
}
context.raw[section].push(...items);
}
}
}
/**
* Convert extracted context to FAF-compatible structure
*/
function contextToFafData(context) {
return {
projectName: context.title || 'Extracted Project',
projectGoal: context.description || context.goals?.join(', '),
mainLanguage: detectMainLanguage(context.techStack || []),
framework: detectFramework(context.techStack || []),
additionalWhat: context.features || [],
additionalWhy: context.goals || [],
additionalHow: context.commands ? Object.keys(context.commands) : []
};
}
function detectMainLanguage(techStack) {
const langs = techStack.map(t => t.toLowerCase());
if (langs.includes('typescript'))
return 'TypeScript';
if (langs.includes('javascript'))
return 'JavaScript';
if (langs.includes('python'))
return 'Python';
if (langs.includes('node'))
return 'JavaScript';
return 'Unknown';
}
function detectFramework(techStack) {
const techs = techStack.map(t => t.toLowerCase());
if (techs.includes('react'))
return 'React';
if (techs.includes('vue'))
return 'Vue';
if (techs.includes('svelte'))
return 'Svelte';
if (techs.includes('angular'))
return 'Angular';
if (techs.includes('express'))
return 'Express';
return 'None';
}
/**
* Smart README ingestion - extract only valuable context
*/
async function ingestReadme(readmePath) {
const fs = await Promise.resolve().then(() => __importStar(require('fs')));
const markdown = fs.readFileSync(readmePath, 'utf-8');
const context = markdownToContext(markdown);
return contextToFafData(context);
}
//# sourceMappingURL=markdown-to-context.js.map