Initial commit: pi-project-map skill scaffolding
- Design doc with full spec (dense markdown format, hybrid AST+LLM pipeline, consumption model, stale data mitigation) - Implementation plan with 6 milestones and rollout strategy - TypeScript package structure with all source stubs - CLI entry point, formatter, discover, init, patch, validate, extract, merge - Pi SKILL.md with tool definitions and format documentation
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
import { dirname, join } from 'path';
|
||||
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
||||
import { parsePackageMap, renderPackageMap } from './format.js';
|
||||
import { extractFileLLM } from './llm-extract.js';
|
||||
import { extractFileAST } from './ast-extract.js';
|
||||
import { mergeFileData } from './merge.js';
|
||||
import { readdirSync } from 'fs';
|
||||
|
||||
const SMALL_PACKAGE_THRESHOLD = 10;
|
||||
|
||||
export async function patchFile(filePath: string): Promise<void> {
|
||||
const dirPath = dirname(filePath);
|
||||
const mapPath = join(dirPath, '.pi-map.md');
|
||||
|
||||
if (!existsSync(mapPath)) {
|
||||
// No map exists yet — would need to generate from scratch
|
||||
console.warn(`No .pi-map.md found in ${dirPath}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const allFiles = readdirSync(dirPath).filter((f: string) => !f.startsWith('.') && !f.endsWith('.md'));
|
||||
const isSmallPackage = allFiles.length < SMALL_PACKAGE_THRESHOLD;
|
||||
|
||||
if (isSmallPackage) {
|
||||
// Full rewrite for small packages
|
||||
// TODO: import and reuse init logic for a single directory
|
||||
console.log(`Full rewrite of ${mapPath} (small package: ${allFiles.length} files)`);
|
||||
} else {
|
||||
// Section-level patch
|
||||
const existing = parsePackageMap(readFileSync(mapPath, 'utf8'));
|
||||
const llmData = await extractFileLLM(filePath);
|
||||
const astData = await extractFileAST(filePath);
|
||||
const fileName = filePath.split('/').pop()!;
|
||||
const updatedFile = mergeFileData(fileName, llmData, astData);
|
||||
|
||||
// Replace the matching file entry
|
||||
const idx = existing.files.findIndex(f => f.name === updatedFile.name);
|
||||
if (idx >= 0) {
|
||||
existing.files[idx] = updatedFile;
|
||||
} else {
|
||||
existing.files.push(updatedFile);
|
||||
}
|
||||
|
||||
existing.dirty = `${new Date().toISOString()}: ${fileName} patched (section-level)`;
|
||||
writeFileSync(mapPath, renderPackageMap(existing));
|
||||
console.log(`Patched ${mapPath}`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user