Spaces:
Running
Running
| import * as fs from 'node:fs'; | |
| import * as path from 'node:path'; | |
| import { log } from './logger.js'; | |
| import { getAssetsPath } from './assets-path.js'; | |
| export function generateTemplates(targetDir, type) { | |
| const absoluteDir = path.resolve(targetDir); | |
| if (!fs.existsSync(absoluteDir)) { | |
| return { success: false, filesCreated: [], error: `Target directory does not exist: ${targetDir}` }; | |
| } | |
| // Create .understand-anything directory structure | |
| const uaDir = path.join(absoluteDir, '.understand-anything'); | |
| const intermediateDir = path.join(uaDir, 'intermediate'); | |
| const tmpDir = path.join(uaDir, 'tmp'); | |
| fs.mkdirSync(intermediateDir, { recursive: true }); | |
| fs.mkdirSync(tmpDir, { recursive: true }); | |
| // Generate .understandignore if it doesn't exist | |
| const ignorePath = path.join(uaDir, '.understandignore'); | |
| if (!fs.existsSync(ignorePath)) { | |
| const ignoreContent = generateUnderstandIgnore(absoluteDir); | |
| fs.writeFileSync(ignorePath, ignoreContent, 'utf-8'); | |
| } | |
| const scriptsDir = getScriptsDir(type); | |
| const templates = getTemplatesForType(type); | |
| const allTemplates = templates; | |
| const filesCreated = []; | |
| // Files that should always be overwritten (steering files with knowledge graph docs) | |
| const alwaysOverwrite = new Set(['AGENTS.md', 'openspec/AGENTS.md', '.agent/AGENT.md', '.claude-plugin/plugin.json']); | |
| for (const template of allTemplates) { | |
| const filePath = path.join(absoluteDir, template.relativePath); | |
| const dir = path.dirname(filePath); | |
| if (!fs.existsSync(dir)) { | |
| fs.mkdirSync(dir, { recursive: true }); | |
| } | |
| if (fs.existsSync(filePath) && !alwaysOverwrite.has(template.relativePath)) { | |
| log('warn', `Skipping existing file: ${template.relativePath}`); | |
| continue; | |
| } | |
| // Replace {{SCRIPTS_DIR}} placeholder with actual path | |
| const content = template.content.replace(/\{\{SCRIPTS_DIR\}\}/g, scriptsDir); | |
| fs.writeFileSync(filePath, content, 'utf-8'); | |
| filesCreated.push(template.relativePath); | |
| } | |
| // Copy bundled asset files (Python scripts, frameworks, languages docs) | |
| const assetsCopied = copyAssetsToTarget(absoluteDir, type, scriptsDir); | |
| filesCreated.push(...assetsCopied); | |
| return { success: true, filesCreated }; | |
| } | |
| /** | |
| * Copy bundled asset files from dist/assets/ to the target project. | |
| * Maps asset paths to the correct location based on platform type. | |
| */ | |
| function copyAssetsToTarget(targetDir, type, scriptsDir) { | |
| let assetsPath; | |
| try { | |
| assetsPath = getAssetsPath(); | |
| } | |
| catch { | |
| log('warn', 'Assets directory not found β skipping bundled scripts/frameworks/languages copy'); | |
| return []; | |
| } | |
| const copied = []; | |
| const skillsBaseDir = getSkillsBaseDir(type); | |
| // Define asset mappings: source (relative to assets/) β target (relative to targetDir) | |
| const assetMappings = [ | |
| // agents definitions (referenced by skills) | |
| { srcDir: 'agents', destDir: `${skillsBaseDir}/understand/agents` }, | |
| // understand skill: scripts + frameworks + languages | |
| { srcDir: 'skills/understand', destDir: `${skillsBaseDir}/understand`, pattern: /\.(py|mjs)$/ }, | |
| { srcDir: 'skills/understand/frameworks', destDir: `${skillsBaseDir}/understand/frameworks` }, | |
| { srcDir: 'skills/understand/languages', destDir: `${skillsBaseDir}/understand/languages` }, | |
| // understand-domain script | |
| { srcDir: 'skills/understand-domain', destDir: `${skillsBaseDir}/understand-domain`, pattern: /\.py$/ }, | |
| // understand-knowledge scripts | |
| { srcDir: 'skills/understand-knowledge', destDir: `${skillsBaseDir}/understand-knowledge`, pattern: /\.py$/ }, | |
| // understand-baseline script | |
| { srcDir: 'skills/understand-baseline', destDir: `${skillsBaseDir}/understand-baseline`, pattern: /\.py$/ }, | |
| // understand-report script | |
| { srcDir: 'skills/understand-report', destDir: `${skillsBaseDir}/understand-report`, pattern: /\.py$/ }, | |
| // understand-mermaid script | |
| { srcDir: 'skills/understand-mermaid', destDir: `${skillsBaseDir}/understand-mermaid`, pattern: /\.py$/ }, | |
| // understand-export scripts + css | |
| { srcDir: 'skills/understand-export', destDir: `${skillsBaseDir}/understand-export`, pattern: /\.(py|css)$/ }, | |
| // hooks (auto-update prompt) | |
| { srcDir: 'hooks', destDir: `${skillsBaseDir}/understand/hooks`, pattern: /\.md$/ }, | |
| ]; | |
| for (const mapping of assetMappings) { | |
| const srcFullDir = path.join(assetsPath, mapping.srcDir); | |
| if (!fs.existsSync(srcFullDir)) | |
| continue; | |
| const entries = fs.readdirSync(srcFullDir, { withFileTypes: true }); | |
| for (const entry of entries) { | |
| if (!entry.isFile()) | |
| continue; | |
| if (mapping.pattern && !mapping.pattern.test(entry.name)) | |
| continue; | |
| // Skip SKILL.md β we generate those from templates | |
| if (entry.name === 'SKILL.md') | |
| continue; | |
| const srcFile = path.join(srcFullDir, entry.name); | |
| const relativeDest = `${mapping.destDir}/${entry.name}`; | |
| const destFile = path.join(targetDir, relativeDest); | |
| const destDir = path.dirname(destFile); | |
| if (!fs.existsSync(destDir)) { | |
| fs.mkdirSync(destDir, { recursive: true }); | |
| } | |
| fs.copyFileSync(srcFile, destFile); | |
| copied.push(relativeDest); | |
| } | |
| } | |
| return copied; | |
| } | |
| /** Get the skills base directory for each type (where skill subdirs go) */ | |
| function getSkillsBaseDir(type) { | |
| switch (type) { | |
| case 'kiro': return '.kiro/skills'; | |
| case 'codex': return '.codex/skills'; | |
| case 'opencode': return '.opencode/skills'; | |
| case 'claude-code': return '.claude-plugin/skills'; | |
| case 'openclaw': return '.agent/skills'; | |
| case 'cursor': return '.cursor/skills'; | |
| case 'openspec': return '.github/prompts'; | |
| } | |
| } | |
| /** Get the scripts directory path relative to project root for each type */ | |
| function getScriptsDir(type) { | |
| // Scripts now live inside skills directories | |
| const base = getSkillsBaseDir(type); | |
| return base; | |
| } | |
| /** | |
| * Generate .understandignore content based on the project's .gitignore and detected directories. | |
| * This runs deterministically without AI β saves tokens. | |
| */ | |
| function generateUnderstandIgnore(projectRoot) { | |
| const defaults = [ | |
| 'node_modules/', 'node_modules', '.git/', 'vendor/', 'venv/', '.venv/', | |
| '__pycache__/', 'dist/', 'dist', 'build/', 'build', 'out/', 'coverage/', | |
| 'coverage', '.next/', '.cache/', '.turbo/', 'target/', 'obj/', | |
| '*.lock', 'package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', | |
| '*.png', '*.jpg', '*.jpeg', '*.gif', '*.svg', '*.ico', | |
| '*.woff', '*.woff2', '*.ttf', '*.eot', | |
| '*.mp3', '*.mp4', '*.pdf', '*.zip', '*.tar', '*.gz', | |
| '*.min.js', '*.min.css', '*.map', '*.generated.*', | |
| '.idea/', '.vscode/', 'LICENSE', '.gitignore', '.editorconfig', | |
| '.prettierrc', '.eslintrc*', '*.log', | |
| ]; | |
| const norm = (p) => p.replace(/\/+$/, ''); | |
| const defaultSet = new Set(defaults.map(norm)); | |
| const header = [ | |
| '# .understandignore β patterns for files/dirs to exclude from analysis', | |
| '# Syntax: same as .gitignore (globs, # comments, ! negation, trailing / for dirs)', | |
| '# Lines below are suggestions β uncomment to activate.', | |
| '# Use ! prefix to force-include something excluded by defaults.', | |
| '#', | |
| '# Built-in defaults (always excluded unless negated):', | |
| '# node_modules/, .git/, dist/, build/, obj/, *.lock, *.min.js, etc.', | |
| '#', | |
| '', | |
| ].join('\n'); | |
| let body = ''; | |
| // Read .gitignore and add non-default patterns as suggestions | |
| const gitignorePath = path.join(projectRoot, '.gitignore'); | |
| if (fs.existsSync(gitignorePath)) { | |
| const gi = fs.readFileSync(gitignorePath, 'utf-8') | |
| .split('\n') | |
| .map(l => l.trim()) | |
| .filter(l => l && !l.startsWith('#')) | |
| .filter(p => !defaultSet.has(norm(p))); | |
| if (gi.length) { | |
| body += '# --- From .gitignore (uncomment to exclude) ---\n\n'; | |
| body += gi.map(p => '# ' + p).join('\n') + '\n\n'; | |
| } | |
| } | |
| // Detect common directories that might be excluded | |
| const dirs = ['__tests__', 'test', 'tests', 'fixtures', 'testdata', 'docs', 'examples', 'scripts', 'migrations', '.storybook']; | |
| const found = dirs.filter(d => fs.existsSync(path.join(projectRoot, d))); | |
| if (found.length) { | |
| body += '# --- Detected directories (uncomment to exclude) ---\n\n'; | |
| body += found.map(d => '# ' + d + '/').join('\n') + '\n\n'; | |
| } | |
| body += '# --- Test file patterns (uncomment to exclude) ---\n\n# *.test.*\n# *.spec.*\n# *.snap\n'; | |
| return header + body; | |
| } | |
| function getTemplatesForType(type) { | |
| switch (type) { | |
| case 'kiro': return getKiroTemplates(); | |
| case 'codex': return getCodexTemplates(); | |
| case 'opencode': return getOpenCodeTemplates(); | |
| case 'claude-code': return getClaudeCodeTemplates(); | |
| case 'openclaw': return getOpenClawTemplates(); | |
| case 'cursor': return getCursorTemplates(); | |
| case 'openspec': return getOpenSpecTemplates(); | |
| } | |
| } | |
| /** Scripts shared across all platform types β copied from dist/assets/ */ | |
| // Shared knowledge graph documentation content | |
| const GRAPH_DOCS = `## Knowledge Graph | |
| The knowledge graph is at \`.understand-anything/knowledge-graph.json\`. | |
| ### Structure | |
| - \`project\` β {name, description, languages, frameworks, analyzedAt, gitCommitHash} | |
| - \`nodes[]\` β {id, type, name, filePath, summary, tags[], complexity} | |
| - \`edges[]\` β {source, target, type, direction, weight} | |
| - \`layers[]\` β {id, name, description, nodeIds[]} | |
| - \`tour[]\` β {order, title, description, nodeIds[]} | |
| ### Node Types | |
| file, function, class, config, document, service, pipeline, table, schema, resource, endpoint | |
| ### Edge Types | |
| imports, contains, calls, depends_on, configures, deploys, triggers, documents, migrates, defines_schema | |
| ### Node ID Format | |
| - \`file:src/path.ts\` β source files | |
| - \`function:src/path.ts:funcName\` β functions | |
| - \`class:src/path.ts:ClassName\` β classes | |
| - \`config:tsconfig.json\` β configuration files | |
| - \`document:README.md\` β documentation files | |
| ### How to Use | |
| 1. Search the graph JSON for relevant nodes before reading source files | |
| 2. Follow edges to trace dependencies and understand relationships | |
| 3. Use layers to understand architectural boundaries | |
| 4. Reference tour steps for onboarding context | |
| `; | |
| const SKILL_UNDERSTAND_CHAT = `# understand-chat | |
| Answer questions about this codebase using the knowledge graph. | |
| ## Instructions | |
| 1. Check that \`.understand-anything/knowledge-graph.json\` exists | |
| 2. Search the graph for nodes matching the query keywords | |
| 3. Find connected edges (1-hop neighborhood) for context | |
| 4. Identify which architectural layers are relevant | |
| 5. Answer using specific file paths and relationships from the graph | |
| `; | |
| const SKILL_UNDERSTAND_DIFF = `# understand-diff | |
| Analyze code changes against the knowledge graph to identify affected components and risks. | |
| ## Instructions | |
| 1. Get changed files from git diff | |
| 2. Find matching nodes in the knowledge graph | |
| 3. Follow edges to find affected components (upstream callers, downstream dependencies) | |
| 4. Identify affected architectural layers | |
| 5. Provide risk assessment based on complexity and blast radius | |
| `; | |
| const SKILL_UNDERSTAND_DOMAIN = `# understand-domain | |
| Extract business domain knowledge from the codebase and identify domains, business flows, and process steps. | |
| ## Instructions | |
| 1. Check if \`.understand-anything/knowledge-graph.json\` exists | |
| 2. If it exists, derive domain knowledge from the graph (nodes, edges, layers) | |
| 3. If not, perform a lightweight scan: file tree + entry point detection | |
| 4. Identify business domains, flows (user journeys, data pipelines), and process steps | |
| 5. Map domains to architectural layers and code components | |
| 6. Output: list of domains, their flows, and which files/functions implement each step | |
| `; | |
| const SKILL_UNDERSTAND_EXPLAIN = `# understand-explain | |
| Provide a thorough, in-depth explanation of a specific file, function, or module. | |
| ## Instructions | |
| 1. Check that \`.understand-anything/knowledge-graph.json\` exists | |
| 2. Find the target node by searching for the file path or function name in the graph | |
| 3. Find all connected edges (incoming and outgoing) to build the component's neighborhood | |
| 4. Identify which architectural layer the component belongs to | |
| 5. Read the actual source file for deep-dive analysis | |
| 6. Explain: role in architecture, internal structure, external connections, data flow | |
| 7. Highlight patterns, idioms, or complexity worth understanding | |
| `; | |
| const SKILL_UNDERSTAND_KNOWLEDGE = `# understand-knowledge | |
| Analyze a knowledge base (wiki with markdown files and wikilinks) and generate a knowledge graph with entity extraction and topic clustering. | |
| ## Instructions | |
| 1. Detect the knowledge base format (markdown files with wikilinks, index.md, optional raw/ sources) | |
| 2. Parse all markdown files: extract wikilinks, headings, frontmatter | |
| 3. Build nodes for articles, topics (from index.md sections), and sources | |
| 4. Build edges from wikilinks (related), index categories (categorized_under) | |
| 5. Analyze articles for implicit relationships and entity extraction | |
| 6. Save the knowledge graph to \`.understand-anything/knowledge-graph.json\` | |
| `; | |
| const SKILL_UNDERSTAND_ONBOARD = `# understand-onboard | |
| Generate a comprehensive onboarding guide for new team members from the knowledge graph. | |
| ## Instructions | |
| 1. Check that \`.understand-anything/knowledge-graph.json\` exists | |
| 2. Read project metadata (name, languages, frameworks, description) | |
| 3. Read layers to understand architectural structure | |
| 4. Read the tour for the recommended learning path | |
| 5. Read file-level nodes to build a file map organized by layer | |
| 6. Identify complexity hotspots (high-complexity files) | |
| 7. Generate onboarding guide with: Project Overview, Architecture Layers, Key Concepts, Guided Tour, File Map, Complexity Hotspots | |
| 8. Offer to save as \`docs/ONBOARDING.md\` | |
| `; | |
| const SKILL_UNDERSTAND = `# understand | |
| Analyze the current codebase and produce a knowledge-graph.json file in \`.understand-anything/\`. | |
| This file powers all other understand-* skills by mapping the project's architecture, components, and relationships. | |
| ## Instructions | |
| 1. Scan the project directory to discover all source files, detect languages and frameworks | |
| 2. Batch files and analyze each batch to extract nodes (files, functions, classes) and edges (imports, calls, depends_on) | |
| 3. Merge batch results, deduplicate nodes and edges, remove dangling references | |
| 4. Identify architectural layers by grouping files based on directory structure and import patterns | |
| 5. Build a guided tour (learning path) through the codebase based on entry points and layers | |
| 6. Assemble the final knowledge graph JSON with: project metadata, nodes, edges, layers, tour | |
| 7. Write to \`.understand-anything/knowledge-graph.json\` | |
| 8. Write metadata to \`.understand-anything/meta.json\` (timestamp, git commit hash, version, file count) | |
| ## Options | |
| - \`--full\` β Force a full rebuild, ignoring any existing graph | |
| - \`--auto-update\` β Enable automatic graph updates on commit | |
| - \`--no-auto-update\` β Disable automatic graph updates | |
| - A directory path β Analyze the given directory instead of current working directory | |
| `; | |
| // (Steering content removed β now lives in SKILL.md files directly) | |
| const SKILL_UNDERSTAND_BASELINE = `# understand-baseline | |
| Create a baseline snapshot of spec files for later comparison and progress tracking. | |
| ## Instructions | |
| 1. Run: \`python {{SCRIPTS_DIR}}/understand-baseline/baseline.py\` | |
| 2. Optionally add a label: \`python {{SCRIPTS_DIR}}/understand-baseline/baseline.py --label "v1.0"\` | |
| 3. To list all baselines: \`python {{SCRIPTS_DIR}}/understand-baseline/baseline.py --list\` | |
| 4. Baselines are saved to \`baselines/{timestamp}/\` with metadata | |
| `; | |
| const SKILL_UNDERSTAND_REPORT = `# understand-report | |
| Generate a progress report comparing current spec files against the most recent baseline. | |
| ## Instructions | |
| 1. Run: \`python {{SCRIPTS_DIR}}/understand-report/report.py\` | |
| 2. Report includes: file changes, requirements count, task progress, velocity, ETA | |
| 3. Reports are saved to \`reports/{timestamp}.md\` | |
| 4. Compare with specific baseline: \`python {{SCRIPTS_DIR}}/understand-report/report.py --baseline TIMESTAMP\` | |
| 5. Requires at least one baseline (run understand-baseline first) | |
| `; | |
| const SKILL_UNDERSTAND_MERMAID = `# understand-mermaid | |
| Render Mermaid diagrams from diagrams.mermaid.md to PNG images offline. | |
| ## Instructions | |
| 1. Run: \`python {{SCRIPTS_DIR}}/understand-mermaid/render_mermaid.py\` | |
| 2. Reads \`diagrams.mermaid.md\` and extracts mermaid code blocks | |
| 3. Renders each to PNG in \`images/diagrams/diagram_XX.png\` | |
| 4. Single diagram: \`python {{SCRIPTS_DIR}}/understand-mermaid/render_mermaid.py --only 01\` | |
| 5. Requires: \`npm install -g @mermaid-js/mermaid-cli\` | |
| `; | |
| const SKILL_UNDERSTAND_EXPORT = `# understand-export | |
| Export spec markdown files to PDF with styled formatting. | |
| ## Instructions | |
| 1. Run: \`python {{SCRIPTS_DIR}}/understand-export/md_to_pdf.py\` | |
| 2. Converts all .md spec files to PDF in \`pdf/\` folder | |
| 3. Single file: \`python {{SCRIPTS_DIR}}/understand-export/md_to_pdf.py design.md\` | |
| 4. Format: A4 landscape, page numbers, styled tables, embedded images | |
| 5. Requires: \`npm install -g md-to-pdf\` | |
| `; | |
| // ============================================================ | |
| // KIRO β .kiro/steering/, .kiro/skills/, .kiro/hooks/ | |
| // ============================================================ | |
| function getKiroTemplates() { | |
| return [ | |
| { | |
| relativePath: '.kiro/steering/understand-project.md', | |
| content: `--- | |
| inclusion: auto | |
| --- | |
| # Project Understanding | |
| This project has a knowledge graph that maps its architecture, components, and relationships. | |
| Use it to answer questions about the codebase without reading every source file. | |
| ${GRAPH_DOCS} | |
| `, | |
| }, | |
| { | |
| relativePath: '.kiro/skills/understand.md', | |
| content: `--- | |
| inclusion: manual | |
| --- | |
| ${SKILL_UNDERSTAND}`, | |
| }, | |
| { | |
| relativePath: '.kiro/skills/understand-chat.md', | |
| content: `--- | |
| inclusion: manual | |
| --- | |
| ${SKILL_UNDERSTAND_CHAT}`, | |
| }, | |
| { | |
| relativePath: '.kiro/skills/understand-diff.md', | |
| content: `--- | |
| inclusion: manual | |
| --- | |
| ${SKILL_UNDERSTAND_DIFF}`, | |
| }, | |
| { | |
| relativePath: '.kiro/skills/understand-domain.md', | |
| content: `--- | |
| inclusion: manual | |
| --- | |
| ${SKILL_UNDERSTAND_DOMAIN}`, | |
| }, | |
| { | |
| relativePath: '.kiro/skills/understand-explain.md', | |
| content: `--- | |
| inclusion: manual | |
| --- | |
| ${SKILL_UNDERSTAND_EXPLAIN}`, | |
| }, | |
| { | |
| relativePath: '.kiro/skills/understand-knowledge.md', | |
| content: `--- | |
| inclusion: manual | |
| --- | |
| ${SKILL_UNDERSTAND_KNOWLEDGE}`, | |
| }, | |
| { | |
| relativePath: '.kiro/skills/understand-onboard.md', | |
| content: `--- | |
| inclusion: manual | |
| --- | |
| ${SKILL_UNDERSTAND_ONBOARD}`, | |
| }, | |
| { | |
| relativePath: '.kiro/skills/understand-baseline.md', | |
| content: `--- | |
| inclusion: manual | |
| --- | |
| ${SKILL_UNDERSTAND_BASELINE}`, | |
| }, | |
| { | |
| relativePath: '.kiro/skills/understand-report.md', | |
| content: `--- | |
| inclusion: manual | |
| --- | |
| ${SKILL_UNDERSTAND_REPORT}`, | |
| }, | |
| { | |
| relativePath: '.kiro/skills/understand-mermaid.md', | |
| content: `--- | |
| inclusion: manual | |
| --- | |
| ${SKILL_UNDERSTAND_MERMAID}`, | |
| }, | |
| { | |
| relativePath: '.kiro/skills/understand-export.md', | |
| content: `--- | |
| inclusion: manual | |
| --- | |
| ${SKILL_UNDERSTAND_EXPORT}`, | |
| }, | |
| { | |
| relativePath: '.kiro/hooks/post-commit-update.json', | |
| content: JSON.stringify({ | |
| name: 'Auto-update knowledge graph', | |
| version: '1.0.0', | |
| description: 'Checks if knowledge graph needs updating after code changes', | |
| when: { | |
| type: 'userTriggered', | |
| }, | |
| then: { | |
| type: 'askAgent', | |
| prompt: 'Check if .understand-anything/knowledge-graph.json exists and if the git commit hash in .understand-anything/meta.json differs from HEAD. If so, suggest running the knowledge graph update.', | |
| }, | |
| }, null, 2) + '\n', | |
| }, | |
| { | |
| relativePath: '.kiro/hooks/baseline-spec.json', | |
| content: JSON.stringify({ | |
| name: 'Baseline Spec Status', | |
| version: '1.0.0', | |
| description: 'Create a baseline snapshot of all spec files for later comparison', | |
| when: { type: 'userTriggered' }, | |
| then: { type: 'runCommand', command: 'python {{SCRIPTS_DIR}}/understand-baseline/baseline.py', timeout: 30 }, | |
| }, null, 2) + '\n', | |
| }, | |
| { | |
| relativePath: '.kiro/hooks/spec-progress-report.json', | |
| content: JSON.stringify({ | |
| name: 'Spec Progress Report', | |
| version: '1.0.0', | |
| description: 'Generate a progress report comparing current spec against the most recent baseline', | |
| when: { type: 'userTriggered' }, | |
| then: { type: 'runCommand', command: 'python {{SCRIPTS_DIR}}/understand-report/report.py', timeout: 30 }, | |
| }, null, 2) + '\n', | |
| }, | |
| { | |
| relativePath: '.kiro/hooks/export-spec-pdf.json', | |
| content: JSON.stringify({ | |
| name: 'Export Spec to PDF', | |
| version: '1.0.0', | |
| description: 'Export all spec markdown files to PDF', | |
| when: { type: 'userTriggered' }, | |
| then: { type: 'runCommand', command: 'python {{SCRIPTS_DIR}}/understand-export/md_to_pdf.py', timeout: 300 }, | |
| }, null, 2) + '\n', | |
| }, | |
| { | |
| relativePath: '.kiro/hooks/render-mermaid-diagrams.json', | |
| content: JSON.stringify({ | |
| name: 'Render Mermaid Diagrams', | |
| version: '1.0.0', | |
| description: 'Render Mermaid diagrams to PNG when diagrams.mermaid.md is edited', | |
| when: { type: 'fileEdited', patterns: ['**/diagrams.mermaid.md'] }, | |
| then: { type: 'runCommand', command: 'python {{SCRIPTS_DIR}}/understand-mermaid/render_mermaid.py', timeout: 120 }, | |
| }, null, 2) + '\n', | |
| }, | |
| ]; | |
| } | |
| // ============================================================ | |
| // CODEX (OpenAI) β AGENTS.md + .codex/skills/ | |
| // ============================================================ | |
| function getCodexTemplates() { | |
| return [ | |
| { | |
| relativePath: 'AGENTS.md', | |
| content: `# Project Agent Instructions | |
| This project has a knowledge graph that maps its architecture, components, and relationships. | |
| Use it to answer questions about the codebase without reading every source file. | |
| ${GRAPH_DOCS} | |
| `, | |
| }, | |
| { | |
| relativePath: '.codex/skills/understand.md', | |
| content: SKILL_UNDERSTAND, | |
| }, | |
| { | |
| relativePath: '.codex/skills/understand-chat.md', | |
| content: SKILL_UNDERSTAND_CHAT, | |
| }, | |
| { | |
| relativePath: '.codex/skills/understand-diff.md', | |
| content: SKILL_UNDERSTAND_DIFF, | |
| }, | |
| { | |
| relativePath: '.codex/skills/understand-domain.md', | |
| content: SKILL_UNDERSTAND_DOMAIN, | |
| }, | |
| { | |
| relativePath: '.codex/skills/understand-explain.md', | |
| content: SKILL_UNDERSTAND_EXPLAIN, | |
| }, | |
| { | |
| relativePath: '.codex/skills/understand-knowledge.md', | |
| content: SKILL_UNDERSTAND_KNOWLEDGE, | |
| }, | |
| { | |
| relativePath: '.codex/skills/understand-onboard.md', | |
| content: SKILL_UNDERSTAND_ONBOARD, | |
| }, | |
| { | |
| relativePath: '.codex/skills/understand-baseline.md', | |
| content: SKILL_UNDERSTAND_BASELINE, | |
| }, | |
| { | |
| relativePath: '.codex/skills/understand-report.md', | |
| content: SKILL_UNDERSTAND_REPORT, | |
| }, | |
| { | |
| relativePath: '.codex/skills/understand-mermaid.md', | |
| content: SKILL_UNDERSTAND_MERMAID, | |
| }, | |
| { | |
| relativePath: '.codex/skills/understand-export.md', | |
| content: SKILL_UNDERSTAND_EXPORT, | |
| }, | |
| ]; | |
| } | |
| // ============================================================ | |
| // OPENCODE β .opencode/skills/ + AGENTS.md | |
| // ============================================================ | |
| function getOpenCodeTemplates() { | |
| return [ | |
| { | |
| relativePath: 'AGENTS.md', | |
| content: `# Project Agent Instructions | |
| This project has a knowledge graph that maps its architecture, components, and relationships. | |
| Use it to answer questions about the codebase without reading every source file. | |
| ${GRAPH_DOCS} | |
| `, | |
| }, | |
| { | |
| relativePath: '.opencode/skills/understand/SKILL.md', | |
| content: SKILL_UNDERSTAND, | |
| }, | |
| { | |
| relativePath: '.opencode/skills/understand-chat/SKILL.md', | |
| content: SKILL_UNDERSTAND_CHAT, | |
| }, | |
| { | |
| relativePath: '.opencode/skills/understand-diff/SKILL.md', | |
| content: SKILL_UNDERSTAND_DIFF, | |
| }, | |
| { | |
| relativePath: '.opencode/skills/understand-domain/SKILL.md', | |
| content: SKILL_UNDERSTAND_DOMAIN, | |
| }, | |
| { | |
| relativePath: '.opencode/skills/understand-explain/SKILL.md', | |
| content: SKILL_UNDERSTAND_EXPLAIN, | |
| }, | |
| { | |
| relativePath: '.opencode/skills/understand-knowledge/SKILL.md', | |
| content: SKILL_UNDERSTAND_KNOWLEDGE, | |
| }, | |
| { | |
| relativePath: '.opencode/skills/understand-onboard/SKILL.md', | |
| content: SKILL_UNDERSTAND_ONBOARD, | |
| }, | |
| { | |
| relativePath: '.opencode/skills/understand-baseline/SKILL.md', | |
| content: SKILL_UNDERSTAND_BASELINE, | |
| }, | |
| { | |
| relativePath: '.opencode/skills/understand-report/SKILL.md', | |
| content: SKILL_UNDERSTAND_REPORT, | |
| }, | |
| { | |
| relativePath: '.opencode/skills/understand-mermaid/SKILL.md', | |
| content: SKILL_UNDERSTAND_MERMAID, | |
| }, | |
| { | |
| relativePath: '.opencode/skills/understand-export/SKILL.md', | |
| content: SKILL_UNDERSTAND_EXPORT, | |
| }, | |
| ]; | |
| } | |
| // ============================================================ | |
| // CLAUDE CODE β .claude-plugin/ with plugin.json + skills/ + hooks | |
| // ============================================================ | |
| function getClaudeCodeTemplates() { | |
| return [ | |
| { | |
| relativePath: '.claude-plugin/plugin.json', | |
| content: JSON.stringify({ | |
| name: 'project-understand', | |
| version: '1.0.0', | |
| description: 'Knowledge graph-powered project understanding', | |
| skills: [ | |
| 'skills/understand', | |
| 'skills/understand-chat', | |
| 'skills/understand-diff', | |
| 'skills/understand-domain', | |
| 'skills/understand-explain', | |
| 'skills/understand-knowledge', | |
| 'skills/understand-onboard', | |
| 'skills/understand-baseline', | |
| 'skills/understand-report', | |
| 'skills/understand-mermaid', | |
| 'skills/understand-export', | |
| ], | |
| hooks: { | |
| PostToolUse: [ | |
| { | |
| matcher: 'Bash', | |
| hooks: [ | |
| { | |
| type: 'command', | |
| command: 'echo "[project-understand] Check if knowledge graph needs updating after code changes"', | |
| }, | |
| ], | |
| }, | |
| ], | |
| }, | |
| }, null, 2) + '\n', | |
| }, | |
| { | |
| relativePath: '.claude-plugin/skills/understand/SKILL.md', | |
| content: `--- | |
| name: understand | |
| description: Analyze the codebase and produce a knowledge-graph.json | |
| argument-hint: [path] [--full|--auto-update] | |
| --- | |
| ${SKILL_UNDERSTAND}`, | |
| }, | |
| { | |
| relativePath: '.claude-plugin/skills/understand-chat/SKILL.md', | |
| content: `--- | |
| name: understand-chat | |
| description: Answer questions about the codebase using the knowledge graph | |
| argument-hint: [query] | |
| --- | |
| ${SKILL_UNDERSTAND_CHAT}`, | |
| }, | |
| { | |
| relativePath: '.claude-plugin/skills/understand-diff/SKILL.md', | |
| content: `--- | |
| name: understand-diff | |
| description: Analyze code changes against the knowledge graph | |
| --- | |
| ${SKILL_UNDERSTAND_DIFF}`, | |
| }, | |
| { | |
| relativePath: '.claude-plugin/skills/understand-domain/SKILL.md', | |
| content: `--- | |
| name: understand-domain | |
| description: Extract business domain knowledge from the codebase | |
| argument-hint: [--full] | |
| --- | |
| ${SKILL_UNDERSTAND_DOMAIN}`, | |
| }, | |
| { | |
| relativePath: '.claude-plugin/skills/understand-explain/SKILL.md', | |
| content: `--- | |
| name: understand-explain | |
| description: Deep-dive explanation of a specific file, function, or module | |
| argument-hint: [file-path] | |
| --- | |
| ${SKILL_UNDERSTAND_EXPLAIN}`, | |
| }, | |
| { | |
| relativePath: '.claude-plugin/skills/understand-knowledge/SKILL.md', | |
| content: `--- | |
| name: understand-knowledge | |
| description: Analyze a knowledge base and generate a knowledge graph | |
| argument-hint: [wiki-directory] | |
| --- | |
| ${SKILL_UNDERSTAND_KNOWLEDGE}`, | |
| }, | |
| { | |
| relativePath: '.claude-plugin/skills/understand-onboard/SKILL.md', | |
| content: `--- | |
| name: understand-onboard | |
| description: Generate an onboarding guide for new team members | |
| --- | |
| ${SKILL_UNDERSTAND_ONBOARD}`, | |
| }, | |
| { | |
| relativePath: '.claude-plugin/skills/understand-baseline/SKILL.md', | |
| content: `--- | |
| name: understand-baseline | |
| description: Create a baseline snapshot of spec files | |
| argument-hint: [--list|--label "name"] | |
| --- | |
| ${SKILL_UNDERSTAND_BASELINE}`, | |
| }, | |
| { | |
| relativePath: '.claude-plugin/skills/understand-report/SKILL.md', | |
| content: `--- | |
| name: understand-report | |
| description: Generate progress report comparing against baseline | |
| argument-hint: [--baseline TIMESTAMP] | |
| --- | |
| ${SKILL_UNDERSTAND_REPORT}`, | |
| }, | |
| { | |
| relativePath: '.claude-plugin/skills/understand-mermaid/SKILL.md', | |
| content: `--- | |
| name: understand-mermaid | |
| description: Render Mermaid diagrams to PNG offline | |
| argument-hint: [--only NN] | |
| --- | |
| ${SKILL_UNDERSTAND_MERMAID}`, | |
| }, | |
| { | |
| relativePath: '.claude-plugin/skills/understand-export/SKILL.md', | |
| content: `--- | |
| name: understand-export | |
| description: Export spec markdown files to PDF | |
| argument-hint: [filename.md] | |
| --- | |
| ${SKILL_UNDERSTAND_EXPORT}`, | |
| }, | |
| ]; | |
| } | |
| // ============================================================ | |
| // OPENCLAW β .agent/AGENT.md + .agent/skills/ + .agent/hooks/ | |
| // ============================================================ | |
| function getOpenClawTemplates() { | |
| return [ | |
| { | |
| relativePath: '.agent/AGENT.md', | |
| content: `# Project Agent Instructions | |
| This project has a knowledge graph that maps its architecture, components, and relationships. | |
| Use it to answer questions about the codebase without reading every source file. | |
| ${GRAPH_DOCS} | |
| `, | |
| }, | |
| { | |
| relativePath: '.agent/skills/understand/SKILL.md', | |
| content: SKILL_UNDERSTAND, | |
| }, | |
| { | |
| relativePath: '.agent/skills/understand-chat/SKILL.md', | |
| content: SKILL_UNDERSTAND_CHAT, | |
| }, | |
| { | |
| relativePath: '.agent/skills/understand-diff/SKILL.md', | |
| content: SKILL_UNDERSTAND_DIFF, | |
| }, | |
| { | |
| relativePath: '.agent/skills/understand-domain/SKILL.md', | |
| content: SKILL_UNDERSTAND_DOMAIN, | |
| }, | |
| { | |
| relativePath: '.agent/skills/understand-explain/SKILL.md', | |
| content: SKILL_UNDERSTAND_EXPLAIN, | |
| }, | |
| { | |
| relativePath: '.agent/skills/understand-knowledge/SKILL.md', | |
| content: SKILL_UNDERSTAND_KNOWLEDGE, | |
| }, | |
| { | |
| relativePath: '.agent/skills/understand-onboard/SKILL.md', | |
| content: SKILL_UNDERSTAND_ONBOARD, | |
| }, | |
| { | |
| relativePath: '.agent/skills/understand-baseline/SKILL.md', | |
| content: SKILL_UNDERSTAND_BASELINE, | |
| }, | |
| { | |
| relativePath: '.agent/skills/understand-report/SKILL.md', | |
| content: SKILL_UNDERSTAND_REPORT, | |
| }, | |
| { | |
| relativePath: '.agent/skills/understand-mermaid/SKILL.md', | |
| content: SKILL_UNDERSTAND_MERMAID, | |
| }, | |
| { | |
| relativePath: '.agent/skills/understand-export/SKILL.md', | |
| content: SKILL_UNDERSTAND_EXPORT, | |
| }, | |
| { | |
| relativePath: '.agent/hooks/post-commit-update.md', | |
| content: `# Post-Commit: Update Knowledge Graph | |
| ## Trigger | |
| PostToolUse β after git commit, merge, or rebase | |
| ## Condition | |
| - \`.understand-anything/knowledge-graph.json\` exists | |
| - \`.understand-anything/meta.json\` exists | |
| - Git commit hash in meta.json differs from current HEAD | |
| ## Action | |
| Suggest running knowledge graph update to reflect structural changes. | |
| `, | |
| }, | |
| { | |
| relativePath: '.agent/hooks/baseline-spec.md', | |
| content: `# Baseline Spec Status | |
| ## Trigger | |
| UserTriggered β when user says "baseline" or "snapshot spec" | |
| ## Action | |
| Run: \`python {{SCRIPTS_DIR}}/understand-baseline/baseline.py\` | |
| Creates a timestamped snapshot of all spec files in baselines/ folder. | |
| `, | |
| }, | |
| { | |
| relativePath: '.agent/hooks/render-mermaid.md', | |
| content: `# Render Mermaid Diagrams | |
| ## Trigger | |
| FileEdited β when \`**/diagrams.mermaid.md\` is modified | |
| ## Action | |
| Run: \`python {{SCRIPTS_DIR}}/understand-mermaid/render_mermaid.py\` | |
| Renders all Mermaid diagrams to PNG in images/diagrams/ folder. | |
| `, | |
| }, | |
| ]; | |
| } | |
| // ============================================================ | |
| // CURSOR β .cursor/rules/ (no official skills, uses rules + tools.json) | |
| // ============================================================ | |
| function getCursorTemplates() { | |
| return [ | |
| { | |
| relativePath: '.cursor/rules/understand-project.mdc', | |
| content: `--- | |
| description: Project understanding via knowledge graph | |
| globs: | |
| alwaysApply: true | |
| --- | |
| # Project Understanding | |
| This project has a knowledge graph that maps its architecture, components, and relationships. | |
| Use it to answer questions about the codebase without reading every source file. | |
| ${GRAPH_DOCS} | |
| `, | |
| }, | |
| { | |
| relativePath: '.cursor/rules/understand-conventions.mdc', | |
| content: `--- | |
| description: Conventions for working with the knowledge graph | |
| globs: | |
| alwaysApply: false | |
| --- | |
| # Knowledge Graph Conventions | |
| ## After Structural Changes | |
| If files are added/removed/renamed or exports change significantly, the knowledge graph at \`.understand-anything/knowledge-graph.json\` may need regeneration. | |
| ## Utility Scripts | |
| - Baseline spec: \`python {{SCRIPTS_DIR}}/understand-baseline/baseline.py\` | |
| - Progress report: \`python {{SCRIPTS_DIR}}/understand-report/report.py\` | |
| - Render diagrams: \`python {{SCRIPTS_DIR}}/understand-mermaid/render_mermaid.py\` | |
| - Export PDF: \`python {{SCRIPTS_DIR}}/understand-export/md_to_pdf.py\` | |
| `, | |
| }, | |
| ]; | |
| } | |
| // ============================================================ | |
| // OPENSPEC β openspec/AGENTS.md + .github/instructions/ + .github/prompts/ | |
| // ============================================================ | |
| function getOpenSpecTemplates() { | |
| return [ | |
| { | |
| relativePath: 'openspec/AGENTS.md', | |
| content: `# Project Agent Instructions | |
| This project has a knowledge graph that maps its architecture, components, and relationships. | |
| Use it to answer questions about the codebase without reading every source file. | |
| ${GRAPH_DOCS} | |
| `, | |
| }, | |
| { | |
| relativePath: '.github/instructions/understand-project.instructions.md', | |
| content: `# Project Understanding Instructions | |
| This project has a knowledge graph at \`.understand-anything/knowledge-graph.json\`. | |
| ### How to Use | |
| 1. Search the JSON for relevant nodes before reading source files | |
| 2. Node summaries provide quick understanding of each component | |
| 3. Follow edges to trace dependency chains | |
| 4. Use layers to understand architectural boundaries | |
| ### Node ID Conventions | |
| - \`file:src/path.ts\` β source files | |
| - \`function:src/path.ts:funcName\` β functions | |
| - \`class:src/path.ts:ClassName\` β classes | |
| - \`config:tsconfig.json\` β configuration files | |
| - \`document:README.md\` β documentation files | |
| `, | |
| }, | |
| { | |
| relativePath: '.github/prompts/understand.prompt.md', | |
| content: SKILL_UNDERSTAND, | |
| }, | |
| { | |
| relativePath: '.github/prompts/understand-chat.prompt.md', | |
| content: SKILL_UNDERSTAND_CHAT, | |
| }, | |
| { | |
| relativePath: '.github/prompts/understand-diff.prompt.md', | |
| content: SKILL_UNDERSTAND_DIFF, | |
| }, | |
| { | |
| relativePath: '.github/prompts/understand-domain.prompt.md', | |
| content: SKILL_UNDERSTAND_DOMAIN, | |
| }, | |
| { | |
| relativePath: '.github/prompts/understand-explain.prompt.md', | |
| content: SKILL_UNDERSTAND_EXPLAIN, | |
| }, | |
| { | |
| relativePath: '.github/prompts/understand-knowledge.prompt.md', | |
| content: SKILL_UNDERSTAND_KNOWLEDGE, | |
| }, | |
| { | |
| relativePath: '.github/prompts/understand-onboard.prompt.md', | |
| content: SKILL_UNDERSTAND_ONBOARD, | |
| }, | |
| { | |
| relativePath: '.github/prompts/understand-baseline.prompt.md', | |
| content: SKILL_UNDERSTAND_BASELINE, | |
| }, | |
| { | |
| relativePath: '.github/prompts/understand-report.prompt.md', | |
| content: SKILL_UNDERSTAND_REPORT, | |
| }, | |
| { | |
| relativePath: '.github/prompts/understand-mermaid.prompt.md', | |
| content: SKILL_UNDERSTAND_MERMAID, | |
| }, | |
| { | |
| relativePath: '.github/prompts/understand-export.prompt.md', | |
| content: SKILL_UNDERSTAND_EXPORT, | |
| }, | |
| ]; | |
| } | |