knowledge-graph-preview / cli /template-generator.js
mr4's picture
Upload 136 files
fd8cdf5 verified
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,
},
];
}