UNPKG

codecanon

Version:

CLI tool that downloads documentation from 3rd party libraries, converts them to Markdown, and optimizes for LLMs

104 lines (102 loc) 3.51 kB
import { promises as fs } from "fs"; import { join } from "path"; const CANON_DIR = ".canon"; const SETTINGS_FILE = "settings.json"; const LOCAL_SETTINGS_FILE = "settings.local.json"; /** * Initialize a new CodeCanon workspace */ export async function initWorkspace(options) { const canonPath = join(options.cwd, CANON_DIR); const settingsPath = join(canonPath, SETTINGS_FILE); // Check if workspace already exists try { await fs.access(canonPath); if (!options.force) { throw new Error(`CodeCanon workspace already exists at ${canonPath}. Use --force to overwrite.`); } } catch (error) { // Directory doesn't exist, which is fine } // Create directory structure await fs.mkdir(canonPath, { recursive: true }); await fs.mkdir(join(canonPath, "cache"), { recursive: true }); await fs.mkdir(join(canonPath, "context"), { recursive: true }); await fs.mkdir(join(canonPath, "db"), { recursive: true }); // Create initial config const config = { version: "0.0.2", model: options.model, createdAt: new Date().toISOString(), packages: [], }; await fs.writeFile(settingsPath, JSON.stringify(config, null, 2)); // Create initial llms.txt following the emerging standard const llmsTxtPath = join(canonPath, "context", "llms.txt"); const llmsTxtContent = `# CodeCanon Context Index # This file follows the llms.txt standard for LLM context discovery # Generated on ${new Date().toISOString()} # No packages added yet. Use 'canon add <package>' to get started. `; await fs.writeFile(llmsTxtPath, llmsTxtContent); } /** * Load workspace configuration */ export async function loadWorkspaceConfig(cwd) { const settingsPath = join(cwd, CANON_DIR, SETTINGS_FILE); const localSettingsPath = join(cwd, CANON_DIR, LOCAL_SETTINGS_FILE); try { // Load base settings const settingsData = await fs.readFile(settingsPath, "utf-8"); const config = JSON.parse(settingsData); // Try to load local settings and merge them try { const localSettingsData = await fs.readFile(localSettingsPath, "utf-8"); const localConfig = JSON.parse(localSettingsData); return { ...config, ...localConfig }; } catch { // Local settings file doesn't exist or is invalid, use base settings return config; } } catch (error) { throw new Error("No CodeCanon workspace found. Run 'canon init' to create one."); } } /** * Save workspace configuration */ export async function saveWorkspaceConfig(cwd, config) { const settingsPath = join(cwd, CANON_DIR, SETTINGS_FILE); await fs.writeFile(settingsPath, JSON.stringify(config, null, 2)); } /** * Check if workspace is initialized */ export async function isWorkspaceInitialized(cwd) { try { await fs.access(join(cwd, CANON_DIR, SETTINGS_FILE)); return true; } catch { return false; } } /** * Get paths for the workspace */ export function getWorkspacePaths(cwd) { const canonPath = join(cwd, CANON_DIR); return { root: canonPath, cache: join(canonPath, "cache"), context: join(canonPath, "context"), db: join(canonPath, "db"), settings: join(canonPath, SETTINGS_FILE), localSettings: join(canonPath, LOCAL_SETTINGS_FILE), llmsTxt: join(canonPath, "context", "llms.txt"), }; }