@chrisdudek/yg 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +12 -2
- package/dist/bin.js.map +1 -1
- package/dist/templates/rules.ts +4 -0
- package/package.json +1 -1
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bin.ts","../src/cli/init.ts","../src/templates/default-config.ts","../src/templates/platform.ts","../src/templates/rules.ts","../src/core/graph-loader.ts","../src/io/config-parser.ts","../src/io/node-parser.ts","../src/io/aspect-parser.ts","../src/io/artifact-reader.ts","../src/io/flow-parser.ts","../src/io/schema-parser.ts","../src/utils/paths.ts","../src/core/context-builder.ts","../src/utils/tokens.ts","../src/core/validator.ts","../src/formatters/context-text.ts","../src/cli/build-context.ts","../src/cli/validate.ts","../src/cli/drift.ts","../src/io/drift-state-store.ts","../src/utils/hash.ts","../src/core/context-files.ts","../src/core/drift-detector.ts","../src/cli/drift-sync.ts","../src/cli/status.ts","../src/cli/tree.ts","../src/cli/owner.ts","../src/core/dependency-resolver.ts","../src/cli/deps.ts","../src/core/graph-from-git.ts","../src/cli/impact.ts","../src/cli/aspects.ts","../src/cli/flows.ts","../src/io/journal-store.ts","../src/cli/journal-add.ts","../src/cli/journal-read.ts","../src/cli/journal-archive.ts","../src/cli/preflight.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { registerInitCommand } from './cli/init.js';\nimport { registerBuildCommand } from './cli/build-context.js';\nimport { registerValidateCommand } from './cli/validate.js';\nimport { registerDriftCommand } from './cli/drift.js';\nimport { registerDriftSyncCommand } from './cli/drift-sync.js';\nimport { registerStatusCommand } from './cli/status.js';\nimport { registerTreeCommand } from './cli/tree.js';\nimport { registerOwnerCommand } from './cli/owner.js';\nimport { registerDepsCommand } from './cli/deps.js';\nimport { registerImpactCommand } from './cli/impact.js';\nimport { registerAspectsCommand } from './cli/aspects.js';\nimport { registerFlowsCommand } from './cli/flows.js';\nimport { registerJournalAddCommand } from './cli/journal-add.js';\nimport { registerJournalReadCommand } from './cli/journal-read.js';\nimport { registerJournalArchiveCommand } from './cli/journal-archive.js';\nimport { registerPreflightCommand } from './cli/preflight.js';\nimport { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));\n\nconst program = new Command();\n\nprogram\n .name('yg')\n .description('Yggdrasil — architectural knowledge infrastructure for AI agents')\n .version(pkg.version);\n\nregisterInitCommand(program);\nregisterBuildCommand(program);\nregisterValidateCommand(program);\nregisterDriftCommand(program);\nregisterDriftSyncCommand(program);\nregisterStatusCommand(program);\nregisterTreeCommand(program);\nregisterOwnerCommand(program);\nregisterDepsCommand(program);\nregisterImpactCommand(program);\nregisterAspectsCommand(program);\nregisterFlowsCommand(program);\nregisterJournalAddCommand(program);\nregisterJournalReadCommand(program);\nregisterJournalArchiveCommand(program);\nregisterPreflightCommand(program);\n\nprogram.parse();\n","import { Command } from 'commander';\nimport { mkdir, writeFile, readdir, readFile, stat } from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { DEFAULT_CONFIG } from '../templates/default-config.js';\nimport { installRulesForPlatform, PLATFORMS, type Platform } from '../templates/platform.js';\n\nfunction getGraphSchemasDir(): string {\n const currentDir = path.dirname(fileURLToPath(import.meta.url));\n const packageRoot = path.join(currentDir, '..');\n return path.join(packageRoot, 'graph-schemas');\n}\n\nconst GITIGNORE_CONTENT = `.journal.yaml\n.drift-state\njournals-archive/\n`;\n\nexport function registerInitCommand(program: Command): void {\n program\n .command('init')\n .description('Initialize Yggdrasil graph in current project')\n .option(\n '--platform <name>',\n 'Agent platform: cursor, claude-code, copilot, cline, roocode, codex, windsurf, aider, gemini, amp, generic',\n 'generic',\n )\n .option('--upgrade', 'Refresh rules only (when .yggdrasil/ already exists)')\n .action(async (options: { platform?: string; upgrade?: boolean }) => {\n const projectRoot = process.cwd();\n const yggRoot = path.join(projectRoot, '.yggdrasil');\n\n let upgradeMode = false;\n try {\n const statResult = await stat(yggRoot);\n if (!statResult.isDirectory()) {\n process.stderr.write('Error: .yggdrasil exists but is not a directory.\\n');\n process.exit(1);\n }\n if (options.upgrade) {\n upgradeMode = true;\n } else {\n process.stderr.write(\n 'Error: .yggdrasil/ already exists. Use --upgrade to refresh rules only.\\n',\n );\n process.exit(1);\n }\n } catch {\n // Directory does not exist — proceed with full init\n }\n\n const platform = (options.platform ?? 'generic') as Platform;\n if (!PLATFORMS.includes(platform)) {\n process.stderr.write(\n `Error: Unknown platform '${platform}'. Use: ${PLATFORMS.join(', ')}\\n`,\n );\n process.exit(1);\n }\n\n if (upgradeMode) {\n const rulesPath = await installRulesForPlatform(projectRoot, platform);\n process.stdout.write('✓ Rules refreshed.\\n');\n process.stdout.write(` ${path.relative(projectRoot, rulesPath)}\\n`);\n return;\n }\n\n await mkdir(path.join(yggRoot, 'model'), { recursive: true });\n await mkdir(path.join(yggRoot, 'aspects'), { recursive: true });\n await mkdir(path.join(yggRoot, 'flows'), { recursive: true });\n const schemasDir = path.join(yggRoot, 'schemas');\n await mkdir(schemasDir, { recursive: true });\n\n const graphSchemasDir = getGraphSchemasDir();\n try {\n const entries = await readdir(graphSchemasDir, { withFileTypes: true });\n const schemaFiles = entries.filter((e) => e.isFile()).map((e) => e.name);\n for (const file of schemaFiles) {\n const srcPath = path.join(graphSchemasDir, file);\n const content = await readFile(srcPath, 'utf-8');\n await writeFile(path.join(schemasDir, file), content, 'utf-8');\n }\n } catch (err) {\n process.stderr.write(\n `Warning: Could not copy graph schemas from ${graphSchemasDir}: ${(err as Error).message}\\n`,\n );\n }\n\n await writeFile(path.join(yggRoot, 'config.yaml'), DEFAULT_CONFIG, 'utf-8');\n await writeFile(path.join(yggRoot, '.gitignore'), GITIGNORE_CONTENT, 'utf-8');\n\n const rulesPath = await installRulesForPlatform(projectRoot, platform);\n\n process.stdout.write('✓ Yggdrasil initialized.\\n\\n');\n process.stdout.write('Created:\\n');\n process.stdout.write(' .yggdrasil/config.yaml\\n');\n process.stdout.write(' .yggdrasil/.gitignore\\n');\n process.stdout.write(' .yggdrasil/model/\\n');\n process.stdout.write(' .yggdrasil/aspects/\\n');\n process.stdout.write(' .yggdrasil/flows/\\n');\n process.stdout.write(' .yggdrasil/schemas/ (config, node, aspect, flow)\\n');\n process.stdout.write(` ${path.relative(projectRoot, rulesPath)} (rules)\\n\\n`);\n process.stdout.write('Next steps:\\n');\n process.stdout.write(' 1. Edit .yggdrasil/config.yaml — set name, stack, standards\\n');\n process.stdout.write(' 2. Create nodes under .yggdrasil/model/\\n');\n process.stdout.write(' 3. Run: yg validate\\n');\n });\n}\n","export const DEFAULT_CONFIG = `name: \"\"\n\nstack:\n language: \"\"\n runtime: \"\"\n\nstandards: \"\"\n\nnode_types:\n - name: module\n - name: service\n - name: library\n\nartifacts:\n responsibility.md:\n required: always\n description: \"What this node is responsible for, and what it is not\"\n structural_context: true\n interface.md:\n required:\n when: has_incoming_relations\n description: \"Public API — methods, parameters, return types, contracts\"\n structural_context: true\n logic.md:\n required: never\n description: \"Algorithmic flow, control flow, branching logic, decision trees — the 'how' of execution\"\n constraints.md:\n required: never\n description: \"Validation rules, business rules, invariants\"\n structural_context: true\n errors.md:\n required:\n when: has_incoming_relations\n description: \"Failure modes, edge cases, error conditions, recovery behavior\"\n structural_context: true\n model.md:\n required: never\n description: \"Data structures, schemas, entities, type definitions — the shape of data this node owns or manages\"\n state.md:\n required: never\n description: \"State machines, lifecycle, transitions\"\n decisions.md:\n required: never\n description: \"Local design decisions and rationale — choices specific to this node, not system-wide\"\n\nquality:\n min_artifact_length: 50\n max_direct_relations: 10\n context_budget:\n warning: 10000\n error: 20000\n`;\n","import { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport { AGENT_RULES_CONTENT } from './rules.js';\n\nconst AGENT_RULES_IMPORT = '@.yggdrasil/agent-rules.md';\nconst YGGDRASIL_START = '<!-- yggdrasil:start -->';\nconst YGGDRASIL_END = '<!-- yggdrasil:end -->';\nconst YGGDRASIL_SECTION = `## Yggdrasil\\n\\n${AGENT_RULES_CONTENT}`;\nconst YGGDRASIL_BLOCK = `${YGGDRASIL_START}\\n${YGGDRASIL_SECTION}\\n${YGGDRASIL_END}`;\n\nexport type Platform =\n | 'cursor'\n | 'claude-code'\n | 'copilot'\n | 'cline'\n | 'roocode'\n | 'codex'\n | 'windsurf'\n | 'aider'\n | 'gemini'\n | 'amp'\n | 'generic';\n\nexport const PLATFORMS: Platform[] = [\n 'cursor',\n 'claude-code',\n 'copilot',\n 'cline',\n 'roocode',\n 'codex',\n 'windsurf',\n 'aider',\n 'gemini',\n 'amp',\n 'generic',\n];\n\nexport async function installRulesForPlatform(\n projectRoot: string,\n platform: Platform,\n): Promise<string> {\n const agentRulesPath = path.join(projectRoot, '.yggdrasil', 'agent-rules.md');\n\n switch (platform) {\n case 'cursor':\n return installForCursor(projectRoot);\n case 'claude-code':\n return installForClaudeCode(projectRoot, agentRulesPath);\n case 'copilot':\n return installForCopilot(projectRoot);\n case 'cline':\n return installForCline(projectRoot);\n case 'roocode':\n return installForRooCode(projectRoot);\n case 'codex':\n return installForCodex(projectRoot);\n case 'windsurf':\n return installForWindsurf(projectRoot);\n case 'aider':\n return installForAider(projectRoot, agentRulesPath);\n case 'gemini':\n return installForGemini(projectRoot, agentRulesPath);\n case 'amp':\n return installForAmp(projectRoot, agentRulesPath);\n case 'generic':\n default:\n return installForGeneric(projectRoot);\n }\n}\n\nasync function ensureAgentRules(agentRulesPath: string): Promise<void> {\n await mkdir(path.dirname(agentRulesPath), { recursive: true });\n await writeFile(agentRulesPath, AGENT_RULES_CONTENT, 'utf-8');\n}\n\nasync function installForCursor(projectRoot: string): Promise<string> {\n const dir = path.join(projectRoot, '.cursor', 'rules');\n await mkdir(dir, { recursive: true });\n const filePath = path.join(dir, 'yggdrasil.mdc');\n const content = `---\ndescription: Yggdrasil — semantic memory of the repository\nalwaysApply: true\n---\n\n${AGENT_RULES_CONTENT}`;\n await writeFile(filePath, content, 'utf-8');\n return filePath;\n}\n\nasync function installForClaudeCode(projectRoot: string, agentRulesPath: string): Promise<string> {\n await ensureAgentRules(agentRulesPath);\n const filePath = path.join(projectRoot, 'CLAUDE.md');\n let existing = '';\n try {\n existing = await readFile(filePath, 'utf-8');\n } catch {\n /* file doesn't exist */\n }\n const importLine = AGENT_RULES_IMPORT;\n if (existing.includes(importLine)) {\n return agentRulesPath;\n }\n const content = existing.trimEnd() ? `${existing.trimEnd()}\\n${importLine}\\n` : `${importLine}\\n`;\n await writeFile(filePath, content, 'utf-8');\n return agentRulesPath;\n}\n\nasync function installForCopilot(projectRoot: string): Promise<string> {\n const dir = path.join(projectRoot, '.github');\n await mkdir(dir, { recursive: true });\n const filePath = path.join(dir, 'copilot-instructions.md');\n let existing = '';\n try {\n existing = await readFile(filePath, 'utf-8');\n } catch {\n /* file doesn't exist */\n }\n let content: string;\n if (existing.includes(YGGDRASIL_START) && existing.includes(YGGDRASIL_END)) {\n content = existing.replace(\n new RegExp(`${escapeRegex(YGGDRASIL_START)}[\\\\s\\\\S]*?${escapeRegex(YGGDRASIL_END)}`, 'g'),\n YGGDRASIL_BLOCK,\n );\n } else {\n content = existing.trimEnd()\n ? `${existing.trimEnd()}\\n\\n${YGGDRASIL_BLOCK}\\n`\n : `${YGGDRASIL_BLOCK}\\n`;\n }\n await writeFile(filePath, content, 'utf-8');\n return filePath;\n}\n\nasync function installForCline(projectRoot: string): Promise<string> {\n const dir = path.join(projectRoot, '.clinerules');\n await mkdir(dir, { recursive: true });\n const filePath = path.join(dir, 'yggdrasil.md');\n await writeFile(filePath, AGENT_RULES_CONTENT, 'utf-8');\n return filePath;\n}\n\nasync function installForRooCode(projectRoot: string): Promise<string> {\n const dir = path.join(projectRoot, '.roo', 'rules');\n await mkdir(dir, { recursive: true });\n const filePath = path.join(dir, 'yggdrasil.md');\n await writeFile(filePath, AGENT_RULES_CONTENT, 'utf-8');\n return filePath;\n}\n\nasync function installForCodex(projectRoot: string): Promise<string> {\n const filePath = path.join(projectRoot, 'AGENTS.md');\n let existing = '';\n try {\n existing = await readFile(filePath, 'utf-8');\n } catch {\n /* file doesn't exist */\n }\n let content: string;\n if (existing.includes(YGGDRASIL_START) && existing.includes(YGGDRASIL_END)) {\n content = existing.replace(\n new RegExp(`${escapeRegex(YGGDRASIL_START)}[\\\\s\\\\S]*?${escapeRegex(YGGDRASIL_END)}`, 'g'),\n YGGDRASIL_BLOCK,\n );\n } else {\n content = existing.trimEnd()\n ? `${existing.trimEnd()}\\n\\n${YGGDRASIL_BLOCK}\\n`\n : `${YGGDRASIL_BLOCK}\\n`;\n }\n await writeFile(filePath, content, 'utf-8');\n return filePath;\n}\n\nasync function installForWindsurf(projectRoot: string): Promise<string> {\n const dir = path.join(projectRoot, '.windsurf', 'rules');\n await mkdir(dir, { recursive: true });\n const filePath = path.join(dir, 'yggdrasil.md');\n await writeFile(filePath, AGENT_RULES_CONTENT, 'utf-8');\n return filePath;\n}\n\nasync function installForAider(projectRoot: string, agentRulesPath: string): Promise<string> {\n await ensureAgentRules(agentRulesPath);\n const filePath = path.join(projectRoot, '.aider.conf.yml');\n const entry = '.yggdrasil/agent-rules.md';\n let existing = '';\n try {\n existing = await readFile(filePath, 'utf-8');\n } catch {\n /* file doesn't exist */\n }\n if (existing.includes(entry)) {\n return agentRulesPath;\n }\n const content = appendAiderReadEntry(existing, entry);\n await writeFile(filePath, content, 'utf-8');\n return agentRulesPath;\n}\n\nfunction appendAiderReadEntry(existing: string, entry: string): string {\n const newItem = ` - ${entry} # added by yg init\\n`;\n const readBlock = /^read:\\s*\\n((?:\\s+-\\s+[^\\n]+\\n)*)/m;\n const match = existing.match(readBlock);\n if (match) {\n return existing.replace(match[0], `read:\\n${match[1]}${newItem}`);\n }\n const readEmpty = /^read:\\s*$/m;\n if (readEmpty.test(existing)) {\n return existing.replace(readEmpty, `read:\\n${newItem}`);\n }\n const trimmed = existing.trimEnd();\n return trimmed ? `${trimmed}\\n\\nread:\\n${newItem}` : `read:\\n${newItem}`;\n}\n\nasync function installForGemini(projectRoot: string, agentRulesPath: string): Promise<string> {\n await ensureAgentRules(agentRulesPath);\n const filePath = path.join(projectRoot, 'GEMINI.md');\n let existing = '';\n try {\n existing = await readFile(filePath, 'utf-8');\n } catch {\n /* file doesn't exist */\n }\n const importLine = AGENT_RULES_IMPORT;\n if (existing.includes(importLine)) {\n return agentRulesPath;\n }\n const content = existing.trimEnd() ? `${existing.trimEnd()}\\n${importLine}\\n` : `${importLine}\\n`;\n await writeFile(filePath, content, 'utf-8');\n return agentRulesPath;\n}\n\nasync function installForAmp(projectRoot: string, agentRulesPath: string): Promise<string> {\n await ensureAgentRules(agentRulesPath);\n const filePath = path.join(projectRoot, 'AGENTS.md');\n let existing = '';\n try {\n existing = await readFile(filePath, 'utf-8');\n } catch {\n /* file doesn't exist */\n }\n const importLine = AGENT_RULES_IMPORT;\n if (existing.includes(importLine)) {\n return agentRulesPath;\n }\n const content = existing.trimEnd() ? `${existing.trimEnd()}\\n${importLine}\\n` : `${importLine}\\n`;\n await writeFile(filePath, content, 'utf-8');\n return agentRulesPath;\n}\n\nasync function installForGeneric(projectRoot: string): Promise<string> {\n const filePath = path.join(projectRoot, '.yggdrasil', 'agent-rules.md');\n await ensureAgentRules(filePath);\n return filePath;\n}\n\nfunction escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n","/**\n * Canonical agent rules content — hand-tuned, do not generate programmatically.\n *\n * Operating manual for agents working in a Yggdrasil-managed repository.\n * Split into three cognitive sections optimized for LLM attention patterns:\n * 1. CORE PROTOCOL — internalize before doing anything (primacy effect)\n * 2. OPERATIONS — execute while working (working memory)\n * 3. KNOWLEDGE BASE — look up when needed (recency effect)\n */\n\n// prettier-ignore\nconst CORE_PROTOCOL = `## CORE PROTOCOL\n\nYggdrasil is persistent semantic memory stored in \\`.yggdrasil/\\`. It maps the repository and provides deterministic implementation context for every node. This document is your complete operating manual. Follow it strictly.\n\n### Quick Start Protocol\n\n\\`\\`\\`\nBEFORE reading, researching, planning, OR modifying ANY mapped file:\n 1. yg owner --file <path>\n 2. yg build-context --node <owner>\n The context package is your primary source of understanding.\n Raw file reads are for implementation details WITHIN a node you\n already understand from its context package.\n If the context package seems insufficient — enrich the graph.\n Do not bypass it.\n\nAFTER modifying:\n 3. Update graph artifacts to reflect changes\n 4. yg validate — fix all errors\n 5. yg drift-sync --node <owner>\n\nEVERY conversation start:\n yg preflight → act on findings (see Operations)\n\nNEVER: modify code without graph coverage.\nNEVER: read mapped source files to understand a component without\n running yg build-context first — the graph captures intent,\n constraints, and relations that source files cannot.\nNEVER: invent rationale, business rules, or decisions.\nNEVER: auto-resolve drift without asking the user.\nWHEN UNSURE: ask the user. Never guess. Never assume.\n\\`\\`\\`\n\n### Five Core Rules\n\n1. **Graph first.** Before reading, researching, planning, or modifying mapped files, run \\`yg owner\\` and \\`yg build-context\\`. Always. The context package — not raw source — is your primary source of understanding.\n2. **Code and graph are one.** Code changed → graph updated in the same response. Graph changed → source verified in the same response. No exceptions.\n3. **Never invent why.** The graph captures human intent. If you don't know why something was decided, ask. Never hallucinate rationale.\n4. **Always capture why — especially why NOT.** When the user explains a reason, record it in the graph immediately. When a design choice is made, also record rejected alternatives: \"Chose X over Y because Z.\" Rejected alternatives are the highest-value information — invisible in code and irrecoverable once forgotten. Conversation evaporates; graph persists.\n5. **Ask before resolving ambiguity.** When multiple valid interpretations exist, stop, list options, ask the user. Never silently choose.\n\n### Failure States\n\nYou have broken Yggdrasil if you do any of the following:\n\n- ❌ Modified source code without running \\`yg owner --file <path>\\` first.\n- ❌ Modified source code without updating graph artifacts in the same response.\n- ❌ Modified graph files without verifying source code alignment in the same response.\n- ❌ Resolved a code-graph inconsistency without asking the user first.\n- ❌ Created or edited a graph element without reading its schema in \\`schemas/\\` first.\n- ❌ Ran \\`yg drift-sync\\` before updating graph artifacts.\n- ❌ Wrote a flow description that describes code sequences instead of a business process.\n- ❌ Used an aspect identifier that has no corresponding \\`aspects/\\` directory.\n- ❌ Placed a cross-cutting requirement in a local node artifact instead of an aspect.\n- ❌ Invented a rationale, business rule, or architectural decision.\n- ❌ Used blackbox coverage for greenfield (new) code.\n- ❌ Answered a question about a mapped file without running \\`yg build-context\\` first.\n- ❌ Read mapped source files to plan or research changes without running \\`yg build-context\\` first.\n- ❌ Deferred \\`yg drift-sync\\` to the end of a multi-step task instead of running it incrementally after each logical group of changes.\n- ❌ Recorded a design decision without documenting which alternatives were rejected and why.\n\n### Escape Hatch\n\nIf the user explicitly requests a code-only change, comply but:\n\n- Warn: \"This creates drift. Run \\`yg drift\\` next session to reconcile.\"\n- Do NOT run \\`yg drift-sync\\` — leave the drift visible.\n\n### Environment Check\n\nBefore preflight:\n\n- Verify \\`yg\\` CLI is available. If not found, inform user and stop.\n- If \\`yg preflight\\` shows 0 nodes → enter BOOTSTRAP MODE (see Operations).\n- If drift report shows >10 drifted nodes → report scope to user, ask which area to prioritize. Do not resolve all at once.`;\n\n// prettier-ignore\nconst OPERATIONS = `## OPERATIONS\n\n### Conversation Lifecycle\n\n\\`\\`\\`\nPREFLIGHT (every conversation, before any work):\n - [ ] 1. yg preflight → read unified report\n - [ ] 2. If journal entries: consolidate to graph, then yg journal-archive\n - [ ] 3. If drift: resolve per Drift Resolution, then yg drift-sync per node\n - [ ] 4. If validation errors: fix, re-run yg validate\n Exception: read-only requests (explain, analyze) — skip preflight.\n\nUNDERSTANDING mapped code (questions, research, OR planning):\n - [ ] 1. yg owner --file <path>\n - [ ] 2. Owner found → yg build-context --node <path>. Use context package as primary source.\n - [ ] 3. Owner not found → use file analysis, state it is not graph-backed.\n Never use grep or raw file reads as primary understanding when graph coverage exists.\n Raw reads supplement the context package — they do not replace it.\n\nWRAP-UP (user signals \"done\", \"wrap up\", \"that's enough\"):\n - [ ] 1. Consolidate journal if used → yg journal-archive\n - [ ] 2. yg drift --drifted-only → resolve\n - [ ] 3. yg validate → fix errors\n - [ ] 4. Report: which nodes and files were changed\n\\`\\`\\`\n\n### Modify Source Code\n\nYou are not allowed to edit or create source code without establishing graph coverage first.\n\n**Step 1** — Check coverage: \\`yg owner --file <path>\\`\n\n**Step 2a** — Owner found: execute checklist:\n\n- [ ] 1. Read specification: \\`yg build-context --node <node_path>\\`\n- [ ] 2. Assess blast radius: \\`yg impact --node <node_path>\\` — review dependents, descendants, and co-aspect nodes before changing interfaces or shared behavior\n- [ ] 3. Modify source code\n- [ ] 4. Sync graph artifacts — edit artifact files to reflect the changes\n- [ ] 5. Run \\`yg validate\\` — fix all errors (if unfixable after 3 attempts → stop, report to user)\n- [ ] 6. Run \\`yg drift-sync --node <node_path>\\` — only after graph and code are both current\n\n**Step 2b** — Owner not found: establish coverage first. Present options to the user:\n\n*Partially mapped* (file unmapped but inside a mapped module): ask whether to add to existing node or create new one.\n\n*Existing code:*\n\n- Option A — Full node: create node(s), map files, write artifacts from code analysis\n- Option B — Blackbox: create a blackbox node at agreed granularity\n- Option C — Abort\n\n*Greenfield (new code):* Only Option A. Blackbox is forbidden for new code. Follow the graph-first workflow:\n\n1. Create aspects first (cross-cutting requirements the new code must satisfy)\n2. Create flows if the code participates in a business process\n3. Create nodes with full artifacts — responsibility, constraints, decisions, interface, logic\n4. Review the context package (\\`yg build-context\\`) — it is now the behavioral specification\n5. Implement code that satisfies the specification\n6. The graph specifies WHAT and WHY; the code implements HOW (framework APIs, library choices)\n\nAfter the user chooses, return to Step 1 and follow Step 2a.\n\n### Modify Graph\n\n- [ ] 1. Read the relevant schema from \\`schemas/\\` before touching any YAML\n- [ ] 2. Before changing an aspect or flow, check scope: \\`yg impact --aspect <id>\\` or \\`yg impact --flow <name>\\` — understand which nodes are affected before modifying shared rules or processes\n- [ ] 3. Make changes\n- [ ] 4. Run \\`yg validate\\` immediately — fix all errors\n- [ ] 5. Verify affected source files are consistent — update if needed\n- [ ] 6. Run \\`yg drift-sync\\` for affected nodes\n\n### Reverse Engineering\n\n**Order:** aspects (cross-cutting patterns) → flows (business processes) → model nodes. Never create nodes before aspects and flows are understood.\n\nPer area checklist:\n\n- [ ] 1. \\`yg owner --file <path>\\` — confirm no coverage\n- [ ] 2. Determine node granularity — propose to user if unclear\n- [ ] 3. Create node directory, read \\`schemas/node.yaml\\`, create \\`node.yaml\\`\n- [ ] 4. Analyze source — for each artifact type in \\`config.artifacts\\`: extract content, do not invent\n- [ ] 5. Identify relations — add to \\`node.yaml\\`\n- [ ] 6. Identify cross-cutting requirements — add matching aspects, create if needed\n- [ ] 7. Identify business process participation — add to flow, ask user if process unclear\n- [ ] 8. \\`yg validate\\` — fix errors\n- [ ] 9. \\`yg drift-sync --node <path>\\`\n\n**When to ask:**\n\n- Business process unclear: \"This code appears to be part of a larger process. Can you describe what it means from a business perspective?\"\n- Constraint without rationale: \"I see [constraint X]. Do you know why this exists? I want to record the reason, not just the rule.\"\n- Unexplained architectural choice: \"I see [approach X]. What was the reason for this choice?\"\n- Decision without alternatives: \"You chose [X]. What alternatives did you consider, and why did you reject them?\" Record the answer in \\`decisions.md\\`.\n\n### Bootstrap Mode\n\nTrigger: \\`yg preflight\\` shows 0 nodes, or no nodes cover the active work area.\n\n- [ ] 1. Identify the active work area (files the user wants to modify)\n- [ ] 2. Scan for cross-cutting patterns → create aspects\n- [ ] 3. Ask user about business processes → create flows if applicable\n- [ ] 4. Propose node structure for the area\n- [ ] 5. Create node(s) with initial artifacts, map files\n- [ ] 6. \\`yg validate\\`, \\`yg drift-sync\\`\n- [ ] 7. Proceed with user's original request\n\nConstraint: Do NOT map the entire repository. Focus on the active area. Expand incrementally.\n\n### Drift Resolution\n\nAlways ask the user before resolving drift. Never auto-resolve.\n\n- **Source drift** (source files changed) → update graph artifacts to match source, then \\`yg drift-sync\\`\n- **Graph drift** (graph artifacts changed) → review affected source, update if needed, then \\`yg drift-sync\\`\n- **Full drift** (both changed) → present both sides to user, ask which direction wins\n- **Missing** → ask: re-materialize or remove mapping?\n- **Unmaterialized** → ask user how to proceed\n\nThreshold: >10 drifted nodes → ask user which area to prioritize. Do not resolve all at once.\n\n### Error Recovery\n\n- **\\`yg\\` not found** → inform user: \"yg CLI is not installed or not in PATH.\" Stop.\n- **Unfixable validate errors** → if not resolved after 3 attempts, stop and report to user. Do not loop.\n- **Budget exceeded** → if \\`yg build-context\\` exits with error (context package exceeds budget), warn user: \"This node should be split.\" Do not proceed with implementation.\n- **Corrupted \\`.yggdrasil/\\` files** → report to user. Do not attempt repair.\n- **Incremental sync** → run \\`yg drift-sync\\` every 3-5 source files during multi-file tasks. Do not defer to end.`;\n\n// prettier-ignore\nconst KNOWLEDGE_BASE = `## KNOWLEDGE BASE\n\n### Graph Structure\n\n\\`\\`\\`\n.yggdrasil/\n config.yaml ← vocabulary, stack, node types, artifact rules, required aspects\n model/ ← what exists: nodes, hierarchy, relations, file mappings\n aspects/ ← what must: cross-cutting requirements with rationale and guidance\n flows/ ← why and in what process: business processes with node participation\n schemas/ ← YAML schemas — read before creating any graph element\n .drift-state ← generated by CLI; never edit manually\n .journal.yaml ← generated by CLI; never edit manually\n\\`\\`\\`\n\nKey facts:\n\n- **Hierarchy:** nodes nest in \\`model/\\`. Children inherit parent context. Do not repeat parent content in children.\n- **Aspect id = directory path** under \\`aspects/\\`. Each aspect has \\`aspect.yaml\\` + content \\`.md\\` files. No automatic parent-child — use \\`implies\\` explicitly.\n- **Flows = business processes.** A flow describes what happens in the world, not code sequences. Flow aspects propagate to all participants.\n\n### Context Assembly\n\nRun \\`yg build-context --node <path>\\` to get the deterministic context package for a node. Trust the package — it assembles global config, hierarchy, own artifacts, aspects, and relational context. If the package is insufficient, enrich the graph. Do not bypass it with raw file exploration.\n\n### Information Routing\n\nWhen you encounter information, route it to the correct location:\n\n- **Specific to this node** → local node artifact (check \\`config.yaml artifacts\\` for available types)\n- **Rule for many nodes** → aspect (\\`aspects/<id>/\\` with \\`aspect.yaml\\` + content \\`.md\\` files). If applies to ALL nodes of a type → \\`node_types[*].required_aspects\\` in \\`config.yaml\\`\n- **Business process** → flow (\\`flows/<name>/\\` with \\`flow.yaml\\` + \\`description.md\\`). Ask user if process unclear.\n- **Shared across a domain** → parent node artifact. Children receive it through hierarchy.\n- **Technology stack or standard** → \\`config.yaml\\` under \\`stack\\` or \\`standards\\` (+ \\`rationale\\` field)\n- **Decision (why + why NOT):** one node → \\`decisions.md\\` with format \"Chose X over Y because Z\"; category of nodes → aspect content files; tech choice → \\`config.yaml\\` rationale field. Always include rejected alternatives — they are the highest-value graph content.\n\n### Creating Aspects\n\n- [ ] 1. Read \\`schemas/aspect.yaml\\`\n- [ ] 2. Create \\`aspects/<id>/\\` directory\n- [ ] 3. Write \\`aspect.yaml\\` — name, optional description, optional implies\n- [ ] 4. Write content \\`.md\\` files: WHAT must be satisfied + WHY (user's words, do not invent)\n- [ ] 5. \\`yg validate\\`\n\nTest: \"Does this requirement apply to more than one node?\" Yes → aspect. No → local artifact.\n\n**Aspect identification heuristic:** If the same pattern, constraint, or rule appears in 3+ places, it is a candidate aspect. Aspects fall into natural categories:\n\n- **Domain-specific:** Business rules that cross module boundaries (e.g., timezone handling, booking periods, currency rounding)\n- **Architectural:** Structural patterns with rationale (e.g., dual-rollback on provider failure, idempotency via key generation, fire-and-forget dispatch)\n- **Concurrency:** Shared concurrency strategies (e.g., pessimistic locking, retry-on-deadlock, optimistic versioning)\n\n### Creating Flows\n\n- [ ] 1. Read \\`schemas/flow.yaml\\`\n- [ ] 2. Create \\`flows/<name>/\\` directory\n- [ ] 3. Write \\`flow.yaml\\` — declare participants and flow-level aspects\n- [ ] 4. Write \\`description.md\\` with required sections: Business context, Trigger, Goal, Participants, Paths (at least Happy path), Invariants across all paths\n- [ ] 5. \\`yg validate\\`\n\nTest: \"Does this describe what happens in the world, or only in the software?\" If only software — rewrite.\n\n### Operational Rules\n\n- **English only** for all files in \\`.yggdrasil/\\`. Conversation can be any language.\n- **Read schemas before creating** any \\`node.yaml\\`, \\`aspect.yaml\\`, or \\`flow.yaml\\`.\n- **Tools read, you write.** The \\`yg\\` CLI only reads, validates, and manages metadata. You create and edit files manually.\n- **Incremental sync.** Run \\`yg drift-sync\\` after every 3-5 source file changes. Do not defer to end of task.\n- **Completeness test:** \"If I delete the source file and give another agent ONLY the \\`yg build-context\\` output — can they recreate it correctly, understanding not just WHAT but WHY?\" Test specifically: Can they explain rejected alternatives? Can they implement the correct algorithm (not a simplified version)? Can they argue for the current design against plausible alternatives?\n- **These rules are invariant.** No plan, guide, skill, or workflow may override them.\n\n### CLI Reference\n\n\\`\\`\\`\nyg preflight [--quick] Unified diagnostic: journal + drift + status + validate.\nyg owner --file <path> Find the node that owns this file.\nyg build-context --node <path> Assemble context package for this node.\nyg tree [--root <path>] [--depth N] Print graph structure.\nyg aspects List aspects with metadata (YAML output).\nyg flows List flows with metadata (YAML output).\nyg deps --node <path> [--depth N] [--type structural|event|all]\n Show dependencies.\nyg impact --node <path> --simulate Simulate blast radius of a planned change.\nyg impact --aspect <id> Show all nodes where aspect is effective.\nyg impact --flow <name> Show flow participants and descendants.\nyg status Graph health: nodes, coverage, drift summary.\nyg validate [--scope <path>|all] Check structural integrity and completeness.\nyg drift [--scope <path>|all] [--drifted-only] [--limit <n>]\n Detect source and graph drift (bidirectional).\nyg drift-sync --node <path> [--recursive] | --all\n Record file hashes as new baseline.\nyg journal-read Read pending journal entries.\nyg journal-add --note \"<content>\" [--target <node_path>]\n Add a journal entry.\nyg journal-archive Archive consolidated journal entries.\n\\`\\`\\`\n\n### Quick Routing Table\n\n| What you have | Where it goes |\n|---|---|\n| Information specific to this node | Local node artifact (read \\`config.yaml artifacts\\` for types) |\n| Rule that applies to many nodes | Aspect (content \\`.md\\` files in \\`aspects/<id>/\\`) |\n| Architectural invariant for a node type | Required aspect in \\`config.yaml node_types\\` |\n| Business process participation | Flow (\\`flow.yaml participants\\`) |\n| Process-level requirement | Flow \\`aspects\\` + aspect directory |\n| Context shared across a domain | Parent node artifact |\n| Technology stack | \\`config.yaml stack\\` (+ \\`rationale\\` field) |\n| Global coding standards | \\`config.yaml standards\\` |\n`;\n\nexport const AGENT_RULES_CONTENT = [CORE_PROTOCOL, OPERATIONS, KNOWLEDGE_BASE].join('\\n\\n---\\n\\n');\n","import { readdir, readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport type {\n Graph,\n GraphNode,\n AspectDef,\n FlowDef,\n SchemaDef,\n YggConfig,\n} from '../model/types.js';\nimport { parseConfig } from '../io/config-parser.js';\nimport { parseNodeYaml } from '../io/node-parser.js';\nimport { parseAspect } from '../io/aspect-parser.js';\nimport { parseFlow } from '../io/flow-parser.js';\nimport { parseSchema } from '../io/schema-parser.js';\nimport { readArtifacts } from '../io/artifact-reader.js';\nimport { findYggRoot } from '../utils/paths.js';\n\nfunction toModelPath(absolutePath: string, modelDir: string): string {\n return path.relative(modelDir, absolutePath).split(path.sep).join('/');\n}\n\nconst FALLBACK_CONFIG: YggConfig = {\n name: '',\n stack: {},\n standards: '',\n node_types: [],\n artifacts: {},\n};\n\nexport async function loadGraph(\n projectRoot: string,\n options: { tolerateInvalidConfig?: boolean } = {},\n): Promise<Graph> {\n const yggRoot = await findYggRoot(projectRoot);\n let configError: string | undefined;\n let config = FALLBACK_CONFIG;\n try {\n config = await parseConfig(path.join(yggRoot, 'config.yaml'));\n } catch (error) {\n if (!options.tolerateInvalidConfig) {\n throw error;\n }\n configError = (error as Error).message;\n }\n\n const modelDir = path.join(yggRoot, 'model');\n const nodes = new Map<string, GraphNode>();\n const nodeParseErrors: Array<{ nodePath: string; message: string }> = [];\n const artifactFilenames = Object.keys(config.artifacts ?? {});\n try {\n await scanModelDirectory(modelDir, modelDir, null, nodes, nodeParseErrors, artifactFilenames);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n throw new Error(`Directory .yggdrasil/model/ does not exist. Run 'yg init' first.`, {\n cause: err,\n });\n }\n throw err;\n }\n\n const aspects = await loadAspects(path.join(yggRoot, 'aspects'));\n const flows = await loadFlows(path.join(yggRoot, 'flows'));\n const schemas = await loadSchemas(path.join(yggRoot, 'schemas'));\n\n return {\n config,\n configError,\n nodeParseErrors: nodeParseErrors.length > 0 ? nodeParseErrors : undefined,\n nodes,\n aspects,\n flows,\n schemas,\n rootPath: yggRoot,\n };\n}\n\nasync function scanModelDirectory(\n dirPath: string,\n modelDir: string,\n parent: GraphNode | null,\n nodes: Map<string, GraphNode>,\n nodeParseErrors: Array<{ nodePath: string; message: string }>,\n artifactFilenames: string[],\n): Promise<void> {\n const entries = await readdir(dirPath, { withFileTypes: true });\n const hasNodeYaml = entries.some((e) => e.isFile() && e.name === 'node.yaml');\n\n if (!hasNodeYaml && dirPath !== modelDir) {\n return;\n }\n\n if (hasNodeYaml) {\n const graphPath = toModelPath(dirPath, modelDir);\n const nodeYamlPath = path.join(dirPath, 'node.yaml');\n let meta;\n let nodeYamlRaw: string | undefined;\n try {\n nodeYamlRaw = await readFile(nodeYamlPath, 'utf-8');\n meta = await parseNodeYaml(nodeYamlPath);\n } catch (err) {\n nodeParseErrors.push({\n nodePath: graphPath,\n message: (err as Error).message,\n });\n return;\n }\n const artifacts = await readArtifacts(dirPath, ['node.yaml'], artifactFilenames);\n\n const node: GraphNode = {\n path: graphPath,\n meta,\n nodeYamlRaw,\n artifacts,\n children: [],\n parent,\n };\n\n nodes.set(graphPath, node);\n if (parent) {\n parent.children.push(node);\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (entry.name.startsWith('.')) continue;\n\n await scanModelDirectory(\n path.join(dirPath, entry.name),\n modelDir,\n node,\n nodes,\n nodeParseErrors,\n artifactFilenames,\n );\n }\n } else {\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (entry.name.startsWith('.')) continue;\n\n await scanModelDirectory(\n path.join(dirPath, entry.name),\n modelDir,\n null,\n nodes,\n nodeParseErrors,\n artifactFilenames,\n );\n }\n }\n}\n\nasync function loadAspects(aspectsDir: string): Promise<AspectDef[]> {\n try {\n const aspects: AspectDef[] = [];\n await scanAspectsDirectory(aspectsDir, aspectsDir, aspects);\n return aspects;\n } catch {\n return [];\n }\n}\n\nasync function scanAspectsDirectory(\n dirPath: string,\n aspectsRoot: string,\n aspects: AspectDef[],\n): Promise<void> {\n const entries = await readdir(dirPath, { withFileTypes: true });\n const hasAspectYaml = entries.some((e) => e.isFile() && e.name === 'aspect.yaml');\n\n if (hasAspectYaml) {\n const id = path.relative(aspectsRoot, dirPath).split(path.sep).join('/');\n const aspectYamlPath = path.join(dirPath, 'aspect.yaml');\n const aspect = await parseAspect(dirPath, aspectYamlPath, id);\n aspects.push(aspect);\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (entry.name.startsWith('.')) continue;\n await scanAspectsDirectory(path.join(dirPath, entry.name), aspectsRoot, aspects);\n }\n}\n\nasync function loadFlows(flowsDir: string): Promise<FlowDef[]> {\n try {\n const entries = await readdir(flowsDir, { withFileTypes: true });\n const flows: FlowDef[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const flowYamlPath = path.join(flowsDir, entry.name, 'flow.yaml');\n const flow = await parseFlow(path.join(flowsDir, entry.name), flowYamlPath);\n flows.push(flow);\n }\n return flows;\n } catch {\n return [];\n }\n}\n\nasync function loadSchemas(schemasDir: string): Promise<SchemaDef[]> {\n try {\n const entries = await readdir(schemasDir, { withFileTypes: true });\n const schemas: SchemaDef[] = [];\n for (const entry of entries) {\n if (!entry.isFile()) continue;\n if (!entry.name.endsWith('.yaml') && !entry.name.endsWith('.yml')) continue;\n const s = await parseSchema(path.join(schemasDir, entry.name));\n schemas.push(s);\n }\n return schemas;\n } catch {\n return [];\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { parse as parseYaml } from 'yaml';\nimport type {\n YggConfig,\n ArtifactConfig,\n QualityConfig,\n NodeTypeConfig,\n} from '../model/types.js';\n\nconst DEFAULT_QUALITY: QualityConfig = {\n min_artifact_length: 50,\n max_direct_relations: 10,\n context_budget: { warning: 10000, error: 20000 },\n};\n\nexport async function parseConfig(filePath: string): Promise<YggConfig> {\n const content = await readFile(filePath, 'utf-8');\n const raw = parseYaml(content) as Record<string, unknown>;\n\n if (!raw || typeof raw !== 'object') {\n throw new Error(`config.yaml: file is empty or not a valid YAML mapping`);\n }\n\n if (!raw.name || typeof raw.name !== 'string' || raw.name.trim() === '') {\n throw new Error(`config.yaml: missing or invalid 'name' field`);\n }\n\n const nodeTypesRaw = raw.node_types;\n if (!Array.isArray(nodeTypesRaw) || nodeTypesRaw.length === 0) {\n throw new Error(`config.yaml: 'node_types' must be a non-empty array`);\n }\n const nodeTypes: NodeTypeConfig[] = nodeTypesRaw.map((item) => {\n if (typeof item === 'string') {\n return { name: item };\n }\n if (\n typeof item === 'object' &&\n item !== null &&\n 'name' in item &&\n typeof (item as { name: unknown }).name === 'string'\n ) {\n const obj = item as { name: string; required_aspects?: unknown; required_tags?: unknown };\n const requiredAspects = Array.isArray(obj.required_aspects)\n ? (obj.required_aspects as unknown[]).filter((t): t is string => typeof t === 'string')\n : Array.isArray(obj.required_tags)\n ? (obj.required_tags as unknown[]).filter((t): t is string => typeof t === 'string')\n : undefined;\n return {\n name: obj.name,\n required_aspects: requiredAspects && requiredAspects.length > 0 ? requiredAspects : undefined,\n };\n }\n throw new Error(\n `config.yaml: node_types entry must be string or { name, required_aspects? }`,\n );\n });\n\n const artifacts = raw.artifacts;\n if (\n !artifacts ||\n typeof artifacts !== 'object' ||\n Array.isArray(artifacts) ||\n Object.keys(artifacts).length === 0\n ) {\n throw new Error(`config.yaml: 'artifacts' must be a non-empty object`);\n }\n\n const artifactsMap: Record<string, ArtifactConfig> = {};\n for (const [key, val] of Object.entries(artifacts)) {\n if (key === 'node.yaml') {\n throw new Error(`config.yaml: artifact name 'node.yaml' is reserved`);\n }\n const a = val as Record<string, unknown>;\n const required = a.required;\n if (\n required !== 'always' &&\n required !== 'never' &&\n (typeof required !== 'object' || !required || !('when' in required))\n ) {\n throw new Error(`config.yaml: artifact '${key}' has invalid 'required' field`);\n }\n if (typeof required === 'object' && required && 'when' in required) {\n const when = (required as { when: string }).when;\n const validWhen =\n when === 'has_incoming_relations' ||\n when === 'has_outgoing_relations' ||\n (typeof when === 'string' &&\n (when.startsWith('has_aspect:') || when.startsWith('has_tag:')));\n if (!validWhen) {\n throw new Error(\n `config.yaml: artifact '${key}' has invalid 'required.when': must be has_incoming_relations, has_outgoing_relations, or has_aspect:<name>`,\n );\n }\n }\n artifactsMap[key] = {\n required: required as ArtifactConfig['required'],\n description: (a.description as string) ?? '',\n structural_context: (a.structural_context as boolean) ?? false,\n };\n }\n\n const qualityRaw = raw.quality as Record<string, unknown> | undefined;\n const quality: QualityConfig = qualityRaw\n ? {\n min_artifact_length:\n (qualityRaw.min_artifact_length as number) ?? DEFAULT_QUALITY.min_artifact_length,\n max_direct_relations:\n (qualityRaw.max_direct_relations as number) ?? DEFAULT_QUALITY.max_direct_relations,\n context_budget: {\n warning:\n (qualityRaw.context_budget as Record<string, number>)?.warning ??\n DEFAULT_QUALITY.context_budget.warning,\n error:\n (qualityRaw.context_budget as Record<string, number>)?.error ??\n DEFAULT_QUALITY.context_budget.error,\n },\n }\n : DEFAULT_QUALITY;\n\n if (quality.context_budget.error < quality.context_budget.warning) {\n throw new Error(\n `config.yaml: quality.context_budget.error (${quality.context_budget.error}) must be >= warning (${quality.context_budget.warning})`,\n );\n }\n\n return {\n name: (raw.name as string).trim(),\n stack: (raw.stack as Record<string, string>) ?? {},\n standards: typeof raw.standards === 'string' ? raw.standards : '',\n node_types: nodeTypes,\n artifacts: artifactsMap,\n quality,\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport { parse as parseYaml } from 'yaml';\nimport type { NodeMeta, NodeMapping, Relation, RelationType } from '../model/types.js';\n\nconst RELATION_TYPES: RelationType[] = [\n 'uses',\n 'calls',\n 'extends',\n 'implements',\n 'emits',\n 'listens',\n];\n\nfunction isValidRelationType(t: unknown): t is RelationType {\n return typeof t === 'string' && RELATION_TYPES.includes(t as RelationType);\n}\n\nexport async function parseNodeYaml(filePath: string): Promise<NodeMeta> {\n const content = await readFile(filePath, 'utf-8');\n const raw = parseYaml(content) as Record<string, unknown>;\n\n if (!raw || typeof raw !== 'object') {\n throw new Error(`node.yaml at ${filePath}: file is empty or not a valid YAML mapping`);\n }\n\n if (!raw.name || typeof raw.name !== 'string' || raw.name.trim() === '') {\n throw new Error(`node.yaml at ${filePath}: missing or empty 'name'`);\n }\n if (!raw.type || typeof raw.type !== 'string' || raw.type.trim() === '') {\n throw new Error(`node.yaml at ${filePath}: missing or empty 'type'`);\n }\n\n const relations = parseRelations(raw.relations, filePath);\n const mapping = parseMapping(raw.mapping, filePath);\n\n return {\n name: (raw.name as string).trim(),\n type: (raw.type as string).trim(),\n aspects: parseStringArray(raw.aspects) ?? parseStringArray(raw.tags),\n blackbox: (raw.blackbox as boolean) ?? false,\n relations: relations.length > 0 ? relations : undefined,\n mapping,\n };\n}\n\nfunction parseStringArray(val: unknown): string[] | undefined {\n if (!Array.isArray(val)) return undefined;\n const arr = val.filter((v): v is string => typeof v === 'string');\n return arr.length > 0 ? arr : undefined;\n}\n\nfunction parseRelations(raw: unknown, filePath: string): Relation[] {\n if (raw === undefined) return [];\n if (!Array.isArray(raw)) {\n throw new Error(`node.yaml at ${filePath}: 'relations' must be an array`);\n }\n\n const result: Relation[] = [];\n for (let index = 0; index < raw.length; index++) {\n const r = raw[index];\n if (typeof r !== 'object' || r === null) {\n throw new Error(`node.yaml at ${filePath}: relations[${index}] must be an object`);\n }\n const obj = r as Record<string, unknown>;\n const target = obj.target;\n const type = obj.type;\n\n if (typeof target !== 'string' || target.trim() === '') {\n throw new Error(\n `node.yaml at ${filePath}: relations[${index}].target must be a non-empty string`,\n );\n }\n if (!isValidRelationType(type)) {\n throw new Error(`node.yaml at ${filePath}: relations[${index}].type is invalid`);\n }\n\n const rel: Relation = {\n target: target.trim(),\n type: type as RelationType,\n };\n if (Array.isArray(obj.consumes)) {\n rel.consumes = (obj.consumes as unknown[]).filter((c): c is string => typeof c === 'string');\n }\n if (typeof obj.failure === 'string') {\n rel.failure = obj.failure;\n }\n if (typeof obj.event_name === 'string' && obj.event_name.trim()) {\n rel.event_name = obj.event_name.trim();\n }\n result.push(rel);\n }\n return result;\n}\n\nfunction validateRelativePath(pathValue: string, filePath: string, fieldName: string): string {\n const normalized = pathValue.trim();\n if (normalized === '') {\n throw new Error(`node.yaml at ${filePath}: '${fieldName}' must be non-empty`);\n }\n if (normalized.startsWith('/')) {\n throw new Error(`node.yaml at ${filePath}: '${fieldName}' must be relative to repository root`);\n }\n return normalized;\n}\n\nfunction parseMapping(rawMapping: unknown, filePath: string): NodeMapping | undefined {\n if (!rawMapping || typeof rawMapping !== 'object') return undefined;\n\n const obj = rawMapping as Record<string, unknown>;\n\n // Unified format: mapping.paths — list of files and/or directories (type auto-detected at runtime)\n if (Array.isArray(obj.paths) && obj.paths.length > 0) {\n const paths = (obj.paths as unknown[])\n .filter((p): p is string => typeof p === 'string')\n .map((p) => validateRelativePath(p, filePath, 'mapping.paths[]'));\n if (paths.length === 0) {\n throw new Error(`node.yaml at ${filePath}: mapping.paths must be a non-empty array`);\n }\n return { paths };\n }\n\n if (obj.paths !== undefined || obj.type !== undefined || obj.path !== undefined) {\n throw new Error(\n `node.yaml at ${filePath}: mapping must have paths (array of file/directory paths)`,\n );\n }\n\n return undefined;\n}\n","import { readFile } from 'node:fs/promises';\nimport { parse as parseYaml } from 'yaml';\nimport type { AspectDef } from '../model/types.js';\nimport { readArtifacts } from './artifact-reader.js';\n\nexport async function parseAspect(\n aspectDir: string,\n aspectYamlPath: string,\n id: string,\n): Promise<AspectDef> {\n const idTrimmed = id?.trim() ?? '';\n if (!idTrimmed) {\n throw new Error(`Aspect id must be non-empty (relative path in aspects/)`);\n }\n const content = await readFile(aspectYamlPath, 'utf-8');\n const raw = parseYaml(content) as Record<string, unknown>;\n\n if (!raw || typeof raw !== 'object') {\n throw new Error(`Aspect file ${aspectYamlPath}: file is empty or not a valid YAML mapping`);\n }\n\n if (!raw.name || typeof raw.name !== 'string' || raw.name.trim() === '') {\n throw new Error(`Aspect file ${aspectYamlPath}: missing or empty 'name'`);\n }\n\n const description = typeof raw.description === 'string' ? raw.description.trim() : undefined;\n\n const artifacts = await readArtifacts(aspectDir, ['aspect.yaml']);\n\n let implies: string[] | undefined;\n if (raw.implies !== undefined) {\n if (!Array.isArray(raw.implies)) {\n throw new Error(`Aspect file ${aspectYamlPath}: 'implies' must be an array of strings`);\n }\n implies = (raw.implies as unknown[]).filter((t): t is string => typeof t === 'string');\n }\n\n return {\n name: (raw.name as string).trim(),\n id: idTrimmed,\n description,\n implies,\n artifacts,\n };\n}\n","import { readFile, readdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Artifact } from '../model/types.js';\n\nexport async function readArtifacts(\n dirPath: string,\n excludeFiles: string[] = ['node.yaml'],\n includeFiles?: string[],\n): Promise<Artifact[]> {\n const entries = await readdir(dirPath, { withFileTypes: true });\n const artifacts: Artifact[] = [];\n const includeSet = includeFiles && includeFiles.length > 0 ? new Set(includeFiles) : null;\n\n for (const entry of entries) {\n if (!entry.isFile()) continue;\n if (excludeFiles.includes(entry.name)) continue;\n if (includeSet && !includeSet.has(entry.name)) continue;\n\n const filePath = path.join(dirPath, entry.name);\n const content = await readFile(filePath, 'utf-8');\n artifacts.push({ filename: entry.name, content });\n }\n\n // Sort by filename for deterministic output\n artifacts.sort((a, b) => a.filename.localeCompare(b.filename));\n return artifacts;\n}\n","import { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { parse as parseYaml } from 'yaml';\nimport type { FlowDef } from '../model/types.js';\nimport { readArtifacts } from './artifact-reader.js';\n\nexport async function parseFlow(flowDir: string, flowYamlPath: string): Promise<FlowDef> {\n const content = await readFile(flowYamlPath, 'utf-8');\n const raw = parseYaml(content) as Record<string, unknown>;\n\n if (!raw || typeof raw !== 'object') {\n throw new Error(`flow.yaml at ${flowYamlPath}: file is empty or not a valid YAML mapping`);\n }\n\n if (!raw.name || typeof raw.name !== 'string' || raw.name.trim() === '') {\n throw new Error(`flow.yaml at ${flowYamlPath}: missing or empty 'name'`);\n }\n\n const nodes = raw.nodes;\n if (!Array.isArray(nodes) || nodes.length === 0) {\n throw new Error(`flow.yaml at ${flowYamlPath}: 'nodes' must be a non-empty array`);\n }\n\n const nodePaths = (nodes as unknown[]).filter((n): n is string => typeof n === 'string');\n if (nodePaths.length === 0) {\n throw new Error(`flow.yaml at ${flowYamlPath}: 'nodes' must contain string node paths`);\n }\n\n let aspects: string[] | undefined;\n if (raw.aspects !== undefined) {\n if (!Array.isArray(raw.aspects)) {\n throw new Error(`flow.yaml at ${flowYamlPath}: 'aspects' must be an array of strings`);\n }\n const aspectTags = (raw.aspects as unknown[]).filter((a): a is string => typeof a === 'string');\n aspects = aspectTags.length > 0 ? aspectTags : [];\n }\n\n const artifacts = await readArtifacts(flowDir, ['flow.yaml']);\n\n return {\n path: path.basename(flowDir),\n name: (raw.name as string).trim(),\n nodes: nodePaths,\n ...(aspects !== undefined && { aspects }),\n artifacts,\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { parse as parseYaml } from 'yaml';\nimport type { SchemaDef } from '../model/types.js';\n\nexport async function parseSchema(filePath: string): Promise<SchemaDef> {\n const content = await readFile(filePath, 'utf-8');\n parseYaml(content); // validate YAML is parseable\n const schemaType = path.basename(filePath, path.extname(filePath));\n return { schemaType };\n}\n","import path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { stat } from 'node:fs/promises';\n\n/**\n * Directory containing the CLI package (dist/ when bundled).\n * Uses import.meta.url so it works when installed globally.\n */\nexport function getPackageRoot(): string {\n return path.dirname(fileURLToPath(import.meta.url));\n}\n\n/**\n * Find the .yggdrasil/ directory starting from projectRoot.\n * Searches upward through parent directories until found or filesystem root.\n * Returns the absolute path to the .yggdrasil/ directory.\n */\nexport async function findYggRoot(projectRoot: string): Promise<string> {\n let current = path.resolve(projectRoot);\n const root = path.parse(current).root;\n\n while (true) {\n const yggPath = path.join(current, '.yggdrasil');\n try {\n const st = await stat(yggPath);\n if (!st.isDirectory()) {\n throw new Error(\n `.yggdrasil exists but is not a directory (${yggPath}). Run 'yg init' in a clean location.`,\n );\n }\n return yggPath;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n if (current === root) {\n throw new Error(`No .yggdrasil/ directory found. Run 'yg init' first.`, { cause: err });\n }\n current = path.dirname(current);\n continue;\n }\n throw err;\n }\n }\n}\n\nimport type { NodeMapping } from '../model/types.js';\n\n/**\n * Normalize a mapping to always return an array of paths (relative to project root).\n * Each path can be a file or directory — type is detected at runtime by hash/owner.\n */\nexport function normalizeMappingPaths(mapping: NodeMapping | undefined): string[] {\n if (!mapping?.paths?.length) return [];\n return mapping.paths.map((p) => p.trim()).filter(Boolean);\n}\n\n/**\n * Convert a node's directory path to its graph path.\n * E.g., \"/abs/path/.yggdrasil/orders/order-service\" → \"orders/order-service\"\n */\nexport function toGraphPath(absolutePath: string, yggRoot: string): string {\n return path.relative(yggRoot, absolutePath).split(path.sep).join('/');\n}\n\n/**\n * Normalize a user-provided path to project-relative POSIX form.\n * Throws when the target path points outside the project root.\n */\nexport function normalizeProjectRelativePath(projectRoot: string, rawPath: string): string {\n const normalizedInput = rawPath.trim().replace(/\\\\/g, '/');\n if (normalizedInput.length === 0) {\n throw new Error('Path cannot be empty');\n }\n\n const absolute = path.resolve(projectRoot, normalizedInput);\n const relative = path.relative(projectRoot, absolute);\n const isOutside = relative.startsWith('..') || path.isAbsolute(relative);\n if (isOutside) {\n throw new Error(`Path is outside project root: ${rawPath}`);\n }\n\n return relative.split(path.sep).join('/');\n}\n\n/**\n * Normalize a --node path argument: strip leading ./ and trailing /.\n */\nexport function normalizeNodePath(rawPath: string): string {\n return rawPath.trim().replace(/^\\.\\//, '').replace(/\\/+$/, '');\n}\n\n/**\n * Derive the actual project root (repo root) from the graph's .yggdrasil/ path.\n */\nexport function projectRootFromGraph(yggRootPath: string): string {\n return path.dirname(yggRootPath);\n}\n","import { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport type {\n Graph,\n GraphNode,\n ContextPackage,\n ContextLayer,\n ContextSection,\n YggConfig,\n AspectDef,\n FlowDef,\n Relation,\n} from '../model/types.js';\nimport { normalizeMappingPaths } from '../utils/paths.js';\nimport { estimateTokens } from '../utils/tokens.js';\n\nconst STRUCTURAL_RELATION_TYPES = new Set(['uses', 'calls', 'extends', 'implements']);\nconst EVENT_RELATION_TYPES = new Set(['emits', 'listens']);\n\nexport async function buildContext(graph: Graph, nodePath: string): Promise<ContextPackage> {\n const node = graph.nodes.get(nodePath);\n if (!node) {\n throw new Error(`Node not found: ${nodePath}`);\n }\n\n const layers: ContextLayer[] = [];\n\n // 1. Global\n layers.push(buildGlobalLayer(graph.config));\n\n // 2. Hierarchy (only configured artifacts that exist in ancestor's directory)\n const ancestors = collectAncestors(node);\n for (const ancestor of ancestors) {\n layers.push(buildHierarchyLayer(ancestor, graph.config, graph));\n }\n\n // 3. Own (node.yaml + configured artifacts)\n layers.push(await buildOwnLayer(node, graph.config, graph.rootPath, graph));\n\n // 4. Relational (structural + event, with consumes/failure)\n // Skip relations targeting ancestors — their context is already in hierarchy layers.\n const ancestorPaths = new Set(ancestors.map((a) => a.path));\n for (const relation of node.meta.relations ?? []) {\n const target = graph.nodes.get(relation.target);\n if (!target) {\n throw new Error(`Broken relation: ${nodePath} -> ${relation.target} (target not found)`);\n }\n if (ancestorPaths.has(relation.target)) continue;\n if (STRUCTURAL_RELATION_TYPES.has(relation.type)) {\n layers.push(buildStructuralRelationLayer(target, relation, graph.config));\n } else if (EVENT_RELATION_TYPES.has(relation.type)) {\n layers.push(buildEventRelationLayer(target, relation));\n }\n }\n\n // 5. Flows (node + all ancestors) — built before aspects so we can collect flow aspect ids\n for (const flow of collectParticipatingFlows(graph, node)) {\n layers.push(buildFlowLayer(flow, graph));\n }\n\n // 6. Aspects: union of aspect ids from hierarchy + own + flow layers\n const allAspectIds = new Set<string>();\n for (const l of layers) {\n const aspects = l.attrs?.aspects;\n if (aspects) {\n for (const id of aspects.split(',').map((t) => t.trim()).filter(Boolean)) {\n allAspectIds.add(id);\n }\n }\n }\n const aspectsToInclude = resolveAspects(allAspectIds, graph.aspects);\n for (const aspect of aspectsToInclude) {\n layers.push(buildAspectLayer(aspect));\n }\n\n const fullText = layers.map((l) => l.content).join('\\n\\n');\n const tokenCount = estimateTokens(fullText);\n const mapping = normalizeMappingPaths(node.meta.mapping);\n const sections = buildSections(layers, mapping.length > 0 ? mapping : null);\n\n return {\n nodePath,\n nodeName: node.meta.name,\n layers,\n sections,\n mapping: mapping.length > 0 ? mapping : null,\n tokenCount,\n };\n}\n\nfunction collectParticipatingFlows(graph: Graph, node: GraphNode): FlowDef[] {\n const paths = new Set<string>([node.path, ...collectAncestors(node).map((a) => a.path)]);\n return graph.flows.filter((f) => f.nodes.some((n) => paths.has(n)));\n}\n\n/** Expand aspect ids to include implied ids recursively. Returns unique list. */\nexport function expandAspects(aspectIds: string[], aspects: AspectDef[]): string[] {\n const idToAspect = new Map<string, AspectDef>();\n for (const a of aspects) {\n idToAspect.set(a.id, a);\n }\n const result: string[] = [];\n const visited = new Set<string>();\n const stack = new Set<string>();\n\n function collect(id: string): void {\n if (stack.has(id)) {\n throw new Error(`Aspect implies cycle detected involving aspect '${id}'`);\n }\n if (visited.has(id)) return;\n stack.add(id);\n visited.add(id);\n result.push(id);\n const aspect = idToAspect.get(id);\n if (aspect) {\n for (const implied of aspect.implies ?? []) {\n collect(implied);\n }\n }\n stack.delete(id);\n }\n\n for (const id of aspectIds) {\n collect(id);\n }\n return result;\n}\n\n/** Expand aspect ids to AspectDefs including implied (recursive, with cycle detection). */\nexport function resolveAspects(\n aspectIds: Iterable<string>,\n aspects: AspectDef[],\n): AspectDef[] {\n const idToAspect = new Map<string, AspectDef>();\n for (const a of aspects) {\n idToAspect.set(a.id, a);\n }\n const expandedIds = expandAspects([...aspectIds], aspects);\n return expandedIds\n .map((id) => idToAspect.get(id))\n .filter((a): a is AspectDef => a !== undefined);\n}\n\n// --- backward-compat aliases (used by tests / external callers) ---\nexport const expandTags = expandAspects;\nexport const expandAspectsForTags = resolveAspects;\n\n// --- Layer builders (exported for testing) ---\n\nexport function buildGlobalLayer(config: YggConfig): ContextLayer {\n let content = `**Project:** ${config.name}\\n\\n`;\n content += `**Stack:**\\n`;\n for (const [key, value] of Object.entries(config.stack)) {\n content += `- ${key}: ${value}\\n`;\n }\n content += `\\n**Standards:**\\n${config.standards || '(none)'}\\n`;\n return { type: 'global', label: 'Global Context', content };\n}\n\nfunction filterArtifactsByConfig(\n artifacts: Array<{ filename: string; content: string }>,\n config: YggConfig,\n): Array<{ filename: string; content: string }> {\n const allowed = new Set(Object.keys(config.artifacts ?? {}));\n return artifacts.filter((a) => allowed.has(a.filename));\n}\n\nexport function buildHierarchyLayer(\n ancestor: GraphNode,\n config: YggConfig,\n graph: Graph,\n): ContextLayer {\n const filtered = filterArtifactsByConfig(ancestor.artifacts, config);\n const content = filtered.map((a) => `### ${a.filename}\\n${a.content}`).join('\\n\\n');\n const nodeAspects = ancestor.meta.aspects ?? [];\n const expanded = expandAspects(nodeAspects, graph.aspects);\n const attrs: Record<string, string> | undefined =\n expanded.length > 0 ? { aspects: expanded.join(',') } : undefined;\n return {\n type: 'hierarchy',\n label: `Module Context (${ancestor.path}/)`,\n content,\n attrs,\n };\n}\n\nexport async function buildOwnLayer(\n node: GraphNode,\n config: YggConfig,\n graphRootPath: string,\n graph: Graph,\n): Promise<ContextLayer> {\n const parts: string[] = [];\n\n if (node.nodeYamlRaw) {\n parts.push(`### node.yaml\\n${node.nodeYamlRaw.trim()}`);\n } else {\n const nodeYamlPath = path.join(graphRootPath, 'model', node.path, 'node.yaml');\n try {\n const nodeYamlContent = await readFile(nodeYamlPath, 'utf-8');\n parts.push(`### node.yaml\\n${nodeYamlContent.trim()}`);\n } catch {\n parts.push(`### node.yaml\\n(not found)`);\n }\n }\n\n const filtered = filterArtifactsByConfig(node.artifacts, config);\n for (const a of filtered) {\n parts.push(`### ${a.filename}\\n${a.content}`);\n }\n\n const content = parts.join('\\n\\n');\n const nodeAspects = node.meta.aspects ?? [];\n const expanded = expandAspects(nodeAspects, graph.aspects);\n const attrs: Record<string, string> | undefined =\n expanded.length > 0 ? { aspects: expanded.join(',') } : undefined;\n return {\n type: 'own',\n label: `Node: ${node.meta.name}`,\n content,\n attrs,\n };\n}\n\nexport function buildStructuralRelationLayer(\n target: GraphNode,\n relation: Relation,\n config: YggConfig,\n): ContextLayer {\n let content = '';\n if (relation.consumes?.length) {\n content += `Consumes: ${relation.consumes.join(', ')}\\n\\n`;\n }\n if (relation.failure) {\n content += `On failure: ${relation.failure}\\n\\n`;\n }\n\n const structuralArtifactFilenames = Object.entries(config.artifacts ?? {})\n .filter(([, c]) => c.structural_context)\n .map(([filename]) => filename);\n\n const structuralArts = structuralArtifactFilenames\n .map((filename) => {\n const art = target.artifacts.find((a) => a.filename === filename);\n return art ? { filename: art.filename, content: art.content } : null;\n })\n .filter((a): a is { filename: string; content: string } => a !== null);\n\n if (structuralArts.length > 0) {\n content += structuralArts.map((a) => `### ${a.filename}\\n${a.content}`).join('\\n\\n');\n } else {\n const filtered = filterArtifactsByConfig(target.artifacts, config);\n content += filtered.map((a) => `### ${a.filename}\\n${a.content}`).join('\\n\\n');\n }\n\n const attrs: Record<string, string> = {\n target: target.path,\n type: relation.type,\n };\n if (relation.consumes?.length) attrs.consumes = relation.consumes.join(', ');\n if (relation.failure) attrs.failure = relation.failure;\n\n return {\n type: 'relational',\n label: `Dependency: ${target.meta.name} (${relation.type}) — ${target.path}`,\n content: content.trim(),\n attrs,\n };\n}\n\nexport function buildEventRelationLayer(target: GraphNode, relation: Relation): ContextLayer {\n const eventName = relation.event_name ?? target.meta.name;\n const isEmit = relation.type === 'emits';\n let content = isEmit\n ? `Target: ${target.path}\\nYou publish ${eventName}.`\n : `Source: ${target.path}\\nYou listen for ${eventName}.`;\n if (relation.consumes?.length) {\n content += `\\nConsumes: ${relation.consumes.join(', ')}`;\n }\n const attrs: Record<string, string> = {\n target: target.path,\n type: relation.type,\n 'event-name': eventName,\n };\n if (relation.consumes?.length) attrs.consumes = relation.consumes.join(', ');\n\n return {\n type: 'relational',\n label: `Event: ${eventName} [${relation.type}]`,\n content,\n attrs,\n };\n}\n\nexport function buildAspectLayer(aspect: AspectDef): ContextLayer {\n const content = aspect.artifacts.map((a) => `### ${a.filename}\\n${a.content}`).join('\\n\\n');\n return {\n type: 'aspects',\n label: `${aspect.name} (aspect: ${aspect.id})`,\n content,\n };\n}\n\nfunction buildFlowLayer(flow: FlowDef, graph: Graph): ContextLayer {\n const content = flow.artifacts.map((a) => `### ${a.filename}\\n${a.content}`).join('\\n\\n');\n const flowAspects = flow.aspects ?? [];\n const expanded = expandAspects(flowAspects, graph.aspects);\n const attrs: Record<string, string> | undefined =\n expanded.length > 0 ? { aspects: expanded.join(',') } : undefined;\n return {\n type: 'flows',\n label: `Flow: ${flow.name}`,\n content: content || '(no artifacts)',\n attrs,\n };\n}\n\nfunction buildSections(layers: ContextLayer[], mapping: string[] | null): ContextSection[] {\n const ownLayers = layers.filter((layer) => layer.type === 'own');\n if (mapping && mapping.length > 0) {\n ownLayers.push({\n type: 'own',\n label: 'Materialization Target',\n content: mapping.join(', '),\n });\n }\n\n return [\n { key: 'Global', layers: layers.filter((l) => l.type === 'global') },\n { key: 'Hierarchy', layers: layers.filter((l) => l.type === 'hierarchy') },\n { key: 'OwnArtifacts', layers: ownLayers },\n { key: 'Aspects', layers: layers.filter((l) => l.type === 'aspects') },\n {\n key: 'Relational',\n layers: [\n ...layers.filter((l) => l.type === 'relational'),\n ...layers.filter((l) => l.type === 'flows'),\n ],\n },\n ];\n}\n\n// --- Helpers (exported for testing) ---\n\nexport function collectAncestors(node: GraphNode): GraphNode[] {\n const ancestors: GraphNode[] = [];\n let current = node.parent;\n while (current) {\n ancestors.unshift(current);\n current = current.parent;\n }\n return ancestors;\n}\n\n/** Compute effective aspect ids for a node: own + hierarchy + flow + implies expanded. */\nexport function collectEffectiveAspectIds(graph: Graph, nodePath: string): Set<string> {\n const node = graph.nodes.get(nodePath);\n if (!node) return new Set();\n\n const raw = new Set<string>(node.meta.aspects ?? []);\n\n // Hierarchy aspects\n let ancestor = node.parent;\n while (ancestor) {\n for (const id of ancestor.meta.aspects ?? []) raw.add(id);\n ancestor = ancestor.parent;\n }\n\n // Flow aspects (flows where node or ancestor participates)\n const ancestorPaths = new Set([nodePath, ...collectAncestors(node).map((a) => a.path)]);\n for (const flow of graph.flows) {\n if (flow.nodes.some((n) => ancestorPaths.has(n))) {\n for (const id of flow.aspects ?? []) raw.add(id);\n }\n }\n\n // Expand implies\n return new Set(expandAspects([...raw], graph.aspects));\n}\n","/**\n * Estimate token count for a string.\n * Heuristic: ~4 characters per token (no tokenizer dependency).\n */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n","import { readdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Graph, ValidationResult, ValidationIssue, ArtifactConfig } from '../model/types.js';\nimport { buildContext, resolveAspects } from './context-builder.js';\nimport { normalizeMappingPaths } from '../utils/paths.js';\n\n/** Reserved directories that are NOT nodes (within model/) */\nconst RESERVED_DIRS = new Set<string>();\n\nexport async function validate(graph: Graph, scope: string = 'all'): Promise<ValidationResult> {\n const issues: ValidationIssue[] = [];\n\n if (graph.configError) {\n issues.push({\n severity: 'error',\n code: 'E012',\n rule: 'invalid-config',\n message: graph.configError,\n });\n }\n\n for (const { nodePath, message } of graph.nodeParseErrors ?? []) {\n issues.push({\n severity: 'error',\n code: 'E001',\n rule: 'invalid-node-yaml',\n message,\n nodePath,\n });\n }\n\n if (!graph.configError) {\n issues.push(...checkNodeTypes(graph));\n issues.push(...checkAspectsDefined(graph));\n issues.push(...checkAspectIds(graph));\n issues.push(...checkAspectIdUniqueness(graph));\n issues.push(...checkImpliedAspectsExist(graph));\n issues.push(...checkImpliesNoCycles(graph));\n issues.push(...checkRequiredAspectsCoverage(graph));\n issues.push(...checkRequiredArtifacts(graph));\n issues.push(...checkInvalidArtifactConditions(graph));\n issues.push(...(await checkContextBudget(graph)));\n issues.push(...checkHighFanOut(graph));\n }\n\n issues.push(...checkSchemas(graph));\n issues.push(...checkRelationTargets(graph));\n issues.push(...checkNoCycles(graph));\n issues.push(...checkMappingOverlap(graph));\n issues.push(...(await checkMappingPathsExist(graph)));\n issues.push(...checkBrokenFlowRefs(graph));\n issues.push(...checkFlowAspectIds(graph));\n issues.push(...(await checkDirectoriesHaveNodeYaml(graph)));\n issues.push(...(await checkShallowArtifacts(graph)));\n issues.push(...checkUnpairedEvents(graph));\n\n let filtered = issues;\n let nodesScanned = graph.nodes.size;\n if (scope !== 'all' && scope.trim()) {\n if (!graph.nodes.has(scope)) {\n // Check if the node exists but has a parse error\n const parseError = (graph.nodeParseErrors ?? []).find(\n (e) => e.nodePath === scope || scope.startsWith(e.nodePath + '/'),\n );\n if (parseError) {\n return {\n issues: [{\n severity: 'error',\n code: 'E001',\n rule: 'invalid-node-yaml',\n message: parseError.message,\n nodePath: parseError.nodePath,\n }],\n nodesScanned: 0,\n };\n }\n return {\n issues: [{ severity: 'error', rule: 'invalid-scope', message: `Node not found: ${scope}` }],\n nodesScanned: 0,\n };\n }\n const scopePrefix = scope + '/';\n filtered = issues.filter((i) => !i.nodePath || i.nodePath === scope || i.nodePath.startsWith(scopePrefix));\n nodesScanned = [...graph.nodes.keys()].filter((p) => p === scope || p.startsWith(scopePrefix)).length;\n }\n\n return { issues: filtered, nodesScanned };\n}\n\n// --- Rule 0: Node types from config ---\n\nfunction checkNodeTypes(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const allowedTypes = new Set((graph.config.node_types ?? []).map((t) => t.name));\n for (const [nodePath, node] of graph.nodes) {\n if (!allowedTypes.has(node.meta.type)) {\n issues.push({\n severity: 'error',\n code: 'E002',\n rule: 'unknown-node-type',\n message: `Node type '${node.meta.type}' not in config.node_types (${[...allowedTypes].join(', ')})`,\n nodePath,\n });\n }\n }\n return issues;\n}\n\n// --- Rule 1: Relation targets exist ---\n\nfunction findSimilar(target: string, candidates: string[]): string | null {\n if (candidates.length === 0) return null;\n\n let best: string | null = null;\n let bestScore = -1;\n\n for (const c of candidates) {\n if (c === target) return c;\n // Simple similarity: shared path segments\n const targetParts = target.split('/');\n const candParts = c.split('/');\n let score = 0;\n for (let i = 0; i < Math.min(targetParts.length, candParts.length); i++) {\n if (targetParts[i] === candParts[i]) score++;\n else break;\n }\n if (score > bestScore && score > 0) {\n bestScore = score;\n best = c;\n }\n }\n return best;\n}\n\nfunction checkRelationTargets(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const nodePaths = [...graph.nodes.keys()];\n for (const [nodePath, node] of graph.nodes) {\n for (const rel of node.meta.relations ?? []) {\n if (!graph.nodes.has(rel.target)) {\n const suggestion = findSimilar(rel.target, nodePaths);\n const parts = rel.target.split('/');\n const parentPrefix = parts.length > 1 ? parts.slice(0, -1).join('/') + '/' : '';\n const existingInParent = nodePaths\n .filter((p) => p.startsWith(parentPrefix) && p !== rel.target)\n .map((p) => {\n const rest = p.slice(parentPrefix.length);\n return rest.split('/')[0];\n })\n .filter((v, i, a) => a.indexOf(v) === i)\n .sort();\n const existingLine =\n existingInParent.length > 0\n ? `\\n Existing nodes in ${parentPrefix || 'model/'}: ${existingInParent.join(', ')}`\n : '';\n const hint = suggestion ? `\\n Did you mean '${suggestion}'?` : '';\n issues.push({\n severity: 'error',\n code: 'E004',\n rule: 'broken-relation',\n message: `Relation target '${rel.target}' does not exist${existingLine}${hint}`,\n nodePath,\n });\n }\n }\n }\n return issues;\n}\n\n// --- Rule 2: Node aspects must reference a defined aspect ---\n\nfunction checkAspectsDefined(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const validAspectIds = new Set(graph.aspects.map((a) => a.id));\n for (const [nodePath, node] of graph.nodes) {\n for (const aspectId of node.meta.aspects ?? []) {\n if (!validAspectIds.has(aspectId)) {\n issues.push({\n severity: 'error',\n code: 'E003',\n rule: 'unknown-aspect',\n message: `Aspect '${aspectId}' has no corresponding directory in aspects/`,\n nodePath,\n });\n }\n }\n }\n return issues;\n}\n\n// --- Rule 3: Aspect ids (derived from directory path) — always valid when aspect exists ---\n\nfunction checkAspectIds(_graph: Graph): ValidationIssue[] {\n // validAspectIds = graph.aspects.map(a => a.id), so every aspect's id is valid by definition\n return [];\n}\n\nfunction checkAspectIdUniqueness(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const byId = new Map<string, string[]>();\n for (const aspect of graph.aspects) {\n const names = byId.get(aspect.id) ?? [];\n names.push(aspect.name);\n byId.set(aspect.id, names);\n }\n for (const [id, names] of byId) {\n if (names.length <= 1) continue;\n issues.push({\n severity: 'error',\n code: 'E014',\n rule: 'duplicate-aspect-binding',\n message: `Aspect '${id}' is bound to multiple aspects (${names.join(', ')})`,\n });\n }\n return issues;\n}\n\n// --- Rule: Implied aspects exist ---\n\nfunction checkImpliedAspectsExist(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const idToAspect = new Map<string, { name: string }>();\n for (const a of graph.aspects) {\n idToAspect.set(a.id, { name: a.name });\n }\n for (const aspect of graph.aspects) {\n for (const impliedId of aspect.implies ?? []) {\n if (!idToAspect.has(impliedId)) {\n issues.push({\n severity: 'error',\n code: 'E016',\n rule: 'implied-aspect-missing',\n message: `Aspect '${aspect.name}' implies '${impliedId}' but no aspect with that id exists in aspects/`,\n });\n }\n }\n }\n return issues;\n}\n\n// --- Rule: No cycles in aspect implies graph ---\n\nfunction checkImpliesNoCycles(graph: Graph): ValidationIssue[] {\n const idToAspect = new Map<string, { implies?: string[] }>();\n for (const a of graph.aspects) {\n idToAspect.set(a.id, { implies: a.implies });\n }\n const WHITE = 0;\n const GRAY = 1;\n const BLACK = 2;\n const color = new Map<string, number>();\n for (const id of idToAspect.keys()) color.set(id, WHITE);\n\n const issues: ValidationIssue[] = [];\n\n function dfs(id: string, pathArr: string[]): boolean {\n color.set(id, GRAY);\n pathArr.push(id);\n const aspect = idToAspect.get(id);\n for (const implied of aspect?.implies ?? []) {\n if (color.get(implied) === GRAY) {\n const cycle = pathArr.slice(pathArr.indexOf(implied)).concat(implied);\n issues.push({\n severity: 'error',\n code: 'E017',\n rule: 'aspect-implies-cycle',\n message: `Aspect implies cycle: ${cycle.join(' → ')}`,\n });\n pathArr.pop();\n color.set(id, BLACK);\n return true;\n }\n if (color.get(implied) === WHITE && dfs(implied, pathArr)) {\n pathArr.pop();\n color.set(id, BLACK);\n return true;\n }\n }\n pathArr.pop();\n color.set(id, BLACK);\n return false;\n }\n\n for (const id of idToAspect.keys()) {\n if (color.get(id) === WHITE) {\n dfs(id, []);\n }\n }\n return issues;\n}\n\n// --- Rule: Required aspects coverage per node type ---\n\nfunction checkRequiredAspectsCoverage(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const typeConfig = new Map(\n (graph.config.node_types ?? []).map((t) => [t.name, t.required_aspects ?? []]),\n );\n for (const [nodePath, node] of graph.nodes) {\n if (node.meta.blackbox) continue;\n const requiredAspects = typeConfig.get(node.meta.type);\n if (!requiredAspects || requiredAspects.length === 0) continue;\n\n const nodeAspects = node.meta.aspects ?? [];\n let effectiveAspects;\n try {\n effectiveAspects = resolveAspects(nodeAspects, graph.aspects);\n } catch {\n continue;\n }\n const effectiveAspectIds = new Set(effectiveAspects.map((a) => a.id));\n\n for (const required of requiredAspects) {\n if (!effectiveAspectIds.has(required)) {\n issues.push({\n severity: 'warning',\n code: 'W011',\n rule: 'missing-required-aspect-coverage',\n message: `Node '${nodePath}' (type: ${node.meta.type}) missing required aspect coverage for '${required}'`,\n nodePath,\n });\n }\n }\n }\n return issues;\n}\n\n// --- Rule 4: No circular dependencies (cycles involving blackbox are tolerated) ---\n\nfunction checkNoCycles(graph: Graph): ValidationIssue[] {\n const WHITE = 0;\n const GRAY = 1;\n const BLACK = 2;\n const color = new Map<string, number>();\n for (const p of graph.nodes.keys()) color.set(p, WHITE);\n\n const issues: ValidationIssue[] = [];\n\n function dfs(nodePath: string, pathSegments: string[]): boolean {\n color.set(nodePath, GRAY);\n const node = graph.nodes.get(nodePath)!;\n const structuralTypes = new Set(['uses', 'calls', 'extends', 'implements']);\n for (const rel of node.meta.relations ?? []) {\n const targetNode = graph.nodes.get(rel.target);\n if (!targetNode) continue;\n if (!structuralTypes.has(rel.type)) continue;\n if (color.get(rel.target) === GRAY) {\n const cyclePath = [...pathSegments, nodePath, rel.target];\n const cycleNodes = pathSegments.slice(pathSegments.indexOf(rel.target)).concat(nodePath);\n const hasBlackboxInCycle = cycleNodes.some(\n (p) => graph.nodes.get(p)?.meta.blackbox === true,\n );\n if (!hasBlackboxInCycle) {\n issues.push({\n severity: 'error',\n code: 'E010',\n rule: 'structural-cycle',\n message: `Circular dependency: ${cyclePath.join(' -> ')}`,\n });\n }\n return true;\n }\n if (color.get(rel.target) === WHITE) {\n if (dfs(rel.target, [...pathSegments, nodePath])) return true;\n }\n }\n color.set(nodePath, BLACK);\n return false;\n }\n\n for (const nodePath of graph.nodes.keys()) {\n if (color.get(nodePath) === WHITE) {\n dfs(nodePath, []);\n }\n }\n\n return issues;\n}\n\n// --- Rule 5: Mapping ownership overlap ---\n\nfunction normalizePathForCompare(mappingPath: string): string {\n return mappingPath.replace(/\\\\/g, '/').replace(/\\/+$/, '');\n}\n\nfunction arePathsOverlapping(pathA: string, pathB: string): boolean {\n if (pathA === pathB) return true;\n return pathA.startsWith(pathB + '/') || pathB.startsWith(pathA + '/');\n}\n\nfunction isAncestorNode(possibleAncestor: string, possibleDescendant: string): boolean {\n return possibleDescendant.startsWith(possibleAncestor + '/');\n}\n\nfunction checkMappingOverlap(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const ownership: Array<{ nodePath: string; mappingPath: string }> = [];\n\n for (const [nodePath, node] of graph.nodes) {\n const mappingPaths = normalizeMappingPaths(node.meta.mapping)\n .map(normalizePathForCompare)\n .filter((mappingPath) => mappingPath.length > 0);\n for (const mappingPath of mappingPaths) {\n ownership.push({ nodePath, mappingPath });\n }\n }\n\n for (let index = 0; index < ownership.length; index++) {\n const current = ownership[index];\n for (let nestedIndex = index + 1; nestedIndex < ownership.length; nestedIndex++) {\n const candidate = ownership[nestedIndex];\n if (current.nodePath === candidate.nodePath) continue;\n if (!arePathsOverlapping(current.mappingPath, candidate.mappingPath)) continue;\n\n // Allow containment overlaps between ancestor-descendant nodes (\"child wins\" model).\n // Exact duplicates (same path) are always errors regardless of hierarchy.\n const isContainment = current.mappingPath !== candidate.mappingPath;\n const isHierarchical =\n isAncestorNode(current.nodePath, candidate.nodePath) ||\n isAncestorNode(candidate.nodePath, current.nodePath);\n\n if (isContainment && isHierarchical) continue;\n\n issues.push({\n severity: 'error',\n code: 'E009',\n rule: 'overlapping-mapping',\n message:\n `Mapping paths '${current.mappingPath}' (${current.nodePath}) and ` +\n `'${candidate.mappingPath}' (${candidate.nodePath}) overlap. ` +\n `Keep one owner mapping and model other concerns via relations.`,\n nodePath: candidate.nodePath,\n });\n }\n }\n\n return issues;\n}\n\n// --- Rule: Mapping paths should exist on disk (W012) ---\n\nasync function checkMappingPathsExist(graph: Graph): Promise<ValidationIssue[]> {\n const issues: ValidationIssue[] = [];\n const projectRoot = path.dirname(graph.rootPath);\n const { access } = await import('node:fs/promises');\n\n for (const [nodePath, node] of graph.nodes) {\n const mappingPaths = normalizeMappingPaths(node.meta.mapping);\n for (const mp of mappingPaths) {\n const absPath = path.join(projectRoot, mp);\n try {\n await access(absPath);\n } catch {\n issues.push({\n severity: 'warning',\n code: 'W012',\n rule: 'mapping-path-missing',\n message: `Mapping path '${mp}' does not exist on disk`,\n nodePath,\n });\n }\n }\n }\n return issues;\n}\n\n// --- Rule 6: Required artifacts per config.artifacts (W001) ---\n\nfunction getIncomingRelationSources(graph: Graph, nodePath: string): string[] {\n const sources: string[] = [];\n for (const [srcPath, node] of graph.nodes) {\n for (const rel of node.meta.relations ?? []) {\n if (rel.target === nodePath) sources.push(srcPath);\n }\n }\n return sources;\n}\n\nfunction artifactRequiredReason(\n graph: Graph,\n nodePath: string,\n node: {\n meta: { relations?: Array<{ target: string }>; aspects?: string[]; blackbox?: boolean };\n artifacts: Array<{ filename: string }>;\n },\n required: ArtifactConfig['required'],\n): string | null {\n if (required === 'never') return null;\n if (required === 'always') {\n return node.meta.blackbox ? null : 'required: always';\n }\n const when = (required as { when: string }).when;\n if (when === 'has_incoming_relations') {\n const sources = getIncomingRelationSources(graph, nodePath);\n return sources.length > 0\n ? `${sources.length} incoming relation(s): ${sources.join(', ')}`\n : null;\n }\n if (when === 'has_outgoing_relations') {\n const count = node.meta.relations?.length ?? 0;\n return count > 0 ? `${count} outgoing relation(s)` : null;\n }\n if (when.startsWith('has_aspect:') || when.startsWith('has_tag:')) {\n const prefix = when.startsWith('has_aspect:') ? 'has_aspect:' : 'has_tag:';\n const aspectId = when.slice(prefix.length);\n return (node.meta.aspects ?? []).includes(aspectId) ? `node has aspect '${aspectId}'` : null;\n }\n return null;\n}\n\nfunction getIncomingRelations(graph: Graph, nodePath: string): string[] {\n const incoming: string[] = [];\n for (const [fromPath, node] of graph.nodes) {\n for (const rel of node.meta.relations ?? []) {\n if (rel.target === nodePath) {\n incoming.push(fromPath);\n break;\n }\n }\n }\n return incoming.sort();\n}\n\nfunction checkRequiredArtifacts(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const artifacts = graph.config.artifacts ?? {};\n\n for (const [nodePath, node] of graph.nodes) {\n for (const [filename, config] of Object.entries(artifacts)) {\n const hasArtifact = node.artifacts.some((a) => a.filename === filename);\n const reason = artifactRequiredReason(graph, nodePath, node, config.required);\n\n if (reason && !hasArtifact) {\n const action = config.description ?? '';\n const incoming = getIncomingRelations(graph, nodePath);\n const incomingStr =\n incoming.length > 0\n ? ` Node has ${incoming.length} incoming relation(s): ${incoming.slice(0, 5).join(', ')}${incoming.length > 5 ? '...' : ''}.`\n : '';\n const msg = action\n ? `Missing required artifact '${filename}' (${reason}).${incomingStr} ${action}`\n : `Missing required artifact '${filename}' (${reason}).${incomingStr}`;\n issues.push({\n severity: 'warning',\n code: 'W001',\n rule: 'missing-artifact',\n message: msg.trim(),\n nodePath,\n });\n }\n }\n }\n\n return issues;\n}\n\n// --- E006: Broken flow refs (flow.nodes) ---\n\nfunction checkBrokenFlowRefs(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const nodePaths = new Set(graph.nodes.keys());\n for (const flow of graph.flows) {\n for (const n of flow.nodes) {\n if (!nodePaths.has(n)) {\n issues.push({\n severity: 'error',\n code: 'E006',\n rule: 'broken-flow-ref',\n message: `Flow '${flow.name}' references non-existent node '${n}'`,\n });\n }\n }\n }\n return issues;\n}\n\n// --- E007: Flow aspect ids must have corresponding aspect ---\n\nfunction checkFlowAspectIds(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const validAspectIds = new Set(graph.aspects.map((a) => a.id));\n\n for (const flow of graph.flows) {\n for (const aspectId of flow.aspects ?? []) {\n if (!validAspectIds.has(aspectId)) {\n issues.push({\n severity: 'error',\n code: 'E007',\n rule: 'broken-aspect-ref',\n message: `Flow '${flow.name}' references aspect '${aspectId}' but no aspect with that id exists in aspects/`,\n });\n }\n }\n }\n return issues;\n}\n\n// --- E013: Invalid artifact condition (has_aspect:X where X has no aspect) ---\n\nfunction checkInvalidArtifactConditions(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const validAspectIds = new Set(graph.aspects.map((a) => a.id));\n const artifacts = graph.config.artifacts ?? {};\n for (const [artifactName, config] of Object.entries(artifacts)) {\n const required = config.required;\n if (typeof required === 'object' && required && 'when' in required) {\n const when = (required as { when: string }).when;\n if (when.startsWith('has_aspect:') || when.startsWith('has_tag:')) {\n const prefix = when.startsWith('has_aspect:') ? 'has_aspect:' : 'has_tag:';\n const aspectId = when.slice(prefix.length);\n if (!validAspectIds.has(aspectId)) {\n issues.push({\n severity: 'error',\n code: 'E013',\n rule: 'invalid-artifact-condition',\n message: `Artifact '${artifactName}' condition has_aspect:${aspectId} has no corresponding aspect in aspects/`,\n });\n }\n }\n }\n }\n return issues;\n}\n\n// --- W002: Shallow artifacts (below min_artifact_length) ---\n\nasync function checkShallowArtifacts(graph: Graph): Promise<ValidationIssue[]> {\n const issues: ValidationIssue[] = [];\n const minLen = graph.config.quality?.min_artifact_length ?? 50;\n for (const [nodePath, node] of graph.nodes) {\n for (const art of node.artifacts) {\n if (art.content.trim().length < minLen) {\n issues.push({\n severity: 'warning',\n code: 'W002',\n rule: 'shallow-artifact',\n message: `Artifact '${art.filename}' is below minimum length (${art.content.trim().length} < ${minLen})`,\n nodePath,\n });\n }\n }\n }\n return issues;\n}\n\n// --- W007: High fan-out (exceeds max_direct_relations) ---\n\nfunction checkHighFanOut(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const maxRel = graph.config.quality?.max_direct_relations ?? 10;\n for (const [nodePath, node] of graph.nodes) {\n const count = node.meta.relations?.length ?? 0;\n if (count > maxRel) {\n issues.push({\n severity: 'warning',\n code: 'W007',\n rule: 'high-fan-out',\n message: `Node has ${count} direct relations (max: ${maxRel})`,\n nodePath,\n });\n }\n }\n return issues;\n}\n\n// --- W009: Unpaired event relations (emits without listens or vice versa) ---\n\nfunction checkUnpairedEvents(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const emitsTo = new Map<string, Set<string>>();\n const listensFrom = new Map<string, Set<string>>();\n for (const [nodePath, node] of graph.nodes) {\n for (const rel of node.meta.relations ?? []) {\n if (rel.type === 'emits') {\n const set = emitsTo.get(nodePath) ?? new Set();\n set.add(rel.target);\n emitsTo.set(nodePath, set);\n }\n if (rel.type === 'listens') {\n const set = listensFrom.get(nodePath) ?? new Set();\n set.add(rel.target);\n listensFrom.set(nodePath, set);\n }\n }\n }\n for (const [emitter, targets] of emitsTo) {\n for (const target of targets) {\n const listenerSet = listensFrom.get(target);\n if (!listenerSet?.has(emitter)) {\n issues.push({\n severity: 'warning',\n code: 'W009',\n rule: 'unpaired-event',\n message: `Node '${emitter}' emits to '${target}' but '${target}' has no listens from '${emitter}'`,\n nodePath: emitter,\n });\n }\n }\n }\n for (const [listener, sources] of listensFrom) {\n for (const source of sources) {\n const emitterSet = emitsTo.get(source);\n if (!emitterSet?.has(listener)) {\n issues.push({\n severity: 'warning',\n code: 'W009',\n rule: 'unpaired-event',\n message: `Node '${listener}' listens from '${source}' but '${source}' has no emits to '${listener}'`,\n nodePath: listener,\n });\n }\n }\n }\n return issues;\n}\n\n// --- Schema validation (required graph-layer schemas present in schemas/) ---\n\nconst REQUIRED_SCHEMAS = ['node', 'aspect', 'flow'] as const;\n\nfunction checkSchemas(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const present = new Set(graph.schemas.map((s) => s.schemaType));\n\n for (const required of REQUIRED_SCHEMAS) {\n if (!present.has(required)) {\n issues.push({\n severity: 'warning',\n code: 'W010',\n rule: 'missing-schema',\n message: `Schema '${required}.yaml' missing from .yggdrasil/schemas/`,\n });\n }\n }\n\n return issues;\n}\n\n// --- Directories have node.yaml ---\n\nasync function checkDirectoriesHaveNodeYaml(graph: Graph): Promise<ValidationIssue[]> {\n const issues: ValidationIssue[] = [];\n const modelDir = path.join(graph.rootPath, 'model');\n\n async function scanDir(dirPath: string, segments: string[]): Promise<void> {\n const entries = await readdir(dirPath, { withFileTypes: true });\n const hasNodeYaml = entries.some((e) => e.isFile() && e.name === 'node.yaml');\n const dirName = path.basename(dirPath);\n\n if (RESERVED_DIRS.has(dirName)) return;\n\n const hasFiles = entries.some((e) => e.isFile());\n const hasSubdirs = entries.some((e) => e.isDirectory() && !RESERVED_DIRS.has(e.name) && !e.name.startsWith('.'));\n const graphPath = segments.join('/');\n\n if (!hasNodeYaml && graphPath !== '') {\n if (hasFiles) {\n issues.push({\n severity: 'error',\n code: 'E015',\n rule: 'missing-node-yaml',\n message: `Directory '${graphPath}' has files but no node.yaml`,\n nodePath: graphPath,\n });\n } else if (hasSubdirs) {\n issues.push({\n severity: 'warning',\n code: 'W013',\n rule: 'directory-without-node',\n message: `Directory '${graphPath}' has subdirectories but no node.yaml — consider creating a node`,\n nodePath: graphPath,\n });\n }\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (RESERVED_DIRS.has(entry.name)) continue;\n if (entry.name.startsWith('.')) continue;\n await scanDir(path.join(dirPath, entry.name), [...segments, entry.name]);\n }\n }\n\n try {\n const rootEntries = await readdir(modelDir, { withFileTypes: true });\n for (const entry of rootEntries) {\n if (!entry.isDirectory()) continue;\n if (entry.name.startsWith('.')) continue;\n await scanDir(path.join(modelDir, entry.name), [entry.name]);\n }\n } catch {\n // model/ may not exist\n }\n\n return issues;\n}\n\n// --- Context budget (W005 warning, W006 error) ---\n\nasync function checkContextBudget(graph: Graph): Promise<ValidationIssue[]> {\n const issues: ValidationIssue[] = [];\n const warningThreshold = graph.config.quality?.context_budget.warning ?? 10000;\n const errorThreshold = graph.config.quality?.context_budget.error ?? 20000;\n\n for (const [nodePath, node] of graph.nodes) {\n if (node.meta.blackbox) continue;\n try {\n const pkg = await buildContext(graph, nodePath);\n if (pkg.tokenCount >= errorThreshold) {\n issues.push({\n severity: 'warning',\n code: 'W006',\n rule: 'budget-error',\n message: `Context is ${pkg.tokenCount.toLocaleString()} tokens (error threshold: ${errorThreshold.toLocaleString()}) — blocks materialization, node must be split`,\n nodePath,\n });\n } else if (pkg.tokenCount >= warningThreshold) {\n issues.push({\n severity: 'warning',\n code: 'W005',\n rule: 'budget-warning',\n message: `Context is ${pkg.tokenCount.toLocaleString()} tokens (warning threshold: ${warningThreshold.toLocaleString()}). Consider splitting the node or reducing dependencies.`,\n nodePath,\n });\n }\n } catch {\n // If context building fails, other rules will catch it\n }\n }\n return issues;\n}\n","import type { ContextPackage, ContextLayer } from '../model/types.js';\n\nfunction escapeAttr(val: string): string {\n return val.replace(/\"/g, '"');\n}\n\nfunction formatLayer(layer: ContextLayer): string {\n switch (layer.type) {\n case 'global':\n return `<global>\\n${layer.content}\\n</global>`;\n case 'hierarchy': {\n const pathMatch = layer.label.match(/\\((.+)\\/\\)/);\n const pathAttr = pathMatch ? ` path=\"${escapeAttr(pathMatch[1])}\"` : '';\n const aspectsAttr = layer.attrs?.aspects ? ` aspects=\"${escapeAttr(layer.attrs.aspects)}\"` : '';\n return `<hierarchy${pathAttr}${aspectsAttr}>\\n${layer.content}\\n</hierarchy>`;\n }\n case 'own': {\n if (layer.label === 'Materialization Target') {\n return `<materialization-target paths=\"${escapeAttr(layer.content)}\" />`;\n }\n const ownAspectsAttr = layer.attrs?.aspects ? ` aspects=\"${escapeAttr(layer.attrs.aspects)}\"` : '';\n return `<own-artifacts${ownAspectsAttr}>\\n${layer.content}\\n</own-artifacts>`;\n }\n case 'aspects': {\n const nameMatch = layer.label.match(/^(.+?) \\(aspect: (.+)\\)$/);\n const name = nameMatch ? escapeAttr(nameMatch[1]) : '';\n const id = nameMatch ? escapeAttr(nameMatch[2]) : '';\n return `<aspect name=\"${name}\" id=\"${id}\">\\n${layer.content}\\n</aspect>`;\n }\n case 'relational': {\n const attrs = layer.attrs ?? {};\n const attrStr = Object.entries(attrs)\n .map(([k, v]) => ` ${k}=\"${escapeAttr(v)}\"`)\n .join('');\n const tagName = attrs.type && ['emits', 'listens'].includes(attrs.type) ? 'event' : 'dependency';\n return `<${tagName}${attrStr}>\\n${layer.content}\\n</${tagName}>`;\n }\n case 'flows': {\n const flowName = layer.label.replace(/^Flow: /, '').trim();\n const flowAspectsAttr = layer.attrs?.aspects ? ` aspects=\"${escapeAttr(layer.attrs.aspects)}\"` : '';\n return `<flow name=\"${escapeAttr(flowName)}\"${flowAspectsAttr}>\\n${layer.content}\\n</flow>`;\n }\n default:\n return layer.content;\n }\n}\n\nexport function formatContextText(pkg: ContextPackage): string {\n const attrs = [\n `node-path=\"${escapeAttr(pkg.nodePath)}\"`,\n `node-name=\"${escapeAttr(pkg.nodeName)}\"`,\n `token-count=\"${pkg.tokenCount}\"`,\n ].join(' ');\n\n let out = `<context-package ${attrs}>\\n\\n`;\n\n for (const section of pkg.sections) {\n for (const layer of section.layers) {\n out += formatLayer(layer) + '\\n\\n';\n }\n }\n\n out += '</context-package>';\n return out;\n}\n","import { Command } from 'commander';\nimport { loadGraph } from '../core/graph-loader.js';\nimport { buildContext, collectAncestors } from '../core/context-builder.js';\nimport { validate } from '../core/validator.js';\nimport { formatContextText } from '../formatters/context-text.js';\nimport type { Graph } from '../model/types.js';\n\n/**\n * Collect the set of node paths that participate in context assembly for a given node:\n * the node itself, its ancestors, and its direct relation targets.\n */\nfunction collectRelevantNodePaths(graph: Graph, nodePath: string): Set<string> {\n const relevant = new Set<string>();\n const node = graph.nodes.get(nodePath);\n if (!node) return relevant;\n\n relevant.add(nodePath);\n\n // Ancestors (hierarchy)\n for (const ancestor of collectAncestors(node)) {\n relevant.add(ancestor.path);\n }\n\n // Direct relation targets\n for (const rel of node.meta.relations ?? []) {\n relevant.add(rel.target);\n }\n\n return relevant;\n}\n\nexport function registerBuildCommand(program: Command): void {\n program\n .command('build-context')\n .description('Assemble a context package for one node')\n .requiredOption('--node <node-path>', 'Node path relative to .yggdrasil/model/')\n .action(async (options: { node: string }) => {\n try {\n const graph = await loadGraph(process.cwd());\n const nodePath = options.node.trim().replace(/^\\.\\//, '').replace(/\\/$/, '');\n\n // Collect nodes relevant to this context assembly\n const relevantNodes = collectRelevantNodePaths(graph, nodePath);\n\n // Validate but only block on errors relevant to this node's context\n const validationResult = await validate(graph, 'all');\n const relevantErrors = validationResult.issues.filter(\n (issue) =>\n issue.severity === 'error' &&\n // Global errors (no nodePath) always block — e.g., E012 invalid config\n (!issue.nodePath || relevantNodes.has(issue.nodePath)),\n );\n if (relevantErrors.length > 0) {\n const totalErrors = validationResult.issues.filter((i) => i.severity === 'error').length;\n const skippedErrors = totalErrors - relevantErrors.length;\n let msg = `Error: build-context blocked by ${relevantErrors.length} error(s) affecting this node's context.\\n`;\n if (skippedErrors > 0) {\n msg += `(${skippedErrors} unrelated error(s) in other nodes ignored.)\\n`;\n }\n for (const err of relevantErrors) {\n const loc = err.nodePath ? `${err.nodePath}: ` : '';\n msg += ` ${err.code ?? ''} ${loc}${err.message}\\n`;\n }\n process.stderr.write(msg);\n process.exit(1);\n }\n\n const pkg = await buildContext(graph, nodePath);\n const warningThreshold = graph.config.quality?.context_budget.warning ?? 10000;\n const errorThreshold = graph.config.quality?.context_budget.error ?? 20000;\n const budgetStatus =\n pkg.tokenCount >= errorThreshold\n ? 'error'\n : pkg.tokenCount >= warningThreshold\n ? 'warning'\n : 'ok';\n\n let output = formatContextText(pkg);\n output += `Budget status: ${budgetStatus}\\n`;\n process.stdout.write(output);\n\n if (budgetStatus === 'error') {\n process.stderr.write(\n `Warning: context package exceeds error budget (${pkg.tokenCount} >= ${errorThreshold}). Consider splitting the node.\\n`,\n );\n }\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { loadGraph } from '../core/graph-loader.js';\nimport { validate } from '../core/validator.js';\n\nexport function registerValidateCommand(program: Command): void {\n program\n .command('validate')\n .description('Validate graph structural integrity and completeness signals')\n .option('--scope <scope>', 'Scope: all or node-path (default: all)', 'all')\n .action(async (options: { scope: string }) => {\n try {\n const graph = await loadGraph(process.cwd(), { tolerateInvalidConfig: true });\n const rawScope = (options.scope ?? 'all').trim() || 'all';\n const scope = rawScope === 'all' ? 'all' : rawScope.replace(/^\\.\\//, '').replace(/\\/+$/, '');\n const result = await validate(graph, scope);\n process.stdout.write(`${result.nodesScanned} nodes scanned\\n\\n`);\n const errors = result.issues.filter((i) => i.severity === 'error');\n const warnings = result.issues.filter((i) => i.severity === 'warning');\n for (const issue of errors) {\n const code = issue.code ?? '';\n const loc = issue.nodePath ?? '';\n const prefix = loc ? `${code} ${loc} -> ` : `${code} `;\n process.stdout.write(chalk.red(`✗ ${prefix}${issue.message}\\n`));\n }\n for (const issue of warnings) {\n const code = issue.code ?? '';\n const loc = issue.nodePath ?? '';\n const prefix = loc ? `${code} ${loc} -> ` : `${code} `;\n process.stdout.write(chalk.yellow(`⚠ ${prefix}${issue.message}\\n`));\n }\n if (errors.length === 0 && warnings.length === 0) {\n process.stdout.write(chalk.green('✓ No issues found.\\n'));\n } else {\n process.stdout.write(`\\n${errors.length} errors, ${warnings.length} warnings.\\n`);\n }\n\n const hasErrors = result.issues.some((i) => i.severity === 'error');\n process.exit(hasErrors ? 1 : 0);\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { loadGraph } from '../core/graph-loader.js';\nimport { detectDrift } from '../core/drift-detector.js';\nimport type { DriftEntry, DriftReport } from '../model/types.js';\n\nexport function registerDriftCommand(program: Command): void {\n program\n .command('drift')\n .description('Detect divergences between graph and mapped files')\n .option('--scope <scope>', 'Scope: \"all\" or node path', 'all')\n .option('--drifted-only', 'Show only nodes with drift (hide ok entries)')\n .option('--limit <n>', 'Maximum number of entries to show per section', parseInt)\n .action(async (opts: { scope: string; driftedOnly?: boolean; limit?: number }) => {\n try {\n const graph = await loadGraph(process.cwd());\n const rawScope = (opts.scope ?? 'all').trim() || 'all';\n const scope = rawScope === 'all' ? 'all' : rawScope.replace(/^\\.\\//, '').replace(/\\/+$/, '');\n\n if (scope !== 'all') {\n const node = graph.nodes.get(scope);\n if (!node) {\n process.stderr.write(`Error: Node not found: ${scope}\\n`);\n process.exit(1);\n }\n // Check if scope or any descendant has a mapping\n const hasAnyMapping = node.meta.mapping ||\n [...graph.nodes.entries()].some(([p, n]) => p.startsWith(scope + '/') && n.meta.mapping);\n if (!hasAnyMapping) {\n process.stderr.write(`Error: Node has no mapping: ${scope}\\n`);\n process.exit(1);\n }\n }\n\n const scopeNode = scope === 'all' ? undefined : scope;\n const report = await detectDrift(graph, scopeNode);\n printReport(report, opts.driftedOnly ?? false, opts.limit);\n\n const hasIssues =\n report.sourceDriftCount > 0 ||\n report.graphDriftCount > 0 ||\n report.fullDriftCount > 0 ||\n report.missingCount > 0 ||\n report.unmaterializedCount > 0;\n process.exit(hasIssues ? 1 : 0);\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n\nfunction printReport(report: DriftReport, driftedOnly: boolean, limit?: number): void {\n const sourceEntries = classifyForSection(report.entries, 'source', driftedOnly);\n const graphEntries = classifyForSection(report.entries, 'graph', driftedOnly);\n\n const sourceShown = limit !== undefined ? sourceEntries.slice(0, limit) : sourceEntries;\n const graphShown = limit !== undefined ? graphEntries.slice(0, limit) : graphEntries;\n\n process.stdout.write('Source drift:\\n');\n printSectionEntries(sourceShown, 'source');\n if (limit !== undefined && sourceEntries.length > limit) {\n process.stdout.write(chalk.dim(` ... ${sourceEntries.length - limit} more (${sourceEntries.length} total)\\n`));\n }\n\n process.stdout.write('\\nGraph drift:\\n');\n printSectionEntries(graphShown, 'graph');\n if (limit !== undefined && graphEntries.length > limit) {\n process.stdout.write(chalk.dim(` ... ${graphEntries.length - limit} more (${graphEntries.length} total)\\n`));\n }\n\n // Summary line\n const parts: string[] = [\n `${report.sourceDriftCount} source-drift`,\n `${report.graphDriftCount} graph-drift`,\n `${report.fullDriftCount} full-drift`,\n `${report.missingCount} missing`,\n `${report.unmaterializedCount} unmaterialized`,\n ];\n\n let summary = `\\nSummary: ${parts.join(', ')}`;\n if (driftedOnly && report.okCount > 0) {\n summary += ` (${report.okCount} ok hidden)`;\n } else {\n summary += `, ${report.okCount} ok`;\n }\n process.stdout.write(summary + '\\n');\n}\n\n/**\n * Classify entries for a given section (source or graph).\n * Source section shows: source-drift, full-drift, missing, unmaterialized, ok\n * Graph section shows: graph-drift, full-drift, ok\n */\nfunction classifyForSection(\n entries: DriftEntry[],\n section: 'source' | 'graph',\n driftedOnly: boolean,\n): DriftEntry[] {\n return entries.filter((entry) => {\n if (section === 'source') {\n // Source section: source-drift, full-drift, missing, unmaterialized, ok\n if (entry.status === 'graph-drift') return false;\n if (entry.status === 'ok' && driftedOnly) return false;\n return true;\n } else {\n // Graph section: graph-drift, full-drift, ok\n if (\n entry.status === 'source-drift' ||\n entry.status === 'missing' ||\n entry.status === 'unmaterialized'\n )\n return false;\n if (entry.status === 'ok' && driftedOnly) return false;\n return true;\n }\n });\n}\n\nfunction printSectionEntries(entries: DriftEntry[], section: 'source' | 'graph'): void {\n if (entries.length === 0) {\n process.stdout.write(chalk.dim(' (none)\\n'));\n return;\n }\n\n for (const entry of entries) {\n printEntryLine(entry);\n printChangedFiles(entry, section);\n }\n}\n\nfunction printEntryLine(entry: DriftEntry): void {\n const pad = 13; // width for status label column\n switch (entry.status) {\n case 'ok':\n process.stdout.write(chalk.green(` ${'[ok]'.padEnd(pad)}${entry.nodePath}\\n`));\n break;\n case 'source-drift':\n process.stdout.write(chalk.red(` ${'[drift]'.padEnd(pad)}${entry.nodePath}\\n`));\n break;\n case 'graph-drift':\n process.stdout.write(chalk.magenta(` ${'[drift]'.padEnd(pad)}${entry.nodePath}\\n`));\n break;\n case 'full-drift':\n process.stdout.write(chalk.red(` ${'[drift]'.padEnd(pad)}${entry.nodePath}\\n`));\n break;\n case 'missing':\n process.stdout.write(chalk.yellow(` ${'[missing]'.padEnd(pad)}${entry.nodePath}\\n`));\n break;\n case 'unmaterialized':\n process.stdout.write(chalk.dim(` ${'[unmat.]'.padEnd(pad)}${entry.nodePath}\\n`));\n break;\n }\n}\n\nfunction printChangedFiles(entry: DriftEntry, section: 'source' | 'graph'): void {\n if (!entry.changedFiles || entry.changedFiles.length === 0) return;\n\n const indent = ' '.repeat(15); // align under node path\n const relevantFiles = entry.changedFiles.filter((f) => {\n if (section === 'source') return f.category === 'source';\n return f.category === 'graph';\n });\n\n for (const file of relevantFiles) {\n process.stdout.write(chalk.dim(`${indent}${file.filePath} (changed)\\n`));\n }\n}\n","import { readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { parse as yamlParse } from 'yaml';\nimport type { DriftState, DriftNodeState } from '../model/types.js';\n\nconst DRIFT_STATE_FILE = '.drift-state';\n\nexport async function readDriftState(yggRoot: string): Promise<DriftState> {\n try {\n const content = await readFile(path.join(yggRoot, DRIFT_STATE_FILE), 'utf-8');\n\n // Try JSON first (new format), fall back to YAML (legacy format)\n let raw: unknown;\n try {\n raw = JSON.parse(content);\n } catch {\n raw = yamlParse(content);\n }\n\n if (!raw || typeof raw !== 'object') return {};\n\n const state: DriftState = {};\n for (const [key, value] of Object.entries(raw)) {\n if (typeof value === 'object' && value !== null && 'hash' in value) {\n state[key] = value as DriftNodeState;\n }\n // Skip legacy string entries silently\n }\n return state;\n } catch {\n return {};\n }\n}\n\nexport async function writeDriftState(yggRoot: string, state: DriftState): Promise<void> {\n const content = JSON.stringify(state);\n await writeFile(path.join(yggRoot, DRIFT_STATE_FILE), content, 'utf-8');\n}\n","import { readFile, readdir, stat } from 'node:fs/promises';\nimport path from 'node:path';\nimport { createHash } from 'node:crypto';\nimport { createRequire } from 'node:module';\nimport { type Ignore, type Options as IgnoreOptions } from 'ignore';\nimport type { TrackedFile } from '../core/context-files.js';\n\nconst require = createRequire(import.meta.url);\nconst ignoreFactory = require('ignore') as (options?: IgnoreOptions) => Ignore;\n\ntype HashPathOptions = {\n projectRoot?: string;\n};\n\ntype GitignoreEntry = { basePath: string; matcher: Ignore };\n\nexport async function hashFile(filePath: string): Promise<string> {\n const content = await readFile(filePath);\n return createHash('sha256').update(content).digest('hex');\n}\n\nexport async function hashPath(targetPath: string, options: HashPathOptions = {}): Promise<string> {\n const projectRoot = options.projectRoot ? path.resolve(options.projectRoot) : undefined;\n const gitignoreStack = await loadRootGitignoreStack(projectRoot);\n const targetStat = await stat(targetPath);\n\n if (targetStat.isFile()) {\n // Mapped files are always hashed — gitignore only applies to directory scans.\n return hashFile(targetPath);\n }\n\n if (targetStat.isDirectory()) {\n const fileHashes = await collectDirectoryFileHashes(targetPath, targetPath, {\n projectRoot,\n gitignoreStack,\n });\n const digestInput = fileHashes\n .sort((a, b) => a.path.localeCompare(b.path))\n .map((entry) => `${entry.path}:${entry.hash}`)\n .join('\\n');\n return hashString(digestInput);\n }\n\n throw new Error(`Unsupported mapping path type: ${targetPath}`);\n}\n\nasync function collectDirectoryFileHashes(\n directoryPath: string,\n rootDirectoryPath: string,\n options: { projectRoot?: string; gitignoreStack?: GitignoreEntry[] },\n): Promise<Array<{ path: string; hash: string }>> {\n const filePaths = await collectDirectoryFilePaths(directoryPath, rootDirectoryPath, options);\n const result: Array<{ path: string; hash: string }> = [];\n for (const entry of filePaths) {\n result.push({ path: entry.relPath, hash: await hashFile(entry.absPath) });\n }\n return result;\n}\n\nasync function loadRootGitignoreStack(projectRoot?: string): Promise<GitignoreEntry[]> {\n if (!projectRoot) return [];\n try {\n const content = await readFile(path.join(projectRoot, '.gitignore'), 'utf-8');\n const matcher = ignoreFactory();\n matcher.add(content);\n return [{ basePath: projectRoot, matcher }];\n } catch {\n return [];\n }\n}\n\nfunction isIgnoredByStack(candidatePath: string, stack: GitignoreEntry[]): boolean {\n for (const { basePath, matcher } of stack) {\n const relativePath = path.relative(basePath, candidatePath);\n if (relativePath === '' || relativePath.startsWith('..')) continue;\n if (matcher.ignores(relativePath) || matcher.ignores(relativePath + '/')) return true;\n }\n return false;\n}\n\nexport function hashString(content: string): string {\n return createHash('sha256').update(content).digest('hex');\n}\n\n/** Compute per-file hashes for a mapping. Used for diagnostics (which files changed). */\nexport async function perFileHashes(\n projectRoot: string,\n mapping: { paths?: string[] },\n): Promise<Array<{ path: string; hash: string }>> {\n const root = path.resolve(projectRoot);\n const paths = mapping.paths ?? [];\n if (paths.length === 0) return [];\n\n const result: Array<{ path: string; hash: string }> = [];\n const gitignoreStack = await loadRootGitignoreStack(root);\n\n for (const p of paths) {\n const absPath = path.join(root, p);\n const st = await stat(absPath);\n if (st.isFile()) {\n result.push({ path: p, hash: await hashFile(absPath) });\n } else if (st.isDirectory()) {\n const hashes = await collectDirectoryFileHashes(absPath, absPath, {\n projectRoot: root,\n gitignoreStack,\n });\n for (const h of hashes) {\n result.push({\n path: path.join(p, h.path).split(path.sep).join('/'),\n hash: h.hash,\n });\n }\n }\n }\n\n return result;\n}\n\n/** Compute drift hash for a node mapping. Returns hex. */\nexport async function hashForMapping(\n projectRoot: string,\n mapping: { paths?: string[] },\n): Promise<string> {\n const root = path.resolve(projectRoot);\n const paths = mapping.paths ?? [];\n if (paths.length === 0) throw new Error('Invalid mapping for hash: no paths');\n\n const pairs: Array<{ path: string; hash: string }> = [];\n\n for (const p of paths) {\n const absPath = path.join(root, p);\n const st = await stat(absPath);\n if (st.isFile()) {\n pairs.push({ path: p, hash: await hashFile(absPath) });\n } else if (st.isDirectory()) {\n const dirHash = await hashPath(absPath, { projectRoot: root });\n pairs.push({ path: p, hash: dirHash });\n }\n }\n\n const digestInput = pairs\n .sort((a, b) => a.path.localeCompare(b.path))\n .map((e) => `${e.path}:${e.hash}`)\n .join('\\n');\n return createHash('sha256').update(digestInput).digest('hex');\n}\n\n/** Stored file data for mtime-based drift optimization. */\nexport interface StoredFileData {\n hashes: Record<string, string>;\n mtimes: Record<string, number>;\n}\n\n/**\n * Hash all tracked files (source + graph) for bidirectional drift detection.\n * Directories in the tracked list are expanded to their contained files.\n * Returns a canonical hash (sorted path:hash digest), per-file hashes, and mtimes.\n *\n * When `storedFileData` is provided, files whose mtime has not changed since\n * the last sync will reuse the stored hash instead of re-reading and hashing.\n * This makes the common case (no changes) nearly instant even for large mappings.\n */\nexport async function hashTrackedFiles(\n projectRoot: string,\n trackedFiles: TrackedFile[],\n storedFileData?: StoredFileData,\n excludePrefixes?: string[],\n): Promise<{ canonicalHash: string; fileHashes: Record<string, string>; fileMtimes: Record<string, number> }> {\n const fileHashes: Record<string, string> = {};\n const fileMtimes: Record<string, number> = {};\n const gitignoreStack = await loadRootGitignoreStack(projectRoot);\n\n // Collect all file entries (expanding directories) with their metadata\n type FileEntry = { relPath: string; absPath: string; mtimeMs: number };\n const allFiles: FileEntry[] = [];\n\n for (const tf of trackedFiles) {\n const absPath = path.join(projectRoot, tf.path);\n try {\n const st = await stat(absPath);\n if (st.isDirectory()) {\n const dirEntries = await collectDirectoryFilePaths(absPath, absPath, {\n projectRoot,\n gitignoreStack,\n });\n for (const entry of dirEntries) {\n allFiles.push({\n relPath: path.join(tf.path, entry.relPath).replace(/\\\\/g, '/'),\n absPath: entry.absPath,\n mtimeMs: entry.mtimeMs,\n });\n }\n } else {\n allFiles.push({ relPath: tf.path, absPath, mtimeMs: st.mtimeMs });\n }\n } catch {\n continue;\n }\n }\n\n // Exclude files owned by descendant nodes (child-wins model)\n const filtered = excludePrefixes?.length\n ? allFiles.filter((entry) =>\n !excludePrefixes.some((prefix) =>\n entry.relPath === prefix || entry.relPath.startsWith(prefix + '/')))\n : allFiles;\n\n // Separate files into cached (mtime match) and dirty (need hashing)\n const dirty: FileEntry[] = [];\n for (const entry of filtered) {\n const storedMtime = storedFileData?.mtimes[entry.relPath];\n const storedHash = storedFileData?.hashes[entry.relPath];\n if (storedMtime !== undefined && storedHash !== undefined && entry.mtimeMs === storedMtime) {\n fileHashes[entry.relPath] = storedHash;\n } else {\n dirty.push(entry);\n }\n fileMtimes[entry.relPath] = entry.mtimeMs;\n }\n\n // Hash dirty files in parallel batches to avoid overwhelming file descriptors\n const BATCH_SIZE = 256;\n for (let i = 0; i < dirty.length; i += BATCH_SIZE) {\n const batch = dirty.slice(i, i + BATCH_SIZE);\n const hashes = await Promise.all(batch.map((e) => hashFile(e.absPath)));\n for (let j = 0; j < batch.length; j++) {\n fileHashes[batch[j].relPath] = hashes[j];\n }\n }\n\n // Canonical hash: sorted path:hash pairs\n const sorted = Object.entries(fileHashes).sort(([a], [b]) => a.localeCompare(b));\n const digest = sorted.map(([p, h]) => `${p}:${h}`).join('\\n');\n const canonicalHash = hashString(digest);\n\n return { canonicalHash, fileHashes, fileMtimes };\n}\n\n/**\n * Collect file paths and mtimes from a directory without hashing.\n * Used by hashTrackedFiles to separate discovery from hashing,\n * enabling mtime-based optimization.\n *\n * Directory recursion and file stat() calls are parallelized for performance.\n */\nasync function collectDirectoryFilePaths(\n directoryPath: string,\n rootDirectoryPath: string,\n options: { projectRoot?: string; gitignoreStack?: GitignoreEntry[] },\n): Promise<Array<{ relPath: string; absPath: string; mtimeMs: number }>> {\n let stack = options.gitignoreStack ?? [];\n try {\n const localContent = await readFile(path.join(directoryPath, '.gitignore'), 'utf-8');\n const localMatcher = ignoreFactory();\n localMatcher.add(localContent);\n stack = [...stack, { basePath: directoryPath, matcher: localMatcher }];\n } catch {\n // No local .gitignore\n }\n\n const entries = await readdir(directoryPath, { withFileTypes: true });\n const dirs: string[] = [];\n const files: string[] = [];\n\n for (const entry of entries) {\n const absoluteChildPath = path.join(directoryPath, entry.name);\n if (isIgnoredByStack(absoluteChildPath, stack)) continue;\n if (entry.isDirectory()) dirs.push(absoluteChildPath);\n else if (entry.isFile()) files.push(absoluteChildPath);\n }\n\n // Parallel: recurse into directories AND stat files concurrently\n const [dirResults, fileStats] = await Promise.all([\n Promise.all(dirs.map((d) => collectDirectoryFilePaths(d, rootDirectoryPath, {\n projectRoot: options.projectRoot,\n gitignoreStack: stack,\n }))),\n Promise.all(files.map(async (f) => {\n const fileStat = await stat(f);\n return {\n relPath: path.relative(rootDirectoryPath, f),\n absPath: f,\n mtimeMs: fileStat.mtimeMs,\n };\n })),\n ]);\n\n const result: Array<{ relPath: string; absPath: string; mtimeMs: number }> = [];\n for (const nested of dirResults) result.push(...nested);\n result.push(...fileStats);\n return result;\n}\n","import path from 'node:path';\nimport type { Graph, GraphNode, DriftCategory, FlowDef } from '../model/types.js';\nimport { normalizeMappingPaths } from '../utils/paths.js';\nimport { collectAncestors, resolveAspects } from './context-builder.js';\n\nexport interface TrackedFile {\n path: string; // relative to project root\n category: DriftCategory; // 'source' or 'graph'\n}\n\nconst STRUCTURAL_RELATION_TYPES = new Set(['uses', 'calls', 'extends', 'implements']);\n\n/**\n * Collect all files tracked by a node's context package.\n * Mirrors the traversal of build-context but returns file paths\n * instead of rendered content. This is the core function for\n * bidirectional drift detection.\n *\n * Synchronous — no I/O needed; all data comes from the loaded Graph.\n */\nexport function collectTrackedFiles(node: GraphNode, graph: Graph): TrackedFile[] {\n const seen = new Set<string>();\n const result: TrackedFile[] = [];\n\n // Compute the .yggdrasil prefix relative to project root.\n // graph.rootPath is absolute path to .yggdrasil/; project root is its parent.\n const projectRoot = path.dirname(graph.rootPath);\n const yggPrefix = path.relative(projectRoot, graph.rootPath);\n // Normalize to forward slashes for consistency\n const yggPrefixNormalized = yggPrefix.split(path.sep).join('/');\n\n const configArtifactKeys = new Set(Object.keys(graph.config.artifacts ?? {}));\n\n function addFile(filePath: string, category: DriftCategory): void {\n if (seen.has(filePath)) return;\n seen.add(filePath);\n result.push({ path: filePath, category });\n }\n\n function graphPath(...segments: string[]): string {\n return [yggPrefixNormalized, ...segments].join('/');\n }\n\n function addNodeFiles(n: GraphNode): void {\n // node.yaml\n addFile(graphPath('model', n.path, 'node.yaml'), 'graph');\n // artifacts filtered by config\n for (const art of n.artifacts) {\n if (configArtifactKeys.has(art.filename)) {\n addFile(graphPath('model', n.path, art.filename), 'graph');\n }\n }\n }\n\n // 1. OWN — node.yaml + config-filtered artifacts\n addNodeFiles(node);\n\n // 2. HIERARCHICAL — ancestors from root to parent\n const ancestors = collectAncestors(node);\n for (const ancestor of ancestors) {\n addNodeFiles(ancestor);\n }\n\n // 3. ASPECTS — resolve all aspects from own + ancestors + flows (with recursive implies)\n // First, collect all aspect ids from own node and ancestors\n const allAspectIds = new Set<string>();\n\n for (const id of node.meta.aspects ?? []) {\n allAspectIds.add(id);\n }\n for (const ancestor of ancestors) {\n for (const id of ancestor.meta.aspects ?? []) {\n allAspectIds.add(id);\n }\n }\n\n // Collect participating flows (same logic as build-context)\n const participatingFlows = collectParticipatingFlows(graph, node, ancestors);\n\n // Add flow-propagated aspects\n for (const flow of participatingFlows) {\n for (const id of flow.aspects ?? []) {\n allAspectIds.add(id);\n }\n }\n\n // Resolve with recursive implies\n const resolvedAspects = resolveAspects(allAspectIds, graph.aspects);\n for (const aspect of resolvedAspects) {\n addFile(graphPath('aspects', aspect.id, 'aspect.yaml'), 'graph');\n for (const art of aspect.artifacts) {\n addFile(graphPath('aspects', aspect.id, art.filename), 'graph');\n }\n }\n\n // 4. RELATIONAL-DEPS — structural relations (uses/calls/extends/implements)\n for (const relation of node.meta.relations ?? []) {\n if (!STRUCTURAL_RELATION_TYPES.has(relation.type)) continue;\n const target = graph.nodes.get(relation.target);\n if (!target) continue;\n\n // Determine which artifacts to include from the target\n const structuralFilenames = Object.entries(graph.config.artifacts ?? {})\n .filter(([, c]) => c.structural_context)\n .map(([filename]) => filename);\n\n // Check if the target actually has any of the structural_context artifacts\n const structuralArts = structuralFilenames.filter((filename) =>\n target.artifacts.some((a) => a.filename === filename),\n );\n\n if (structuralArts.length > 0) {\n // Use only structural_context artifacts that exist on target\n for (const filename of structuralArts) {\n addFile(graphPath('model', target.path, filename), 'graph');\n }\n } else {\n // Fallback: all config-allowed artifacts\n for (const art of target.artifacts) {\n if (configArtifactKeys.has(art.filename)) {\n addFile(graphPath('model', target.path, art.filename), 'graph');\n }\n }\n }\n }\n\n // 5. RELATIONAL-FLOWS — flow.yaml + flow artifacts for participating flows\n for (const flow of participatingFlows) {\n addFile(graphPath('flows', flow.path, 'flow.yaml'), 'graph');\n for (const art of flow.artifacts) {\n addFile(graphPath('flows', flow.path, art.filename), 'graph');\n }\n }\n\n // 6. SOURCE — files from mapping.paths\n const mappingPaths = normalizeMappingPaths(node.meta.mapping);\n for (const p of mappingPaths) {\n addFile(p, 'source');\n }\n\n return result;\n}\n\n/**\n * Find all flows where the node or any of its ancestors is a participant.\n * Same logic as collectParticipatingFlows in context-builder.ts.\n */\nfunction collectParticipatingFlows(\n graph: Graph,\n node: GraphNode,\n ancestors: GraphNode[],\n): FlowDef[] {\n const paths = new Set<string>([node.path, ...ancestors.map((a) => a.path)]);\n return graph.flows.filter((f) => f.nodes.some((n) => paths.has(n)));\n}\n","import type {\n Graph,\n DriftReport,\n DriftEntry,\n DriftStatus,\n DriftFileChange,\n DriftCategory,\n} from '../model/types.js';\nimport {\n readDriftState,\n writeDriftState,\n} from '../io/drift-state-store.js';\nimport { hashTrackedFiles } from '../utils/hash.js';\nimport { collectTrackedFiles } from './context-files.js';\nimport { normalizeMappingPaths } from '../utils/paths.js';\nimport { access } from 'node:fs/promises';\nimport path from 'node:path';\n\n/**\n * Compute mapping paths owned by descendant nodes that overlap with a node's own\n * mapping paths. Used to exclude child-owned files from parent drift hashing\n * (\"child wins\" model).\n */\nfunction getChildMappingExclusions(graph: Graph, nodePath: string): string[] {\n const node = graph.nodes.get(nodePath);\n if (!node) return [];\n const parentMappings = normalizeMappingPaths(node.meta.mapping);\n if (parentMappings.length === 0) return [];\n\n const exclusions: string[] = [];\n for (const [childPath, childNode] of graph.nodes) {\n if (childPath === nodePath) continue;\n if (!childPath.startsWith(nodePath + '/')) continue; // not a descendant\n const childMappings = normalizeMappingPaths(childNode.meta.mapping);\n for (const cm of childMappings) {\n for (const pm of parentMappings) {\n if (cm === pm || cm.startsWith(pm + '/')) {\n exclusions.push(cm);\n }\n }\n }\n }\n return exclusions;\n}\n\nexport async function detectDrift(graph: Graph, filterNodePath?: string): Promise<DriftReport> {\n const projectRoot = path.dirname(graph.rootPath);\n const driftState = await readDriftState(graph.rootPath);\n const entries: DriftEntry[] = [];\n\n for (const [nodePath, node] of graph.nodes) {\n if (filterNodePath && nodePath !== filterNodePath && !nodePath.startsWith(filterNodePath + '/')) continue;\n const mapping = node.meta.mapping;\n if (!mapping) continue;\n\n const mappingPaths = normalizeMappingPaths(mapping);\n if (mappingPaths.length === 0) continue;\n\n const storedEntry = driftState[nodePath];\n\n if (!storedEntry) {\n const allMissing = await allPathsMissing(projectRoot, mappingPaths);\n entries.push({\n nodePath,\n status: allMissing ? 'unmaterialized' : 'source-drift',\n details: allMissing\n ? 'No drift state recorded, files do not exist'\n : 'No drift state recorded, files exist (run drift-sync after materialization)',\n });\n continue;\n }\n\n // Check if source files are entirely missing (all mapping paths gone)\n // This must happen BEFORE hash comparison — a node whose source files\n // are all gone is 'missing' regardless of whether graph-only hashes match.\n const sourceFilesMissing = await allPathsMissing(projectRoot, mappingPaths);\n if (sourceFilesMissing) {\n entries.push({\n nodePath,\n status: 'missing',\n details: 'All source mapping paths are missing',\n });\n continue;\n }\n\n // Collect all tracked files (source + graph) for this node\n const trackedFiles = collectTrackedFiles(node, graph);\n // Exclude files owned by descendant nodes (child-wins model)\n const excludePrefixes = getChildMappingExclusions(graph, nodePath);\n // Pass stored file data for mtime-based optimization: skip hashing files whose\n // modification time has not changed since the last drift-sync.\n const storedFileData = storedEntry.files\n ? { hashes: storedEntry.files, mtimes: storedEntry.mtimes ?? {} }\n : undefined;\n const { canonicalHash, fileHashes } = await hashTrackedFiles(projectRoot, trackedFiles, storedFileData, excludePrefixes);\n\n if (canonicalHash === storedEntry.hash) {\n entries.push({ nodePath, status: 'ok' });\n continue;\n }\n\n // Something changed — determine what\n const changedFiles: DriftFileChange[] = [];\n const storedFiles = storedEntry.files;\n\n // Check current files against stored\n for (const [filePath, hash] of Object.entries(fileHashes)) {\n const storedHash = storedFiles[filePath];\n if (!storedHash || storedHash !== hash) {\n changedFiles.push({\n filePath,\n category: categorizeFile(filePath, graph.rootPath, projectRoot),\n });\n }\n }\n\n // Check for deleted files (in stored but not in current)\n for (const storedPath of Object.keys(storedFiles)) {\n if (!(storedPath in fileHashes)) {\n changedFiles.push({\n filePath: `${storedPath} (deleted)`,\n category: categorizeFile(storedPath, graph.rootPath, projectRoot),\n });\n }\n }\n\n // Determine drift status from changed file categories\n const hasSourceChanges = changedFiles.some((f) => f.category === 'source');\n const hasGraphChanges = changedFiles.some((f) => f.category === 'graph');\n\n let status: DriftStatus;\n if (hasSourceChanges && hasGraphChanges) {\n status = 'full-drift';\n } else if (hasGraphChanges) {\n status = 'graph-drift';\n } else if (hasSourceChanges) {\n status = 'source-drift';\n } else {\n // Hash changed but no individual file identified — fallback\n status = 'source-drift';\n }\n\n const details =\n changedFiles.length > 0\n ? `Changed files: ${changedFiles.map((f) => f.filePath).join(', ')}`\n : 'File(s) modified since last sync';\n\n entries.push({ nodePath, status, details, changedFiles });\n }\n\n return {\n entries,\n totalChecked: entries.length,\n okCount: entries.filter((e) => e.status === 'ok').length,\n sourceDriftCount: entries.filter((e) => e.status === 'source-drift').length,\n graphDriftCount: entries.filter((e) => e.status === 'graph-drift').length,\n fullDriftCount: entries.filter((e) => e.status === 'full-drift').length,\n missingCount: entries.filter((e) => e.status === 'missing').length,\n unmaterializedCount: entries.filter((e) => e.status === 'unmaterialized').length,\n };\n}\n\n/**\n * Categorize a file path as 'source' or 'graph' based on whether it lives\n * under the .yggdrasil/ directory.\n */\nfunction categorizeFile(filePath: string, _rootPath: string, projectRoot: string): DriftCategory {\n const yggPrefix = path.relative(projectRoot, _rootPath);\n const normalizedPrefix = yggPrefix.split(path.sep).join('/');\n const normalizedFilePath = filePath.replace(/\\\\/g, '/');\n return normalizedFilePath.startsWith(normalizedPrefix) ? 'graph' : 'source';\n}\n\nasync function allPathsMissing(projectRoot: string, mappingPaths: string[]): Promise<boolean> {\n for (const mp of mappingPaths) {\n const absPath = path.join(projectRoot, mp);\n try {\n await access(absPath);\n return false;\n } catch {\n // path missing\n }\n }\n return true;\n}\n\nexport async function syncDriftState(\n graph: Graph,\n nodePath: string,\n): Promise<{ previousHash?: string; currentHash: string }> {\n const projectRoot = path.dirname(graph.rootPath);\n const node = graph.nodes.get(nodePath);\n if (!node) throw new Error(`Node not found: ${nodePath}`);\n if (!node.meta.mapping) throw new Error(`Node has no mapping: ${nodePath}`);\n\n const trackedFiles = collectTrackedFiles(node, graph);\n // Exclude files owned by descendant nodes (child-wins model)\n const excludePrefixes = getChildMappingExclusions(graph, nodePath);\n // For sync, pass stored data so unchanged files can reuse cached hashes.\n const existingState = await readDriftState(graph.rootPath);\n const existingEntry = existingState[nodePath];\n const storedFileData = existingEntry?.files\n ? { hashes: existingEntry.files, mtimes: existingEntry.mtimes ?? {} }\n : undefined;\n const { canonicalHash, fileHashes, fileMtimes } = await hashTrackedFiles(projectRoot, trackedFiles, storedFileData, excludePrefixes);\n\n const previousHash = existingEntry?.hash;\n\n existingState[nodePath] = { hash: canonicalHash, files: fileHashes, mtimes: fileMtimes };\n\n // Garbage collection: remove orphaned entries for nodes that no longer exist\n for (const key of Object.keys(existingState)) {\n if (!graph.nodes.has(key)) {\n delete existingState[key];\n }\n }\n\n await writeDriftState(graph.rootPath, existingState);\n\n return { previousHash, currentHash: canonicalHash };\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { loadGraph } from '../core/graph-loader.js';\nimport { syncDriftState } from '../core/drift-detector.js';\nimport { normalizeMappingPaths } from '../utils/paths.js';\n\nexport function registerDriftSyncCommand(program: Command): void {\n program\n .command('drift-sync')\n .description('Record current file hash after resolving drift')\n .option('--node <path>', 'Node path to sync')\n .option('--recursive', 'Also sync all descendant nodes')\n .option('--all', 'Sync all nodes with mappings')\n .action(async (options: { node?: string; recursive?: boolean; all?: boolean }) => {\n try {\n if (!options.node && !options.all) {\n process.stderr.write(\"Error: either '--node <path>' or '--all' is required\\n\");\n process.exit(1);\n }\n\n const graph = await loadGraph(process.cwd());\n\n let nodesToSync: string[];\n\n if (options.all) {\n nodesToSync = [...graph.nodes.entries()]\n .filter(([, n]) => normalizeMappingPaths(n.meta.mapping).length > 0)\n .map(([p]) => p)\n .sort();\n } else {\n const nodePath = options.node!.trim().replace(/^\\.\\//, '').replace(/\\/+$/, '');\n\n if (!graph.nodes.has(nodePath)) {\n await syncDriftState(graph, nodePath); // will throw with proper error\n return;\n }\n\n nodesToSync = [nodePath];\n if (options.recursive) {\n const prefix = nodePath + '/';\n for (const [p] of graph.nodes) {\n if (p.startsWith(prefix)) {\n nodesToSync.push(p);\n }\n }\n nodesToSync.sort();\n }\n }\n\n for (const np of nodesToSync) {\n const node = graph.nodes.get(np)!;\n if (normalizeMappingPaths(node.meta.mapping).length === 0) {\n if (!options.all && !options.recursive && np === options.node) {\n await syncDriftState(graph, np); // will throw with proper error\n }\n continue;\n }\n const { previousHash, currentHash } = await syncDriftState(graph, np);\n process.stdout.write(chalk.green(`Synchronized: ${np}\\n`));\n process.stdout.write(\n ` Hash: ${previousHash ? previousHash.slice(0, 8) : 'none'} -> ${currentHash.slice(0, 8)}\\n`,\n );\n }\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport { loadGraph } from '../core/graph-loader.js';\nimport { detectDrift } from '../core/drift-detector.js';\nimport { validate } from '../core/validator.js';\nimport { collectEffectiveAspectIds } from '../core/context-builder.js';\nimport { normalizeMappingPaths } from '../utils/paths.js';\n\nexport function registerStatusCommand(program: Command): void {\n program\n .command('status')\n .description('Show graph summary')\n .action(async () => {\n try {\n const graph = await loadGraph(process.cwd());\n\n // Count nodes by type\n const typeCounts = new Map<string, number>();\n let blackboxCount = 0;\n\n for (const node of graph.nodes.values()) {\n typeCounts.set(node.meta.type, (typeCounts.get(node.meta.type) ?? 0) + 1);\n if (node.meta.blackbox) blackboxCount++;\n }\n\n // Count relations\n let structuralRelations = 0;\n let eventRelations = 0;\n const structuralTypes = new Set(['uses', 'calls', 'extends', 'implements']);\n let maxRelCount = 0;\n let maxRelNode = '';\n for (const node of graph.nodes.values()) {\n const relCount = (node.meta.relations ?? []).length;\n if (relCount > maxRelCount) {\n maxRelCount = relCount;\n maxRelNode = node.path;\n }\n for (const rel of node.meta.relations ?? []) {\n if (structuralTypes.has(rel.type)) structuralRelations += 1;\n else eventRelations += 1;\n }\n }\n\n const flowCount = graph.flows.length;\n\n const drift = await detectDrift(graph);\n const validation = await validate(graph, 'all');\n const errorCount = validation.issues.filter((issue) => issue.severity === 'error').length;\n const warningCount = validation.issues.filter(\n (issue) => issue.severity === 'warning',\n ).length;\n\n // Quality metrics\n const configuredArtifactTypes = Object.keys(graph.config.artifacts ?? {});\n const totalSlots = graph.nodes.size * configuredArtifactTypes.length;\n let filledSlots = 0;\n let mappedNodeCount = 0;\n\n for (const node of graph.nodes.values()) {\n const allowed = new Set(configuredArtifactTypes);\n filledSlots += node.artifacts.filter((a) => allowed.has(a.filename)).length;\n if (normalizeMappingPaths(node.meta.mapping).length > 0) mappedNodeCount++;\n }\n\n let aspectCoveredNodes = 0;\n for (const node of graph.nodes.values()) {\n const effective = collectEffectiveAspectIds(graph, node.path);\n if (effective.size > 0) aspectCoveredNodes++;\n }\n\n process.stdout.write(`Graph: ${graph.config.name}\\n`);\n const pluralize = (word: string, count: number) =>\n count === 1 ? word : word.endsWith('y') ? word.slice(0, -1) + 'ies' : word + 's';\n const typeStr = [...typeCounts.entries()]\n .map(([t, c]) => `${c} ${pluralize(t, c)}`)\n .join(', ');\n process.stdout.write(\n `Nodes: ${graph.nodes.size} (${typeStr}) + ${blackboxCount} blackbox\\n`,\n );\n process.stdout.write(\n `Relations: ${structuralRelations} structural, ${eventRelations} event\\n`,\n );\n process.stdout.write(\n `Aspects: ${graph.aspects.length} Flows: ${flowCount}\\n`,\n );\n process.stdout.write(\n `Drift: ${drift.sourceDriftCount} source-drift, ${drift.graphDriftCount} graph-drift, ${drift.fullDriftCount} full-drift, ${drift.missingCount} missing, ${drift.unmaterializedCount} unmaterialized, ${drift.okCount} ok\\n`,\n );\n process.stdout.write(`Validation: ${errorCount} errors, ${warningCount} warnings\\n`);\n\n // Quality section\n const fillPct = totalSlots > 0 ? Math.round((filledSlots / totalSlots) * 100) : 0;\n const totalRelations = structuralRelations + eventRelations;\n const avgRel = graph.nodes.size > 0 ? (totalRelations / graph.nodes.size).toFixed(1) : '0';\n process.stdout.write(`\\nQuality:\\n`);\n process.stdout.write(\n ` Artifacts: ${filledSlots}/${totalSlots} slots filled (${fillPct}%) — ${configuredArtifactTypes.length} types × ${graph.nodes.size} nodes\\n`,\n );\n process.stdout.write(\n ` Relations: avg ${avgRel}/node, max ${maxRelCount}${maxRelNode ? ` (${maxRelNode})` : ''}\\n`,\n );\n process.stdout.write(\n ` Mapping: ${mappedNodeCount}/${graph.nodes.size} nodes mapped to source\\n`,\n );\n process.stdout.write(\n ` Aspects: ${aspectCoveredNodes}/${graph.nodes.size} nodes have aspect coverage\\n`,\n );\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport { loadGraph } from '../core/graph-loader.js';\nimport type { GraphNode } from '../model/types.js';\n\nexport function registerTreeCommand(program: Command): void {\n program\n .command('tree')\n .description('Display graph structure as a tree')\n .option('--root <path>', 'Show only subtree rooted at this path')\n .option('--depth <n>', 'Maximum depth', (v) => parseInt(v, 10))\n .action(async (options: { root?: string; depth?: number }) => {\n try {\n const graph = await loadGraph(process.cwd());\n\n let roots: GraphNode[];\n let showProjectName: boolean;\n\n if (options.root?.trim()) {\n const path = options.root.trim().replace(/\\/$/, '');\n const node = graph.nodes.get(path);\n if (!node) {\n process.stderr.write(`Error: path '${path}' not found\\n`);\n process.exit(1);\n }\n roots = [node];\n showProjectName = false;\n } else {\n roots = [...graph.nodes.values()]\n .filter((n) => n.parent === null)\n .sort((a, b) => a.path.localeCompare(b.path));\n showProjectName = true;\n }\n\n if (showProjectName) {\n process.stdout.write('model/\\n');\n }\n\n for (let i = 0; i < roots.length; i++) {\n const isLast = i === roots.length - 1;\n printNode(roots[i], '', isLast, 1, options.depth);\n }\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n\nfunction printNode(\n node: GraphNode,\n prefix: string,\n isLast: boolean,\n depth: number,\n maxDepth: number | undefined,\n): void {\n const connector = isLast ? '└── ' : '├── ';\n const name = node.path.split('/').pop() ?? node.path;\n const type = `[${node.meta.type}]`;\n const tags = node.meta.aspects?.length ? ` aspects:${node.meta.aspects.join(',')}` : '';\n const blackbox = node.meta.blackbox ? ' ■ blackbox' : '';\n const relationCount = node.meta.relations?.length ?? 0;\n\n process.stdout.write(\n `${prefix}${connector}${name}/ ${type}${tags}${blackbox} -> ${relationCount} relations\\n`,\n );\n\n const childPrefix = prefix + (isLast ? ' ' : '│ ');\n\n // Recurse into children\n if (maxDepth !== undefined && depth >= maxDepth) return;\n\n const children = [...node.children].sort((a, b) => a.path.localeCompare(b.path));\n for (let i = 0; i < children.length; i++) {\n printNode(children[i], childPrefix, i === children.length - 1, depth + 1, maxDepth);\n }\n}\n","import path from 'node:path';\nimport { access } from 'node:fs/promises';\nimport { Command } from 'commander';\nimport { loadGraph } from '../core/graph-loader.js';\nimport type { Graph, OwnerResult } from '../model/types.js';\nimport { normalizeMappingPaths, normalizeProjectRelativePath, projectRootFromGraph } from '../utils/paths.js';\n\nfunction normalizeForMatch(inputPath: string): string {\n return inputPath.replace(/\\\\/g, '/').replace(/\\/+$/, '');\n}\n\nexport function findOwner(graph: Graph, projectRoot: string, rawPath: string): OwnerResult {\n const file = normalizeForMatch(normalizeProjectRelativePath(projectRoot, rawPath));\n let best: { nodePath: string; mappingPath: string; exact: boolean } | null = null;\n\n for (const [nodePath, node] of graph.nodes) {\n const mappingPaths = normalizeMappingPaths(node.meta.mapping)\n .map(normalizeForMatch)\n .filter((mappingPath) => mappingPath.length > 0);\n\n for (const mappingPath of mappingPaths) {\n if (file === mappingPath) {\n return { file, nodePath, mappingPath };\n }\n if (file.startsWith(mappingPath + '/')) {\n if (!best || (best && mappingPath.length > best.mappingPath.length)) {\n best = { nodePath, mappingPath, exact: false };\n }\n }\n }\n }\n\n return best\n ? { file, nodePath: best.nodePath, mappingPath: best.mappingPath }\n : { file, nodePath: null };\n}\n\nexport function registerOwnerCommand(program: Command): void {\n program\n .command('owner')\n .description('Find which graph node owns a source file')\n .requiredOption('--file <path>', 'File path (relative to repository root)')\n .action(async (options: { file: string }) => {\n try {\n const cwd = process.cwd();\n const graph = await loadGraph(cwd);\n // Resolve the file path relative to CWD (so subdirectory-relative paths work),\n // then make it relative to the actual repo root (where .yggdrasil/ lives).\n const repoRoot = projectRootFromGraph(graph.rootPath);\n const rawPath = options.file.trim();\n const absolute = path.resolve(cwd, rawPath);\n const repoRelative = path.relative(repoRoot, absolute).split(path.sep).join('/');\n const result = findOwner(graph, repoRoot, repoRelative);\n\n if (!result.nodePath) {\n // Distinguish \"file doesn't exist\" from \"file exists but not mapped\"\n const absPath = path.resolve(repoRoot, result.file);\n let exists = true;\n try { await access(absPath); } catch { exists = false; }\n if (exists) {\n process.stdout.write(`${result.file} -> no graph coverage\\n`);\n } else {\n process.stdout.write(`${result.file} -> no graph coverage (file not found)\\n`);\n }\n } else {\n process.stdout.write(`${result.file} -> ${result.nodePath}\\n`);\n }\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n","import type { Graph, Stage } from '../model/types.js';\nimport { execSync } from 'node:child_process';\nimport path from 'node:path';\n\nexport interface ResolveOptions {\n mode: 'all' | 'changed' | 'node';\n nodePath?: string; // required when mode === 'node'\n ref?: string; // git ref for --changed mode (default: HEAD)\n depth?: number; // max depth for tree (when mode === 'node')\n relationType?: 'structural' | 'event' | 'all'; // filter for tree\n}\n\nconst STRUCTURAL_RELATION_TYPES = new Set(['uses', 'calls', 'extends', 'implements']);\nconst EVENT_RELATION_TYPES = new Set(['emits', 'listens']);\n\n/** Expand changed set with direct dependents only (one level, no cascade) */\nfunction expandWithDependents(graph: Graph, changed: string[]): string[] {\n const dependents = new Map<string, string[]>();\n for (const [nodePath, node] of graph.nodes) {\n for (const rel of node.meta.relations ?? []) {\n if (!STRUCTURAL_RELATION_TYPES.has(rel.type)) continue;\n const deps = dependents.get(rel.target) ?? [];\n deps.push(nodePath);\n dependents.set(rel.target, deps);\n }\n }\n\n const result = new Set<string>(changed);\n for (const node of changed) {\n for (const dep of dependents.get(node) ?? []) {\n result.add(dep);\n }\n }\n\n return [...result];\n}\n\n/** Find nodes whose graph files have changed according to git */\nexport function findChangedNodes(graph: Graph, ref?: string): string[] {\n const gitRef = ref ?? 'HEAD';\n const yggDirName = path.basename(graph.rootPath);\n const projectRoot = path.dirname(graph.rootPath);\n\n let changedFiles: string[];\n try {\n const output = execSync(`git diff --name-only ${gitRef} -- ${yggDirName}/`, {\n cwd: projectRoot,\n encoding: 'utf-8',\n }).trim();\n changedFiles = output ? output.split('\\n') : [];\n } catch {\n // If git diff fails (no commits, not a repo, etc.), fall back to empty\n changedFiles = [];\n }\n\n // Map changed file paths back to node paths\n const changedNodePaths = new Set<string>();\n for (const filePath of changedFiles) {\n // filePath is like \".yggdrasil/auth/login-service/node.yaml\"\n // Strip the yggdrasil dir prefix to get \"auth/login-service/node.yaml\"\n const relative = filePath.startsWith(yggDirName + '/')\n ? filePath.slice(yggDirName.length + 1)\n : filePath;\n\n // Walk up directories to find matching node paths (nodes are under model/)\n const parts = relative.split('/');\n const modelIdx = parts.indexOf('model');\n const startIdx = modelIdx >= 0 ? modelIdx + 1 : 0;\n for (let i = parts.length - 1; i >= startIdx + 1; i--) {\n const candidate = parts.slice(startIdx, i).join('/');\n if (graph.nodes.has(candidate)) {\n changedNodePaths.add(candidate);\n break;\n }\n }\n }\n\n return expandWithDependents(graph, [...changedNodePaths]);\n}\n\n/** Collect node and its transitive dependencies (for --node mode) */\nexport function collectTransitiveDeps(graph: Graph, nodePath: string): string[] {\n return collectTransitiveDepsFiltered(graph, nodePath, undefined, 'structural');\n}\n\n/** Filter relation types for inclusion */\nfunction filterRelationType(relType: string, filter: 'structural' | 'event' | 'all'): boolean {\n if (filter === 'all') return true;\n if (filter === 'structural') return STRUCTURAL_RELATION_TYPES.has(relType);\n if (filter === 'event') return EVENT_RELATION_TYPES.has(relType);\n return false;\n}\n\n/** Collect transitive deps with depth and type filter */\nfunction collectTransitiveDepsFiltered(\n graph: Graph,\n nodePath: string,\n maxDepth: number | undefined,\n relationType: 'structural' | 'event' | 'all',\n): string[] {\n const node = graph.nodes.get(nodePath);\n if (!node) {\n throw new Error(`Node not found: ${nodePath}`);\n }\n\n const result = new Set<string>();\n const queue: Array<{ path: string; depth: number }> = [{ path: nodePath, depth: 0 }];\n\n while (queue.length > 0) {\n const { path: p, depth } = queue.shift()!;\n if (result.has(p)) continue;\n result.add(p);\n if (maxDepth !== undefined && depth >= maxDepth) continue;\n\n const n = graph.nodes.get(p)!;\n for (const rel of n.meta.relations ?? []) {\n if (!filterRelationType(rel.type, relationType)) continue;\n if (!graph.nodes.has(rel.target)) {\n throw new Error(`Relation target not found: ${rel.target}`);\n }\n if (!result.has(rel.target)) {\n queue.push({ path: rel.target, depth: depth + 1 });\n }\n }\n }\n\n return [...result];\n}\n\n/** Tree node for dependency tree output */\nexport interface DepTreeNode {\n nodePath: string;\n relationType: string;\n relationTarget?: string;\n blackbox: boolean;\n children: DepTreeNode[];\n}\n\n/** Build dependency tree for a node (spec format) */\nexport function buildDependencyTree(\n graph: Graph,\n nodePath: string,\n options: { depth?: number; relationType?: 'structural' | 'event' | 'all' } = {},\n): DepTreeNode[] {\n const node = graph.nodes.get(nodePath);\n if (!node) {\n throw new Error(`Node not found: ${nodePath}`);\n }\n\n const maxDepth = options.depth ?? Infinity;\n const typeFilter = options.relationType ?? 'all';\n\n function buildChildren(\n fromPath: string,\n currentDepth: number,\n branch: Set<string>,\n ): DepTreeNode[] {\n if (currentDepth >= maxDepth) return [];\n const fromNode = graph.nodes.get(fromPath)!;\n const children: DepTreeNode[] = [];\n for (const rel of fromNode.meta.relations ?? []) {\n if (!filterRelationType(rel.type, typeFilter)) continue;\n if (!graph.nodes.has(rel.target)) continue;\n if (branch.has(rel.target)) continue;\n const targetNode = graph.nodes.get(rel.target)!;\n const nextBranch = new Set(branch);\n nextBranch.add(rel.target);\n children.push({\n nodePath: rel.target,\n relationType: rel.type,\n relationTarget: fromPath,\n blackbox: targetNode.meta.blackbox ?? false,\n children: buildChildren(rel.target, currentDepth + 1, nextBranch),\n });\n }\n return children;\n }\n\n return buildChildren(nodePath, 0, new Set([nodePath]));\n}\n\n/** Format tree as text (spec format) */\nexport function formatDependencyTree(\n graph: Graph,\n nodePath: string,\n options: { depth?: number; relationType?: 'structural' | 'event' | 'all' } = {},\n): string {\n const roots = buildDependencyTree(graph, nodePath, options);\n const lines: string[] = [nodePath];\n\n function formatNode(node: DepTreeNode, prefix: string, isLast: boolean): void {\n const connector = isLast ? '└── ' : '├── ';\n const blackbox = node.blackbox ? ' ■ blackbox' : '';\n lines.push(`${prefix}${connector}${node.relationType} ${node.nodePath}${blackbox}`);\n const childPrefix = prefix + (isLast ? ' ' : '│ ');\n const lastIdx = node.children.length - 1;\n node.children.forEach((c, i) => formatNode(c, childPrefix, i === lastIdx));\n }\n\n roots.forEach((r, i) => formatNode(r, '', i === roots.length - 1));\n return lines.join('\\n');\n}\n\nexport async function resolveDeps(graph: Graph, options: ResolveOptions): Promise<Stage[]> {\n let candidatePaths: string[];\n\n switch (options.mode) {\n case 'all':\n candidatePaths = [...graph.nodes.keys()];\n break;\n case 'changed':\n candidatePaths = findChangedNodes(graph, options.ref);\n break;\n case 'node':\n candidatePaths = collectTransitiveDeps(graph, options.nodePath!);\n break;\n }\n\n candidatePaths = candidatePaths.filter((p) => {\n const node = graph.nodes.get(p)!;\n return !node.meta.blackbox && node.meta.mapping;\n });\n\n if (candidatePaths.length === 0) return [];\n\n const candidateSet = new Set(candidatePaths);\n\n // Validate relations: broken relation = target not in graph\n for (const p of candidatePaths) {\n const node = graph.nodes.get(p)!;\n for (const rel of node.meta.relations ?? []) {\n if (!graph.nodes.has(rel.target)) {\n throw new Error(`Relation target not found: ${rel.target}`);\n }\n }\n }\n\n const inDegree = new Map<string, number>();\n const dependents = new Map<string, string[]>();\n\n for (const p of candidatePaths) {\n inDegree.set(p, 0);\n dependents.set(p, []);\n }\n\n for (const p of candidatePaths) {\n const node = graph.nodes.get(p)!;\n for (const rel of node.meta.relations ?? []) {\n if (!STRUCTURAL_RELATION_TYPES.has(rel.type)) continue;\n if (candidateSet.has(rel.target)) {\n inDegree.set(p, (inDegree.get(p) ?? 0) + 1);\n dependents.get(rel.target)!.push(p);\n }\n }\n }\n\n const stages: Stage[] = [];\n let queue = candidatePaths.filter((p) => inDegree.get(p) === 0);\n let stageNum = 1;\n const processed = new Set<string>();\n\n while (queue.length > 0) {\n stages.push({\n stage: stageNum,\n parallel: queue.length > 1,\n nodes: [...queue],\n });\n\n const nextQueue: string[] = [];\n for (const nodePath of queue) {\n processed.add(nodePath);\n for (const dep of dependents.get(nodePath) ?? []) {\n inDegree.set(dep, (inDegree.get(dep) ?? 0) - 1);\n if (inDegree.get(dep) === 0) {\n nextQueue.push(dep);\n }\n }\n }\n\n queue = nextQueue;\n stageNum++;\n }\n\n if (processed.size < candidatePaths.length) {\n const cycleNodes = candidatePaths.filter((p) => !processed.has(p));\n throw new Error(`Circular dependency detected involving: ${cycleNodes.join(', ')}`);\n }\n\n return stages;\n}\n","import { Command } from 'commander';\nimport { loadGraph } from '../core/graph-loader.js';\nimport { formatDependencyTree } from '../core/dependency-resolver.js';\n\nexport function registerDepsCommand(program: Command): void {\n program\n .command('deps')\n .description('Show direct and transitive node dependencies')\n .requiredOption('--node <path>', 'Node path relative to .yggdrasil/model/')\n .option('--depth <n>', 'Maximum depth for tree (when using --node)', (v) => parseInt(v, 10))\n .option('--type <type>', 'Relation type filter: structural, event, all (default: all)', 'all')\n .action(async (options: { node: string; depth?: number; type?: string }) => {\n try {\n const graph = await loadGraph(process.cwd());\n const typeFilter =\n options.type === 'structural' || options.type === 'event' || options.type === 'all'\n ? options.type\n : 'all';\n const nodePath = options.node.trim().replace(/^\\.\\//, '').replace(/\\/+$/, '');\n const text = formatDependencyTree(graph, nodePath, {\n depth: options.depth,\n relationType: typeFilter,\n });\n process.stdout.write(text + '\\n');\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n","import { mkdtemp, rm } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport path from 'node:path';\nimport { execSync } from 'node:child_process';\nimport { loadGraph } from './graph-loader.js';\nimport type { Graph } from '../model/types.js';\n\n/**\n * Load graph from a git ref (e.g. HEAD) by extracting .yggdrasil to temp dir.\n * Returns null if not a git repo, ref doesn't exist, or .yggdrasil not in ref.\n */\nexport async function loadGraphFromRef(\n projectRoot: string,\n ref: string = 'HEAD',\n): Promise<Graph | null> {\n const yggPath = '.yggdrasil';\n let tmpDir: string | null = null;\n\n try {\n execSync(`git rev-parse ${ref}`, { cwd: projectRoot, stdio: 'pipe' });\n } catch {\n return null;\n }\n\n try {\n tmpDir = await mkdtemp(path.join(tmpdir(), 'ygg-git-'));\n const archivePath = path.join(tmpDir, 'archive.tar');\n execSync(`git archive ${ref} ${yggPath} -o \"${archivePath}\"`, {\n cwd: projectRoot,\n stdio: 'pipe',\n });\n execSync(`tar -xf \"${archivePath}\" -C \"${tmpDir}\"`, { stdio: 'pipe' });\n const graph = await loadGraph(tmpDir);\n return graph;\n } catch {\n return null;\n } finally {\n if (tmpDir) {\n await rm(tmpDir, { recursive: true, force: true });\n }\n }\n}\n","import { Command } from 'commander';\nimport { loadGraph } from '../core/graph-loader.js';\nimport { loadGraphFromRef } from '../core/graph-from-git.js';\nimport {\n buildContext,\n collectAncestors,\n collectEffectiveAspectIds,\n} from '../core/context-builder.js';\nimport { detectDrift } from '../core/drift-detector.js';\nimport type { Graph } from '../model/types.js';\n\nconst STRUCTURAL_TYPES = new Set(['uses', 'calls', 'extends', 'implements']);\n\nexport function collectReverseDependents(\n graph: Graph,\n targetNode: string,\n): {\n direct: string[];\n allDependents: string[];\n reverse: Map<string, Set<string>>;\n relationFrom: Map<string, { type: string; consumes?: string[] }>;\n} {\n const reverse = new Map<string, Set<string>>();\n const relationFrom = new Map<string, { type: string; consumes?: string[] }>();\n for (const [nodePath, node] of graph.nodes) {\n for (const rel of node.meta.relations ?? []) {\n if (!STRUCTURAL_TYPES.has(rel.type)) continue;\n const deps = reverse.get(rel.target) ?? new Set<string>();\n deps.add(nodePath);\n reverse.set(rel.target, deps);\n relationFrom.set(`${nodePath}->${rel.target}`, {\n type: rel.type,\n consumes: rel.consumes,\n });\n }\n }\n\n const direct = [...(reverse.get(targetNode) ?? [])].sort();\n const seen = new Set<string>(direct);\n const queue = [...direct];\n while (queue.length > 0) {\n const current = queue.shift()!;\n for (const next of reverse.get(current) ?? []) {\n if (seen.has(next)) continue;\n seen.add(next);\n queue.push(next);\n }\n }\n\n return {\n direct,\n allDependents: [...seen].sort(),\n reverse,\n relationFrom,\n };\n}\n\nexport function buildTransitiveChains(\n targetNode: string,\n direct: string[],\n allDependents: string[],\n reverse: Map<string, Set<string>>,\n): string[] {\n const directSet = new Set(direct);\n const transitiveOnly = allDependents.filter((t) => !directSet.has(t));\n if (transitiveOnly.length === 0) return [];\n\n const parent = new Map<string, string>();\n const queue: string[] = [targetNode];\n const visited = new Set<string>([targetNode]);\n while (queue.length > 0) {\n const current = queue.shift()!;\n for (const next of reverse.get(current) ?? []) {\n if (visited.has(next)) continue;\n visited.add(next);\n parent.set(next, current);\n queue.push(next);\n }\n }\n\n const chains: string[] = [];\n for (const node of transitiveOnly) {\n const path: string[] = [];\n let current: string | undefined = node;\n while (current) {\n path.unshift(current);\n current = parent.get(current);\n }\n if (path.length >= 3) {\n chains.push(path.slice(1).map((p) => `<- ${p}`).join(' '));\n }\n }\n return chains.sort();\n}\n\nexport function collectDescendants(graph: Graph, nodePath: string): string[] {\n const node = graph.nodes.get(nodePath);\n if (!node) return [];\n const result: string[] = [];\n const stack = [...node.children];\n while (stack.length > 0) {\n const child = stack.pop()!;\n result.push(child.path);\n stack.push(...child.children);\n }\n return result.sort();\n}\n\nasync function runSimulation(\n graph: Graph,\n nodePaths: Iterable<string>,\n targetNodePath: string | null,\n): Promise<void> {\n const budget = graph.config.quality?.context_budget ?? { warning: 10000, error: 20000 };\n process.stdout.write('\\nChanges in context packages:\\n\\n');\n const baselineGraph = await loadGraphFromRef(process.cwd(), 'HEAD');\n const driftReport = await detectDrift(graph);\n const driftByNode = new Map(driftReport.entries.map((e) => [e.nodePath, e]));\n\n for (const dep of nodePaths) {\n try {\n const pkg = await buildContext(graph, dep);\n const status =\n pkg.tokenCount >= budget.error\n ? 'error'\n : pkg.tokenCount >= budget.warning\n ? 'warning'\n : 'ok';\n\n let baselineTokens: number | null = null;\n if (baselineGraph?.nodes.has(dep)) {\n try {\n const baselinePkg = await buildContext(baselineGraph, dep);\n baselineTokens = baselinePkg.tokenCount;\n } catch {\n /* ignore */\n }\n }\n\n const hasDepOnTarget =\n targetNodePath &&\n graph.nodes\n .get(dep)\n ?.meta.relations?.some(\n (r) => r.target === targetNodePath && STRUCTURAL_TYPES.has(r.type),\n );\n const changedLine = hasDepOnTarget\n ? ` + Changed dependency interface: ${targetNodePath}\\n`\n : '';\n\n const budgetLine =\n baselineTokens !== null\n ? ` Budget: ${baselineTokens} -> ${pkg.tokenCount} tokens (${status})\\n`\n : ` Budget: ${pkg.tokenCount} tokens (${status})\\n`;\n\n const driftEntry = driftByNode.get(dep);\n const driftLine =\n driftEntry && driftEntry.status !== 'ok'\n ? ` Mapped files (on-disk): ${driftEntry.status}${driftEntry.details ? ` (${driftEntry.details})` : ''}\\n`\n : driftEntry\n ? ` Mapped files (on-disk): ok\\n`\n : '';\n\n process.stdout.write(`${dep}:\\n${changedLine}${budgetLine}${driftLine}\\n`);\n } catch {\n process.stdout.write(`${dep}:\\n failed to build context\\n\\n`);\n }\n }\n}\n\nasync function handleAspectImpact(\n graph: Graph,\n aspectId: string,\n simulate?: boolean,\n): Promise<void> {\n const aspect = graph.aspects.find((a) => a.id === aspectId);\n if (!aspect) {\n process.stderr.write(`Aspect not found: ${aspectId}\\n`);\n process.exit(1);\n }\n\n const affected: Array<{ path: string; source: string }> = [];\n for (const [nodePath] of graph.nodes) {\n const effective = collectEffectiveAspectIds(graph, nodePath);\n if (effective.has(aspectId)) {\n const node = graph.nodes.get(nodePath)!;\n const ownAspects = new Set(node.meta.aspects ?? []);\n if (ownAspects.has(aspectId)) {\n affected.push({ path: nodePath, source: 'own' });\n } else {\n let fromHierarchy = false;\n let anc = node.parent;\n while (anc) {\n if ((anc.meta.aspects ?? []).includes(aspectId)) {\n fromHierarchy = true;\n break;\n }\n anc = anc.parent;\n }\n if (fromHierarchy) {\n affected.push({ path: nodePath, source: `hierarchy from ${anc!.path}` });\n } else {\n const ancestorPaths = new Set([nodePath, ...collectAncestors(node).map((a) => a.path)]);\n const flow = graph.flows.find(\n (f) =>\n (f.aspects ?? []).includes(aspectId) &&\n f.nodes.some((n) => ancestorPaths.has(n)),\n );\n affected.push({ path: nodePath, source: flow ? `flow: ${flow.name}` : 'implied' });\n }\n }\n }\n }\n\n affected.sort((a, b) => a.path.localeCompare(b.path));\n\n const propagatingFlows = graph.flows\n .filter((f) => (f.aspects ?? []).includes(aspectId))\n .map((f) => f.name);\n\n const impliedBy = graph.aspects\n .filter((a) => (a.implies ?? []).includes(aspectId))\n .map((a) => a.id);\n const implies = aspect.implies ?? [];\n\n process.stdout.write(`Impact of changes in aspect ${aspectId}:\\n\\n`);\n process.stdout.write(`Affected nodes (${affected.length}):\\n`);\n if (affected.length === 0) {\n process.stdout.write(' (none)\\n');\n } else {\n for (const { path: p, source } of affected) {\n process.stdout.write(` ${p} (${source})\\n`);\n }\n }\n process.stdout.write(\n `\\nFlows propagating this aspect: ${propagatingFlows.length > 0 ? propagatingFlows.join(', ') : '(none)'}\\n`,\n );\n process.stdout.write(`Implied by: ${impliedBy.length > 0 ? impliedBy.join(', ') : '(none)'}\\n`);\n process.stdout.write(`Implies: ${implies.length > 0 ? implies.join(', ') : '(none)'}\\n`);\n process.stdout.write(`\\nTotal scope: ${affected.length} nodes, ${propagatingFlows.length} flows\\n`);\n\n if (simulate && affected.length > 0) {\n await runSimulation(\n graph,\n affected.map((a) => a.path),\n null,\n );\n }\n}\n\nasync function handleFlowImpact(\n graph: Graph,\n flowName: string,\n simulate?: boolean,\n): Promise<void> {\n const flow = graph.flows.find((f) => f.name === flowName || f.path === flowName);\n if (!flow) {\n process.stderr.write(`Flow not found: ${flowName}\\n`);\n process.exit(1);\n }\n\n const participants = new Set<string>();\n for (const nodePath of flow.nodes) {\n if (graph.nodes.has(nodePath)) {\n participants.add(nodePath);\n for (const desc of collectDescendants(graph, nodePath)) {\n participants.add(desc);\n }\n }\n }\n\n const sorted = [...participants].sort();\n const flowAspects = flow.aspects ?? [];\n\n process.stdout.write(`Impact of changes in flow ${flow.name}:\\n\\n`);\n process.stdout.write('Participants:\\n');\n if (sorted.length === 0) {\n process.stdout.write(' (none)\\n');\n } else {\n for (const p of sorted) {\n const isDeclared = flow.nodes.includes(p);\n const suffix = isDeclared ? '' : ' (descendant)';\n process.stdout.write(` ${p}${suffix}\\n`);\n }\n }\n process.stdout.write(\n `\\nFlow aspects: ${flowAspects.length > 0 ? flowAspects.join(', ') : '(none)'}\\n`,\n );\n process.stdout.write(`\\nTotal scope: ${sorted.length} nodes\\n`);\n\n if (simulate && sorted.length > 0) {\n await runSimulation(graph, sorted, null);\n }\n}\n\nexport function registerImpactCommand(program: Command): void {\n program\n .command('impact')\n .description('Show reverse dependency impact for a node, aspect, or flow')\n .option('--node <path>', 'Node path relative to .yggdrasil/model/')\n .option('--aspect <id>', 'Aspect id (directory path under aspects/)')\n .option('--flow <name>', 'Flow name (directory name under flows/)')\n .option('--simulate', 'Simulate context package impact (compare HEAD vs current)')\n .action(\n async (options: { node?: string; aspect?: string; flow?: string; simulate?: boolean }) => {\n try {\n const modeCount = [options.node, options.aspect, options.flow].filter(Boolean).length;\n if (modeCount === 0) {\n process.stderr.write(\n 'Error: one of --node, --aspect, or --flow is required\\n',\n );\n process.exit(1);\n }\n if (modeCount > 1) {\n process.stderr.write(\n 'Error: --node, --aspect, and --flow are mutually exclusive\\n',\n );\n process.exit(1);\n }\n\n const graph = await loadGraph(process.cwd());\n\n if (options.aspect) {\n await handleAspectImpact(graph, options.aspect.trim(), options.simulate);\n return;\n }\n if (options.flow) {\n await handleFlowImpact(graph, options.flow.trim(), options.simulate);\n return;\n }\n\n const nodePath = options.node!.trim().replace(/^\\.\\//, '').replace(/\\/+$/, '');\n\n if (!graph.nodes.has(nodePath)) {\n process.stderr.write(`Node not found: ${nodePath}\\n`);\n process.exit(1);\n }\n\n const { direct, allDependents, reverse, relationFrom } = collectReverseDependents(\n graph,\n nodePath,\n );\n const chains = buildTransitiveChains(nodePath, direct, allDependents, reverse);\n\n const flows: string[] = [];\n for (const flow of graph.flows) {\n if (flow.nodes.includes(nodePath)) {\n flows.push(flow.name);\n }\n }\n\n const targetEffective = collectEffectiveAspectIds(graph, nodePath);\n const aspectsInScope: string[] = [];\n for (const aspect of graph.aspects) {\n if (targetEffective.has(aspect.id)) {\n aspectsInScope.push(aspect.name);\n }\n }\n\n process.stdout.write(`Impact of changes in ${nodePath}:\\n\\n`);\n process.stdout.write('Directly dependent:\\n');\n if (direct.length === 0) {\n process.stdout.write(' (none)\\n');\n } else {\n for (const dep of direct) {\n const rel = relationFrom.get(`${dep}->${nodePath}`);\n const annot = rel?.consumes?.length\n ? ` (${rel.type}, you consume: ${rel.consumes.join(', ')})`\n : rel\n ? ` (${rel.type})`\n : '';\n process.stdout.write(` <- ${dep}${annot}\\n`);\n }\n }\n process.stdout.write('\\nTransitively dependent:\\n');\n if (chains.length === 0) {\n process.stdout.write(' (none)\\n');\n } else {\n for (const chain of chains) {\n process.stdout.write(` ${chain}\\n`);\n }\n }\n\n const descendants = collectDescendants(graph, nodePath);\n if (descendants.length > 0) {\n process.stdout.write('\\nDescendants (hierarchy impact):\\n');\n for (const desc of descendants) {\n process.stdout.write(` ${desc}\\n`);\n }\n }\n\n process.stdout.write(\n `\\nFlows: ${flows.length > 0 ? flows.join(', ') : '(none)'}\\n`,\n );\n process.stdout.write(\n `Aspects (scope covers node): ${aspectsInScope.length > 0 ? aspectsInScope.join(', ') : '(none)'}\\n`,\n );\n\n const coAspectNodes: Array<{ path: string; shared: string[] }> = [];\n if (targetEffective.size > 0) {\n for (const [p] of graph.nodes) {\n if (p === nodePath) continue;\n const nodeEffective = collectEffectiveAspectIds(graph, p);\n const shared = [...targetEffective].filter((id) => nodeEffective.has(id));\n if (shared.length > 0) {\n coAspectNodes.push({ path: p, shared });\n }\n }\n }\n if (coAspectNodes.length > 0) {\n process.stdout.write('Nodes sharing aspects:\\n');\n for (const { path: p, shared } of coAspectNodes.sort((a, b) =>\n a.path.localeCompare(b.path),\n )) {\n process.stdout.write(` ${p} (${shared.join(', ')})\\n`);\n }\n }\n\n const allAffected = new Set([...allDependents, ...descendants]);\n process.stdout.write(\n `\\nTotal scope: ${allAffected.size} nodes, ${flows.length} flows, ${aspectsInScope.length} aspects\\n`,\n );\n\n if (options.simulate && allAffected.size > 0) {\n await runSimulation(graph, allAffected, nodePath);\n }\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n },\n );\n}\n","import { Command } from 'commander';\nimport { stringify as yamlStringify } from 'yaml';\nimport { loadGraph } from '../core/graph-loader.js';\nimport { findYggRoot } from '../utils/paths.js';\n\nexport function registerAspectsCommand(program: Command): void {\n program\n .command('aspects')\n .description('List aspects with metadata (YAML output)')\n .action(async () => {\n try {\n const yggRoot = await findYggRoot(process.cwd());\n const graph = await loadGraph(yggRoot);\n const output = graph.aspects\n .sort((a, b) => a.id.localeCompare(b.id))\n .map((aspect) => {\n const entry: Record<string, unknown> = { id: aspect.id, name: aspect.name };\n if (aspect.description) entry.description = aspect.description;\n if (aspect.implies && aspect.implies.length > 0) entry.implies = aspect.implies;\n return entry;\n });\n process.stdout.write(yamlStringify(output));\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n if (err.code === 'ENOENT') {\n process.stderr.write(\n `Error: No .yggdrasil/ directory found. Run 'yg init' first.\\n`,\n );\n } else {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n }\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport { stringify as yamlStringify } from 'yaml';\nimport { loadGraph } from '../core/graph-loader.js';\nimport { findYggRoot } from '../utils/paths.js';\n\nexport function registerFlowsCommand(program: Command): void {\n program\n .command('flows')\n .description('List flows with metadata (YAML output)')\n .action(async () => {\n try {\n const yggRoot = await findYggRoot(process.cwd());\n const graph = await loadGraph(yggRoot);\n const output = graph.flows\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((flow) => {\n const entry: Record<string, unknown> = {\n name: flow.name,\n participants: flow.nodes.length,\n nodes: flow.nodes.sort(),\n };\n if (flow.aspects && flow.aspects.length > 0) entry.aspects = flow.aspects;\n return entry;\n });\n process.stdout.write(yamlStringify(output));\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n if (err.code === 'ENOENT') {\n process.stderr.write(\n `Error: No .yggdrasil/ directory found. Run 'yg init' first.\\n`,\n );\n } else {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n }\n process.exit(1);\n }\n });\n}\n","import { readFile, writeFile, mkdir, rename, access } from 'node:fs/promises';\nimport { parse as parseYaml, stringify as stringifyYaml } from 'yaml';\nimport path from 'node:path';\nimport type { JournalEntry } from '../model/types.js';\n\nconst JOURNAL_FILE = '.journal.yaml';\nconst ARCHIVE_DIR = 'journals-archive';\n\nexport async function readJournal(yggRoot: string): Promise<JournalEntry[]> {\n const filePath = path.join(yggRoot, JOURNAL_FILE);\n try {\n const content = await readFile(filePath, 'utf-8');\n const raw = parseYaml(content) as { entries?: JournalEntry[] };\n const entries = raw.entries ?? [];\n return Array.isArray(entries) ? entries : [];\n } catch {\n return [];\n }\n}\n\nexport async function appendJournalEntry(\n yggRoot: string,\n note: string,\n target?: string,\n): Promise<JournalEntry> {\n const entries = await readJournal(yggRoot);\n const at = new Date().toISOString();\n const entry: JournalEntry = target ? { at, target, note } : { at, note };\n\n entries.push(entry);\n\n const filePath = path.join(yggRoot, JOURNAL_FILE);\n const content = stringifyYaml({ entries });\n await writeFile(filePath, content, 'utf-8');\n\n return entry;\n}\n\nexport async function archiveJournal(\n yggRoot: string,\n): Promise<{ archiveName: string; entryCount: number } | null> {\n const journalPath = path.join(yggRoot, JOURNAL_FILE);\n try {\n await access(journalPath);\n } catch {\n return null;\n }\n\n const entries = await readJournal(yggRoot);\n if (entries.length === 0) return null;\n\n const archiveDir = path.join(yggRoot, ARCHIVE_DIR);\n await mkdir(archiveDir, { recursive: true });\n\n const now = new Date();\n const timestamp =\n `${now.getUTCFullYear()}` +\n `${String(now.getUTCMonth() + 1).padStart(2, '0')}` +\n `${String(now.getUTCDate()).padStart(2, '0')}` +\n `-` +\n `${String(now.getUTCHours()).padStart(2, '0')}` +\n `${String(now.getUTCMinutes()).padStart(2, '0')}` +\n `${String(now.getUTCSeconds()).padStart(2, '0')}`;\n const archiveName = `.journal.${timestamp}.yaml`;\n const archivePath = path.join(archiveDir, archiveName);\n\n await rename(journalPath, archivePath);\n\n return { archiveName, entryCount: entries.length };\n}\n","import { Command } from 'commander';\nimport { findYggRoot } from '../utils/paths.js';\nimport { appendJournalEntry, readJournal } from '../io/journal-store.js';\n\nexport function registerJournalAddCommand(program: Command): void {\n program\n .command('journal-add')\n .description('Add a note to the session journal')\n .requiredOption('--note <text>', 'Note content')\n .option('--target <node-path>', 'Node path this note relates to')\n .action(async (options: { note: string; target?: string }) => {\n try {\n const projectRoot = process.cwd();\n const yggRoot = await findYggRoot(projectRoot);\n await appendJournalEntry(yggRoot, options.note, options.target);\n const entries = await readJournal(yggRoot);\n process.stdout.write(`Note added to journal (${entries.length} entries total)\\n`);\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport { findYggRoot } from '../utils/paths.js';\nimport { readJournal } from '../io/journal-store.js';\n\nexport function registerJournalReadCommand(program: Command): void {\n program\n .command('journal-read')\n .description('List pending journal entries')\n .action(async () => {\n try {\n const projectRoot = process.cwd();\n const yggRoot = await findYggRoot(projectRoot);\n const entries = await readJournal(yggRoot);\n\n if (entries.length === 0) {\n process.stdout.write('Session journal: empty (clean state)\\n');\n return;\n }\n\n process.stdout.write(`Session journal (${entries.length} entries):\\n\\n`);\n for (const e of entries) {\n const date = e.at.slice(0, 19).replace('T', ' ');\n const target = e.target ? ` ${e.target}` : '';\n process.stdout.write(`[${date}]${target}\\n ${e.note}\\n\\n`);\n }\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport { findYggRoot } from '../utils/paths.js';\nimport { archiveJournal } from '../io/journal-store.js';\n\nexport function registerJournalArchiveCommand(program: Command): void {\n program\n .command('journal-archive')\n .description('Archive journal after consolidating notes to graph')\n .action(async () => {\n try {\n const projectRoot = process.cwd();\n const yggRoot = await findYggRoot(projectRoot);\n const result = await archiveJournal(yggRoot);\n\n if (!result) {\n process.stdout.write('No active journal - nothing to archive.\\n');\n return;\n }\n\n process.stdout.write(\n `Archived journal (${result.entryCount} entries) -> journals-archive/${result.archiveName}\\n`,\n );\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport { loadGraph } from '../core/graph-loader.js';\nimport { detectDrift } from '../core/drift-detector.js';\nimport { validate } from '../core/validator.js';\nimport { readJournal } from '../io/journal-store.js';\nimport { findYggRoot } from '../utils/paths.js';\nimport { normalizeMappingPaths } from '../utils/paths.js';\n\nexport function registerPreflightCommand(program: Command): void {\n program\n .command('preflight')\n .description('Unified diagnostic report: journal, drift, status, validation')\n .option('--quick', 'Skip drift detection for faster results')\n .action(async (options: { quick?: boolean }) => {\n try {\n const cwd = process.cwd();\n const graph = await loadGraph(cwd);\n const yggRoot = await findYggRoot(cwd);\n\n // --- Journal ---\n const journalEntries = await readJournal(yggRoot);\n\n // --- Drift ---\n const driftedEntries = options.quick\n ? []\n : (await detectDrift(graph)).entries.filter((e) => e.status !== 'ok');\n\n // --- Status counts ---\n const nodeCount = graph.nodes.size;\n const aspectCount = graph.aspects.length;\n const flowCount = graph.flows.length;\n let mappedPathCount = 0;\n for (const node of graph.nodes.values()) {\n mappedPathCount += normalizeMappingPaths(node.meta.mapping).length;\n }\n\n // --- Validation ---\n const validation = await validate(graph, 'all');\n const errors = validation.issues.filter((i) => i.severity === 'error');\n const warnings = validation.issues.filter((i) => i.severity === 'warning');\n\n // --- Build output ---\n const lines: string[] = [];\n lines.push('=== Preflight Report ===');\n lines.push('');\n\n // Journal section\n if (journalEntries.length === 0) {\n lines.push('Journal: clean');\n } else {\n lines.push(`Journal: ${journalEntries.length} pending entries`);\n for (const entry of journalEntries) {\n const target = entry.target ? ` [${entry.target}]` : '';\n lines.push(` - ${entry.note}${target}`);\n }\n }\n lines.push('');\n\n // Drift section\n if (options.quick) {\n lines.push('Drift: skipped (--quick)');\n } else if (driftedEntries.length === 0) {\n lines.push('Drift: clean');\n } else {\n lines.push(`Drift: ${driftedEntries.length} nodes need attention`);\n for (const entry of driftedEntries) {\n lines.push(` - ${entry.nodePath}: ${entry.status}`);\n }\n }\n lines.push('');\n\n // Status section\n lines.push(\n `Status: ${nodeCount} nodes, ${aspectCount} aspects, ${flowCount} flows, ${mappedPathCount} mapped paths`,\n );\n if (nodeCount === 0) {\n lines.push('');\n lines.push(' ⚡ No nodes found. Enter BOOTSTRAP MODE:');\n lines.push(' Create nodes under .yggdrasil/model/ for your active work area.');\n lines.push(' See: yg help build-context');\n }\n lines.push('');\n\n // Validation section\n if (errors.length === 0 && warnings.length === 0) {\n lines.push('Validation: clean');\n } else {\n const parts: string[] = [];\n if (errors.length > 0) parts.push(`${errors.length} errors`);\n if (warnings.length > 0) parts.push(`${warnings.length} warnings`);\n lines.push(`Validation: ${parts.join(', ')}`);\n for (const issue of [...errors, ...warnings]) {\n const code = issue.code ? `[${issue.code}] ` : '';\n const loc = issue.nodePath ? `${issue.nodePath} -> ` : '';\n lines.push(` - ${code}${loc}${issue.message}`);\n }\n }\n lines.push('');\n\n process.stdout.write(lines.join('\\n'));\n\n // Exit code: 1 if journal entries, drift, or validation errors exist.\n // Warnings alone do not cause exit 1.\n const hasIssues =\n journalEntries.length > 0 || (!options.quick && driftedEntries.length > 0) || errors.length > 0;\n process.exit(hasIssues ? 1 : 0);\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n"],"mappings":"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","names":["mkdir","writeFile","readFile","path","path","program","rulesPath","mkdir","readFile","writeFile","readdir","readFile","path","readFile","readFile","parseYaml","readFile","parseYaml","readFile","readdir","path","readFile","parseYaml","readFile","path","parseYaml","readFile","parseYaml","path","readFile","path","parseYaml","path","fileURLToPath","stat","path","stat","path","path","path","readdir","readFile","readFile","path","path","readFile","readdir","path","path","access","readdir","pkg","pkg","program","pkg","program","chalk","readFile","writeFile","path","readFile","readdir","stat","path","require","readFile","path","path","stat","readFile","readdir","path","STRUCTURAL_RELATION_TYPES","path","collectParticipatingFlows","path","program","chalk","chalk","program","chalk","program","program","path","path","access","program","path","access","path","STRUCTURAL_RELATION_TYPES","EVENT_RELATION_TYPES","STRUCTURAL_RELATION_TYPES","EVENT_RELATION_TYPES","program","path","execSync","execSync","path","path","pkg","program","program","yamlStringify","program","yamlStringify","readFile","writeFile","mkdir","access","parseYaml","path","program","program","program","program","fileURLToPath"]}
|
|
1
|
+
{"version":3,"sources":["../src/bin.ts","../src/cli/init.ts","../src/templates/default-config.ts","../src/templates/platform.ts","../src/templates/rules.ts","../src/core/graph-loader.ts","../src/io/config-parser.ts","../src/io/node-parser.ts","../src/io/aspect-parser.ts","../src/io/artifact-reader.ts","../src/io/flow-parser.ts","../src/io/schema-parser.ts","../src/utils/paths.ts","../src/core/context-builder.ts","../src/utils/tokens.ts","../src/core/validator.ts","../src/formatters/context-text.ts","../src/cli/build-context.ts","../src/cli/validate.ts","../src/cli/drift.ts","../src/io/drift-state-store.ts","../src/utils/hash.ts","../src/core/context-files.ts","../src/core/drift-detector.ts","../src/cli/drift-sync.ts","../src/cli/status.ts","../src/cli/tree.ts","../src/cli/owner.ts","../src/core/dependency-resolver.ts","../src/cli/deps.ts","../src/core/graph-from-git.ts","../src/cli/impact.ts","../src/cli/aspects.ts","../src/cli/flows.ts","../src/io/journal-store.ts","../src/cli/journal-add.ts","../src/cli/journal-read.ts","../src/cli/journal-archive.ts","../src/cli/preflight.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { registerInitCommand } from './cli/init.js';\nimport { registerBuildCommand } from './cli/build-context.js';\nimport { registerValidateCommand } from './cli/validate.js';\nimport { registerDriftCommand } from './cli/drift.js';\nimport { registerDriftSyncCommand } from './cli/drift-sync.js';\nimport { registerStatusCommand } from './cli/status.js';\nimport { registerTreeCommand } from './cli/tree.js';\nimport { registerOwnerCommand } from './cli/owner.js';\nimport { registerDepsCommand } from './cli/deps.js';\nimport { registerImpactCommand } from './cli/impact.js';\nimport { registerAspectsCommand } from './cli/aspects.js';\nimport { registerFlowsCommand } from './cli/flows.js';\nimport { registerJournalAddCommand } from './cli/journal-add.js';\nimport { registerJournalReadCommand } from './cli/journal-read.js';\nimport { registerJournalArchiveCommand } from './cli/journal-archive.js';\nimport { registerPreflightCommand } from './cli/preflight.js';\nimport { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\nconst pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));\n\nconst program = new Command();\n\nprogram\n .name('yg')\n .description('Yggdrasil — architectural knowledge infrastructure for AI agents')\n .version(pkg.version);\n\nregisterInitCommand(program);\nregisterBuildCommand(program);\nregisterValidateCommand(program);\nregisterDriftCommand(program);\nregisterDriftSyncCommand(program);\nregisterStatusCommand(program);\nregisterTreeCommand(program);\nregisterOwnerCommand(program);\nregisterDepsCommand(program);\nregisterImpactCommand(program);\nregisterAspectsCommand(program);\nregisterFlowsCommand(program);\nregisterJournalAddCommand(program);\nregisterJournalReadCommand(program);\nregisterJournalArchiveCommand(program);\nregisterPreflightCommand(program);\n\nprogram.parse();\n","import { Command } from 'commander';\nimport { mkdir, writeFile, readdir, readFile, stat } from 'node:fs/promises';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { DEFAULT_CONFIG } from '../templates/default-config.js';\nimport { installRulesForPlatform, PLATFORMS, type Platform } from '../templates/platform.js';\n\nfunction getGraphSchemasDir(): string {\n const currentDir = path.dirname(fileURLToPath(import.meta.url));\n const packageRoot = path.join(currentDir, '..');\n return path.join(packageRoot, 'graph-schemas');\n}\n\nconst GITIGNORE_CONTENT = `.journal.yaml\n.drift-state\njournals-archive/\n`;\n\nexport function registerInitCommand(program: Command): void {\n program\n .command('init')\n .description('Initialize Yggdrasil graph in current project')\n .option(\n '--platform <name>',\n 'Agent platform: cursor, claude-code, copilot, cline, roocode, codex, windsurf, aider, gemini, amp, generic',\n 'generic',\n )\n .option('--upgrade', 'Refresh rules only (when .yggdrasil/ already exists)')\n .action(async (options: { platform?: string; upgrade?: boolean }) => {\n const projectRoot = process.cwd();\n const yggRoot = path.join(projectRoot, '.yggdrasil');\n\n let upgradeMode = false;\n try {\n const statResult = await stat(yggRoot);\n if (!statResult.isDirectory()) {\n process.stderr.write('Error: .yggdrasil exists but is not a directory.\\n');\n process.exit(1);\n }\n if (options.upgrade) {\n upgradeMode = true;\n } else {\n process.stderr.write(\n 'Error: .yggdrasil/ already exists. Use --upgrade to refresh rules only.\\n',\n );\n process.exit(1);\n }\n } catch {\n // Directory does not exist — proceed with full init\n }\n\n const platform = (options.platform ?? 'generic') as Platform;\n if (!PLATFORMS.includes(platform)) {\n process.stderr.write(\n `Error: Unknown platform '${platform}'. Use: ${PLATFORMS.join(', ')}\\n`,\n );\n process.exit(1);\n }\n\n if (upgradeMode) {\n const rulesPath = await installRulesForPlatform(projectRoot, platform);\n process.stdout.write('✓ Rules refreshed.\\n');\n process.stdout.write(` ${path.relative(projectRoot, rulesPath)}\\n`);\n return;\n }\n\n await mkdir(path.join(yggRoot, 'model'), { recursive: true });\n await mkdir(path.join(yggRoot, 'aspects'), { recursive: true });\n await mkdir(path.join(yggRoot, 'flows'), { recursive: true });\n const schemasDir = path.join(yggRoot, 'schemas');\n await mkdir(schemasDir, { recursive: true });\n\n const graphSchemasDir = getGraphSchemasDir();\n try {\n const entries = await readdir(graphSchemasDir, { withFileTypes: true });\n const schemaFiles = entries.filter((e) => e.isFile()).map((e) => e.name);\n for (const file of schemaFiles) {\n const srcPath = path.join(graphSchemasDir, file);\n const content = await readFile(srcPath, 'utf-8');\n await writeFile(path.join(schemasDir, file), content, 'utf-8');\n }\n } catch (err) {\n process.stderr.write(\n `Warning: Could not copy graph schemas from ${graphSchemasDir}: ${(err as Error).message}\\n`,\n );\n }\n\n await writeFile(path.join(yggRoot, 'config.yaml'), DEFAULT_CONFIG, 'utf-8');\n await writeFile(path.join(yggRoot, '.gitignore'), GITIGNORE_CONTENT, 'utf-8');\n\n const rulesPath = await installRulesForPlatform(projectRoot, platform);\n\n process.stdout.write('✓ Yggdrasil initialized.\\n\\n');\n process.stdout.write('Created:\\n');\n process.stdout.write(' .yggdrasil/config.yaml\\n');\n process.stdout.write(' .yggdrasil/.gitignore\\n');\n process.stdout.write(' .yggdrasil/model/\\n');\n process.stdout.write(' .yggdrasil/aspects/\\n');\n process.stdout.write(' .yggdrasil/flows/\\n');\n process.stdout.write(' .yggdrasil/schemas/ (config, node, aspect, flow)\\n');\n process.stdout.write(` ${path.relative(projectRoot, rulesPath)} (rules)\\n\\n`);\n process.stdout.write('Next steps:\\n');\n process.stdout.write(' 1. Edit .yggdrasil/config.yaml — set name, stack, standards\\n');\n process.stdout.write(' 2. Create nodes under .yggdrasil/model/\\n');\n process.stdout.write(' 3. Run: yg validate\\n');\n });\n}\n","export const DEFAULT_CONFIG = `name: \"\"\n\nstack:\n language: \"\"\n runtime: \"\"\n\nstandards: \"\"\n\nnode_types:\n - name: module\n - name: service\n - name: library\n\nartifacts:\n responsibility.md:\n required: always\n description: \"What this node is responsible for, and what it is not\"\n structural_context: true\n interface.md:\n required:\n when: has_incoming_relations\n description: \"Public API — methods, parameters, return types, contracts\"\n structural_context: true\n logic.md:\n required: never\n description: \"Algorithmic flow, control flow, branching logic, decision trees — the 'how' of execution\"\n constraints.md:\n required: never\n description: \"Validation rules, business rules, invariants\"\n structural_context: true\n errors.md:\n required:\n when: has_incoming_relations\n description: \"Failure modes, edge cases, error conditions, recovery behavior\"\n structural_context: true\n model.md:\n required: never\n description: \"Data structures, schemas, entities, type definitions — the shape of data this node owns or manages\"\n state.md:\n required: never\n description: \"State machines, lifecycle, transitions\"\n decisions.md:\n required: never\n description: \"Local design decisions and rationale — choices specific to this node, not system-wide\"\n\nquality:\n min_artifact_length: 50\n max_direct_relations: 10\n context_budget:\n warning: 10000\n error: 20000\n`;\n","import { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport { AGENT_RULES_CONTENT } from './rules.js';\n\nconst AGENT_RULES_IMPORT = '@.yggdrasil/agent-rules.md';\nconst YGGDRASIL_START = '<!-- yggdrasil:start -->';\nconst YGGDRASIL_END = '<!-- yggdrasil:end -->';\nconst YGGDRASIL_SECTION = `## Yggdrasil\\n\\n${AGENT_RULES_CONTENT}`;\nconst YGGDRASIL_BLOCK = `${YGGDRASIL_START}\\n${YGGDRASIL_SECTION}\\n${YGGDRASIL_END}`;\n\nexport type Platform =\n | 'cursor'\n | 'claude-code'\n | 'copilot'\n | 'cline'\n | 'roocode'\n | 'codex'\n | 'windsurf'\n | 'aider'\n | 'gemini'\n | 'amp'\n | 'generic';\n\nexport const PLATFORMS: Platform[] = [\n 'cursor',\n 'claude-code',\n 'copilot',\n 'cline',\n 'roocode',\n 'codex',\n 'windsurf',\n 'aider',\n 'gemini',\n 'amp',\n 'generic',\n];\n\nexport async function installRulesForPlatform(\n projectRoot: string,\n platform: Platform,\n): Promise<string> {\n const agentRulesPath = path.join(projectRoot, '.yggdrasil', 'agent-rules.md');\n\n switch (platform) {\n case 'cursor':\n return installForCursor(projectRoot);\n case 'claude-code':\n return installForClaudeCode(projectRoot, agentRulesPath);\n case 'copilot':\n return installForCopilot(projectRoot);\n case 'cline':\n return installForCline(projectRoot);\n case 'roocode':\n return installForRooCode(projectRoot);\n case 'codex':\n return installForCodex(projectRoot);\n case 'windsurf':\n return installForWindsurf(projectRoot);\n case 'aider':\n return installForAider(projectRoot, agentRulesPath);\n case 'gemini':\n return installForGemini(projectRoot, agentRulesPath);\n case 'amp':\n return installForAmp(projectRoot, agentRulesPath);\n case 'generic':\n default:\n return installForGeneric(projectRoot);\n }\n}\n\nasync function ensureAgentRules(agentRulesPath: string): Promise<void> {\n await mkdir(path.dirname(agentRulesPath), { recursive: true });\n await writeFile(agentRulesPath, AGENT_RULES_CONTENT, 'utf-8');\n}\n\nasync function installForCursor(projectRoot: string): Promise<string> {\n const dir = path.join(projectRoot, '.cursor', 'rules');\n await mkdir(dir, { recursive: true });\n const filePath = path.join(dir, 'yggdrasil.mdc');\n const content = `---\ndescription: Yggdrasil — semantic memory of the repository\nalwaysApply: true\n---\n\n${AGENT_RULES_CONTENT}`;\n await writeFile(filePath, content, 'utf-8');\n return filePath;\n}\n\nasync function installForClaudeCode(projectRoot: string, agentRulesPath: string): Promise<string> {\n await ensureAgentRules(agentRulesPath);\n const filePath = path.join(projectRoot, 'CLAUDE.md');\n let existing = '';\n try {\n existing = await readFile(filePath, 'utf-8');\n } catch {\n /* file doesn't exist */\n }\n const importLine = AGENT_RULES_IMPORT;\n if (existing.includes(importLine)) {\n return agentRulesPath;\n }\n const content = existing.trimEnd() ? `${existing.trimEnd()}\\n${importLine}\\n` : `${importLine}\\n`;\n await writeFile(filePath, content, 'utf-8');\n return agentRulesPath;\n}\n\nasync function installForCopilot(projectRoot: string): Promise<string> {\n const dir = path.join(projectRoot, '.github');\n await mkdir(dir, { recursive: true });\n const filePath = path.join(dir, 'copilot-instructions.md');\n let existing = '';\n try {\n existing = await readFile(filePath, 'utf-8');\n } catch {\n /* file doesn't exist */\n }\n let content: string;\n if (existing.includes(YGGDRASIL_START) && existing.includes(YGGDRASIL_END)) {\n content = existing.replace(\n new RegExp(`${escapeRegex(YGGDRASIL_START)}[\\\\s\\\\S]*?${escapeRegex(YGGDRASIL_END)}`, 'g'),\n YGGDRASIL_BLOCK,\n );\n } else {\n content = existing.trimEnd()\n ? `${existing.trimEnd()}\\n\\n${YGGDRASIL_BLOCK}\\n`\n : `${YGGDRASIL_BLOCK}\\n`;\n }\n await writeFile(filePath, content, 'utf-8');\n return filePath;\n}\n\nasync function installForCline(projectRoot: string): Promise<string> {\n const dir = path.join(projectRoot, '.clinerules');\n await mkdir(dir, { recursive: true });\n const filePath = path.join(dir, 'yggdrasil.md');\n await writeFile(filePath, AGENT_RULES_CONTENT, 'utf-8');\n return filePath;\n}\n\nasync function installForRooCode(projectRoot: string): Promise<string> {\n const dir = path.join(projectRoot, '.roo', 'rules');\n await mkdir(dir, { recursive: true });\n const filePath = path.join(dir, 'yggdrasil.md');\n await writeFile(filePath, AGENT_RULES_CONTENT, 'utf-8');\n return filePath;\n}\n\nasync function installForCodex(projectRoot: string): Promise<string> {\n const filePath = path.join(projectRoot, 'AGENTS.md');\n let existing = '';\n try {\n existing = await readFile(filePath, 'utf-8');\n } catch {\n /* file doesn't exist */\n }\n let content: string;\n if (existing.includes(YGGDRASIL_START) && existing.includes(YGGDRASIL_END)) {\n content = existing.replace(\n new RegExp(`${escapeRegex(YGGDRASIL_START)}[\\\\s\\\\S]*?${escapeRegex(YGGDRASIL_END)}`, 'g'),\n YGGDRASIL_BLOCK,\n );\n } else {\n content = existing.trimEnd()\n ? `${existing.trimEnd()}\\n\\n${YGGDRASIL_BLOCK}\\n`\n : `${YGGDRASIL_BLOCK}\\n`;\n }\n await writeFile(filePath, content, 'utf-8');\n return filePath;\n}\n\nasync function installForWindsurf(projectRoot: string): Promise<string> {\n const dir = path.join(projectRoot, '.windsurf', 'rules');\n await mkdir(dir, { recursive: true });\n const filePath = path.join(dir, 'yggdrasil.md');\n await writeFile(filePath, AGENT_RULES_CONTENT, 'utf-8');\n return filePath;\n}\n\nasync function installForAider(projectRoot: string, agentRulesPath: string): Promise<string> {\n await ensureAgentRules(agentRulesPath);\n const filePath = path.join(projectRoot, '.aider.conf.yml');\n const entry = '.yggdrasil/agent-rules.md';\n let existing = '';\n try {\n existing = await readFile(filePath, 'utf-8');\n } catch {\n /* file doesn't exist */\n }\n if (existing.includes(entry)) {\n return agentRulesPath;\n }\n const content = appendAiderReadEntry(existing, entry);\n await writeFile(filePath, content, 'utf-8');\n return agentRulesPath;\n}\n\nfunction appendAiderReadEntry(existing: string, entry: string): string {\n const newItem = ` - ${entry} # added by yg init\\n`;\n const readBlock = /^read:\\s*\\n((?:\\s+-\\s+[^\\n]+\\n)*)/m;\n const match = existing.match(readBlock);\n if (match) {\n return existing.replace(match[0], `read:\\n${match[1]}${newItem}`);\n }\n const readEmpty = /^read:\\s*$/m;\n if (readEmpty.test(existing)) {\n return existing.replace(readEmpty, `read:\\n${newItem}`);\n }\n const trimmed = existing.trimEnd();\n return trimmed ? `${trimmed}\\n\\nread:\\n${newItem}` : `read:\\n${newItem}`;\n}\n\nasync function installForGemini(projectRoot: string, agentRulesPath: string): Promise<string> {\n await ensureAgentRules(agentRulesPath);\n const filePath = path.join(projectRoot, 'GEMINI.md');\n let existing = '';\n try {\n existing = await readFile(filePath, 'utf-8');\n } catch {\n /* file doesn't exist */\n }\n const importLine = AGENT_RULES_IMPORT;\n if (existing.includes(importLine)) {\n return agentRulesPath;\n }\n const content = existing.trimEnd() ? `${existing.trimEnd()}\\n${importLine}\\n` : `${importLine}\\n`;\n await writeFile(filePath, content, 'utf-8');\n return agentRulesPath;\n}\n\nasync function installForAmp(projectRoot: string, agentRulesPath: string): Promise<string> {\n await ensureAgentRules(agentRulesPath);\n const filePath = path.join(projectRoot, 'AGENTS.md');\n let existing = '';\n try {\n existing = await readFile(filePath, 'utf-8');\n } catch {\n /* file doesn't exist */\n }\n const importLine = AGENT_RULES_IMPORT;\n if (existing.includes(importLine)) {\n return agentRulesPath;\n }\n const content = existing.trimEnd() ? `${existing.trimEnd()}\\n${importLine}\\n` : `${importLine}\\n`;\n await writeFile(filePath, content, 'utf-8');\n return agentRulesPath;\n}\n\nasync function installForGeneric(projectRoot: string): Promise<string> {\n const filePath = path.join(projectRoot, '.yggdrasil', 'agent-rules.md');\n await ensureAgentRules(filePath);\n return filePath;\n}\n\nfunction escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n","/**\n * Canonical agent rules content — hand-tuned, do not generate programmatically.\n *\n * Operating manual for agents working in a Yggdrasil-managed repository.\n * Split into three cognitive sections optimized for LLM attention patterns:\n * 1. CORE PROTOCOL — internalize before doing anything (primacy effect)\n * 2. OPERATIONS — execute while working (working memory)\n * 3. KNOWLEDGE BASE — look up when needed (recency effect)\n */\n\n// prettier-ignore\nconst CORE_PROTOCOL = `## CORE PROTOCOL\n\nYggdrasil is persistent semantic memory stored in \\`.yggdrasil/\\`. It maps the repository and provides deterministic implementation context for every node. This document is your complete operating manual. Follow it strictly.\n\n### Quick Start Protocol\n\n\\`\\`\\`\nBEFORE reading, researching, planning, OR modifying ANY mapped file:\n 1. yg owner --file <path>\n 2. yg build-context --node <owner>\n The context package is your primary source of understanding.\n Raw file reads are for implementation details WITHIN a node you\n already understand from its context package.\n If the context package seems insufficient — enrich the graph.\n Do not bypass it.\n\nAFTER modifying:\n 3. Update graph artifacts to reflect changes\n 4. yg validate — fix all errors\n 5. yg drift-sync --node <owner>\n\nEVERY conversation start:\n yg preflight → act on findings (see Operations)\n\nNEVER: modify code without graph coverage.\nNEVER: read mapped source files to understand a component without\n running yg build-context first — the graph captures intent,\n constraints, and relations that source files cannot.\nNEVER: invent rationale, business rules, or decisions.\nNEVER: auto-resolve drift without asking the user.\nWHEN UNSURE: ask the user. Never guess. Never assume.\n\\`\\`\\`\n\n### Five Core Rules\n\n1. **Graph first.** Before reading, researching, planning, or modifying mapped files, run \\`yg owner\\` and \\`yg build-context\\`. Always. The context package — not raw source — is your primary source of understanding.\n2. **Code and graph are one.** Code changed → graph updated in the same response. Graph changed → source verified in the same response. No exceptions.\n3. **Never invent why.** The graph captures human intent. If you don't know why something was decided, ask. Never hallucinate rationale.\n4. **Always capture why — especially why NOT.** When the user explains a reason, record it in the graph immediately. When a design choice is made, also record rejected alternatives: \"Chose X over Y because Z.\" Rejected alternatives are the highest-value information — invisible in code and irrecoverable once forgotten. Conversation evaporates; graph persists.\n5. **Ask before resolving ambiguity.** When multiple valid interpretations exist, stop, list options, ask the user. Never silently choose.\n\n### Failure States\n\nYou have broken Yggdrasil if you do any of the following:\n\n- ❌ Modified source code without running \\`yg owner --file <path>\\` first.\n- ❌ Modified source code without updating graph artifacts in the same response.\n- ❌ Modified graph files without verifying source code alignment in the same response.\n- ❌ Resolved a code-graph inconsistency without asking the user first.\n- ❌ Created or edited a graph element without reading its schema in \\`schemas/\\` first.\n- ❌ Ran \\`yg drift-sync\\` before updating graph artifacts.\n- ❌ Wrote a flow description that describes code sequences instead of a business process.\n- ❌ Used an aspect identifier that has no corresponding \\`aspects/\\` directory.\n- ❌ Placed a cross-cutting requirement in a local node artifact instead of an aspect.\n- ❌ Invented a rationale, business rule, or architectural decision.\n- ❌ Used blackbox coverage for greenfield (new) code.\n- ❌ Answered a question about a mapped file without running \\`yg build-context\\` first.\n- ❌ Read mapped source files to plan or research changes without running \\`yg build-context\\` first.\n- ❌ Deferred \\`yg drift-sync\\` to the end of a multi-step task instead of running it incrementally after each logical group of changes.\n- ❌ Recorded a design decision without documenting which alternatives were rejected and why.\n\n### Escape Hatch\n\nIf the user explicitly requests a code-only change, comply but:\n\n- Warn: \"This creates drift. Run \\`yg drift\\` next session to reconcile.\"\n- Do NOT run \\`yg drift-sync\\` — leave the drift visible.\n\n### Environment Check\n\nBefore preflight:\n\n- Verify \\`yg\\` CLI is available. If not found, inform user and stop.\n- If \\`yg preflight\\` shows 0 nodes → enter BOOTSTRAP MODE (see Operations).\n- If drift report shows >10 drifted nodes → report scope to user, ask which area to prioritize. Do not resolve all at once.`;\n\n// prettier-ignore\nconst OPERATIONS = `## OPERATIONS\n\n### Conversation Lifecycle\n\n\\`\\`\\`\nPREFLIGHT (every conversation, before any work):\n - [ ] 1. yg preflight → read unified report\n - [ ] 2. If journal entries: consolidate to graph, then yg journal-archive\n - [ ] 3. If drift: resolve per Drift Resolution, then yg drift-sync per node\n - [ ] 4. If validation errors: fix, re-run yg validate\n Exception: read-only requests (explain, analyze) — skip preflight.\n\nUNDERSTANDING mapped code (questions, research, OR planning):\n - [ ] 1. yg owner --file <path>\n - [ ] 2. Owner found → yg build-context --node <path>. Use context package as primary source.\n - [ ] 3. Owner not found → use file analysis, state it is not graph-backed.\n Never use grep or raw file reads as primary understanding when graph coverage exists.\n Raw reads supplement the context package — they do not replace it.\n\nWRAP-UP (user signals \"done\", \"wrap up\", \"that's enough\"):\n - [ ] 1. Consolidate journal if used → yg journal-archive\n - [ ] 2. yg drift --drifted-only → resolve\n - [ ] 3. yg validate → fix errors\n - [ ] 4. Report: which nodes and files were changed\n\nBEFORE ENDING ANY RESPONSE (self-audit):\n - [ ] Did I modify source code? If yes → did I update graph artifacts in this same response?\n - [ ] If you changed code and did not sync the graph, you have broken the protocol. Do not finish until both are done.\n\\`\\`\\`\n\n### Modify Source Code\n\nYou are not allowed to edit or create source code without establishing graph coverage first.\n\n**Step 1** — Check coverage: \\`yg owner --file <path>\\`\n\n**Step 2a** — Owner found: execute checklist:\n\n- [ ] 1. Read specification: \\`yg build-context --node <node_path>\\`\n- [ ] 2. Assess blast radius: \\`yg impact --node <node_path>\\` — review dependents, descendants, and co-aspect nodes before changing interfaces or shared behavior\n- [ ] 3. Modify source code\n- [ ] 4. Sync graph artifacts — edit artifact files to reflect the changes\n- [ ] 5. Run \\`yg validate\\` — fix all errors (if unfixable after 3 attempts → stop, report to user)\n- [ ] 6. Run \\`yg drift-sync --node <node_path>\\` — only after graph and code are both current\n\n**Step 2b** — Owner not found: establish coverage first. Present options to the user:\n\n*Partially mapped* (file unmapped but inside a mapped module): ask whether to add to existing node or create new one.\n\n*Existing code:*\n\n- Option A — Full node: create node(s), map files, write artifacts from code analysis\n- Option B — Blackbox: create a blackbox node at agreed granularity\n- Option C — Abort\n\n*Greenfield (new code):* Only Option A. Blackbox is forbidden for new code. Follow the graph-first workflow:\n\n1. Create aspects first (cross-cutting requirements the new code must satisfy)\n2. Create flows if the code participates in a business process\n3. Create nodes with full artifacts — responsibility, constraints, decisions, interface, logic\n4. Review the context package (\\`yg build-context\\`) — it is now the behavioral specification\n5. Implement code that satisfies the specification\n6. The graph specifies WHAT and WHY; the code implements HOW (framework APIs, library choices)\n\nAfter the user chooses, return to Step 1 and follow Step 2a.\n\n### Modify Graph\n\n- [ ] 1. Read the relevant schema from \\`schemas/\\` before touching any YAML\n- [ ] 2. Before changing an aspect or flow, check scope: \\`yg impact --aspect <id>\\` or \\`yg impact --flow <name>\\` — understand which nodes are affected before modifying shared rules or processes\n- [ ] 3. Make changes\n- [ ] 4. Run \\`yg validate\\` immediately — fix all errors\n- [ ] 5. Verify affected source files are consistent — update if needed\n- [ ] 6. Run \\`yg drift-sync\\` for affected nodes\n\n### Reverse Engineering\n\n**Order:** aspects (cross-cutting patterns) → flows (business processes) → model nodes. Never create nodes before aspects and flows are understood.\n\nPer area checklist:\n\n- [ ] 1. \\`yg owner --file <path>\\` — confirm no coverage\n- [ ] 2. Determine node granularity — propose to user if unclear\n- [ ] 3. Create node directory, read \\`schemas/node.yaml\\`, create \\`node.yaml\\`\n- [ ] 4. Analyze source — for each artifact type in \\`config.artifacts\\`: extract content, do not invent\n- [ ] 5. Identify relations — add to \\`node.yaml\\`\n- [ ] 6. Identify cross-cutting requirements — add matching aspects, create if needed\n- [ ] 7. Identify business process participation — add to flow, ask user if process unclear\n- [ ] 8. \\`yg validate\\` — fix errors\n- [ ] 9. \\`yg drift-sync --node <path>\\`\n\n**When to ask:**\n\n- Business process unclear: \"This code appears to be part of a larger process. Can you describe what it means from a business perspective?\"\n- Constraint without rationale: \"I see [constraint X]. Do you know why this exists? I want to record the reason, not just the rule.\"\n- Unexplained architectural choice: \"I see [approach X]. What was the reason for this choice?\"\n- Decision without alternatives: \"You chose [X]. What alternatives did you consider, and why did you reject them?\" Record the answer in \\`decisions.md\\`.\n\n### Bootstrap Mode\n\nTrigger: \\`yg preflight\\` shows 0 nodes, or no nodes cover the active work area.\n\n- [ ] 1. Identify the active work area (files the user wants to modify)\n- [ ] 2. Scan for cross-cutting patterns → create aspects\n- [ ] 3. Ask user about business processes → create flows if applicable\n- [ ] 4. Propose node structure for the area\n- [ ] 5. Create node(s) with initial artifacts, map files\n- [ ] 6. \\`yg validate\\`, \\`yg drift-sync\\`\n- [ ] 7. Proceed with user's original request\n\nConstraint: Do NOT map the entire repository. Focus on the active area. Expand incrementally.\n\n### Drift Resolution\n\nAlways ask the user before resolving drift. Never auto-resolve.\n\n- **Source drift** (source files changed) → update graph artifacts to match source, then \\`yg drift-sync\\`\n- **Graph drift** (graph artifacts changed) → review affected source, update if needed, then \\`yg drift-sync\\`\n- **Full drift** (both changed) → present both sides to user, ask which direction wins\n- **Missing** → ask: re-materialize or remove mapping?\n- **Unmaterialized** → ask user how to proceed\n\nThreshold: >10 drifted nodes → ask user which area to prioritize. Do not resolve all at once.\n\n### Error Recovery\n\n- **\\`yg\\` not found** → inform user: \"yg CLI is not installed or not in PATH.\" Stop.\n- **Unfixable validate errors** → if not resolved after 3 attempts, stop and report to user. Do not loop.\n- **Budget exceeded** → if \\`yg build-context\\` exits with error (context package exceeds budget), warn user: \"This node should be split.\" Do not proceed with implementation.\n- **Corrupted \\`.yggdrasil/\\` files** → report to user. Do not attempt repair.\n- **Incremental sync** → run \\`yg drift-sync\\` every 3-5 source files during multi-file tasks. Do not defer to end.`;\n\n// prettier-ignore\nconst KNOWLEDGE_BASE = `## KNOWLEDGE BASE\n\n### Graph Structure\n\n\\`\\`\\`\n.yggdrasil/\n config.yaml ← vocabulary, stack, node types, artifact rules, required aspects\n model/ ← what exists: nodes, hierarchy, relations, file mappings\n aspects/ ← what must: cross-cutting requirements with rationale and guidance\n flows/ ← why and in what process: business processes with node participation\n schemas/ ← YAML schemas — read before creating any graph element\n .drift-state ← generated by CLI; never edit manually\n .journal.yaml ← generated by CLI; never edit manually\n\\`\\`\\`\n\nKey facts:\n\n- **Hierarchy:** nodes nest in \\`model/\\`. Children inherit parent context. Do not repeat parent content in children.\n- **Aspect id = directory path** under \\`aspects/\\`. Each aspect has \\`aspect.yaml\\` + content \\`.md\\` files. No automatic parent-child — use \\`implies\\` explicitly.\n- **Flows = business processes.** A flow describes what happens in the world, not code sequences. Flow aspects propagate to all participants.\n\n### Context Assembly\n\nRun \\`yg build-context --node <path>\\` to get the deterministic context package for a node. Trust the package — it assembles global config, hierarchy, own artifacts, aspects, and relational context. If the package is insufficient, enrich the graph. Do not bypass it with raw file exploration.\n\n### Information Routing\n\nWhen you encounter information, route it to the correct location:\n\n- **Specific to this node** → local node artifact (check \\`config.yaml artifacts\\` for available types)\n- **Rule for many nodes** → aspect (\\`aspects/<id>/\\` with \\`aspect.yaml\\` + content \\`.md\\` files). If applies to ALL nodes of a type → \\`node_types[*].required_aspects\\` in \\`config.yaml\\`\n- **Business process** → flow (\\`flows/<name>/\\` with \\`flow.yaml\\` + \\`description.md\\`). Ask user if process unclear.\n- **Shared across a domain** → parent node artifact. Children receive it through hierarchy.\n- **Technology stack or standard** → \\`config.yaml\\` under \\`stack\\` or \\`standards\\` (+ \\`rationale\\` field)\n- **Decision (why + why NOT):** one node → \\`decisions.md\\` with format \"Chose X over Y because Z\"; category of nodes → aspect content files; tech choice → \\`config.yaml\\` rationale field. Always include rejected alternatives — they are the highest-value graph content.\n\n### Creating Aspects\n\n- [ ] 1. Read \\`schemas/aspect.yaml\\`\n- [ ] 2. Create \\`aspects/<id>/\\` directory\n- [ ] 3. Write \\`aspect.yaml\\` — name, optional description, optional implies\n- [ ] 4. Write content \\`.md\\` files: WHAT must be satisfied + WHY (user's words, do not invent)\n- [ ] 5. \\`yg validate\\`\n\nTest: \"Does this requirement apply to more than one node?\" Yes → aspect. No → local artifact.\n\n**Aspect identification heuristic:** If the same pattern, constraint, or rule appears in 3+ places, it is a candidate aspect. Aspects fall into natural categories:\n\n- **Domain-specific:** Business rules that cross module boundaries (e.g., timezone handling, booking periods, currency rounding)\n- **Architectural:** Structural patterns with rationale (e.g., dual-rollback on provider failure, idempotency via key generation, fire-and-forget dispatch)\n- **Concurrency:** Shared concurrency strategies (e.g., pessimistic locking, retry-on-deadlock, optimistic versioning)\n\n### Creating Flows\n\n- [ ] 1. Read \\`schemas/flow.yaml\\`\n- [ ] 2. Create \\`flows/<name>/\\` directory\n- [ ] 3. Write \\`flow.yaml\\` — declare participants and flow-level aspects\n- [ ] 4. Write \\`description.md\\` with required sections: Business context, Trigger, Goal, Participants, Paths (at least Happy path), Invariants across all paths\n- [ ] 5. \\`yg validate\\`\n\nTest: \"Does this describe what happens in the world, or only in the software?\" If only software — rewrite.\n\n### Operational Rules\n\n- **English only** for all files in \\`.yggdrasil/\\`. Conversation can be any language.\n- **Read schemas before creating** any \\`node.yaml\\`, \\`aspect.yaml\\`, or \\`flow.yaml\\`.\n- **Tools read, you write.** The \\`yg\\` CLI only reads, validates, and manages metadata. You create and edit files manually.\n- **Incremental sync.** Run \\`yg drift-sync\\` after every 3-5 source file changes. Do not defer to end of task.\n- **Completeness test:** \"If I delete the source file and give another agent ONLY the \\`yg build-context\\` output — can they recreate it correctly, understanding not just WHAT but WHY?\" Test specifically: Can they explain rejected alternatives? Can they implement the correct algorithm (not a simplified version)? Can they argue for the current design against plausible alternatives?\n- **These rules are invariant.** No plan, guide, skill, or workflow may override them.\n\n### CLI Reference\n\n\\`\\`\\`\nyg preflight [--quick] Unified diagnostic: journal + drift + status + validate.\nyg owner --file <path> Find the node that owns this file.\nyg build-context --node <path> Assemble context package for this node.\nyg tree [--root <path>] [--depth N] Print graph structure.\nyg aspects List aspects with metadata (YAML output).\nyg flows List flows with metadata (YAML output).\nyg deps --node <path> [--depth N] [--type structural|event|all]\n Show dependencies.\nyg impact --node <path> --simulate Simulate blast radius of a planned change.\nyg impact --aspect <id> Show all nodes where aspect is effective.\nyg impact --flow <name> Show flow participants and descendants.\nyg status Graph health: nodes, coverage, drift summary.\nyg validate [--scope <path>|all] Check structural integrity and completeness.\nyg drift [--scope <path>|all] [--drifted-only] [--limit <n>]\n Detect source and graph drift (bidirectional).\nyg drift-sync --node <path> [--recursive] | --all\n Record file hashes as new baseline.\nyg journal-read Read pending journal entries.\nyg journal-add --note \"<content>\" [--target <node_path>]\n Add a journal entry.\nyg journal-archive Archive consolidated journal entries.\n\\`\\`\\`\n\n### Quick Routing Table\n\n| What you have | Where it goes |\n|---|---|\n| Information specific to this node | Local node artifact (read \\`config.yaml artifacts\\` for types) |\n| Rule that applies to many nodes | Aspect (content \\`.md\\` files in \\`aspects/<id>/\\`) |\n| Architectural invariant for a node type | Required aspect in \\`config.yaml node_types\\` |\n| Business process participation | Flow (\\`flow.yaml participants\\`) |\n| Process-level requirement | Flow \\`aspects\\` + aspect directory |\n| Context shared across a domain | Parent node artifact |\n| Technology stack | \\`config.yaml stack\\` (+ \\`rationale\\` field) |\n| Global coding standards | \\`config.yaml standards\\` |\n`;\n\nexport const AGENT_RULES_CONTENT = [CORE_PROTOCOL, OPERATIONS, KNOWLEDGE_BASE].join('\\n\\n---\\n\\n');\n","import { readdir, readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport type {\n Graph,\n GraphNode,\n AspectDef,\n FlowDef,\n SchemaDef,\n YggConfig,\n} from '../model/types.js';\nimport { parseConfig } from '../io/config-parser.js';\nimport { parseNodeYaml } from '../io/node-parser.js';\nimport { parseAspect } from '../io/aspect-parser.js';\nimport { parseFlow } from '../io/flow-parser.js';\nimport { parseSchema } from '../io/schema-parser.js';\nimport { readArtifacts } from '../io/artifact-reader.js';\nimport { findYggRoot } from '../utils/paths.js';\n\nfunction toModelPath(absolutePath: string, modelDir: string): string {\n return path.relative(modelDir, absolutePath).split(path.sep).join('/');\n}\n\nconst FALLBACK_CONFIG: YggConfig = {\n name: '',\n stack: {},\n standards: '',\n node_types: [],\n artifacts: {},\n};\n\nexport async function loadGraph(\n projectRoot: string,\n options: { tolerateInvalidConfig?: boolean } = {},\n): Promise<Graph> {\n const yggRoot = await findYggRoot(projectRoot);\n let configError: string | undefined;\n let config = FALLBACK_CONFIG;\n try {\n config = await parseConfig(path.join(yggRoot, 'config.yaml'));\n } catch (error) {\n if (!options.tolerateInvalidConfig) {\n throw error;\n }\n configError = (error as Error).message;\n }\n\n const modelDir = path.join(yggRoot, 'model');\n const nodes = new Map<string, GraphNode>();\n const nodeParseErrors: Array<{ nodePath: string; message: string }> = [];\n const artifactFilenames = Object.keys(config.artifacts ?? {});\n try {\n await scanModelDirectory(modelDir, modelDir, null, nodes, nodeParseErrors, artifactFilenames);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n throw new Error(`Directory .yggdrasil/model/ does not exist. Run 'yg init' first.`, {\n cause: err,\n });\n }\n throw err;\n }\n\n const aspects = await loadAspects(path.join(yggRoot, 'aspects'));\n const flows = await loadFlows(path.join(yggRoot, 'flows'));\n const schemas = await loadSchemas(path.join(yggRoot, 'schemas'));\n\n return {\n config,\n configError,\n nodeParseErrors: nodeParseErrors.length > 0 ? nodeParseErrors : undefined,\n nodes,\n aspects,\n flows,\n schemas,\n rootPath: yggRoot,\n };\n}\n\nasync function scanModelDirectory(\n dirPath: string,\n modelDir: string,\n parent: GraphNode | null,\n nodes: Map<string, GraphNode>,\n nodeParseErrors: Array<{ nodePath: string; message: string }>,\n artifactFilenames: string[],\n): Promise<void> {\n const entries = await readdir(dirPath, { withFileTypes: true });\n const hasNodeYaml = entries.some((e) => e.isFile() && e.name === 'node.yaml');\n\n if (!hasNodeYaml && dirPath !== modelDir) {\n return;\n }\n\n if (hasNodeYaml) {\n const graphPath = toModelPath(dirPath, modelDir);\n const nodeYamlPath = path.join(dirPath, 'node.yaml');\n let meta;\n let nodeYamlRaw: string | undefined;\n try {\n nodeYamlRaw = await readFile(nodeYamlPath, 'utf-8');\n meta = await parseNodeYaml(nodeYamlPath);\n } catch (err) {\n nodeParseErrors.push({\n nodePath: graphPath,\n message: (err as Error).message,\n });\n return;\n }\n const artifacts = await readArtifacts(dirPath, ['node.yaml'], artifactFilenames);\n\n const node: GraphNode = {\n path: graphPath,\n meta,\n nodeYamlRaw,\n artifacts,\n children: [],\n parent,\n };\n\n nodes.set(graphPath, node);\n if (parent) {\n parent.children.push(node);\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (entry.name.startsWith('.')) continue;\n\n await scanModelDirectory(\n path.join(dirPath, entry.name),\n modelDir,\n node,\n nodes,\n nodeParseErrors,\n artifactFilenames,\n );\n }\n } else {\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (entry.name.startsWith('.')) continue;\n\n await scanModelDirectory(\n path.join(dirPath, entry.name),\n modelDir,\n null,\n nodes,\n nodeParseErrors,\n artifactFilenames,\n );\n }\n }\n}\n\nasync function loadAspects(aspectsDir: string): Promise<AspectDef[]> {\n try {\n const aspects: AspectDef[] = [];\n await scanAspectsDirectory(aspectsDir, aspectsDir, aspects);\n return aspects;\n } catch {\n return [];\n }\n}\n\nasync function scanAspectsDirectory(\n dirPath: string,\n aspectsRoot: string,\n aspects: AspectDef[],\n): Promise<void> {\n const entries = await readdir(dirPath, { withFileTypes: true });\n const hasAspectYaml = entries.some((e) => e.isFile() && e.name === 'aspect.yaml');\n\n if (hasAspectYaml) {\n const id = path.relative(aspectsRoot, dirPath).split(path.sep).join('/');\n const aspectYamlPath = path.join(dirPath, 'aspect.yaml');\n const aspect = await parseAspect(dirPath, aspectYamlPath, id);\n aspects.push(aspect);\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (entry.name.startsWith('.')) continue;\n await scanAspectsDirectory(path.join(dirPath, entry.name), aspectsRoot, aspects);\n }\n}\n\nasync function loadFlows(flowsDir: string): Promise<FlowDef[]> {\n try {\n const entries = await readdir(flowsDir, { withFileTypes: true });\n const flows: FlowDef[] = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const flowYamlPath = path.join(flowsDir, entry.name, 'flow.yaml');\n const flow = await parseFlow(path.join(flowsDir, entry.name), flowYamlPath);\n flows.push(flow);\n }\n return flows;\n } catch {\n return [];\n }\n}\n\nasync function loadSchemas(schemasDir: string): Promise<SchemaDef[]> {\n try {\n const entries = await readdir(schemasDir, { withFileTypes: true });\n const schemas: SchemaDef[] = [];\n for (const entry of entries) {\n if (!entry.isFile()) continue;\n if (!entry.name.endsWith('.yaml') && !entry.name.endsWith('.yml')) continue;\n const s = await parseSchema(path.join(schemasDir, entry.name));\n schemas.push(s);\n }\n return schemas;\n } catch {\n return [];\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { parse as parseYaml } from 'yaml';\nimport type {\n YggConfig,\n ArtifactConfig,\n QualityConfig,\n NodeTypeConfig,\n} from '../model/types.js';\n\nconst DEFAULT_QUALITY: QualityConfig = {\n min_artifact_length: 50,\n max_direct_relations: 10,\n context_budget: { warning: 10000, error: 20000 },\n};\n\nexport async function parseConfig(filePath: string): Promise<YggConfig> {\n const content = await readFile(filePath, 'utf-8');\n const raw = parseYaml(content) as Record<string, unknown>;\n\n if (!raw || typeof raw !== 'object') {\n throw new Error(`config.yaml: file is empty or not a valid YAML mapping`);\n }\n\n if (!raw.name || typeof raw.name !== 'string' || raw.name.trim() === '') {\n throw new Error(`config.yaml: missing or invalid 'name' field`);\n }\n\n const nodeTypesRaw = raw.node_types;\n if (!Array.isArray(nodeTypesRaw) || nodeTypesRaw.length === 0) {\n throw new Error(`config.yaml: 'node_types' must be a non-empty array`);\n }\n const nodeTypes: NodeTypeConfig[] = nodeTypesRaw.map((item) => {\n if (typeof item === 'string') {\n return { name: item };\n }\n if (\n typeof item === 'object' &&\n item !== null &&\n 'name' in item &&\n typeof (item as { name: unknown }).name === 'string'\n ) {\n const obj = item as { name: string; required_aspects?: unknown; required_tags?: unknown };\n const requiredAspects = Array.isArray(obj.required_aspects)\n ? (obj.required_aspects as unknown[]).filter((t): t is string => typeof t === 'string')\n : Array.isArray(obj.required_tags)\n ? (obj.required_tags as unknown[]).filter((t): t is string => typeof t === 'string')\n : undefined;\n return {\n name: obj.name,\n required_aspects: requiredAspects && requiredAspects.length > 0 ? requiredAspects : undefined,\n };\n }\n throw new Error(\n `config.yaml: node_types entry must be string or { name, required_aspects? }`,\n );\n });\n\n const artifacts = raw.artifacts;\n if (\n !artifacts ||\n typeof artifacts !== 'object' ||\n Array.isArray(artifacts) ||\n Object.keys(artifacts).length === 0\n ) {\n throw new Error(`config.yaml: 'artifacts' must be a non-empty object`);\n }\n\n const artifactsMap: Record<string, ArtifactConfig> = {};\n for (const [key, val] of Object.entries(artifacts)) {\n if (key === 'node.yaml') {\n throw new Error(`config.yaml: artifact name 'node.yaml' is reserved`);\n }\n const a = val as Record<string, unknown>;\n const required = a.required;\n if (\n required !== 'always' &&\n required !== 'never' &&\n (typeof required !== 'object' || !required || !('when' in required))\n ) {\n throw new Error(`config.yaml: artifact '${key}' has invalid 'required' field`);\n }\n if (typeof required === 'object' && required && 'when' in required) {\n const when = (required as { when: string }).when;\n const validWhen =\n when === 'has_incoming_relations' ||\n when === 'has_outgoing_relations' ||\n (typeof when === 'string' &&\n (when.startsWith('has_aspect:') || when.startsWith('has_tag:')));\n if (!validWhen) {\n throw new Error(\n `config.yaml: artifact '${key}' has invalid 'required.when': must be has_incoming_relations, has_outgoing_relations, or has_aspect:<name>`,\n );\n }\n }\n artifactsMap[key] = {\n required: required as ArtifactConfig['required'],\n description: (a.description as string) ?? '',\n structural_context: (a.structural_context as boolean) ?? false,\n };\n }\n\n const qualityRaw = raw.quality as Record<string, unknown> | undefined;\n const quality: QualityConfig = qualityRaw\n ? {\n min_artifact_length:\n (qualityRaw.min_artifact_length as number) ?? DEFAULT_QUALITY.min_artifact_length,\n max_direct_relations:\n (qualityRaw.max_direct_relations as number) ?? DEFAULT_QUALITY.max_direct_relations,\n context_budget: {\n warning:\n (qualityRaw.context_budget as Record<string, number>)?.warning ??\n DEFAULT_QUALITY.context_budget.warning,\n error:\n (qualityRaw.context_budget as Record<string, number>)?.error ??\n DEFAULT_QUALITY.context_budget.error,\n },\n }\n : DEFAULT_QUALITY;\n\n if (quality.context_budget.error < quality.context_budget.warning) {\n throw new Error(\n `config.yaml: quality.context_budget.error (${quality.context_budget.error}) must be >= warning (${quality.context_budget.warning})`,\n );\n }\n\n return {\n name: (raw.name as string).trim(),\n stack: (raw.stack as Record<string, string>) ?? {},\n standards: typeof raw.standards === 'string' ? raw.standards : '',\n node_types: nodeTypes,\n artifacts: artifactsMap,\n quality,\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport { parse as parseYaml } from 'yaml';\nimport type { NodeMeta, NodeMapping, Relation, RelationType } from '../model/types.js';\n\nconst RELATION_TYPES: RelationType[] = [\n 'uses',\n 'calls',\n 'extends',\n 'implements',\n 'emits',\n 'listens',\n];\n\nfunction isValidRelationType(t: unknown): t is RelationType {\n return typeof t === 'string' && RELATION_TYPES.includes(t as RelationType);\n}\n\nexport async function parseNodeYaml(filePath: string): Promise<NodeMeta> {\n const content = await readFile(filePath, 'utf-8');\n const raw = parseYaml(content) as Record<string, unknown>;\n\n if (!raw || typeof raw !== 'object') {\n throw new Error(`node.yaml at ${filePath}: file is empty or not a valid YAML mapping`);\n }\n\n if (!raw.name || typeof raw.name !== 'string' || raw.name.trim() === '') {\n throw new Error(`node.yaml at ${filePath}: missing or empty 'name'`);\n }\n if (!raw.type || typeof raw.type !== 'string' || raw.type.trim() === '') {\n throw new Error(`node.yaml at ${filePath}: missing or empty 'type'`);\n }\n\n const relations = parseRelations(raw.relations, filePath);\n const mapping = parseMapping(raw.mapping, filePath);\n\n return {\n name: (raw.name as string).trim(),\n type: (raw.type as string).trim(),\n aspects: parseStringArray(raw.aspects) ?? parseStringArray(raw.tags),\n blackbox: (raw.blackbox as boolean) ?? false,\n relations: relations.length > 0 ? relations : undefined,\n mapping,\n };\n}\n\nfunction parseStringArray(val: unknown): string[] | undefined {\n if (!Array.isArray(val)) return undefined;\n const arr = val.filter((v): v is string => typeof v === 'string');\n return arr.length > 0 ? arr : undefined;\n}\n\nfunction parseRelations(raw: unknown, filePath: string): Relation[] {\n if (raw === undefined) return [];\n if (!Array.isArray(raw)) {\n throw new Error(`node.yaml at ${filePath}: 'relations' must be an array`);\n }\n\n const result: Relation[] = [];\n for (let index = 0; index < raw.length; index++) {\n const r = raw[index];\n if (typeof r !== 'object' || r === null) {\n throw new Error(`node.yaml at ${filePath}: relations[${index}] must be an object`);\n }\n const obj = r as Record<string, unknown>;\n const target = obj.target;\n const type = obj.type;\n\n if (typeof target !== 'string' || target.trim() === '') {\n throw new Error(\n `node.yaml at ${filePath}: relations[${index}].target must be a non-empty string`,\n );\n }\n if (!isValidRelationType(type)) {\n throw new Error(`node.yaml at ${filePath}: relations[${index}].type is invalid`);\n }\n\n const rel: Relation = {\n target: target.trim(),\n type: type as RelationType,\n };\n if (Array.isArray(obj.consumes)) {\n rel.consumes = (obj.consumes as unknown[]).filter((c): c is string => typeof c === 'string');\n }\n if (typeof obj.failure === 'string') {\n rel.failure = obj.failure;\n }\n if (typeof obj.event_name === 'string' && obj.event_name.trim()) {\n rel.event_name = obj.event_name.trim();\n }\n result.push(rel);\n }\n return result;\n}\n\nfunction validateRelativePath(pathValue: string, filePath: string, fieldName: string): string {\n const normalized = pathValue.trim();\n if (normalized === '') {\n throw new Error(`node.yaml at ${filePath}: '${fieldName}' must be non-empty`);\n }\n if (normalized.startsWith('/')) {\n throw new Error(`node.yaml at ${filePath}: '${fieldName}' must be relative to repository root`);\n }\n return normalized;\n}\n\nfunction parseMapping(rawMapping: unknown, filePath: string): NodeMapping | undefined {\n if (!rawMapping || typeof rawMapping !== 'object') return undefined;\n\n const obj = rawMapping as Record<string, unknown>;\n\n // Unified format: mapping.paths — list of files and/or directories (type auto-detected at runtime)\n if (Array.isArray(obj.paths) && obj.paths.length > 0) {\n const paths = (obj.paths as unknown[])\n .filter((p): p is string => typeof p === 'string')\n .map((p) => validateRelativePath(p, filePath, 'mapping.paths[]'));\n if (paths.length === 0) {\n throw new Error(`node.yaml at ${filePath}: mapping.paths must be a non-empty array`);\n }\n return { paths };\n }\n\n if (obj.paths !== undefined || obj.type !== undefined || obj.path !== undefined) {\n throw new Error(\n `node.yaml at ${filePath}: mapping must have paths (array of file/directory paths)`,\n );\n }\n\n return undefined;\n}\n","import { readFile } from 'node:fs/promises';\nimport { parse as parseYaml } from 'yaml';\nimport type { AspectDef } from '../model/types.js';\nimport { readArtifacts } from './artifact-reader.js';\n\nexport async function parseAspect(\n aspectDir: string,\n aspectYamlPath: string,\n id: string,\n): Promise<AspectDef> {\n const idTrimmed = id?.trim() ?? '';\n if (!idTrimmed) {\n throw new Error(`Aspect id must be non-empty (relative path in aspects/)`);\n }\n const content = await readFile(aspectYamlPath, 'utf-8');\n const raw = parseYaml(content) as Record<string, unknown>;\n\n if (!raw || typeof raw !== 'object') {\n throw new Error(`Aspect file ${aspectYamlPath}: file is empty or not a valid YAML mapping`);\n }\n\n if (!raw.name || typeof raw.name !== 'string' || raw.name.trim() === '') {\n throw new Error(`Aspect file ${aspectYamlPath}: missing or empty 'name'`);\n }\n\n const description = typeof raw.description === 'string' ? raw.description.trim() : undefined;\n\n const artifacts = await readArtifacts(aspectDir, ['aspect.yaml']);\n\n let implies: string[] | undefined;\n if (raw.implies !== undefined) {\n if (!Array.isArray(raw.implies)) {\n throw new Error(`Aspect file ${aspectYamlPath}: 'implies' must be an array of strings`);\n }\n implies = (raw.implies as unknown[]).filter((t): t is string => typeof t === 'string');\n }\n\n return {\n name: (raw.name as string).trim(),\n id: idTrimmed,\n description,\n implies,\n artifacts,\n };\n}\n","import { readFile, readdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Artifact } from '../model/types.js';\n\nexport async function readArtifacts(\n dirPath: string,\n excludeFiles: string[] = ['node.yaml'],\n includeFiles?: string[],\n): Promise<Artifact[]> {\n const entries = await readdir(dirPath, { withFileTypes: true });\n const artifacts: Artifact[] = [];\n const includeSet = includeFiles && includeFiles.length > 0 ? new Set(includeFiles) : null;\n\n for (const entry of entries) {\n if (!entry.isFile()) continue;\n if (excludeFiles.includes(entry.name)) continue;\n if (includeSet && !includeSet.has(entry.name)) continue;\n\n const filePath = path.join(dirPath, entry.name);\n const content = await readFile(filePath, 'utf-8');\n artifacts.push({ filename: entry.name, content });\n }\n\n // Sort by filename for deterministic output\n artifacts.sort((a, b) => a.filename.localeCompare(b.filename));\n return artifacts;\n}\n","import { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { parse as parseYaml } from 'yaml';\nimport type { FlowDef } from '../model/types.js';\nimport { readArtifacts } from './artifact-reader.js';\n\nexport async function parseFlow(flowDir: string, flowYamlPath: string): Promise<FlowDef> {\n const content = await readFile(flowYamlPath, 'utf-8');\n const raw = parseYaml(content) as Record<string, unknown>;\n\n if (!raw || typeof raw !== 'object') {\n throw new Error(`flow.yaml at ${flowYamlPath}: file is empty or not a valid YAML mapping`);\n }\n\n if (!raw.name || typeof raw.name !== 'string' || raw.name.trim() === '') {\n throw new Error(`flow.yaml at ${flowYamlPath}: missing or empty 'name'`);\n }\n\n const nodes = raw.nodes;\n if (!Array.isArray(nodes) || nodes.length === 0) {\n throw new Error(`flow.yaml at ${flowYamlPath}: 'nodes' must be a non-empty array`);\n }\n\n const nodePaths = (nodes as unknown[]).filter((n): n is string => typeof n === 'string');\n if (nodePaths.length === 0) {\n throw new Error(`flow.yaml at ${flowYamlPath}: 'nodes' must contain string node paths`);\n }\n\n let aspects: string[] | undefined;\n if (raw.aspects !== undefined) {\n if (!Array.isArray(raw.aspects)) {\n throw new Error(`flow.yaml at ${flowYamlPath}: 'aspects' must be an array of strings`);\n }\n const aspectTags = (raw.aspects as unknown[]).filter((a): a is string => typeof a === 'string');\n aspects = aspectTags.length > 0 ? aspectTags : [];\n }\n\n const artifacts = await readArtifacts(flowDir, ['flow.yaml']);\n\n return {\n path: path.basename(flowDir),\n name: (raw.name as string).trim(),\n nodes: nodePaths,\n ...(aspects !== undefined && { aspects }),\n artifacts,\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { parse as parseYaml } from 'yaml';\nimport type { SchemaDef } from '../model/types.js';\n\nexport async function parseSchema(filePath: string): Promise<SchemaDef> {\n const content = await readFile(filePath, 'utf-8');\n parseYaml(content); // validate YAML is parseable\n const schemaType = path.basename(filePath, path.extname(filePath));\n return { schemaType };\n}\n","import path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { stat } from 'node:fs/promises';\n\n/**\n * Directory containing the CLI package (dist/ when bundled).\n * Uses import.meta.url so it works when installed globally.\n */\nexport function getPackageRoot(): string {\n return path.dirname(fileURLToPath(import.meta.url));\n}\n\n/**\n * Find the .yggdrasil/ directory starting from projectRoot.\n * Searches upward through parent directories until found or filesystem root.\n * Returns the absolute path to the .yggdrasil/ directory.\n */\nexport async function findYggRoot(projectRoot: string): Promise<string> {\n let current = path.resolve(projectRoot);\n const root = path.parse(current).root;\n\n while (true) {\n const yggPath = path.join(current, '.yggdrasil');\n try {\n const st = await stat(yggPath);\n if (!st.isDirectory()) {\n throw new Error(\n `.yggdrasil exists but is not a directory (${yggPath}). Run 'yg init' in a clean location.`,\n );\n }\n return yggPath;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n if (current === root) {\n throw new Error(`No .yggdrasil/ directory found. Run 'yg init' first.`, { cause: err });\n }\n current = path.dirname(current);\n continue;\n }\n throw err;\n }\n }\n}\n\nimport type { NodeMapping } from '../model/types.js';\n\n/**\n * Normalize a mapping to always return an array of paths (relative to project root).\n * Each path can be a file or directory — type is detected at runtime by hash/owner.\n */\nexport function normalizeMappingPaths(mapping: NodeMapping | undefined): string[] {\n if (!mapping?.paths?.length) return [];\n return mapping.paths.map((p) => p.trim()).filter(Boolean);\n}\n\n/**\n * Convert a node's directory path to its graph path.\n * E.g., \"/abs/path/.yggdrasil/orders/order-service\" → \"orders/order-service\"\n */\nexport function toGraphPath(absolutePath: string, yggRoot: string): string {\n return path.relative(yggRoot, absolutePath).split(path.sep).join('/');\n}\n\n/**\n * Normalize a user-provided path to project-relative POSIX form.\n * Throws when the target path points outside the project root.\n */\nexport function normalizeProjectRelativePath(projectRoot: string, rawPath: string): string {\n const normalizedInput = rawPath.trim().replace(/\\\\/g, '/');\n if (normalizedInput.length === 0) {\n throw new Error('Path cannot be empty');\n }\n\n const absolute = path.resolve(projectRoot, normalizedInput);\n const relative = path.relative(projectRoot, absolute);\n const isOutside = relative.startsWith('..') || path.isAbsolute(relative);\n if (isOutside) {\n throw new Error(`Path is outside project root: ${rawPath}`);\n }\n\n return relative.split(path.sep).join('/');\n}\n\n/**\n * Normalize a --node path argument: strip leading ./ and trailing /.\n */\nexport function normalizeNodePath(rawPath: string): string {\n return rawPath.trim().replace(/^\\.\\//, '').replace(/\\/+$/, '');\n}\n\n/**\n * Derive the actual project root (repo root) from the graph's .yggdrasil/ path.\n */\nexport function projectRootFromGraph(yggRootPath: string): string {\n return path.dirname(yggRootPath);\n}\n","import { readFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport type {\n Graph,\n GraphNode,\n ContextPackage,\n ContextLayer,\n ContextSection,\n YggConfig,\n AspectDef,\n FlowDef,\n Relation,\n} from '../model/types.js';\nimport { normalizeMappingPaths } from '../utils/paths.js';\nimport { estimateTokens } from '../utils/tokens.js';\n\nconst STRUCTURAL_RELATION_TYPES = new Set(['uses', 'calls', 'extends', 'implements']);\nconst EVENT_RELATION_TYPES = new Set(['emits', 'listens']);\n\nexport async function buildContext(graph: Graph, nodePath: string): Promise<ContextPackage> {\n const node = graph.nodes.get(nodePath);\n if (!node) {\n throw new Error(`Node not found: ${nodePath}`);\n }\n\n const layers: ContextLayer[] = [];\n\n // 1. Global\n layers.push(buildGlobalLayer(graph.config));\n\n // 2. Hierarchy (only configured artifacts that exist in ancestor's directory)\n const ancestors = collectAncestors(node);\n for (const ancestor of ancestors) {\n layers.push(buildHierarchyLayer(ancestor, graph.config, graph));\n }\n\n // 3. Own (node.yaml + configured artifacts)\n layers.push(await buildOwnLayer(node, graph.config, graph.rootPath, graph));\n\n // 4. Relational (structural + event, with consumes/failure)\n // Skip relations targeting ancestors — their context is already in hierarchy layers.\n const ancestorPaths = new Set(ancestors.map((a) => a.path));\n for (const relation of node.meta.relations ?? []) {\n const target = graph.nodes.get(relation.target);\n if (!target) {\n throw new Error(`Broken relation: ${nodePath} -> ${relation.target} (target not found)`);\n }\n if (ancestorPaths.has(relation.target)) continue;\n if (STRUCTURAL_RELATION_TYPES.has(relation.type)) {\n layers.push(buildStructuralRelationLayer(target, relation, graph.config));\n } else if (EVENT_RELATION_TYPES.has(relation.type)) {\n layers.push(buildEventRelationLayer(target, relation));\n }\n }\n\n // 5. Flows (node + all ancestors) — built before aspects so we can collect flow aspect ids\n for (const flow of collectParticipatingFlows(graph, node)) {\n layers.push(buildFlowLayer(flow, graph));\n }\n\n // 6. Aspects: union of aspect ids from hierarchy + own + flow layers\n const allAspectIds = new Set<string>();\n for (const l of layers) {\n const aspects = l.attrs?.aspects;\n if (aspects) {\n for (const id of aspects.split(',').map((t) => t.trim()).filter(Boolean)) {\n allAspectIds.add(id);\n }\n }\n }\n const aspectsToInclude = resolveAspects(allAspectIds, graph.aspects);\n for (const aspect of aspectsToInclude) {\n layers.push(buildAspectLayer(aspect));\n }\n\n const fullText = layers.map((l) => l.content).join('\\n\\n');\n const tokenCount = estimateTokens(fullText);\n const mapping = normalizeMappingPaths(node.meta.mapping);\n const sections = buildSections(layers, mapping.length > 0 ? mapping : null);\n\n return {\n nodePath,\n nodeName: node.meta.name,\n layers,\n sections,\n mapping: mapping.length > 0 ? mapping : null,\n tokenCount,\n };\n}\n\nfunction collectParticipatingFlows(graph: Graph, node: GraphNode): FlowDef[] {\n const paths = new Set<string>([node.path, ...collectAncestors(node).map((a) => a.path)]);\n return graph.flows.filter((f) => f.nodes.some((n) => paths.has(n)));\n}\n\n/** Expand aspect ids to include implied ids recursively. Returns unique list. */\nexport function expandAspects(aspectIds: string[], aspects: AspectDef[]): string[] {\n const idToAspect = new Map<string, AspectDef>();\n for (const a of aspects) {\n idToAspect.set(a.id, a);\n }\n const result: string[] = [];\n const visited = new Set<string>();\n const stack = new Set<string>();\n\n function collect(id: string): void {\n if (stack.has(id)) {\n throw new Error(`Aspect implies cycle detected involving aspect '${id}'`);\n }\n if (visited.has(id)) return;\n stack.add(id);\n visited.add(id);\n result.push(id);\n const aspect = idToAspect.get(id);\n if (aspect) {\n for (const implied of aspect.implies ?? []) {\n collect(implied);\n }\n }\n stack.delete(id);\n }\n\n for (const id of aspectIds) {\n collect(id);\n }\n return result;\n}\n\n/** Expand aspect ids to AspectDefs including implied (recursive, with cycle detection). */\nexport function resolveAspects(\n aspectIds: Iterable<string>,\n aspects: AspectDef[],\n): AspectDef[] {\n const idToAspect = new Map<string, AspectDef>();\n for (const a of aspects) {\n idToAspect.set(a.id, a);\n }\n const expandedIds = expandAspects([...aspectIds], aspects);\n return expandedIds\n .map((id) => idToAspect.get(id))\n .filter((a): a is AspectDef => a !== undefined);\n}\n\n// --- backward-compat aliases (used by tests / external callers) ---\nexport const expandTags = expandAspects;\nexport const expandAspectsForTags = resolveAspects;\n\n// --- Layer builders (exported for testing) ---\n\nexport function buildGlobalLayer(config: YggConfig): ContextLayer {\n let content = `**Project:** ${config.name}\\n\\n`;\n content += `**Stack:**\\n`;\n for (const [key, value] of Object.entries(config.stack)) {\n content += `- ${key}: ${value}\\n`;\n }\n content += `\\n**Standards:**\\n${config.standards || '(none)'}\\n`;\n return { type: 'global', label: 'Global Context', content };\n}\n\nfunction filterArtifactsByConfig(\n artifacts: Array<{ filename: string; content: string }>,\n config: YggConfig,\n): Array<{ filename: string; content: string }> {\n const allowed = new Set(Object.keys(config.artifacts ?? {}));\n return artifacts.filter((a) => allowed.has(a.filename));\n}\n\nexport function buildHierarchyLayer(\n ancestor: GraphNode,\n config: YggConfig,\n graph: Graph,\n): ContextLayer {\n const filtered = filterArtifactsByConfig(ancestor.artifacts, config);\n const content = filtered.map((a) => `### ${a.filename}\\n${a.content}`).join('\\n\\n');\n const nodeAspects = ancestor.meta.aspects ?? [];\n const expanded = expandAspects(nodeAspects, graph.aspects);\n const attrs: Record<string, string> | undefined =\n expanded.length > 0 ? { aspects: expanded.join(',') } : undefined;\n return {\n type: 'hierarchy',\n label: `Module Context (${ancestor.path}/)`,\n content,\n attrs,\n };\n}\n\nexport async function buildOwnLayer(\n node: GraphNode,\n config: YggConfig,\n graphRootPath: string,\n graph: Graph,\n): Promise<ContextLayer> {\n const parts: string[] = [];\n\n if (node.nodeYamlRaw) {\n parts.push(`### node.yaml\\n${node.nodeYamlRaw.trim()}`);\n } else {\n const nodeYamlPath = path.join(graphRootPath, 'model', node.path, 'node.yaml');\n try {\n const nodeYamlContent = await readFile(nodeYamlPath, 'utf-8');\n parts.push(`### node.yaml\\n${nodeYamlContent.trim()}`);\n } catch {\n parts.push(`### node.yaml\\n(not found)`);\n }\n }\n\n const filtered = filterArtifactsByConfig(node.artifacts, config);\n for (const a of filtered) {\n parts.push(`### ${a.filename}\\n${a.content}`);\n }\n\n const content = parts.join('\\n\\n');\n const nodeAspects = node.meta.aspects ?? [];\n const expanded = expandAspects(nodeAspects, graph.aspects);\n const attrs: Record<string, string> | undefined =\n expanded.length > 0 ? { aspects: expanded.join(',') } : undefined;\n return {\n type: 'own',\n label: `Node: ${node.meta.name}`,\n content,\n attrs,\n };\n}\n\nexport function buildStructuralRelationLayer(\n target: GraphNode,\n relation: Relation,\n config: YggConfig,\n): ContextLayer {\n let content = '';\n if (relation.consumes?.length) {\n content += `Consumes: ${relation.consumes.join(', ')}\\n\\n`;\n }\n if (relation.failure) {\n content += `On failure: ${relation.failure}\\n\\n`;\n }\n\n const structuralArtifactFilenames = Object.entries(config.artifacts ?? {})\n .filter(([, c]) => c.structural_context)\n .map(([filename]) => filename);\n\n const structuralArts = structuralArtifactFilenames\n .map((filename) => {\n const art = target.artifacts.find((a) => a.filename === filename);\n return art ? { filename: art.filename, content: art.content } : null;\n })\n .filter((a): a is { filename: string; content: string } => a !== null);\n\n if (structuralArts.length > 0) {\n content += structuralArts.map((a) => `### ${a.filename}\\n${a.content}`).join('\\n\\n');\n } else {\n const filtered = filterArtifactsByConfig(target.artifacts, config);\n content += filtered.map((a) => `### ${a.filename}\\n${a.content}`).join('\\n\\n');\n }\n\n const attrs: Record<string, string> = {\n target: target.path,\n type: relation.type,\n };\n if (relation.consumes?.length) attrs.consumes = relation.consumes.join(', ');\n if (relation.failure) attrs.failure = relation.failure;\n\n return {\n type: 'relational',\n label: `Dependency: ${target.meta.name} (${relation.type}) — ${target.path}`,\n content: content.trim(),\n attrs,\n };\n}\n\nexport function buildEventRelationLayer(target: GraphNode, relation: Relation): ContextLayer {\n const eventName = relation.event_name ?? target.meta.name;\n const isEmit = relation.type === 'emits';\n let content = isEmit\n ? `Target: ${target.path}\\nYou publish ${eventName}.`\n : `Source: ${target.path}\\nYou listen for ${eventName}.`;\n if (relation.consumes?.length) {\n content += `\\nConsumes: ${relation.consumes.join(', ')}`;\n }\n const attrs: Record<string, string> = {\n target: target.path,\n type: relation.type,\n 'event-name': eventName,\n };\n if (relation.consumes?.length) attrs.consumes = relation.consumes.join(', ');\n\n return {\n type: 'relational',\n label: `Event: ${eventName} [${relation.type}]`,\n content,\n attrs,\n };\n}\n\nexport function buildAspectLayer(aspect: AspectDef): ContextLayer {\n const content = aspect.artifacts.map((a) => `### ${a.filename}\\n${a.content}`).join('\\n\\n');\n return {\n type: 'aspects',\n label: `${aspect.name} (aspect: ${aspect.id})`,\n content,\n };\n}\n\nfunction buildFlowLayer(flow: FlowDef, graph: Graph): ContextLayer {\n const content = flow.artifacts.map((a) => `### ${a.filename}\\n${a.content}`).join('\\n\\n');\n const flowAspects = flow.aspects ?? [];\n const expanded = expandAspects(flowAspects, graph.aspects);\n const attrs: Record<string, string> | undefined =\n expanded.length > 0 ? { aspects: expanded.join(',') } : undefined;\n return {\n type: 'flows',\n label: `Flow: ${flow.name}`,\n content: content || '(no artifacts)',\n attrs,\n };\n}\n\nfunction buildSections(layers: ContextLayer[], mapping: string[] | null): ContextSection[] {\n const ownLayers = layers.filter((layer) => layer.type === 'own');\n if (mapping && mapping.length > 0) {\n ownLayers.push({\n type: 'own',\n label: 'Materialization Target',\n content: mapping.join(', '),\n });\n }\n\n return [\n { key: 'Global', layers: layers.filter((l) => l.type === 'global') },\n { key: 'Hierarchy', layers: layers.filter((l) => l.type === 'hierarchy') },\n { key: 'OwnArtifacts', layers: ownLayers },\n { key: 'Aspects', layers: layers.filter((l) => l.type === 'aspects') },\n {\n key: 'Relational',\n layers: [\n ...layers.filter((l) => l.type === 'relational'),\n ...layers.filter((l) => l.type === 'flows'),\n ],\n },\n ];\n}\n\n// --- Helpers (exported for testing) ---\n\nexport function collectAncestors(node: GraphNode): GraphNode[] {\n const ancestors: GraphNode[] = [];\n let current = node.parent;\n while (current) {\n ancestors.unshift(current);\n current = current.parent;\n }\n return ancestors;\n}\n\n/** Compute effective aspect ids for a node: own + hierarchy + flow + implies expanded. */\nexport function collectEffectiveAspectIds(graph: Graph, nodePath: string): Set<string> {\n const node = graph.nodes.get(nodePath);\n if (!node) return new Set();\n\n const raw = new Set<string>(node.meta.aspects ?? []);\n\n // Hierarchy aspects\n let ancestor = node.parent;\n while (ancestor) {\n for (const id of ancestor.meta.aspects ?? []) raw.add(id);\n ancestor = ancestor.parent;\n }\n\n // Flow aspects (flows where node or ancestor participates)\n const ancestorPaths = new Set([nodePath, ...collectAncestors(node).map((a) => a.path)]);\n for (const flow of graph.flows) {\n if (flow.nodes.some((n) => ancestorPaths.has(n))) {\n for (const id of flow.aspects ?? []) raw.add(id);\n }\n }\n\n // Expand implies\n return new Set(expandAspects([...raw], graph.aspects));\n}\n","/**\n * Estimate token count for a string.\n * Heuristic: ~4 characters per token (no tokenizer dependency).\n */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n","import { readdir } from 'node:fs/promises';\nimport path from 'node:path';\nimport type { Graph, ValidationResult, ValidationIssue, ArtifactConfig } from '../model/types.js';\nimport { buildContext, resolveAspects } from './context-builder.js';\nimport { normalizeMappingPaths } from '../utils/paths.js';\n\n/** Reserved directories that are NOT nodes (within model/) */\nconst RESERVED_DIRS = new Set<string>();\n\nexport async function validate(graph: Graph, scope: string = 'all'): Promise<ValidationResult> {\n const issues: ValidationIssue[] = [];\n\n if (graph.configError) {\n issues.push({\n severity: 'error',\n code: 'E012',\n rule: 'invalid-config',\n message: graph.configError,\n });\n }\n\n for (const { nodePath, message } of graph.nodeParseErrors ?? []) {\n issues.push({\n severity: 'error',\n code: 'E001',\n rule: 'invalid-node-yaml',\n message,\n nodePath,\n });\n }\n\n if (!graph.configError) {\n issues.push(...checkNodeTypes(graph));\n issues.push(...checkAspectsDefined(graph));\n issues.push(...checkAspectIds(graph));\n issues.push(...checkAspectIdUniqueness(graph));\n issues.push(...checkImpliedAspectsExist(graph));\n issues.push(...checkImpliesNoCycles(graph));\n issues.push(...checkRequiredAspectsCoverage(graph));\n issues.push(...checkRequiredArtifacts(graph));\n issues.push(...checkInvalidArtifactConditions(graph));\n issues.push(...(await checkContextBudget(graph)));\n issues.push(...checkHighFanOut(graph));\n }\n\n issues.push(...checkSchemas(graph));\n issues.push(...checkRelationTargets(graph));\n issues.push(...checkNoCycles(graph));\n issues.push(...checkMappingOverlap(graph));\n issues.push(...(await checkMappingPathsExist(graph)));\n issues.push(...checkBrokenFlowRefs(graph));\n issues.push(...checkFlowAspectIds(graph));\n issues.push(...(await checkDirectoriesHaveNodeYaml(graph)));\n issues.push(...(await checkShallowArtifacts(graph)));\n issues.push(...checkUnpairedEvents(graph));\n\n let filtered = issues;\n let nodesScanned = graph.nodes.size;\n if (scope !== 'all' && scope.trim()) {\n if (!graph.nodes.has(scope)) {\n // Check if the node exists but has a parse error\n const parseError = (graph.nodeParseErrors ?? []).find(\n (e) => e.nodePath === scope || scope.startsWith(e.nodePath + '/'),\n );\n if (parseError) {\n return {\n issues: [{\n severity: 'error',\n code: 'E001',\n rule: 'invalid-node-yaml',\n message: parseError.message,\n nodePath: parseError.nodePath,\n }],\n nodesScanned: 0,\n };\n }\n return {\n issues: [{ severity: 'error', rule: 'invalid-scope', message: `Node not found: ${scope}` }],\n nodesScanned: 0,\n };\n }\n const scopePrefix = scope + '/';\n filtered = issues.filter((i) => !i.nodePath || i.nodePath === scope || i.nodePath.startsWith(scopePrefix));\n nodesScanned = [...graph.nodes.keys()].filter((p) => p === scope || p.startsWith(scopePrefix)).length;\n }\n\n return { issues: filtered, nodesScanned };\n}\n\n// --- Rule 0: Node types from config ---\n\nfunction checkNodeTypes(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const allowedTypes = new Set((graph.config.node_types ?? []).map((t) => t.name));\n for (const [nodePath, node] of graph.nodes) {\n if (!allowedTypes.has(node.meta.type)) {\n issues.push({\n severity: 'error',\n code: 'E002',\n rule: 'unknown-node-type',\n message: `Node type '${node.meta.type}' not in config.node_types (${[...allowedTypes].join(', ')})`,\n nodePath,\n });\n }\n }\n return issues;\n}\n\n// --- Rule 1: Relation targets exist ---\n\nfunction findSimilar(target: string, candidates: string[]): string | null {\n if (candidates.length === 0) return null;\n\n let best: string | null = null;\n let bestScore = -1;\n\n for (const c of candidates) {\n if (c === target) return c;\n // Simple similarity: shared path segments\n const targetParts = target.split('/');\n const candParts = c.split('/');\n let score = 0;\n for (let i = 0; i < Math.min(targetParts.length, candParts.length); i++) {\n if (targetParts[i] === candParts[i]) score++;\n else break;\n }\n if (score > bestScore && score > 0) {\n bestScore = score;\n best = c;\n }\n }\n return best;\n}\n\nfunction checkRelationTargets(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const nodePaths = [...graph.nodes.keys()];\n for (const [nodePath, node] of graph.nodes) {\n for (const rel of node.meta.relations ?? []) {\n if (!graph.nodes.has(rel.target)) {\n const suggestion = findSimilar(rel.target, nodePaths);\n const parts = rel.target.split('/');\n const parentPrefix = parts.length > 1 ? parts.slice(0, -1).join('/') + '/' : '';\n const existingInParent = nodePaths\n .filter((p) => p.startsWith(parentPrefix) && p !== rel.target)\n .map((p) => {\n const rest = p.slice(parentPrefix.length);\n return rest.split('/')[0];\n })\n .filter((v, i, a) => a.indexOf(v) === i)\n .sort();\n const existingLine =\n existingInParent.length > 0\n ? `\\n Existing nodes in ${parentPrefix || 'model/'}: ${existingInParent.join(', ')}`\n : '';\n const hint = suggestion ? `\\n Did you mean '${suggestion}'?` : '';\n issues.push({\n severity: 'error',\n code: 'E004',\n rule: 'broken-relation',\n message: `Relation target '${rel.target}' does not exist${existingLine}${hint}`,\n nodePath,\n });\n }\n }\n }\n return issues;\n}\n\n// --- Rule 2: Node aspects must reference a defined aspect ---\n\nfunction checkAspectsDefined(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const validAspectIds = new Set(graph.aspects.map((a) => a.id));\n for (const [nodePath, node] of graph.nodes) {\n for (const aspectId of node.meta.aspects ?? []) {\n if (!validAspectIds.has(aspectId)) {\n issues.push({\n severity: 'error',\n code: 'E003',\n rule: 'unknown-aspect',\n message: `Aspect '${aspectId}' has no corresponding directory in aspects/`,\n nodePath,\n });\n }\n }\n }\n return issues;\n}\n\n// --- Rule 3: Aspect ids (derived from directory path) — always valid when aspect exists ---\n\nfunction checkAspectIds(_graph: Graph): ValidationIssue[] {\n // validAspectIds = graph.aspects.map(a => a.id), so every aspect's id is valid by definition\n return [];\n}\n\nfunction checkAspectIdUniqueness(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const byId = new Map<string, string[]>();\n for (const aspect of graph.aspects) {\n const names = byId.get(aspect.id) ?? [];\n names.push(aspect.name);\n byId.set(aspect.id, names);\n }\n for (const [id, names] of byId) {\n if (names.length <= 1) continue;\n issues.push({\n severity: 'error',\n code: 'E014',\n rule: 'duplicate-aspect-binding',\n message: `Aspect '${id}' is bound to multiple aspects (${names.join(', ')})`,\n });\n }\n return issues;\n}\n\n// --- Rule: Implied aspects exist ---\n\nfunction checkImpliedAspectsExist(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const idToAspect = new Map<string, { name: string }>();\n for (const a of graph.aspects) {\n idToAspect.set(a.id, { name: a.name });\n }\n for (const aspect of graph.aspects) {\n for (const impliedId of aspect.implies ?? []) {\n if (!idToAspect.has(impliedId)) {\n issues.push({\n severity: 'error',\n code: 'E016',\n rule: 'implied-aspect-missing',\n message: `Aspect '${aspect.name}' implies '${impliedId}' but no aspect with that id exists in aspects/`,\n });\n }\n }\n }\n return issues;\n}\n\n// --- Rule: No cycles in aspect implies graph ---\n\nfunction checkImpliesNoCycles(graph: Graph): ValidationIssue[] {\n const idToAspect = new Map<string, { implies?: string[] }>();\n for (const a of graph.aspects) {\n idToAspect.set(a.id, { implies: a.implies });\n }\n const WHITE = 0;\n const GRAY = 1;\n const BLACK = 2;\n const color = new Map<string, number>();\n for (const id of idToAspect.keys()) color.set(id, WHITE);\n\n const issues: ValidationIssue[] = [];\n\n function dfs(id: string, pathArr: string[]): boolean {\n color.set(id, GRAY);\n pathArr.push(id);\n const aspect = idToAspect.get(id);\n for (const implied of aspect?.implies ?? []) {\n if (color.get(implied) === GRAY) {\n const cycle = pathArr.slice(pathArr.indexOf(implied)).concat(implied);\n issues.push({\n severity: 'error',\n code: 'E017',\n rule: 'aspect-implies-cycle',\n message: `Aspect implies cycle: ${cycle.join(' → ')}`,\n });\n pathArr.pop();\n color.set(id, BLACK);\n return true;\n }\n if (color.get(implied) === WHITE && dfs(implied, pathArr)) {\n pathArr.pop();\n color.set(id, BLACK);\n return true;\n }\n }\n pathArr.pop();\n color.set(id, BLACK);\n return false;\n }\n\n for (const id of idToAspect.keys()) {\n if (color.get(id) === WHITE) {\n dfs(id, []);\n }\n }\n return issues;\n}\n\n// --- Rule: Required aspects coverage per node type ---\n\nfunction checkRequiredAspectsCoverage(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const typeConfig = new Map(\n (graph.config.node_types ?? []).map((t) => [t.name, t.required_aspects ?? []]),\n );\n for (const [nodePath, node] of graph.nodes) {\n if (node.meta.blackbox) continue;\n const requiredAspects = typeConfig.get(node.meta.type);\n if (!requiredAspects || requiredAspects.length === 0) continue;\n\n const nodeAspects = node.meta.aspects ?? [];\n let effectiveAspects;\n try {\n effectiveAspects = resolveAspects(nodeAspects, graph.aspects);\n } catch {\n continue;\n }\n const effectiveAspectIds = new Set(effectiveAspects.map((a) => a.id));\n\n for (const required of requiredAspects) {\n if (!effectiveAspectIds.has(required)) {\n issues.push({\n severity: 'warning',\n code: 'W011',\n rule: 'missing-required-aspect-coverage',\n message: `Node '${nodePath}' (type: ${node.meta.type}) missing required aspect coverage for '${required}'`,\n nodePath,\n });\n }\n }\n }\n return issues;\n}\n\n// --- Rule 4: No circular dependencies (cycles involving blackbox are tolerated) ---\n\nfunction checkNoCycles(graph: Graph): ValidationIssue[] {\n const WHITE = 0;\n const GRAY = 1;\n const BLACK = 2;\n const color = new Map<string, number>();\n for (const p of graph.nodes.keys()) color.set(p, WHITE);\n\n const issues: ValidationIssue[] = [];\n\n function dfs(nodePath: string, pathSegments: string[]): boolean {\n color.set(nodePath, GRAY);\n const node = graph.nodes.get(nodePath)!;\n const structuralTypes = new Set(['uses', 'calls', 'extends', 'implements']);\n for (const rel of node.meta.relations ?? []) {\n const targetNode = graph.nodes.get(rel.target);\n if (!targetNode) continue;\n if (!structuralTypes.has(rel.type)) continue;\n if (color.get(rel.target) === GRAY) {\n const cyclePath = [...pathSegments, nodePath, rel.target];\n const cycleNodes = pathSegments.slice(pathSegments.indexOf(rel.target)).concat(nodePath);\n const hasBlackboxInCycle = cycleNodes.some(\n (p) => graph.nodes.get(p)?.meta.blackbox === true,\n );\n if (!hasBlackboxInCycle) {\n issues.push({\n severity: 'error',\n code: 'E010',\n rule: 'structural-cycle',\n message: `Circular dependency: ${cyclePath.join(' -> ')}`,\n });\n }\n return true;\n }\n if (color.get(rel.target) === WHITE) {\n if (dfs(rel.target, [...pathSegments, nodePath])) return true;\n }\n }\n color.set(nodePath, BLACK);\n return false;\n }\n\n for (const nodePath of graph.nodes.keys()) {\n if (color.get(nodePath) === WHITE) {\n dfs(nodePath, []);\n }\n }\n\n return issues;\n}\n\n// --- Rule 5: Mapping ownership overlap ---\n\nfunction normalizePathForCompare(mappingPath: string): string {\n return mappingPath.replace(/\\\\/g, '/').replace(/\\/+$/, '');\n}\n\nfunction arePathsOverlapping(pathA: string, pathB: string): boolean {\n if (pathA === pathB) return true;\n return pathA.startsWith(pathB + '/') || pathB.startsWith(pathA + '/');\n}\n\nfunction isAncestorNode(possibleAncestor: string, possibleDescendant: string): boolean {\n return possibleDescendant.startsWith(possibleAncestor + '/');\n}\n\nfunction checkMappingOverlap(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const ownership: Array<{ nodePath: string; mappingPath: string }> = [];\n\n for (const [nodePath, node] of graph.nodes) {\n const mappingPaths = normalizeMappingPaths(node.meta.mapping)\n .map(normalizePathForCompare)\n .filter((mappingPath) => mappingPath.length > 0);\n for (const mappingPath of mappingPaths) {\n ownership.push({ nodePath, mappingPath });\n }\n }\n\n for (let index = 0; index < ownership.length; index++) {\n const current = ownership[index];\n for (let nestedIndex = index + 1; nestedIndex < ownership.length; nestedIndex++) {\n const candidate = ownership[nestedIndex];\n if (current.nodePath === candidate.nodePath) continue;\n if (!arePathsOverlapping(current.mappingPath, candidate.mappingPath)) continue;\n\n // Allow containment overlaps between ancestor-descendant nodes (\"child wins\" model).\n // Exact duplicates (same path) are always errors regardless of hierarchy.\n const isContainment = current.mappingPath !== candidate.mappingPath;\n const isHierarchical =\n isAncestorNode(current.nodePath, candidate.nodePath) ||\n isAncestorNode(candidate.nodePath, current.nodePath);\n\n if (isContainment && isHierarchical) continue;\n\n issues.push({\n severity: 'error',\n code: 'E009',\n rule: 'overlapping-mapping',\n message:\n `Mapping paths '${current.mappingPath}' (${current.nodePath}) and ` +\n `'${candidate.mappingPath}' (${candidate.nodePath}) overlap. ` +\n `Keep one owner mapping and model other concerns via relations.`,\n nodePath: candidate.nodePath,\n });\n }\n }\n\n return issues;\n}\n\n// --- Rule: Mapping paths should exist on disk (W012) ---\n\nasync function checkMappingPathsExist(graph: Graph): Promise<ValidationIssue[]> {\n const issues: ValidationIssue[] = [];\n const projectRoot = path.dirname(graph.rootPath);\n const { access } = await import('node:fs/promises');\n\n for (const [nodePath, node] of graph.nodes) {\n const mappingPaths = normalizeMappingPaths(node.meta.mapping);\n for (const mp of mappingPaths) {\n const absPath = path.join(projectRoot, mp);\n try {\n await access(absPath);\n } catch {\n issues.push({\n severity: 'warning',\n code: 'W012',\n rule: 'mapping-path-missing',\n message: `Mapping path '${mp}' does not exist on disk`,\n nodePath,\n });\n }\n }\n }\n return issues;\n}\n\n// --- Rule 6: Required artifacts per config.artifacts (W001) ---\n\nfunction getIncomingRelationSources(graph: Graph, nodePath: string): string[] {\n const sources: string[] = [];\n for (const [srcPath, node] of graph.nodes) {\n for (const rel of node.meta.relations ?? []) {\n if (rel.target === nodePath) sources.push(srcPath);\n }\n }\n return sources;\n}\n\nfunction artifactRequiredReason(\n graph: Graph,\n nodePath: string,\n node: {\n meta: { relations?: Array<{ target: string }>; aspects?: string[]; blackbox?: boolean };\n artifacts: Array<{ filename: string }>;\n },\n required: ArtifactConfig['required'],\n): string | null {\n if (required === 'never') return null;\n if (required === 'always') {\n return node.meta.blackbox ? null : 'required: always';\n }\n const when = (required as { when: string }).when;\n if (when === 'has_incoming_relations') {\n const sources = getIncomingRelationSources(graph, nodePath);\n return sources.length > 0\n ? `${sources.length} incoming relation(s): ${sources.join(', ')}`\n : null;\n }\n if (when === 'has_outgoing_relations') {\n const count = node.meta.relations?.length ?? 0;\n return count > 0 ? `${count} outgoing relation(s)` : null;\n }\n if (when.startsWith('has_aspect:') || when.startsWith('has_tag:')) {\n const prefix = when.startsWith('has_aspect:') ? 'has_aspect:' : 'has_tag:';\n const aspectId = when.slice(prefix.length);\n return (node.meta.aspects ?? []).includes(aspectId) ? `node has aspect '${aspectId}'` : null;\n }\n return null;\n}\n\nfunction getIncomingRelations(graph: Graph, nodePath: string): string[] {\n const incoming: string[] = [];\n for (const [fromPath, node] of graph.nodes) {\n for (const rel of node.meta.relations ?? []) {\n if (rel.target === nodePath) {\n incoming.push(fromPath);\n break;\n }\n }\n }\n return incoming.sort();\n}\n\nfunction checkRequiredArtifacts(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const artifacts = graph.config.artifacts ?? {};\n\n for (const [nodePath, node] of graph.nodes) {\n for (const [filename, config] of Object.entries(artifacts)) {\n const hasArtifact = node.artifacts.some((a) => a.filename === filename);\n const reason = artifactRequiredReason(graph, nodePath, node, config.required);\n\n if (reason && !hasArtifact) {\n const action = config.description ?? '';\n const incoming = getIncomingRelations(graph, nodePath);\n const incomingStr =\n incoming.length > 0\n ? ` Node has ${incoming.length} incoming relation(s): ${incoming.slice(0, 5).join(', ')}${incoming.length > 5 ? '...' : ''}.`\n : '';\n const msg = action\n ? `Missing required artifact '${filename}' (${reason}).${incomingStr} ${action}`\n : `Missing required artifact '${filename}' (${reason}).${incomingStr}`;\n issues.push({\n severity: 'warning',\n code: 'W001',\n rule: 'missing-artifact',\n message: msg.trim(),\n nodePath,\n });\n }\n }\n }\n\n return issues;\n}\n\n// --- E006: Broken flow refs (flow.nodes) ---\n\nfunction checkBrokenFlowRefs(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const nodePaths = new Set(graph.nodes.keys());\n for (const flow of graph.flows) {\n for (const n of flow.nodes) {\n if (!nodePaths.has(n)) {\n issues.push({\n severity: 'error',\n code: 'E006',\n rule: 'broken-flow-ref',\n message: `Flow '${flow.name}' references non-existent node '${n}'`,\n });\n }\n }\n }\n return issues;\n}\n\n// --- E007: Flow aspect ids must have corresponding aspect ---\n\nfunction checkFlowAspectIds(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const validAspectIds = new Set(graph.aspects.map((a) => a.id));\n\n for (const flow of graph.flows) {\n for (const aspectId of flow.aspects ?? []) {\n if (!validAspectIds.has(aspectId)) {\n issues.push({\n severity: 'error',\n code: 'E007',\n rule: 'broken-aspect-ref',\n message: `Flow '${flow.name}' references aspect '${aspectId}' but no aspect with that id exists in aspects/`,\n });\n }\n }\n }\n return issues;\n}\n\n// --- E013: Invalid artifact condition (has_aspect:X where X has no aspect) ---\n\nfunction checkInvalidArtifactConditions(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const validAspectIds = new Set(graph.aspects.map((a) => a.id));\n const artifacts = graph.config.artifacts ?? {};\n for (const [artifactName, config] of Object.entries(artifacts)) {\n const required = config.required;\n if (typeof required === 'object' && required && 'when' in required) {\n const when = (required as { when: string }).when;\n if (when.startsWith('has_aspect:') || when.startsWith('has_tag:')) {\n const prefix = when.startsWith('has_aspect:') ? 'has_aspect:' : 'has_tag:';\n const aspectId = when.slice(prefix.length);\n if (!validAspectIds.has(aspectId)) {\n issues.push({\n severity: 'error',\n code: 'E013',\n rule: 'invalid-artifact-condition',\n message: `Artifact '${artifactName}' condition has_aspect:${aspectId} has no corresponding aspect in aspects/`,\n });\n }\n }\n }\n }\n return issues;\n}\n\n// --- W002: Shallow artifacts (below min_artifact_length) ---\n\nasync function checkShallowArtifacts(graph: Graph): Promise<ValidationIssue[]> {\n const issues: ValidationIssue[] = [];\n const minLen = graph.config.quality?.min_artifact_length ?? 50;\n for (const [nodePath, node] of graph.nodes) {\n for (const art of node.artifacts) {\n if (art.content.trim().length < minLen) {\n issues.push({\n severity: 'warning',\n code: 'W002',\n rule: 'shallow-artifact',\n message: `Artifact '${art.filename}' is below minimum length (${art.content.trim().length} < ${minLen})`,\n nodePath,\n });\n }\n }\n }\n return issues;\n}\n\n// --- W007: High fan-out (exceeds max_direct_relations) ---\n\nfunction checkHighFanOut(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const maxRel = graph.config.quality?.max_direct_relations ?? 10;\n for (const [nodePath, node] of graph.nodes) {\n const count = node.meta.relations?.length ?? 0;\n if (count > maxRel) {\n issues.push({\n severity: 'warning',\n code: 'W007',\n rule: 'high-fan-out',\n message: `Node has ${count} direct relations (max: ${maxRel})`,\n nodePath,\n });\n }\n }\n return issues;\n}\n\n// --- W009: Unpaired event relations (emits without listens or vice versa) ---\n\nfunction checkUnpairedEvents(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const emitsTo = new Map<string, Set<string>>();\n const listensFrom = new Map<string, Set<string>>();\n for (const [nodePath, node] of graph.nodes) {\n for (const rel of node.meta.relations ?? []) {\n if (rel.type === 'emits') {\n const set = emitsTo.get(nodePath) ?? new Set();\n set.add(rel.target);\n emitsTo.set(nodePath, set);\n }\n if (rel.type === 'listens') {\n const set = listensFrom.get(nodePath) ?? new Set();\n set.add(rel.target);\n listensFrom.set(nodePath, set);\n }\n }\n }\n for (const [emitter, targets] of emitsTo) {\n for (const target of targets) {\n const listenerSet = listensFrom.get(target);\n if (!listenerSet?.has(emitter)) {\n issues.push({\n severity: 'warning',\n code: 'W009',\n rule: 'unpaired-event',\n message: `Node '${emitter}' emits to '${target}' but '${target}' has no listens from '${emitter}'`,\n nodePath: emitter,\n });\n }\n }\n }\n for (const [listener, sources] of listensFrom) {\n for (const source of sources) {\n const emitterSet = emitsTo.get(source);\n if (!emitterSet?.has(listener)) {\n issues.push({\n severity: 'warning',\n code: 'W009',\n rule: 'unpaired-event',\n message: `Node '${listener}' listens from '${source}' but '${source}' has no emits to '${listener}'`,\n nodePath: listener,\n });\n }\n }\n }\n return issues;\n}\n\n// --- Schema validation (required graph-layer schemas present in schemas/) ---\n\nconst REQUIRED_SCHEMAS = ['node', 'aspect', 'flow'] as const;\n\nfunction checkSchemas(graph: Graph): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const present = new Set(graph.schemas.map((s) => s.schemaType));\n\n for (const required of REQUIRED_SCHEMAS) {\n if (!present.has(required)) {\n issues.push({\n severity: 'warning',\n code: 'W010',\n rule: 'missing-schema',\n message: `Schema '${required}.yaml' missing from .yggdrasil/schemas/`,\n });\n }\n }\n\n return issues;\n}\n\n// --- Directories have node.yaml ---\n\nasync function checkDirectoriesHaveNodeYaml(graph: Graph): Promise<ValidationIssue[]> {\n const issues: ValidationIssue[] = [];\n const modelDir = path.join(graph.rootPath, 'model');\n\n async function scanDir(dirPath: string, segments: string[]): Promise<void> {\n const entries = await readdir(dirPath, { withFileTypes: true });\n const hasNodeYaml = entries.some((e) => e.isFile() && e.name === 'node.yaml');\n const dirName = path.basename(dirPath);\n\n if (RESERVED_DIRS.has(dirName)) return;\n\n const hasFiles = entries.some((e) => e.isFile());\n const hasSubdirs = entries.some((e) => e.isDirectory() && !RESERVED_DIRS.has(e.name) && !e.name.startsWith('.'));\n const graphPath = segments.join('/');\n\n if (!hasNodeYaml && graphPath !== '') {\n if (hasFiles) {\n issues.push({\n severity: 'error',\n code: 'E015',\n rule: 'missing-node-yaml',\n message: `Directory '${graphPath}' has files but no node.yaml`,\n nodePath: graphPath,\n });\n } else if (hasSubdirs) {\n issues.push({\n severity: 'warning',\n code: 'W013',\n rule: 'directory-without-node',\n message: `Directory '${graphPath}' has subdirectories but no node.yaml — consider creating a node`,\n nodePath: graphPath,\n });\n }\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (RESERVED_DIRS.has(entry.name)) continue;\n if (entry.name.startsWith('.')) continue;\n await scanDir(path.join(dirPath, entry.name), [...segments, entry.name]);\n }\n }\n\n try {\n const rootEntries = await readdir(modelDir, { withFileTypes: true });\n for (const entry of rootEntries) {\n if (!entry.isDirectory()) continue;\n if (entry.name.startsWith('.')) continue;\n await scanDir(path.join(modelDir, entry.name), [entry.name]);\n }\n } catch {\n // model/ may not exist\n }\n\n return issues;\n}\n\n// --- Context budget (W005 warning, W006 error) ---\n\nasync function checkContextBudget(graph: Graph): Promise<ValidationIssue[]> {\n const issues: ValidationIssue[] = [];\n const warningThreshold = graph.config.quality?.context_budget.warning ?? 10000;\n const errorThreshold = graph.config.quality?.context_budget.error ?? 20000;\n\n for (const [nodePath, node] of graph.nodes) {\n if (node.meta.blackbox) continue;\n try {\n const pkg = await buildContext(graph, nodePath);\n if (pkg.tokenCount >= errorThreshold) {\n issues.push({\n severity: 'warning',\n code: 'W006',\n rule: 'budget-error',\n message: `Context is ${pkg.tokenCount.toLocaleString()} tokens (error threshold: ${errorThreshold.toLocaleString()}) — blocks materialization, node must be split`,\n nodePath,\n });\n } else if (pkg.tokenCount >= warningThreshold) {\n issues.push({\n severity: 'warning',\n code: 'W005',\n rule: 'budget-warning',\n message: `Context is ${pkg.tokenCount.toLocaleString()} tokens (warning threshold: ${warningThreshold.toLocaleString()}). Consider splitting the node or reducing dependencies.`,\n nodePath,\n });\n }\n } catch {\n // If context building fails, other rules will catch it\n }\n }\n return issues;\n}\n","import type { ContextPackage, ContextLayer } from '../model/types.js';\n\nfunction escapeAttr(val: string): string {\n return val.replace(/\"/g, '"');\n}\n\nfunction formatLayer(layer: ContextLayer): string {\n switch (layer.type) {\n case 'global':\n return `<global>\\n${layer.content}\\n</global>`;\n case 'hierarchy': {\n const pathMatch = layer.label.match(/\\((.+)\\/\\)/);\n const pathAttr = pathMatch ? ` path=\"${escapeAttr(pathMatch[1])}\"` : '';\n const aspectsAttr = layer.attrs?.aspects ? ` aspects=\"${escapeAttr(layer.attrs.aspects)}\"` : '';\n return `<hierarchy${pathAttr}${aspectsAttr}>\\n${layer.content}\\n</hierarchy>`;\n }\n case 'own': {\n if (layer.label === 'Materialization Target') {\n return `<materialization-target paths=\"${escapeAttr(layer.content)}\" />`;\n }\n const ownAspectsAttr = layer.attrs?.aspects ? ` aspects=\"${escapeAttr(layer.attrs.aspects)}\"` : '';\n return `<own-artifacts${ownAspectsAttr}>\\n${layer.content}\\n</own-artifacts>`;\n }\n case 'aspects': {\n const nameMatch = layer.label.match(/^(.+?) \\(aspect: (.+)\\)$/);\n const name = nameMatch ? escapeAttr(nameMatch[1]) : '';\n const id = nameMatch ? escapeAttr(nameMatch[2]) : '';\n return `<aspect name=\"${name}\" id=\"${id}\">\\n${layer.content}\\n</aspect>`;\n }\n case 'relational': {\n const attrs = layer.attrs ?? {};\n const attrStr = Object.entries(attrs)\n .map(([k, v]) => ` ${k}=\"${escapeAttr(v)}\"`)\n .join('');\n const tagName = attrs.type && ['emits', 'listens'].includes(attrs.type) ? 'event' : 'dependency';\n return `<${tagName}${attrStr}>\\n${layer.content}\\n</${tagName}>`;\n }\n case 'flows': {\n const flowName = layer.label.replace(/^Flow: /, '').trim();\n const flowAspectsAttr = layer.attrs?.aspects ? ` aspects=\"${escapeAttr(layer.attrs.aspects)}\"` : '';\n return `<flow name=\"${escapeAttr(flowName)}\"${flowAspectsAttr}>\\n${layer.content}\\n</flow>`;\n }\n default:\n return layer.content;\n }\n}\n\nexport function formatContextText(pkg: ContextPackage): string {\n const attrs = [\n `node-path=\"${escapeAttr(pkg.nodePath)}\"`,\n `node-name=\"${escapeAttr(pkg.nodeName)}\"`,\n `token-count=\"${pkg.tokenCount}\"`,\n ].join(' ');\n\n let out = `<context-package ${attrs}>\\n\\n`;\n\n for (const section of pkg.sections) {\n for (const layer of section.layers) {\n out += formatLayer(layer) + '\\n\\n';\n }\n }\n\n out += '</context-package>';\n return out;\n}\n","import { Command } from 'commander';\nimport { loadGraph } from '../core/graph-loader.js';\nimport { buildContext, collectAncestors } from '../core/context-builder.js';\nimport { validate } from '../core/validator.js';\nimport { formatContextText } from '../formatters/context-text.js';\nimport type { Graph } from '../model/types.js';\n\n/**\n * Collect the set of node paths that participate in context assembly for a given node:\n * the node itself, its ancestors, and its direct relation targets.\n */\nfunction collectRelevantNodePaths(graph: Graph, nodePath: string): Set<string> {\n const relevant = new Set<string>();\n const node = graph.nodes.get(nodePath);\n if (!node) return relevant;\n\n relevant.add(nodePath);\n\n // Ancestors (hierarchy)\n for (const ancestor of collectAncestors(node)) {\n relevant.add(ancestor.path);\n }\n\n // Direct relation targets\n for (const rel of node.meta.relations ?? []) {\n relevant.add(rel.target);\n }\n\n return relevant;\n}\n\nexport function registerBuildCommand(program: Command): void {\n program\n .command('build-context')\n .description('Assemble a context package for one node')\n .requiredOption('--node <node-path>', 'Node path relative to .yggdrasil/model/')\n .action(async (options: { node: string }) => {\n try {\n const graph = await loadGraph(process.cwd());\n const nodePath = options.node.trim().replace(/^\\.\\//, '').replace(/\\/$/, '');\n\n // Collect nodes relevant to this context assembly\n const relevantNodes = collectRelevantNodePaths(graph, nodePath);\n\n // Validate but only block on errors relevant to this node's context\n const validationResult = await validate(graph, 'all');\n const relevantErrors = validationResult.issues.filter(\n (issue) =>\n issue.severity === 'error' &&\n // Global errors (no nodePath) always block — e.g., E012 invalid config\n (!issue.nodePath || relevantNodes.has(issue.nodePath)),\n );\n if (relevantErrors.length > 0) {\n const totalErrors = validationResult.issues.filter((i) => i.severity === 'error').length;\n const skippedErrors = totalErrors - relevantErrors.length;\n let msg = `Error: build-context blocked by ${relevantErrors.length} error(s) affecting this node's context.\\n`;\n if (skippedErrors > 0) {\n msg += `(${skippedErrors} unrelated error(s) in other nodes ignored.)\\n`;\n }\n for (const err of relevantErrors) {\n const loc = err.nodePath ? `${err.nodePath}: ` : '';\n msg += ` ${err.code ?? ''} ${loc}${err.message}\\n`;\n }\n process.stderr.write(msg);\n process.exit(1);\n }\n\n const pkg = await buildContext(graph, nodePath);\n const warningThreshold = graph.config.quality?.context_budget.warning ?? 10000;\n const errorThreshold = graph.config.quality?.context_budget.error ?? 20000;\n const budgetStatus =\n pkg.tokenCount >= errorThreshold\n ? 'error'\n : pkg.tokenCount >= warningThreshold\n ? 'warning'\n : 'ok';\n\n let output = formatContextText(pkg);\n output += `Budget status: ${budgetStatus}\\n`;\n process.stdout.write(output);\n\n if (budgetStatus === 'error') {\n process.stderr.write(\n `Warning: context package exceeds error budget (${pkg.tokenCount} >= ${errorThreshold}). Consider splitting the node.\\n`,\n );\n }\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { loadGraph } from '../core/graph-loader.js';\nimport { validate } from '../core/validator.js';\n\nexport function registerValidateCommand(program: Command): void {\n program\n .command('validate')\n .description('Validate graph structural integrity and completeness signals')\n .option('--scope <scope>', 'Scope: all or node-path (default: all)', 'all')\n .action(async (options: { scope: string }) => {\n try {\n const graph = await loadGraph(process.cwd(), { tolerateInvalidConfig: true });\n const rawScope = (options.scope ?? 'all').trim() || 'all';\n const scope = rawScope === 'all' ? 'all' : rawScope.replace(/^\\.\\//, '').replace(/\\/+$/, '');\n const result = await validate(graph, scope);\n process.stdout.write(`${result.nodesScanned} nodes scanned\\n\\n`);\n const errors = result.issues.filter((i) => i.severity === 'error');\n const warnings = result.issues.filter((i) => i.severity === 'warning');\n for (const issue of errors) {\n const code = issue.code ?? '';\n const loc = issue.nodePath ?? '';\n const prefix = loc ? `${code} ${loc} -> ` : `${code} `;\n process.stdout.write(chalk.red(`✗ ${prefix}${issue.message}\\n`));\n }\n for (const issue of warnings) {\n const code = issue.code ?? '';\n const loc = issue.nodePath ?? '';\n const prefix = loc ? `${code} ${loc} -> ` : `${code} `;\n process.stdout.write(chalk.yellow(`⚠ ${prefix}${issue.message}\\n`));\n }\n if (errors.length === 0 && warnings.length === 0) {\n process.stdout.write(chalk.green('✓ No issues found.\\n'));\n } else {\n process.stdout.write(`\\n${errors.length} errors, ${warnings.length} warnings.\\n`);\n }\n\n const hasErrors = result.issues.some((i) => i.severity === 'error');\n process.exit(hasErrors ? 1 : 0);\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { loadGraph } from '../core/graph-loader.js';\nimport { detectDrift } from '../core/drift-detector.js';\nimport type { DriftEntry, DriftReport } from '../model/types.js';\n\nexport function registerDriftCommand(program: Command): void {\n program\n .command('drift')\n .description('Detect divergences between graph and mapped files')\n .option('--scope <scope>', 'Scope: \"all\" or node path', 'all')\n .option('--drifted-only', 'Show only nodes with drift (hide ok entries)')\n .option('--limit <n>', 'Maximum number of entries to show per section', parseInt)\n .action(async (opts: { scope: string; driftedOnly?: boolean; limit?: number }) => {\n try {\n const graph = await loadGraph(process.cwd());\n const rawScope = (opts.scope ?? 'all').trim() || 'all';\n const scope = rawScope === 'all' ? 'all' : rawScope.replace(/^\\.\\//, '').replace(/\\/+$/, '');\n\n if (scope !== 'all') {\n const node = graph.nodes.get(scope);\n if (!node) {\n process.stderr.write(`Error: Node not found: ${scope}\\n`);\n process.exit(1);\n }\n // Check if scope or any descendant has a mapping\n const hasAnyMapping = node.meta.mapping ||\n [...graph.nodes.entries()].some(([p, n]) => p.startsWith(scope + '/') && n.meta.mapping);\n if (!hasAnyMapping) {\n process.stderr.write(`Error: Node has no mapping: ${scope}\\n`);\n process.exit(1);\n }\n }\n\n const scopeNode = scope === 'all' ? undefined : scope;\n const report = await detectDrift(graph, scopeNode);\n printReport(report, opts.driftedOnly ?? false, opts.limit);\n\n const hasIssues =\n report.sourceDriftCount > 0 ||\n report.graphDriftCount > 0 ||\n report.fullDriftCount > 0 ||\n report.missingCount > 0 ||\n report.unmaterializedCount > 0;\n process.exit(hasIssues ? 1 : 0);\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n\nfunction printReport(report: DriftReport, driftedOnly: boolean, limit?: number): void {\n const sourceEntries = classifyForSection(report.entries, 'source', driftedOnly);\n const graphEntries = classifyForSection(report.entries, 'graph', driftedOnly);\n\n const sourceShown = limit !== undefined ? sourceEntries.slice(0, limit) : sourceEntries;\n const graphShown = limit !== undefined ? graphEntries.slice(0, limit) : graphEntries;\n\n process.stdout.write('Source drift:\\n');\n printSectionEntries(sourceShown, 'source');\n if (limit !== undefined && sourceEntries.length > limit) {\n process.stdout.write(chalk.dim(` ... ${sourceEntries.length - limit} more (${sourceEntries.length} total)\\n`));\n }\n\n process.stdout.write('\\nGraph drift:\\n');\n printSectionEntries(graphShown, 'graph');\n if (limit !== undefined && graphEntries.length > limit) {\n process.stdout.write(chalk.dim(` ... ${graphEntries.length - limit} more (${graphEntries.length} total)\\n`));\n }\n\n // Summary line\n const parts: string[] = [\n `${report.sourceDriftCount} source-drift`,\n `${report.graphDriftCount} graph-drift`,\n `${report.fullDriftCount} full-drift`,\n `${report.missingCount} missing`,\n `${report.unmaterializedCount} unmaterialized`,\n ];\n\n let summary = `\\nSummary: ${parts.join(', ')}`;\n if (driftedOnly && report.okCount > 0) {\n summary += ` (${report.okCount} ok hidden)`;\n } else {\n summary += `, ${report.okCount} ok`;\n }\n process.stdout.write(summary + '\\n');\n}\n\n/**\n * Classify entries for a given section (source or graph).\n * Source section shows: source-drift, full-drift, missing, unmaterialized, ok\n * Graph section shows: graph-drift, full-drift, ok\n */\nfunction classifyForSection(\n entries: DriftEntry[],\n section: 'source' | 'graph',\n driftedOnly: boolean,\n): DriftEntry[] {\n return entries.filter((entry) => {\n if (section === 'source') {\n // Source section: source-drift, full-drift, missing, unmaterialized, ok\n if (entry.status === 'graph-drift') return false;\n if (entry.status === 'ok' && driftedOnly) return false;\n return true;\n } else {\n // Graph section: graph-drift, full-drift, ok\n if (\n entry.status === 'source-drift' ||\n entry.status === 'missing' ||\n entry.status === 'unmaterialized'\n )\n return false;\n if (entry.status === 'ok' && driftedOnly) return false;\n return true;\n }\n });\n}\n\nfunction printSectionEntries(entries: DriftEntry[], section: 'source' | 'graph'): void {\n if (entries.length === 0) {\n process.stdout.write(chalk.dim(' (none)\\n'));\n return;\n }\n\n for (const entry of entries) {\n printEntryLine(entry);\n printChangedFiles(entry, section);\n }\n}\n\nfunction printEntryLine(entry: DriftEntry): void {\n const pad = 13; // width for status label column\n switch (entry.status) {\n case 'ok':\n process.stdout.write(chalk.green(` ${'[ok]'.padEnd(pad)}${entry.nodePath}\\n`));\n break;\n case 'source-drift':\n process.stdout.write(chalk.red(` ${'[drift]'.padEnd(pad)}${entry.nodePath}\\n`));\n break;\n case 'graph-drift':\n process.stdout.write(chalk.magenta(` ${'[drift]'.padEnd(pad)}${entry.nodePath}\\n`));\n break;\n case 'full-drift':\n process.stdout.write(chalk.red(` ${'[drift]'.padEnd(pad)}${entry.nodePath}\\n`));\n break;\n case 'missing':\n process.stdout.write(chalk.yellow(` ${'[missing]'.padEnd(pad)}${entry.nodePath}\\n`));\n break;\n case 'unmaterialized':\n process.stdout.write(chalk.dim(` ${'[unmat.]'.padEnd(pad)}${entry.nodePath}\\n`));\n break;\n }\n}\n\nfunction printChangedFiles(entry: DriftEntry, section: 'source' | 'graph'): void {\n if (!entry.changedFiles || entry.changedFiles.length === 0) return;\n\n const indent = ' '.repeat(15); // align under node path\n const relevantFiles = entry.changedFiles.filter((f) => {\n if (section === 'source') return f.category === 'source';\n return f.category === 'graph';\n });\n\n for (const file of relevantFiles) {\n process.stdout.write(chalk.dim(`${indent}${file.filePath} (changed)\\n`));\n }\n}\n","import { readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport { parse as yamlParse } from 'yaml';\nimport type { DriftState, DriftNodeState } from '../model/types.js';\n\nconst DRIFT_STATE_FILE = '.drift-state';\n\nexport async function readDriftState(yggRoot: string): Promise<DriftState> {\n try {\n const content = await readFile(path.join(yggRoot, DRIFT_STATE_FILE), 'utf-8');\n\n // Try JSON first (new format), fall back to YAML (legacy format)\n let raw: unknown;\n try {\n raw = JSON.parse(content);\n } catch {\n raw = yamlParse(content);\n }\n\n if (!raw || typeof raw !== 'object') return {};\n\n const state: DriftState = {};\n for (const [key, value] of Object.entries(raw)) {\n if (typeof value === 'object' && value !== null && 'hash' in value) {\n state[key] = value as DriftNodeState;\n }\n // Skip legacy string entries silently\n }\n return state;\n } catch {\n return {};\n }\n}\n\nexport async function writeDriftState(yggRoot: string, state: DriftState): Promise<void> {\n const content = JSON.stringify(state);\n await writeFile(path.join(yggRoot, DRIFT_STATE_FILE), content, 'utf-8');\n}\n","import { readFile, readdir, stat } from 'node:fs/promises';\nimport path from 'node:path';\nimport { createHash } from 'node:crypto';\nimport { createRequire } from 'node:module';\nimport { type Ignore, type Options as IgnoreOptions } from 'ignore';\nimport type { TrackedFile } from '../core/context-files.js';\n\nconst require = createRequire(import.meta.url);\nconst ignoreFactory = require('ignore') as (options?: IgnoreOptions) => Ignore;\n\ntype HashPathOptions = {\n projectRoot?: string;\n};\n\ntype GitignoreEntry = { basePath: string; matcher: Ignore };\n\nexport async function hashFile(filePath: string): Promise<string> {\n const content = await readFile(filePath);\n return createHash('sha256').update(content).digest('hex');\n}\n\nexport async function hashPath(targetPath: string, options: HashPathOptions = {}): Promise<string> {\n const projectRoot = options.projectRoot ? path.resolve(options.projectRoot) : undefined;\n const gitignoreStack = await loadRootGitignoreStack(projectRoot);\n const targetStat = await stat(targetPath);\n\n if (targetStat.isFile()) {\n // Mapped files are always hashed — gitignore only applies to directory scans.\n return hashFile(targetPath);\n }\n\n if (targetStat.isDirectory()) {\n const fileHashes = await collectDirectoryFileHashes(targetPath, targetPath, {\n projectRoot,\n gitignoreStack,\n });\n const digestInput = fileHashes\n .sort((a, b) => a.path.localeCompare(b.path))\n .map((entry) => `${entry.path}:${entry.hash}`)\n .join('\\n');\n return hashString(digestInput);\n }\n\n throw new Error(`Unsupported mapping path type: ${targetPath}`);\n}\n\nasync function collectDirectoryFileHashes(\n directoryPath: string,\n rootDirectoryPath: string,\n options: { projectRoot?: string; gitignoreStack?: GitignoreEntry[] },\n): Promise<Array<{ path: string; hash: string }>> {\n const filePaths = await collectDirectoryFilePaths(directoryPath, rootDirectoryPath, options);\n const result: Array<{ path: string; hash: string }> = [];\n for (const entry of filePaths) {\n result.push({ path: entry.relPath, hash: await hashFile(entry.absPath) });\n }\n return result;\n}\n\nasync function loadRootGitignoreStack(projectRoot?: string): Promise<GitignoreEntry[]> {\n if (!projectRoot) return [];\n try {\n const content = await readFile(path.join(projectRoot, '.gitignore'), 'utf-8');\n const matcher = ignoreFactory();\n matcher.add(content);\n return [{ basePath: projectRoot, matcher }];\n } catch {\n return [];\n }\n}\n\nfunction isIgnoredByStack(candidatePath: string, stack: GitignoreEntry[]): boolean {\n for (const { basePath, matcher } of stack) {\n const relativePath = path.relative(basePath, candidatePath);\n if (relativePath === '' || relativePath.startsWith('..')) continue;\n if (matcher.ignores(relativePath) || matcher.ignores(relativePath + '/')) return true;\n }\n return false;\n}\n\nexport function hashString(content: string): string {\n return createHash('sha256').update(content).digest('hex');\n}\n\n/** Compute per-file hashes for a mapping. Used for diagnostics (which files changed). */\nexport async function perFileHashes(\n projectRoot: string,\n mapping: { paths?: string[] },\n): Promise<Array<{ path: string; hash: string }>> {\n const root = path.resolve(projectRoot);\n const paths = mapping.paths ?? [];\n if (paths.length === 0) return [];\n\n const result: Array<{ path: string; hash: string }> = [];\n const gitignoreStack = await loadRootGitignoreStack(root);\n\n for (const p of paths) {\n const absPath = path.join(root, p);\n const st = await stat(absPath);\n if (st.isFile()) {\n result.push({ path: p, hash: await hashFile(absPath) });\n } else if (st.isDirectory()) {\n const hashes = await collectDirectoryFileHashes(absPath, absPath, {\n projectRoot: root,\n gitignoreStack,\n });\n for (const h of hashes) {\n result.push({\n path: path.join(p, h.path).split(path.sep).join('/'),\n hash: h.hash,\n });\n }\n }\n }\n\n return result;\n}\n\n/** Compute drift hash for a node mapping. Returns hex. */\nexport async function hashForMapping(\n projectRoot: string,\n mapping: { paths?: string[] },\n): Promise<string> {\n const root = path.resolve(projectRoot);\n const paths = mapping.paths ?? [];\n if (paths.length === 0) throw new Error('Invalid mapping for hash: no paths');\n\n const pairs: Array<{ path: string; hash: string }> = [];\n\n for (const p of paths) {\n const absPath = path.join(root, p);\n const st = await stat(absPath);\n if (st.isFile()) {\n pairs.push({ path: p, hash: await hashFile(absPath) });\n } else if (st.isDirectory()) {\n const dirHash = await hashPath(absPath, { projectRoot: root });\n pairs.push({ path: p, hash: dirHash });\n }\n }\n\n const digestInput = pairs\n .sort((a, b) => a.path.localeCompare(b.path))\n .map((e) => `${e.path}:${e.hash}`)\n .join('\\n');\n return createHash('sha256').update(digestInput).digest('hex');\n}\n\n/** Stored file data for mtime-based drift optimization. */\nexport interface StoredFileData {\n hashes: Record<string, string>;\n mtimes: Record<string, number>;\n}\n\n/**\n * Hash all tracked files (source + graph) for bidirectional drift detection.\n * Directories in the tracked list are expanded to their contained files.\n * Returns a canonical hash (sorted path:hash digest), per-file hashes, and mtimes.\n *\n * When `storedFileData` is provided, files whose mtime has not changed since\n * the last sync will reuse the stored hash instead of re-reading and hashing.\n * This makes the common case (no changes) nearly instant even for large mappings.\n */\nexport async function hashTrackedFiles(\n projectRoot: string,\n trackedFiles: TrackedFile[],\n storedFileData?: StoredFileData,\n excludePrefixes?: string[],\n): Promise<{ canonicalHash: string; fileHashes: Record<string, string>; fileMtimes: Record<string, number> }> {\n const fileHashes: Record<string, string> = {};\n const fileMtimes: Record<string, number> = {};\n const gitignoreStack = await loadRootGitignoreStack(projectRoot);\n\n // Collect all file entries (expanding directories) with their metadata\n type FileEntry = { relPath: string; absPath: string; mtimeMs: number };\n const allFiles: FileEntry[] = [];\n\n for (const tf of trackedFiles) {\n const absPath = path.join(projectRoot, tf.path);\n try {\n const st = await stat(absPath);\n if (st.isDirectory()) {\n const dirEntries = await collectDirectoryFilePaths(absPath, absPath, {\n projectRoot,\n gitignoreStack,\n });\n for (const entry of dirEntries) {\n allFiles.push({\n relPath: path.join(tf.path, entry.relPath).replace(/\\\\/g, '/'),\n absPath: entry.absPath,\n mtimeMs: entry.mtimeMs,\n });\n }\n } else {\n allFiles.push({ relPath: tf.path, absPath, mtimeMs: st.mtimeMs });\n }\n } catch {\n continue;\n }\n }\n\n // Exclude files owned by descendant nodes (child-wins model)\n const filtered = excludePrefixes?.length\n ? allFiles.filter((entry) =>\n !excludePrefixes.some((prefix) =>\n entry.relPath === prefix || entry.relPath.startsWith(prefix + '/')))\n : allFiles;\n\n // Separate files into cached (mtime match) and dirty (need hashing)\n const dirty: FileEntry[] = [];\n for (const entry of filtered) {\n const storedMtime = storedFileData?.mtimes[entry.relPath];\n const storedHash = storedFileData?.hashes[entry.relPath];\n if (storedMtime !== undefined && storedHash !== undefined && entry.mtimeMs === storedMtime) {\n fileHashes[entry.relPath] = storedHash;\n } else {\n dirty.push(entry);\n }\n fileMtimes[entry.relPath] = entry.mtimeMs;\n }\n\n // Hash dirty files in parallel batches to avoid overwhelming file descriptors\n const BATCH_SIZE = 256;\n for (let i = 0; i < dirty.length; i += BATCH_SIZE) {\n const batch = dirty.slice(i, i + BATCH_SIZE);\n const hashes = await Promise.all(batch.map((e) => hashFile(e.absPath)));\n for (let j = 0; j < batch.length; j++) {\n fileHashes[batch[j].relPath] = hashes[j];\n }\n }\n\n // Canonical hash: sorted path:hash pairs\n const sorted = Object.entries(fileHashes).sort(([a], [b]) => a.localeCompare(b));\n const digest = sorted.map(([p, h]) => `${p}:${h}`).join('\\n');\n const canonicalHash = hashString(digest);\n\n return { canonicalHash, fileHashes, fileMtimes };\n}\n\n/**\n * Collect file paths and mtimes from a directory without hashing.\n * Used by hashTrackedFiles to separate discovery from hashing,\n * enabling mtime-based optimization.\n *\n * Directory recursion and file stat() calls are parallelized for performance.\n */\nasync function collectDirectoryFilePaths(\n directoryPath: string,\n rootDirectoryPath: string,\n options: { projectRoot?: string; gitignoreStack?: GitignoreEntry[] },\n): Promise<Array<{ relPath: string; absPath: string; mtimeMs: number }>> {\n let stack = options.gitignoreStack ?? [];\n try {\n const localContent = await readFile(path.join(directoryPath, '.gitignore'), 'utf-8');\n const localMatcher = ignoreFactory();\n localMatcher.add(localContent);\n stack = [...stack, { basePath: directoryPath, matcher: localMatcher }];\n } catch {\n // No local .gitignore\n }\n\n const entries = await readdir(directoryPath, { withFileTypes: true });\n const dirs: string[] = [];\n const files: string[] = [];\n\n for (const entry of entries) {\n const absoluteChildPath = path.join(directoryPath, entry.name);\n if (isIgnoredByStack(absoluteChildPath, stack)) continue;\n if (entry.isDirectory()) dirs.push(absoluteChildPath);\n else if (entry.isFile()) files.push(absoluteChildPath);\n }\n\n // Parallel: recurse into directories AND stat files concurrently\n const [dirResults, fileStats] = await Promise.all([\n Promise.all(dirs.map((d) => collectDirectoryFilePaths(d, rootDirectoryPath, {\n projectRoot: options.projectRoot,\n gitignoreStack: stack,\n }))),\n Promise.all(files.map(async (f) => {\n const fileStat = await stat(f);\n return {\n relPath: path.relative(rootDirectoryPath, f),\n absPath: f,\n mtimeMs: fileStat.mtimeMs,\n };\n })),\n ]);\n\n const result: Array<{ relPath: string; absPath: string; mtimeMs: number }> = [];\n for (const nested of dirResults) result.push(...nested);\n result.push(...fileStats);\n return result;\n}\n","import path from 'node:path';\nimport type { Graph, GraphNode, DriftCategory, FlowDef } from '../model/types.js';\nimport { normalizeMappingPaths } from '../utils/paths.js';\nimport { collectAncestors, resolveAspects } from './context-builder.js';\n\nexport interface TrackedFile {\n path: string; // relative to project root\n category: DriftCategory; // 'source' or 'graph'\n}\n\nconst STRUCTURAL_RELATION_TYPES = new Set(['uses', 'calls', 'extends', 'implements']);\n\n/**\n * Collect all files tracked by a node's context package.\n * Mirrors the traversal of build-context but returns file paths\n * instead of rendered content. This is the core function for\n * bidirectional drift detection.\n *\n * Synchronous — no I/O needed; all data comes from the loaded Graph.\n */\nexport function collectTrackedFiles(node: GraphNode, graph: Graph): TrackedFile[] {\n const seen = new Set<string>();\n const result: TrackedFile[] = [];\n\n // Compute the .yggdrasil prefix relative to project root.\n // graph.rootPath is absolute path to .yggdrasil/; project root is its parent.\n const projectRoot = path.dirname(graph.rootPath);\n const yggPrefix = path.relative(projectRoot, graph.rootPath);\n // Normalize to forward slashes for consistency\n const yggPrefixNormalized = yggPrefix.split(path.sep).join('/');\n\n const configArtifactKeys = new Set(Object.keys(graph.config.artifacts ?? {}));\n\n function addFile(filePath: string, category: DriftCategory): void {\n if (seen.has(filePath)) return;\n seen.add(filePath);\n result.push({ path: filePath, category });\n }\n\n function graphPath(...segments: string[]): string {\n return [yggPrefixNormalized, ...segments].join('/');\n }\n\n function addNodeFiles(n: GraphNode): void {\n // node.yaml\n addFile(graphPath('model', n.path, 'node.yaml'), 'graph');\n // artifacts filtered by config\n for (const art of n.artifacts) {\n if (configArtifactKeys.has(art.filename)) {\n addFile(graphPath('model', n.path, art.filename), 'graph');\n }\n }\n }\n\n // 1. OWN — node.yaml + config-filtered artifacts\n addNodeFiles(node);\n\n // 2. HIERARCHICAL — ancestors from root to parent\n const ancestors = collectAncestors(node);\n for (const ancestor of ancestors) {\n addNodeFiles(ancestor);\n }\n\n // 3. ASPECTS — resolve all aspects from own + ancestors + flows (with recursive implies)\n // First, collect all aspect ids from own node and ancestors\n const allAspectIds = new Set<string>();\n\n for (const id of node.meta.aspects ?? []) {\n allAspectIds.add(id);\n }\n for (const ancestor of ancestors) {\n for (const id of ancestor.meta.aspects ?? []) {\n allAspectIds.add(id);\n }\n }\n\n // Collect participating flows (same logic as build-context)\n const participatingFlows = collectParticipatingFlows(graph, node, ancestors);\n\n // Add flow-propagated aspects\n for (const flow of participatingFlows) {\n for (const id of flow.aspects ?? []) {\n allAspectIds.add(id);\n }\n }\n\n // Resolve with recursive implies\n const resolvedAspects = resolveAspects(allAspectIds, graph.aspects);\n for (const aspect of resolvedAspects) {\n addFile(graphPath('aspects', aspect.id, 'aspect.yaml'), 'graph');\n for (const art of aspect.artifacts) {\n addFile(graphPath('aspects', aspect.id, art.filename), 'graph');\n }\n }\n\n // 4. RELATIONAL-DEPS — structural relations (uses/calls/extends/implements)\n for (const relation of node.meta.relations ?? []) {\n if (!STRUCTURAL_RELATION_TYPES.has(relation.type)) continue;\n const target = graph.nodes.get(relation.target);\n if (!target) continue;\n\n // Determine which artifacts to include from the target\n const structuralFilenames = Object.entries(graph.config.artifacts ?? {})\n .filter(([, c]) => c.structural_context)\n .map(([filename]) => filename);\n\n // Check if the target actually has any of the structural_context artifacts\n const structuralArts = structuralFilenames.filter((filename) =>\n target.artifacts.some((a) => a.filename === filename),\n );\n\n if (structuralArts.length > 0) {\n // Use only structural_context artifacts that exist on target\n for (const filename of structuralArts) {\n addFile(graphPath('model', target.path, filename), 'graph');\n }\n } else {\n // Fallback: all config-allowed artifacts\n for (const art of target.artifacts) {\n if (configArtifactKeys.has(art.filename)) {\n addFile(graphPath('model', target.path, art.filename), 'graph');\n }\n }\n }\n }\n\n // 5. RELATIONAL-FLOWS — flow.yaml + flow artifacts for participating flows\n for (const flow of participatingFlows) {\n addFile(graphPath('flows', flow.path, 'flow.yaml'), 'graph');\n for (const art of flow.artifacts) {\n addFile(graphPath('flows', flow.path, art.filename), 'graph');\n }\n }\n\n // 6. SOURCE — files from mapping.paths\n const mappingPaths = normalizeMappingPaths(node.meta.mapping);\n for (const p of mappingPaths) {\n addFile(p, 'source');\n }\n\n return result;\n}\n\n/**\n * Find all flows where the node or any of its ancestors is a participant.\n * Same logic as collectParticipatingFlows in context-builder.ts.\n */\nfunction collectParticipatingFlows(\n graph: Graph,\n node: GraphNode,\n ancestors: GraphNode[],\n): FlowDef[] {\n const paths = new Set<string>([node.path, ...ancestors.map((a) => a.path)]);\n return graph.flows.filter((f) => f.nodes.some((n) => paths.has(n)));\n}\n","import type {\n Graph,\n DriftReport,\n DriftEntry,\n DriftStatus,\n DriftFileChange,\n DriftCategory,\n} from '../model/types.js';\nimport {\n readDriftState,\n writeDriftState,\n} from '../io/drift-state-store.js';\nimport { hashTrackedFiles } from '../utils/hash.js';\nimport { collectTrackedFiles } from './context-files.js';\nimport { normalizeMappingPaths } from '../utils/paths.js';\nimport { access } from 'node:fs/promises';\nimport path from 'node:path';\n\n/**\n * Compute mapping paths owned by descendant nodes that overlap with a node's own\n * mapping paths. Used to exclude child-owned files from parent drift hashing\n * (\"child wins\" model).\n */\nfunction getChildMappingExclusions(graph: Graph, nodePath: string): string[] {\n const node = graph.nodes.get(nodePath);\n if (!node) return [];\n const parentMappings = normalizeMappingPaths(node.meta.mapping);\n if (parentMappings.length === 0) return [];\n\n const exclusions: string[] = [];\n for (const [childPath, childNode] of graph.nodes) {\n if (childPath === nodePath) continue;\n if (!childPath.startsWith(nodePath + '/')) continue; // not a descendant\n const childMappings = normalizeMappingPaths(childNode.meta.mapping);\n for (const cm of childMappings) {\n for (const pm of parentMappings) {\n if (cm === pm || cm.startsWith(pm + '/')) {\n exclusions.push(cm);\n }\n }\n }\n }\n return exclusions;\n}\n\nexport async function detectDrift(graph: Graph, filterNodePath?: string): Promise<DriftReport> {\n const projectRoot = path.dirname(graph.rootPath);\n const driftState = await readDriftState(graph.rootPath);\n const entries: DriftEntry[] = [];\n\n for (const [nodePath, node] of graph.nodes) {\n if (filterNodePath && nodePath !== filterNodePath && !nodePath.startsWith(filterNodePath + '/')) continue;\n const mapping = node.meta.mapping;\n if (!mapping) continue;\n\n const mappingPaths = normalizeMappingPaths(mapping);\n if (mappingPaths.length === 0) continue;\n\n const storedEntry = driftState[nodePath];\n\n if (!storedEntry) {\n const allMissing = await allPathsMissing(projectRoot, mappingPaths);\n entries.push({\n nodePath,\n status: allMissing ? 'unmaterialized' : 'source-drift',\n details: allMissing\n ? 'No drift state recorded, files do not exist'\n : 'No drift state recorded, files exist (run drift-sync after materialization)',\n });\n continue;\n }\n\n // Check if source files are entirely missing (all mapping paths gone)\n // This must happen BEFORE hash comparison — a node whose source files\n // are all gone is 'missing' regardless of whether graph-only hashes match.\n const sourceFilesMissing = await allPathsMissing(projectRoot, mappingPaths);\n if (sourceFilesMissing) {\n entries.push({\n nodePath,\n status: 'missing',\n details: 'All source mapping paths are missing',\n });\n continue;\n }\n\n // Collect all tracked files (source + graph) for this node\n const trackedFiles = collectTrackedFiles(node, graph);\n // Exclude files owned by descendant nodes (child-wins model)\n const excludePrefixes = getChildMappingExclusions(graph, nodePath);\n // Pass stored file data for mtime-based optimization: skip hashing files whose\n // modification time has not changed since the last drift-sync.\n const storedFileData = storedEntry.files\n ? { hashes: storedEntry.files, mtimes: storedEntry.mtimes ?? {} }\n : undefined;\n const { canonicalHash, fileHashes } = await hashTrackedFiles(projectRoot, trackedFiles, storedFileData, excludePrefixes);\n\n if (canonicalHash === storedEntry.hash) {\n entries.push({ nodePath, status: 'ok' });\n continue;\n }\n\n // Something changed — determine what\n const changedFiles: DriftFileChange[] = [];\n const storedFiles = storedEntry.files;\n\n // Check current files against stored\n for (const [filePath, hash] of Object.entries(fileHashes)) {\n const storedHash = storedFiles[filePath];\n if (!storedHash || storedHash !== hash) {\n changedFiles.push({\n filePath,\n category: categorizeFile(filePath, graph.rootPath, projectRoot),\n });\n }\n }\n\n // Check for deleted files (in stored but not in current)\n for (const storedPath of Object.keys(storedFiles)) {\n if (!(storedPath in fileHashes)) {\n changedFiles.push({\n filePath: `${storedPath} (deleted)`,\n category: categorizeFile(storedPath, graph.rootPath, projectRoot),\n });\n }\n }\n\n // Determine drift status from changed file categories\n const hasSourceChanges = changedFiles.some((f) => f.category === 'source');\n const hasGraphChanges = changedFiles.some((f) => f.category === 'graph');\n\n let status: DriftStatus;\n if (hasSourceChanges && hasGraphChanges) {\n status = 'full-drift';\n } else if (hasGraphChanges) {\n status = 'graph-drift';\n } else if (hasSourceChanges) {\n status = 'source-drift';\n } else {\n // Hash changed but no individual file identified — fallback\n status = 'source-drift';\n }\n\n const details =\n changedFiles.length > 0\n ? `Changed files: ${changedFiles.map((f) => f.filePath).join(', ')}`\n : 'File(s) modified since last sync';\n\n entries.push({ nodePath, status, details, changedFiles });\n }\n\n return {\n entries,\n totalChecked: entries.length,\n okCount: entries.filter((e) => e.status === 'ok').length,\n sourceDriftCount: entries.filter((e) => e.status === 'source-drift').length,\n graphDriftCount: entries.filter((e) => e.status === 'graph-drift').length,\n fullDriftCount: entries.filter((e) => e.status === 'full-drift').length,\n missingCount: entries.filter((e) => e.status === 'missing').length,\n unmaterializedCount: entries.filter((e) => e.status === 'unmaterialized').length,\n };\n}\n\n/**\n * Categorize a file path as 'source' or 'graph' based on whether it lives\n * under the .yggdrasil/ directory.\n */\nfunction categorizeFile(filePath: string, _rootPath: string, projectRoot: string): DriftCategory {\n const yggPrefix = path.relative(projectRoot, _rootPath);\n const normalizedPrefix = yggPrefix.split(path.sep).join('/');\n const normalizedFilePath = filePath.replace(/\\\\/g, '/');\n return normalizedFilePath.startsWith(normalizedPrefix) ? 'graph' : 'source';\n}\n\nasync function allPathsMissing(projectRoot: string, mappingPaths: string[]): Promise<boolean> {\n for (const mp of mappingPaths) {\n const absPath = path.join(projectRoot, mp);\n try {\n await access(absPath);\n return false;\n } catch {\n // path missing\n }\n }\n return true;\n}\n\nexport async function syncDriftState(\n graph: Graph,\n nodePath: string,\n): Promise<{ previousHash?: string; currentHash: string }> {\n const projectRoot = path.dirname(graph.rootPath);\n const node = graph.nodes.get(nodePath);\n if (!node) throw new Error(`Node not found: ${nodePath}`);\n if (!node.meta.mapping) throw new Error(`Node has no mapping: ${nodePath}`);\n\n const trackedFiles = collectTrackedFiles(node, graph);\n // Exclude files owned by descendant nodes (child-wins model)\n const excludePrefixes = getChildMappingExclusions(graph, nodePath);\n // For sync, pass stored data so unchanged files can reuse cached hashes.\n const existingState = await readDriftState(graph.rootPath);\n const existingEntry = existingState[nodePath];\n const storedFileData = existingEntry?.files\n ? { hashes: existingEntry.files, mtimes: existingEntry.mtimes ?? {} }\n : undefined;\n const { canonicalHash, fileHashes, fileMtimes } = await hashTrackedFiles(projectRoot, trackedFiles, storedFileData, excludePrefixes);\n\n const previousHash = existingEntry?.hash;\n\n existingState[nodePath] = { hash: canonicalHash, files: fileHashes, mtimes: fileMtimes };\n\n // Garbage collection: remove orphaned entries for nodes that no longer exist\n for (const key of Object.keys(existingState)) {\n if (!graph.nodes.has(key)) {\n delete existingState[key];\n }\n }\n\n await writeDriftState(graph.rootPath, existingState);\n\n return { previousHash, currentHash: canonicalHash };\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { loadGraph } from '../core/graph-loader.js';\nimport { syncDriftState } from '../core/drift-detector.js';\nimport { normalizeMappingPaths } from '../utils/paths.js';\n\nexport function registerDriftSyncCommand(program: Command): void {\n program\n .command('drift-sync')\n .description('Record current file hash after resolving drift')\n .option('--node <path>', 'Node path to sync')\n .option('--recursive', 'Also sync all descendant nodes')\n .option('--all', 'Sync all nodes with mappings')\n .action(async (options: { node?: string; recursive?: boolean; all?: boolean }) => {\n try {\n if (!options.node && !options.all) {\n process.stderr.write(\"Error: either '--node <path>' or '--all' is required\\n\");\n process.exit(1);\n }\n\n const graph = await loadGraph(process.cwd());\n\n let nodesToSync: string[];\n\n if (options.all) {\n nodesToSync = [...graph.nodes.entries()]\n .filter(([, n]) => normalizeMappingPaths(n.meta.mapping).length > 0)\n .map(([p]) => p)\n .sort();\n } else {\n const nodePath = options.node!.trim().replace(/^\\.\\//, '').replace(/\\/+$/, '');\n\n if (!graph.nodes.has(nodePath)) {\n await syncDriftState(graph, nodePath); // will throw with proper error\n return;\n }\n\n nodesToSync = [nodePath];\n if (options.recursive) {\n const prefix = nodePath + '/';\n for (const [p] of graph.nodes) {\n if (p.startsWith(prefix)) {\n nodesToSync.push(p);\n }\n }\n nodesToSync.sort();\n }\n }\n\n for (const np of nodesToSync) {\n const node = graph.nodes.get(np)!;\n if (normalizeMappingPaths(node.meta.mapping).length === 0) {\n if (!options.all && !options.recursive && np === options.node) {\n await syncDriftState(graph, np); // will throw with proper error\n }\n continue;\n }\n const { previousHash, currentHash } = await syncDriftState(graph, np);\n process.stdout.write(chalk.green(`Synchronized: ${np}\\n`));\n process.stdout.write(\n ` Hash: ${previousHash ? previousHash.slice(0, 8) : 'none'} -> ${currentHash.slice(0, 8)}\\n`,\n );\n }\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport { loadGraph } from '../core/graph-loader.js';\nimport { detectDrift } from '../core/drift-detector.js';\nimport { validate } from '../core/validator.js';\nimport { collectEffectiveAspectIds } from '../core/context-builder.js';\nimport { normalizeMappingPaths } from '../utils/paths.js';\n\nexport function registerStatusCommand(program: Command): void {\n program\n .command('status')\n .description('Show graph summary')\n .action(async () => {\n try {\n const graph = await loadGraph(process.cwd());\n\n // Count nodes by type\n const typeCounts = new Map<string, number>();\n let blackboxCount = 0;\n\n for (const node of graph.nodes.values()) {\n typeCounts.set(node.meta.type, (typeCounts.get(node.meta.type) ?? 0) + 1);\n if (node.meta.blackbox) blackboxCount++;\n }\n\n // Count relations\n let structuralRelations = 0;\n let eventRelations = 0;\n const structuralTypes = new Set(['uses', 'calls', 'extends', 'implements']);\n let maxRelCount = 0;\n let maxRelNode = '';\n for (const node of graph.nodes.values()) {\n const relCount = (node.meta.relations ?? []).length;\n if (relCount > maxRelCount) {\n maxRelCount = relCount;\n maxRelNode = node.path;\n }\n for (const rel of node.meta.relations ?? []) {\n if (structuralTypes.has(rel.type)) structuralRelations += 1;\n else eventRelations += 1;\n }\n }\n\n const flowCount = graph.flows.length;\n\n const drift = await detectDrift(graph);\n const validation = await validate(graph, 'all');\n const errorCount = validation.issues.filter((issue) => issue.severity === 'error').length;\n const warningCount = validation.issues.filter(\n (issue) => issue.severity === 'warning',\n ).length;\n\n // Quality metrics\n const configuredArtifactTypes = Object.keys(graph.config.artifacts ?? {});\n const totalSlots = graph.nodes.size * configuredArtifactTypes.length;\n let filledSlots = 0;\n let mappedNodeCount = 0;\n\n for (const node of graph.nodes.values()) {\n const allowed = new Set(configuredArtifactTypes);\n filledSlots += node.artifacts.filter((a) => allowed.has(a.filename)).length;\n if (normalizeMappingPaths(node.meta.mapping).length > 0) mappedNodeCount++;\n }\n\n let aspectCoveredNodes = 0;\n for (const node of graph.nodes.values()) {\n const effective = collectEffectiveAspectIds(graph, node.path);\n if (effective.size > 0) aspectCoveredNodes++;\n }\n\n process.stdout.write(`Graph: ${graph.config.name}\\n`);\n const pluralize = (word: string, count: number) =>\n count === 1 ? word : word.endsWith('y') ? word.slice(0, -1) + 'ies' : word + 's';\n const typeStr = [...typeCounts.entries()]\n .map(([t, c]) => `${c} ${pluralize(t, c)}`)\n .join(', ');\n process.stdout.write(\n `Nodes: ${graph.nodes.size} (${typeStr}) + ${blackboxCount} blackbox\\n`,\n );\n process.stdout.write(\n `Relations: ${structuralRelations} structural, ${eventRelations} event\\n`,\n );\n process.stdout.write(\n `Aspects: ${graph.aspects.length} Flows: ${flowCount}\\n`,\n );\n process.stdout.write(\n `Drift: ${drift.sourceDriftCount} source-drift, ${drift.graphDriftCount} graph-drift, ${drift.fullDriftCount} full-drift, ${drift.missingCount} missing, ${drift.unmaterializedCount} unmaterialized, ${drift.okCount} ok\\n`,\n );\n process.stdout.write(`Validation: ${errorCount} errors, ${warningCount} warnings\\n`);\n\n // Quality section\n const fillPct = totalSlots > 0 ? Math.round((filledSlots / totalSlots) * 100) : 0;\n const totalRelations = structuralRelations + eventRelations;\n const avgRel = graph.nodes.size > 0 ? (totalRelations / graph.nodes.size).toFixed(1) : '0';\n process.stdout.write(`\\nQuality:\\n`);\n process.stdout.write(\n ` Artifacts: ${filledSlots}/${totalSlots} slots filled (${fillPct}%) — ${configuredArtifactTypes.length} types × ${graph.nodes.size} nodes\\n`,\n );\n process.stdout.write(\n ` Relations: avg ${avgRel}/node, max ${maxRelCount}${maxRelNode ? ` (${maxRelNode})` : ''}\\n`,\n );\n process.stdout.write(\n ` Mapping: ${mappedNodeCount}/${graph.nodes.size} nodes mapped to source\\n`,\n );\n process.stdout.write(\n ` Aspects: ${aspectCoveredNodes}/${graph.nodes.size} nodes have aspect coverage\\n`,\n );\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport { loadGraph } from '../core/graph-loader.js';\nimport type { GraphNode } from '../model/types.js';\n\nexport function registerTreeCommand(program: Command): void {\n program\n .command('tree')\n .description('Display graph structure as a tree')\n .option('--root <path>', 'Show only subtree rooted at this path')\n .option('--depth <n>', 'Maximum depth', (v) => parseInt(v, 10))\n .action(async (options: { root?: string; depth?: number }) => {\n try {\n const graph = await loadGraph(process.cwd());\n\n let roots: GraphNode[];\n let showProjectName: boolean;\n\n if (options.root?.trim()) {\n const path = options.root.trim().replace(/\\/$/, '');\n const node = graph.nodes.get(path);\n if (!node) {\n process.stderr.write(`Error: path '${path}' not found\\n`);\n process.exit(1);\n }\n roots = [node];\n showProjectName = false;\n } else {\n roots = [...graph.nodes.values()]\n .filter((n) => n.parent === null)\n .sort((a, b) => a.path.localeCompare(b.path));\n showProjectName = true;\n }\n\n if (showProjectName) {\n process.stdout.write('model/\\n');\n }\n\n for (let i = 0; i < roots.length; i++) {\n const isLast = i === roots.length - 1;\n printNode(roots[i], '', isLast, 1, options.depth);\n }\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n\nfunction printNode(\n node: GraphNode,\n prefix: string,\n isLast: boolean,\n depth: number,\n maxDepth: number | undefined,\n): void {\n const connector = isLast ? '└── ' : '├── ';\n const name = node.path.split('/').pop() ?? node.path;\n const type = `[${node.meta.type}]`;\n const tags = node.meta.aspects?.length ? ` aspects:${node.meta.aspects.join(',')}` : '';\n const blackbox = node.meta.blackbox ? ' ■ blackbox' : '';\n const relationCount = node.meta.relations?.length ?? 0;\n\n process.stdout.write(\n `${prefix}${connector}${name}/ ${type}${tags}${blackbox} -> ${relationCount} relations\\n`,\n );\n\n const childPrefix = prefix + (isLast ? ' ' : '│ ');\n\n // Recurse into children\n if (maxDepth !== undefined && depth >= maxDepth) return;\n\n const children = [...node.children].sort((a, b) => a.path.localeCompare(b.path));\n for (let i = 0; i < children.length; i++) {\n printNode(children[i], childPrefix, i === children.length - 1, depth + 1, maxDepth);\n }\n}\n","import path from 'node:path';\nimport { access } from 'node:fs/promises';\nimport { Command } from 'commander';\nimport { loadGraph } from '../core/graph-loader.js';\nimport type { Graph, OwnerResult } from '../model/types.js';\nimport { normalizeMappingPaths, normalizeProjectRelativePath, projectRootFromGraph } from '../utils/paths.js';\n\nfunction normalizeForMatch(inputPath: string): string {\n return inputPath.replace(/\\\\/g, '/').replace(/\\/+$/, '');\n}\n\nexport function findOwner(graph: Graph, projectRoot: string, rawPath: string): OwnerResult {\n const file = normalizeForMatch(normalizeProjectRelativePath(projectRoot, rawPath));\n let best: { nodePath: string; mappingPath: string; exact: boolean } | null = null;\n\n for (const [nodePath, node] of graph.nodes) {\n const mappingPaths = normalizeMappingPaths(node.meta.mapping)\n .map(normalizeForMatch)\n .filter((mappingPath) => mappingPath.length > 0);\n\n for (const mappingPath of mappingPaths) {\n if (file === mappingPath) {\n return { file, nodePath, mappingPath, direct: true };\n }\n if (file.startsWith(mappingPath + '/')) {\n if (!best || (best && mappingPath.length > best.mappingPath.length)) {\n best = { nodePath, mappingPath, exact: false };\n }\n }\n }\n }\n\n return best\n ? { file, nodePath: best.nodePath, mappingPath: best.mappingPath, direct: false }\n : { file, nodePath: null };\n}\n\nexport function registerOwnerCommand(program: Command): void {\n program\n .command('owner')\n .description('Find which graph node owns a source file')\n .requiredOption('--file <path>', 'File path (relative to repository root)')\n .action(async (options: { file: string }) => {\n try {\n const cwd = process.cwd();\n const graph = await loadGraph(cwd);\n // Resolve the file path relative to CWD (so subdirectory-relative paths work),\n // then make it relative to the actual repo root (where .yggdrasil/ lives).\n const repoRoot = projectRootFromGraph(graph.rootPath);\n const rawPath = options.file.trim();\n const absolute = path.resolve(cwd, rawPath);\n const repoRelative = path.relative(repoRoot, absolute).split(path.sep).join('/');\n const result = findOwner(graph, repoRoot, repoRelative);\n\n if (!result.nodePath) {\n // Distinguish \"file doesn't exist\" from \"file exists but not mapped\"\n const absPath = path.resolve(repoRoot, result.file);\n let exists = true;\n try { await access(absPath); } catch { exists = false; }\n if (exists) {\n process.stdout.write(`${result.file} -> no graph coverage\\n`);\n } else {\n process.stdout.write(`${result.file} -> no graph coverage (file not found)\\n`);\n }\n } else {\n process.stdout.write(`${result.file} -> ${result.nodePath}\\n`);\n if (result.direct === false && result.mappingPath) {\n process.stdout.write(\n ` Plik nie ma własnego mapowania; kontekst pochodzi z nadrzędnego katalogu ${result.mappingPath}. Użyj: yg build-context --node ${result.nodePath}\\n`,\n );\n }\n }\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n","import type { Graph, Stage } from '../model/types.js';\nimport { execSync } from 'node:child_process';\nimport path from 'node:path';\n\nexport interface ResolveOptions {\n mode: 'all' | 'changed' | 'node';\n nodePath?: string; // required when mode === 'node'\n ref?: string; // git ref for --changed mode (default: HEAD)\n depth?: number; // max depth for tree (when mode === 'node')\n relationType?: 'structural' | 'event' | 'all'; // filter for tree\n}\n\nconst STRUCTURAL_RELATION_TYPES = new Set(['uses', 'calls', 'extends', 'implements']);\nconst EVENT_RELATION_TYPES = new Set(['emits', 'listens']);\n\n/** Expand changed set with direct dependents only (one level, no cascade) */\nfunction expandWithDependents(graph: Graph, changed: string[]): string[] {\n const dependents = new Map<string, string[]>();\n for (const [nodePath, node] of graph.nodes) {\n for (const rel of node.meta.relations ?? []) {\n if (!STRUCTURAL_RELATION_TYPES.has(rel.type)) continue;\n const deps = dependents.get(rel.target) ?? [];\n deps.push(nodePath);\n dependents.set(rel.target, deps);\n }\n }\n\n const result = new Set<string>(changed);\n for (const node of changed) {\n for (const dep of dependents.get(node) ?? []) {\n result.add(dep);\n }\n }\n\n return [...result];\n}\n\n/** Find nodes whose graph files have changed according to git */\nexport function findChangedNodes(graph: Graph, ref?: string): string[] {\n const gitRef = ref ?? 'HEAD';\n const yggDirName = path.basename(graph.rootPath);\n const projectRoot = path.dirname(graph.rootPath);\n\n let changedFiles: string[];\n try {\n const output = execSync(`git diff --name-only ${gitRef} -- ${yggDirName}/`, {\n cwd: projectRoot,\n encoding: 'utf-8',\n }).trim();\n changedFiles = output ? output.split('\\n') : [];\n } catch {\n // If git diff fails (no commits, not a repo, etc.), fall back to empty\n changedFiles = [];\n }\n\n // Map changed file paths back to node paths\n const changedNodePaths = new Set<string>();\n for (const filePath of changedFiles) {\n // filePath is like \".yggdrasil/auth/login-service/node.yaml\"\n // Strip the yggdrasil dir prefix to get \"auth/login-service/node.yaml\"\n const relative = filePath.startsWith(yggDirName + '/')\n ? filePath.slice(yggDirName.length + 1)\n : filePath;\n\n // Walk up directories to find matching node paths (nodes are under model/)\n const parts = relative.split('/');\n const modelIdx = parts.indexOf('model');\n const startIdx = modelIdx >= 0 ? modelIdx + 1 : 0;\n for (let i = parts.length - 1; i >= startIdx + 1; i--) {\n const candidate = parts.slice(startIdx, i).join('/');\n if (graph.nodes.has(candidate)) {\n changedNodePaths.add(candidate);\n break;\n }\n }\n }\n\n return expandWithDependents(graph, [...changedNodePaths]);\n}\n\n/** Collect node and its transitive dependencies (for --node mode) */\nexport function collectTransitiveDeps(graph: Graph, nodePath: string): string[] {\n return collectTransitiveDepsFiltered(graph, nodePath, undefined, 'structural');\n}\n\n/** Filter relation types for inclusion */\nfunction filterRelationType(relType: string, filter: 'structural' | 'event' | 'all'): boolean {\n if (filter === 'all') return true;\n if (filter === 'structural') return STRUCTURAL_RELATION_TYPES.has(relType);\n if (filter === 'event') return EVENT_RELATION_TYPES.has(relType);\n return false;\n}\n\n/** Collect transitive deps with depth and type filter */\nfunction collectTransitiveDepsFiltered(\n graph: Graph,\n nodePath: string,\n maxDepth: number | undefined,\n relationType: 'structural' | 'event' | 'all',\n): string[] {\n const node = graph.nodes.get(nodePath);\n if (!node) {\n throw new Error(`Node not found: ${nodePath}`);\n }\n\n const result = new Set<string>();\n const queue: Array<{ path: string; depth: number }> = [{ path: nodePath, depth: 0 }];\n\n while (queue.length > 0) {\n const { path: p, depth } = queue.shift()!;\n if (result.has(p)) continue;\n result.add(p);\n if (maxDepth !== undefined && depth >= maxDepth) continue;\n\n const n = graph.nodes.get(p)!;\n for (const rel of n.meta.relations ?? []) {\n if (!filterRelationType(rel.type, relationType)) continue;\n if (!graph.nodes.has(rel.target)) {\n throw new Error(`Relation target not found: ${rel.target}`);\n }\n if (!result.has(rel.target)) {\n queue.push({ path: rel.target, depth: depth + 1 });\n }\n }\n }\n\n return [...result];\n}\n\n/** Tree node for dependency tree output */\nexport interface DepTreeNode {\n nodePath: string;\n relationType: string;\n relationTarget?: string;\n blackbox: boolean;\n children: DepTreeNode[];\n}\n\n/** Build dependency tree for a node (spec format) */\nexport function buildDependencyTree(\n graph: Graph,\n nodePath: string,\n options: { depth?: number; relationType?: 'structural' | 'event' | 'all' } = {},\n): DepTreeNode[] {\n const node = graph.nodes.get(nodePath);\n if (!node) {\n throw new Error(`Node not found: ${nodePath}`);\n }\n\n const maxDepth = options.depth ?? Infinity;\n const typeFilter = options.relationType ?? 'all';\n\n function buildChildren(\n fromPath: string,\n currentDepth: number,\n branch: Set<string>,\n ): DepTreeNode[] {\n if (currentDepth >= maxDepth) return [];\n const fromNode = graph.nodes.get(fromPath)!;\n const children: DepTreeNode[] = [];\n for (const rel of fromNode.meta.relations ?? []) {\n if (!filterRelationType(rel.type, typeFilter)) continue;\n if (!graph.nodes.has(rel.target)) continue;\n if (branch.has(rel.target)) continue;\n const targetNode = graph.nodes.get(rel.target)!;\n const nextBranch = new Set(branch);\n nextBranch.add(rel.target);\n children.push({\n nodePath: rel.target,\n relationType: rel.type,\n relationTarget: fromPath,\n blackbox: targetNode.meta.blackbox ?? false,\n children: buildChildren(rel.target, currentDepth + 1, nextBranch),\n });\n }\n return children;\n }\n\n return buildChildren(nodePath, 0, new Set([nodePath]));\n}\n\n/** Format tree as text (spec format) */\nexport function formatDependencyTree(\n graph: Graph,\n nodePath: string,\n options: { depth?: number; relationType?: 'structural' | 'event' | 'all' } = {},\n): string {\n const roots = buildDependencyTree(graph, nodePath, options);\n const lines: string[] = [nodePath];\n\n function formatNode(node: DepTreeNode, prefix: string, isLast: boolean): void {\n const connector = isLast ? '└── ' : '├── ';\n const blackbox = node.blackbox ? ' ■ blackbox' : '';\n lines.push(`${prefix}${connector}${node.relationType} ${node.nodePath}${blackbox}`);\n const childPrefix = prefix + (isLast ? ' ' : '│ ');\n const lastIdx = node.children.length - 1;\n node.children.forEach((c, i) => formatNode(c, childPrefix, i === lastIdx));\n }\n\n roots.forEach((r, i) => formatNode(r, '', i === roots.length - 1));\n return lines.join('\\n');\n}\n\nexport async function resolveDeps(graph: Graph, options: ResolveOptions): Promise<Stage[]> {\n let candidatePaths: string[];\n\n switch (options.mode) {\n case 'all':\n candidatePaths = [...graph.nodes.keys()];\n break;\n case 'changed':\n candidatePaths = findChangedNodes(graph, options.ref);\n break;\n case 'node':\n candidatePaths = collectTransitiveDeps(graph, options.nodePath!);\n break;\n }\n\n candidatePaths = candidatePaths.filter((p) => {\n const node = graph.nodes.get(p)!;\n return !node.meta.blackbox && node.meta.mapping;\n });\n\n if (candidatePaths.length === 0) return [];\n\n const candidateSet = new Set(candidatePaths);\n\n // Validate relations: broken relation = target not in graph\n for (const p of candidatePaths) {\n const node = graph.nodes.get(p)!;\n for (const rel of node.meta.relations ?? []) {\n if (!graph.nodes.has(rel.target)) {\n throw new Error(`Relation target not found: ${rel.target}`);\n }\n }\n }\n\n const inDegree = new Map<string, number>();\n const dependents = new Map<string, string[]>();\n\n for (const p of candidatePaths) {\n inDegree.set(p, 0);\n dependents.set(p, []);\n }\n\n for (const p of candidatePaths) {\n const node = graph.nodes.get(p)!;\n for (const rel of node.meta.relations ?? []) {\n if (!STRUCTURAL_RELATION_TYPES.has(rel.type)) continue;\n if (candidateSet.has(rel.target)) {\n inDegree.set(p, (inDegree.get(p) ?? 0) + 1);\n dependents.get(rel.target)!.push(p);\n }\n }\n }\n\n const stages: Stage[] = [];\n let queue = candidatePaths.filter((p) => inDegree.get(p) === 0);\n let stageNum = 1;\n const processed = new Set<string>();\n\n while (queue.length > 0) {\n stages.push({\n stage: stageNum,\n parallel: queue.length > 1,\n nodes: [...queue],\n });\n\n const nextQueue: string[] = [];\n for (const nodePath of queue) {\n processed.add(nodePath);\n for (const dep of dependents.get(nodePath) ?? []) {\n inDegree.set(dep, (inDegree.get(dep) ?? 0) - 1);\n if (inDegree.get(dep) === 0) {\n nextQueue.push(dep);\n }\n }\n }\n\n queue = nextQueue;\n stageNum++;\n }\n\n if (processed.size < candidatePaths.length) {\n const cycleNodes = candidatePaths.filter((p) => !processed.has(p));\n throw new Error(`Circular dependency detected involving: ${cycleNodes.join(', ')}`);\n }\n\n return stages;\n}\n","import { Command } from 'commander';\nimport { loadGraph } from '../core/graph-loader.js';\nimport { formatDependencyTree } from '../core/dependency-resolver.js';\n\nexport function registerDepsCommand(program: Command): void {\n program\n .command('deps')\n .description('Show direct and transitive node dependencies')\n .requiredOption('--node <path>', 'Node path relative to .yggdrasil/model/')\n .option('--depth <n>', 'Maximum depth for tree (when using --node)', (v) => parseInt(v, 10))\n .option('--type <type>', 'Relation type filter: structural, event, all (default: all)', 'all')\n .action(async (options: { node: string; depth?: number; type?: string }) => {\n try {\n const graph = await loadGraph(process.cwd());\n const typeFilter =\n options.type === 'structural' || options.type === 'event' || options.type === 'all'\n ? options.type\n : 'all';\n const nodePath = options.node.trim().replace(/^\\.\\//, '').replace(/\\/+$/, '');\n const text = formatDependencyTree(graph, nodePath, {\n depth: options.depth,\n relationType: typeFilter,\n });\n process.stdout.write(text + '\\n');\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n","import { mkdtemp, rm } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport path from 'node:path';\nimport { execSync } from 'node:child_process';\nimport { loadGraph } from './graph-loader.js';\nimport type { Graph } from '../model/types.js';\n\n/**\n * Load graph from a git ref (e.g. HEAD) by extracting .yggdrasil to temp dir.\n * Returns null if not a git repo, ref doesn't exist, or .yggdrasil not in ref.\n */\nexport async function loadGraphFromRef(\n projectRoot: string,\n ref: string = 'HEAD',\n): Promise<Graph | null> {\n const yggPath = '.yggdrasil';\n let tmpDir: string | null = null;\n\n try {\n execSync(`git rev-parse ${ref}`, { cwd: projectRoot, stdio: 'pipe' });\n } catch {\n return null;\n }\n\n try {\n tmpDir = await mkdtemp(path.join(tmpdir(), 'ygg-git-'));\n const archivePath = path.join(tmpDir, 'archive.tar');\n execSync(`git archive ${ref} ${yggPath} -o \"${archivePath}\"`, {\n cwd: projectRoot,\n stdio: 'pipe',\n });\n execSync(`tar -xf \"${archivePath}\" -C \"${tmpDir}\"`, { stdio: 'pipe' });\n const graph = await loadGraph(tmpDir);\n return graph;\n } catch {\n return null;\n } finally {\n if (tmpDir) {\n await rm(tmpDir, { recursive: true, force: true });\n }\n }\n}\n","import { Command } from 'commander';\nimport { loadGraph } from '../core/graph-loader.js';\nimport { loadGraphFromRef } from '../core/graph-from-git.js';\nimport {\n buildContext,\n collectAncestors,\n collectEffectiveAspectIds,\n} from '../core/context-builder.js';\nimport { detectDrift } from '../core/drift-detector.js';\nimport type { Graph } from '../model/types.js';\n\nconst STRUCTURAL_TYPES = new Set(['uses', 'calls', 'extends', 'implements']);\n\nexport function collectReverseDependents(\n graph: Graph,\n targetNode: string,\n): {\n direct: string[];\n allDependents: string[];\n reverse: Map<string, Set<string>>;\n relationFrom: Map<string, { type: string; consumes?: string[] }>;\n} {\n const reverse = new Map<string, Set<string>>();\n const relationFrom = new Map<string, { type: string; consumes?: string[] }>();\n for (const [nodePath, node] of graph.nodes) {\n for (const rel of node.meta.relations ?? []) {\n if (!STRUCTURAL_TYPES.has(rel.type)) continue;\n const deps = reverse.get(rel.target) ?? new Set<string>();\n deps.add(nodePath);\n reverse.set(rel.target, deps);\n relationFrom.set(`${nodePath}->${rel.target}`, {\n type: rel.type,\n consumes: rel.consumes,\n });\n }\n }\n\n const direct = [...(reverse.get(targetNode) ?? [])].sort();\n const seen = new Set<string>(direct);\n const queue = [...direct];\n while (queue.length > 0) {\n const current = queue.shift()!;\n for (const next of reverse.get(current) ?? []) {\n if (seen.has(next)) continue;\n seen.add(next);\n queue.push(next);\n }\n }\n\n return {\n direct,\n allDependents: [...seen].sort(),\n reverse,\n relationFrom,\n };\n}\n\nexport function buildTransitiveChains(\n targetNode: string,\n direct: string[],\n allDependents: string[],\n reverse: Map<string, Set<string>>,\n): string[] {\n const directSet = new Set(direct);\n const transitiveOnly = allDependents.filter((t) => !directSet.has(t));\n if (transitiveOnly.length === 0) return [];\n\n const parent = new Map<string, string>();\n const queue: string[] = [targetNode];\n const visited = new Set<string>([targetNode]);\n while (queue.length > 0) {\n const current = queue.shift()!;\n for (const next of reverse.get(current) ?? []) {\n if (visited.has(next)) continue;\n visited.add(next);\n parent.set(next, current);\n queue.push(next);\n }\n }\n\n const chains: string[] = [];\n for (const node of transitiveOnly) {\n const path: string[] = [];\n let current: string | undefined = node;\n while (current) {\n path.unshift(current);\n current = parent.get(current);\n }\n if (path.length >= 3) {\n chains.push(path.slice(1).map((p) => `<- ${p}`).join(' '));\n }\n }\n return chains.sort();\n}\n\nexport function collectDescendants(graph: Graph, nodePath: string): string[] {\n const node = graph.nodes.get(nodePath);\n if (!node) return [];\n const result: string[] = [];\n const stack = [...node.children];\n while (stack.length > 0) {\n const child = stack.pop()!;\n result.push(child.path);\n stack.push(...child.children);\n }\n return result.sort();\n}\n\nasync function runSimulation(\n graph: Graph,\n nodePaths: Iterable<string>,\n targetNodePath: string | null,\n): Promise<void> {\n const budget = graph.config.quality?.context_budget ?? { warning: 10000, error: 20000 };\n process.stdout.write('\\nChanges in context packages:\\n\\n');\n const baselineGraph = await loadGraphFromRef(process.cwd(), 'HEAD');\n const driftReport = await detectDrift(graph);\n const driftByNode = new Map(driftReport.entries.map((e) => [e.nodePath, e]));\n\n for (const dep of nodePaths) {\n try {\n const pkg = await buildContext(graph, dep);\n const status =\n pkg.tokenCount >= budget.error\n ? 'error'\n : pkg.tokenCount >= budget.warning\n ? 'warning'\n : 'ok';\n\n let baselineTokens: number | null = null;\n if (baselineGraph?.nodes.has(dep)) {\n try {\n const baselinePkg = await buildContext(baselineGraph, dep);\n baselineTokens = baselinePkg.tokenCount;\n } catch {\n /* ignore */\n }\n }\n\n const hasDepOnTarget =\n targetNodePath &&\n graph.nodes\n .get(dep)\n ?.meta.relations?.some(\n (r) => r.target === targetNodePath && STRUCTURAL_TYPES.has(r.type),\n );\n const changedLine = hasDepOnTarget\n ? ` + Changed dependency interface: ${targetNodePath}\\n`\n : '';\n\n const budgetLine =\n baselineTokens !== null\n ? ` Budget: ${baselineTokens} -> ${pkg.tokenCount} tokens (${status})\\n`\n : ` Budget: ${pkg.tokenCount} tokens (${status})\\n`;\n\n const driftEntry = driftByNode.get(dep);\n const driftLine =\n driftEntry && driftEntry.status !== 'ok'\n ? ` Mapped files (on-disk): ${driftEntry.status}${driftEntry.details ? ` (${driftEntry.details})` : ''}\\n`\n : driftEntry\n ? ` Mapped files (on-disk): ok\\n`\n : '';\n\n process.stdout.write(`${dep}:\\n${changedLine}${budgetLine}${driftLine}\\n`);\n } catch {\n process.stdout.write(`${dep}:\\n failed to build context\\n\\n`);\n }\n }\n}\n\nasync function handleAspectImpact(\n graph: Graph,\n aspectId: string,\n simulate?: boolean,\n): Promise<void> {\n const aspect = graph.aspects.find((a) => a.id === aspectId);\n if (!aspect) {\n process.stderr.write(`Aspect not found: ${aspectId}\\n`);\n process.exit(1);\n }\n\n const affected: Array<{ path: string; source: string }> = [];\n for (const [nodePath] of graph.nodes) {\n const effective = collectEffectiveAspectIds(graph, nodePath);\n if (effective.has(aspectId)) {\n const node = graph.nodes.get(nodePath)!;\n const ownAspects = new Set(node.meta.aspects ?? []);\n if (ownAspects.has(aspectId)) {\n affected.push({ path: nodePath, source: 'own' });\n } else {\n let fromHierarchy = false;\n let anc = node.parent;\n while (anc) {\n if ((anc.meta.aspects ?? []).includes(aspectId)) {\n fromHierarchy = true;\n break;\n }\n anc = anc.parent;\n }\n if (fromHierarchy) {\n affected.push({ path: nodePath, source: `hierarchy from ${anc!.path}` });\n } else {\n const ancestorPaths = new Set([nodePath, ...collectAncestors(node).map((a) => a.path)]);\n const flow = graph.flows.find(\n (f) =>\n (f.aspects ?? []).includes(aspectId) &&\n f.nodes.some((n) => ancestorPaths.has(n)),\n );\n affected.push({ path: nodePath, source: flow ? `flow: ${flow.name}` : 'implied' });\n }\n }\n }\n }\n\n affected.sort((a, b) => a.path.localeCompare(b.path));\n\n const propagatingFlows = graph.flows\n .filter((f) => (f.aspects ?? []).includes(aspectId))\n .map((f) => f.name);\n\n const impliedBy = graph.aspects\n .filter((a) => (a.implies ?? []).includes(aspectId))\n .map((a) => a.id);\n const implies = aspect.implies ?? [];\n\n process.stdout.write(`Impact of changes in aspect ${aspectId}:\\n\\n`);\n process.stdout.write(`Affected nodes (${affected.length}):\\n`);\n if (affected.length === 0) {\n process.stdout.write(' (none)\\n');\n } else {\n for (const { path: p, source } of affected) {\n process.stdout.write(` ${p} (${source})\\n`);\n }\n }\n process.stdout.write(\n `\\nFlows propagating this aspect: ${propagatingFlows.length > 0 ? propagatingFlows.join(', ') : '(none)'}\\n`,\n );\n process.stdout.write(`Implied by: ${impliedBy.length > 0 ? impliedBy.join(', ') : '(none)'}\\n`);\n process.stdout.write(`Implies: ${implies.length > 0 ? implies.join(', ') : '(none)'}\\n`);\n process.stdout.write(`\\nTotal scope: ${affected.length} nodes, ${propagatingFlows.length} flows\\n`);\n\n if (simulate && affected.length > 0) {\n await runSimulation(\n graph,\n affected.map((a) => a.path),\n null,\n );\n }\n}\n\nasync function handleFlowImpact(\n graph: Graph,\n flowName: string,\n simulate?: boolean,\n): Promise<void> {\n const flow = graph.flows.find((f) => f.name === flowName || f.path === flowName);\n if (!flow) {\n process.stderr.write(`Flow not found: ${flowName}\\n`);\n process.exit(1);\n }\n\n const participants = new Set<string>();\n for (const nodePath of flow.nodes) {\n if (graph.nodes.has(nodePath)) {\n participants.add(nodePath);\n for (const desc of collectDescendants(graph, nodePath)) {\n participants.add(desc);\n }\n }\n }\n\n const sorted = [...participants].sort();\n const flowAspects = flow.aspects ?? [];\n\n process.stdout.write(`Impact of changes in flow ${flow.name}:\\n\\n`);\n process.stdout.write('Participants:\\n');\n if (sorted.length === 0) {\n process.stdout.write(' (none)\\n');\n } else {\n for (const p of sorted) {\n const isDeclared = flow.nodes.includes(p);\n const suffix = isDeclared ? '' : ' (descendant)';\n process.stdout.write(` ${p}${suffix}\\n`);\n }\n }\n process.stdout.write(\n `\\nFlow aspects: ${flowAspects.length > 0 ? flowAspects.join(', ') : '(none)'}\\n`,\n );\n process.stdout.write(`\\nTotal scope: ${sorted.length} nodes\\n`);\n\n if (simulate && sorted.length > 0) {\n await runSimulation(graph, sorted, null);\n }\n}\n\nexport function registerImpactCommand(program: Command): void {\n program\n .command('impact')\n .description('Show reverse dependency impact for a node, aspect, or flow')\n .option('--node <path>', 'Node path relative to .yggdrasil/model/')\n .option('--aspect <id>', 'Aspect id (directory path under aspects/)')\n .option('--flow <name>', 'Flow name (directory name under flows/)')\n .option('--simulate', 'Simulate context package impact (compare HEAD vs current)')\n .action(\n async (options: { node?: string; aspect?: string; flow?: string; simulate?: boolean }) => {\n try {\n const modeCount = [options.node, options.aspect, options.flow].filter(Boolean).length;\n if (modeCount === 0) {\n process.stderr.write(\n 'Error: one of --node, --aspect, or --flow is required\\n',\n );\n process.exit(1);\n }\n if (modeCount > 1) {\n process.stderr.write(\n 'Error: --node, --aspect, and --flow are mutually exclusive\\n',\n );\n process.exit(1);\n }\n\n const graph = await loadGraph(process.cwd());\n\n if (options.aspect) {\n await handleAspectImpact(graph, options.aspect.trim(), options.simulate);\n return;\n }\n if (options.flow) {\n await handleFlowImpact(graph, options.flow.trim(), options.simulate);\n return;\n }\n\n const nodePath = options.node!.trim().replace(/^\\.\\//, '').replace(/\\/+$/, '');\n\n if (!graph.nodes.has(nodePath)) {\n process.stderr.write(`Node not found: ${nodePath}\\n`);\n process.exit(1);\n }\n\n const { direct, allDependents, reverse, relationFrom } = collectReverseDependents(\n graph,\n nodePath,\n );\n const chains = buildTransitiveChains(nodePath, direct, allDependents, reverse);\n\n const flows: string[] = [];\n for (const flow of graph.flows) {\n if (flow.nodes.includes(nodePath)) {\n flows.push(flow.name);\n }\n }\n\n const targetEffective = collectEffectiveAspectIds(graph, nodePath);\n const aspectsInScope: string[] = [];\n for (const aspect of graph.aspects) {\n if (targetEffective.has(aspect.id)) {\n aspectsInScope.push(aspect.name);\n }\n }\n\n process.stdout.write(`Impact of changes in ${nodePath}:\\n\\n`);\n process.stdout.write('Directly dependent:\\n');\n if (direct.length === 0) {\n process.stdout.write(' (none)\\n');\n } else {\n for (const dep of direct) {\n const rel = relationFrom.get(`${dep}->${nodePath}`);\n const annot = rel?.consumes?.length\n ? ` (${rel.type}, you consume: ${rel.consumes.join(', ')})`\n : rel\n ? ` (${rel.type})`\n : '';\n process.stdout.write(` <- ${dep}${annot}\\n`);\n }\n }\n process.stdout.write('\\nTransitively dependent:\\n');\n if (chains.length === 0) {\n process.stdout.write(' (none)\\n');\n } else {\n for (const chain of chains) {\n process.stdout.write(` ${chain}\\n`);\n }\n }\n\n const descendants = collectDescendants(graph, nodePath);\n if (descendants.length > 0) {\n process.stdout.write('\\nDescendants (hierarchy impact):\\n');\n for (const desc of descendants) {\n process.stdout.write(` ${desc}\\n`);\n }\n }\n\n process.stdout.write(\n `\\nFlows: ${flows.length > 0 ? flows.join(', ') : '(none)'}\\n`,\n );\n process.stdout.write(\n `Aspects (scope covers node): ${aspectsInScope.length > 0 ? aspectsInScope.join(', ') : '(none)'}\\n`,\n );\n\n const coAspectNodes: Array<{ path: string; shared: string[] }> = [];\n if (targetEffective.size > 0) {\n for (const [p] of graph.nodes) {\n if (p === nodePath) continue;\n const nodeEffective = collectEffectiveAspectIds(graph, p);\n const shared = [...targetEffective].filter((id) => nodeEffective.has(id));\n if (shared.length > 0) {\n coAspectNodes.push({ path: p, shared });\n }\n }\n }\n if (coAspectNodes.length > 0) {\n process.stdout.write('Nodes sharing aspects:\\n');\n for (const { path: p, shared } of coAspectNodes.sort((a, b) =>\n a.path.localeCompare(b.path),\n )) {\n process.stdout.write(` ${p} (${shared.join(', ')})\\n`);\n }\n }\n\n const allAffected = new Set([...allDependents, ...descendants]);\n process.stdout.write(\n `\\nTotal scope: ${allAffected.size} nodes, ${flows.length} flows, ${aspectsInScope.length} aspects\\n`,\n );\n\n if (options.simulate && allAffected.size > 0) {\n await runSimulation(graph, allAffected, nodePath);\n }\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n },\n );\n}\n","import { Command } from 'commander';\nimport { stringify as yamlStringify } from 'yaml';\nimport { loadGraph } from '../core/graph-loader.js';\nimport { findYggRoot } from '../utils/paths.js';\n\nexport function registerAspectsCommand(program: Command): void {\n program\n .command('aspects')\n .description('List aspects with metadata (YAML output)')\n .action(async () => {\n try {\n const yggRoot = await findYggRoot(process.cwd());\n const graph = await loadGraph(yggRoot);\n const output = graph.aspects\n .sort((a, b) => a.id.localeCompare(b.id))\n .map((aspect) => {\n const entry: Record<string, unknown> = { id: aspect.id, name: aspect.name };\n if (aspect.description) entry.description = aspect.description;\n if (aspect.implies && aspect.implies.length > 0) entry.implies = aspect.implies;\n return entry;\n });\n process.stdout.write(yamlStringify(output));\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n if (err.code === 'ENOENT') {\n process.stderr.write(\n `Error: No .yggdrasil/ directory found. Run 'yg init' first.\\n`,\n );\n } else {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n }\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport { stringify as yamlStringify } from 'yaml';\nimport { loadGraph } from '../core/graph-loader.js';\nimport { findYggRoot } from '../utils/paths.js';\n\nexport function registerFlowsCommand(program: Command): void {\n program\n .command('flows')\n .description('List flows with metadata (YAML output)')\n .action(async () => {\n try {\n const yggRoot = await findYggRoot(process.cwd());\n const graph = await loadGraph(yggRoot);\n const output = graph.flows\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((flow) => {\n const entry: Record<string, unknown> = {\n name: flow.name,\n participants: flow.nodes.length,\n nodes: flow.nodes.sort(),\n };\n if (flow.aspects && flow.aspects.length > 0) entry.aspects = flow.aspects;\n return entry;\n });\n process.stdout.write(yamlStringify(output));\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n if (err.code === 'ENOENT') {\n process.stderr.write(\n `Error: No .yggdrasil/ directory found. Run 'yg init' first.\\n`,\n );\n } else {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n }\n process.exit(1);\n }\n });\n}\n","import { readFile, writeFile, mkdir, rename, access } from 'node:fs/promises';\nimport { parse as parseYaml, stringify as stringifyYaml } from 'yaml';\nimport path from 'node:path';\nimport type { JournalEntry } from '../model/types.js';\n\nconst JOURNAL_FILE = '.journal.yaml';\nconst ARCHIVE_DIR = 'journals-archive';\n\nexport async function readJournal(yggRoot: string): Promise<JournalEntry[]> {\n const filePath = path.join(yggRoot, JOURNAL_FILE);\n try {\n const content = await readFile(filePath, 'utf-8');\n const raw = parseYaml(content) as { entries?: JournalEntry[] };\n const entries = raw.entries ?? [];\n return Array.isArray(entries) ? entries : [];\n } catch {\n return [];\n }\n}\n\nexport async function appendJournalEntry(\n yggRoot: string,\n note: string,\n target?: string,\n): Promise<JournalEntry> {\n const entries = await readJournal(yggRoot);\n const at = new Date().toISOString();\n const entry: JournalEntry = target ? { at, target, note } : { at, note };\n\n entries.push(entry);\n\n const filePath = path.join(yggRoot, JOURNAL_FILE);\n const content = stringifyYaml({ entries });\n await writeFile(filePath, content, 'utf-8');\n\n return entry;\n}\n\nexport async function archiveJournal(\n yggRoot: string,\n): Promise<{ archiveName: string; entryCount: number } | null> {\n const journalPath = path.join(yggRoot, JOURNAL_FILE);\n try {\n await access(journalPath);\n } catch {\n return null;\n }\n\n const entries = await readJournal(yggRoot);\n if (entries.length === 0) return null;\n\n const archiveDir = path.join(yggRoot, ARCHIVE_DIR);\n await mkdir(archiveDir, { recursive: true });\n\n const now = new Date();\n const timestamp =\n `${now.getUTCFullYear()}` +\n `${String(now.getUTCMonth() + 1).padStart(2, '0')}` +\n `${String(now.getUTCDate()).padStart(2, '0')}` +\n `-` +\n `${String(now.getUTCHours()).padStart(2, '0')}` +\n `${String(now.getUTCMinutes()).padStart(2, '0')}` +\n `${String(now.getUTCSeconds()).padStart(2, '0')}`;\n const archiveName = `.journal.${timestamp}.yaml`;\n const archivePath = path.join(archiveDir, archiveName);\n\n await rename(journalPath, archivePath);\n\n return { archiveName, entryCount: entries.length };\n}\n","import { Command } from 'commander';\nimport { findYggRoot } from '../utils/paths.js';\nimport { appendJournalEntry, readJournal } from '../io/journal-store.js';\n\nexport function registerJournalAddCommand(program: Command): void {\n program\n .command('journal-add')\n .description('Add a note to the session journal')\n .requiredOption('--note <text>', 'Note content')\n .option('--target <node-path>', 'Node path this note relates to')\n .action(async (options: { note: string; target?: string }) => {\n try {\n const projectRoot = process.cwd();\n const yggRoot = await findYggRoot(projectRoot);\n await appendJournalEntry(yggRoot, options.note, options.target);\n const entries = await readJournal(yggRoot);\n process.stdout.write(`Note added to journal (${entries.length} entries total)\\n`);\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport { findYggRoot } from '../utils/paths.js';\nimport { readJournal } from '../io/journal-store.js';\n\nexport function registerJournalReadCommand(program: Command): void {\n program\n .command('journal-read')\n .description('List pending journal entries')\n .action(async () => {\n try {\n const projectRoot = process.cwd();\n const yggRoot = await findYggRoot(projectRoot);\n const entries = await readJournal(yggRoot);\n\n if (entries.length === 0) {\n process.stdout.write('Session journal: empty (clean state)\\n');\n return;\n }\n\n process.stdout.write(`Session journal (${entries.length} entries):\\n\\n`);\n for (const e of entries) {\n const date = e.at.slice(0, 19).replace('T', ' ');\n const target = e.target ? ` ${e.target}` : '';\n process.stdout.write(`[${date}]${target}\\n ${e.note}\\n\\n`);\n }\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport { findYggRoot } from '../utils/paths.js';\nimport { archiveJournal } from '../io/journal-store.js';\n\nexport function registerJournalArchiveCommand(program: Command): void {\n program\n .command('journal-archive')\n .description('Archive journal after consolidating notes to graph')\n .action(async () => {\n try {\n const projectRoot = process.cwd();\n const yggRoot = await findYggRoot(projectRoot);\n const result = await archiveJournal(yggRoot);\n\n if (!result) {\n process.stdout.write('No active journal - nothing to archive.\\n');\n return;\n }\n\n process.stdout.write(\n `Archived journal (${result.entryCount} entries) -> journals-archive/${result.archiveName}\\n`,\n );\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n","import { Command } from 'commander';\nimport { loadGraph } from '../core/graph-loader.js';\nimport { detectDrift } from '../core/drift-detector.js';\nimport { validate } from '../core/validator.js';\nimport { readJournal } from '../io/journal-store.js';\nimport { findYggRoot } from '../utils/paths.js';\nimport { normalizeMappingPaths } from '../utils/paths.js';\n\nexport function registerPreflightCommand(program: Command): void {\n program\n .command('preflight')\n .description('Unified diagnostic report: journal, drift, status, validation')\n .option('--quick', 'Skip drift detection for faster results')\n .action(async (options: { quick?: boolean }) => {\n try {\n const cwd = process.cwd();\n const graph = await loadGraph(cwd);\n const yggRoot = await findYggRoot(cwd);\n\n // --- Journal ---\n const journalEntries = await readJournal(yggRoot);\n\n // --- Drift ---\n const driftedEntries = options.quick\n ? []\n : (await detectDrift(graph)).entries.filter((e) => e.status !== 'ok');\n\n // --- Status counts ---\n const nodeCount = graph.nodes.size;\n const aspectCount = graph.aspects.length;\n const flowCount = graph.flows.length;\n let mappedPathCount = 0;\n for (const node of graph.nodes.values()) {\n mappedPathCount += normalizeMappingPaths(node.meta.mapping).length;\n }\n\n // --- Validation ---\n const validation = await validate(graph, 'all');\n const errors = validation.issues.filter((i) => i.severity === 'error');\n const warnings = validation.issues.filter((i) => i.severity === 'warning');\n\n // --- Build output ---\n const lines: string[] = [];\n lines.push('=== Preflight Report ===');\n lines.push('');\n\n // Journal section\n if (journalEntries.length === 0) {\n lines.push('Journal: clean');\n } else {\n lines.push(`Journal: ${journalEntries.length} pending entries`);\n for (const entry of journalEntries) {\n const target = entry.target ? ` [${entry.target}]` : '';\n lines.push(` - ${entry.note}${target}`);\n }\n }\n lines.push('');\n\n // Drift section\n if (options.quick) {\n lines.push('Drift: skipped (--quick)');\n } else if (driftedEntries.length === 0) {\n lines.push('Drift: clean');\n } else {\n lines.push(`Drift: ${driftedEntries.length} nodes need attention`);\n for (const entry of driftedEntries) {\n lines.push(` - ${entry.nodePath}: ${entry.status}`);\n }\n }\n lines.push('');\n\n // Status section\n lines.push(\n `Status: ${nodeCount} nodes, ${aspectCount} aspects, ${flowCount} flows, ${mappedPathCount} mapped paths`,\n );\n if (nodeCount === 0) {\n lines.push('');\n lines.push(' ⚡ No nodes found. Enter BOOTSTRAP MODE:');\n lines.push(' Create nodes under .yggdrasil/model/ for your active work area.');\n lines.push(' See: yg help build-context');\n }\n lines.push('');\n\n // Validation section\n if (errors.length === 0 && warnings.length === 0) {\n lines.push('Validation: clean');\n } else {\n const parts: string[] = [];\n if (errors.length > 0) parts.push(`${errors.length} errors`);\n if (warnings.length > 0) parts.push(`${warnings.length} warnings`);\n lines.push(`Validation: ${parts.join(', ')}`);\n for (const issue of [...errors, ...warnings]) {\n const code = issue.code ? `[${issue.code}] ` : '';\n const loc = issue.nodePath ? `${issue.nodePath} -> ` : '';\n lines.push(` - ${code}${loc}${issue.message}`);\n }\n }\n lines.push('');\n\n process.stdout.write(lines.join('\\n'));\n\n // Exit code: 1 if journal entries, drift, or validation errors exist.\n // Warnings alone do not cause exit 1.\n const hasIssues =\n journalEntries.length > 0 || (!options.quick && driftedEntries.length > 0) || errors.length > 0;\n process.exit(hasIssues ? 1 : 0);\n } catch (error) {\n process.stderr.write(`Error: ${(error as Error).message}\\n`);\n process.exit(1);\n }\n });\n}\n"],"mappings":"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","names":["mkdir","writeFile","readFile","path","path","program","rulesPath","mkdir","readFile","writeFile","readdir","readFile","path","readFile","readFile","parseYaml","readFile","parseYaml","readFile","readdir","path","readFile","parseYaml","readFile","path","parseYaml","readFile","parseYaml","path","readFile","path","parseYaml","path","fileURLToPath","stat","path","stat","path","path","path","readdir","readFile","readFile","path","path","readFile","readdir","path","path","access","readdir","pkg","pkg","program","pkg","program","chalk","readFile","writeFile","path","readFile","readdir","stat","path","require","readFile","path","path","stat","readFile","readdir","path","STRUCTURAL_RELATION_TYPES","path","collectParticipatingFlows","path","program","chalk","chalk","program","chalk","program","program","path","path","access","program","path","access","path","STRUCTURAL_RELATION_TYPES","EVENT_RELATION_TYPES","STRUCTURAL_RELATION_TYPES","EVENT_RELATION_TYPES","program","path","execSync","execSync","path","path","pkg","program","program","yamlStringify","program","yamlStringify","readFile","writeFile","mkdir","access","parseYaml","path","program","program","program","program","fileURLToPath"]}
|