@thanh01.pmt/domain-kit 0.2.1 → 0.4.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.
Files changed (51) hide show
  1. package/README.md +42 -11
  2. package/dist/{chunk-CRN6D4HG.mjs → chunk-HILSUZOF.mjs} +32 -8
  3. package/dist/chunk-HILSUZOF.mjs.map +1 -0
  4. package/dist/{chunk-23TQPTHG.mjs → chunk-LZQLLAYP.mjs} +5 -5
  5. package/dist/{chunk-23TQPTHG.mjs.map → chunk-LZQLLAYP.mjs.map} +1 -1
  6. package/dist/{chunk-HH4UX65C.mjs → chunk-PKUEOSZ3.mjs} +42 -4
  7. package/dist/chunk-PKUEOSZ3.mjs.map +1 -0
  8. package/dist/{chunk-HUDFN4IX.mjs → chunk-QJF4QCBJ.mjs} +99 -4
  9. package/dist/chunk-QJF4QCBJ.mjs.map +1 -0
  10. package/dist/{chunk-WHBAGJWN.mjs → chunk-VCPIWJ7R.mjs} +4 -4
  11. package/dist/chunk-VCPIWJ7R.mjs.map +1 -0
  12. package/dist/curriculumFeedEmitter-6IK6PFDH.mjs +4 -0
  13. package/dist/{curriculumFeedEmitter-E5DAJYUZ.mjs.map → curriculumFeedEmitter-6IK6PFDH.mjs.map} +1 -1
  14. package/dist/{curriculumFeedSchema-TEeQg2bY.d.ts → curriculumFeedSchema-B66H3gEV.d.cts} +148 -8
  15. package/dist/{curriculumFeedSchema-TEeQg2bY.d.cts → curriculumFeedSchema-B66H3gEV.d.ts} +148 -8
  16. package/dist/feed/index.cjs +136 -3
  17. package/dist/feed/index.cjs.map +1 -1
  18. package/dist/feed/index.d.cts +1 -1
  19. package/dist/feed/index.d.ts +1 -1
  20. package/dist/feed/index.mjs +2 -2
  21. package/dist/graph/index.cjs +30 -5
  22. package/dist/graph/index.cjs.map +1 -1
  23. package/dist/graph/index.d.cts +2 -2
  24. package/dist/graph/index.d.ts +2 -2
  25. package/dist/graph/index.mjs +1 -1
  26. package/dist/{hybridGraphPipeline-DVZYLCAQ.d.ts → hybridGraphPipeline-DXQDbBEj.d.ts} +14 -2
  27. package/dist/{hybridGraphPipeline-DmWRKYXf.d.cts → hybridGraphPipeline-dT-bio-3.d.cts} +14 -2
  28. package/dist/{hybridGraphSchema-BCgXicgA.d.ts → hybridGraphSchema-nrUeSwpU.d.cts} +15 -15
  29. package/dist/{hybridGraphSchema-BCgXicgA.d.cts → hybridGraphSchema-nrUeSwpU.d.ts} +15 -15
  30. package/dist/index.cjs +168 -10
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.cts +3 -3
  33. package/dist/index.d.ts +3 -3
  34. package/dist/index.mjs +5 -5
  35. package/dist/pipeline/index.cjs +165 -8
  36. package/dist/pipeline/index.cjs.map +1 -1
  37. package/dist/pipeline/index.d.cts +3 -3
  38. package/dist/pipeline/index.d.ts +3 -3
  39. package/dist/pipeline/index.mjs +4 -4
  40. package/dist/schemas/index.cjs +42 -4
  41. package/dist/schemas/index.cjs.map +1 -1
  42. package/dist/schemas/index.d.cts +2 -2
  43. package/dist/schemas/index.d.ts +2 -2
  44. package/dist/schemas/index.mjs +2 -2
  45. package/package.json +10 -9
  46. package/LICENSE +0 -21
  47. package/dist/chunk-CRN6D4HG.mjs.map +0 -1
  48. package/dist/chunk-HH4UX65C.mjs.map +0 -1
  49. package/dist/chunk-HUDFN4IX.mjs.map +0 -1
  50. package/dist/chunk-WHBAGJWN.mjs.map +0 -1
  51. package/dist/curriculumFeedEmitter-E5DAJYUZ.mjs +0 -4
@@ -1,8 +1,8 @@
1
- import { emitCurriculumFeed } from './chunk-HUDFN4IX.mjs';
1
+ import { emitCurriculumFeed } from './chunk-QJF4QCBJ.mjs';
2
2
  import { parseSwiftFile, parseTsFile, parsePythonFile, parseCppFile, mergeSwiftResults, mergeTsResults, mergePythonResults, mergeCppResults } from './chunk-DRVOV5ZD.mjs';
3
3
  import { extractKeywords } from './chunk-XMHKWHVK.mjs';
4
4
  import { detectDomainProfile } from './chunk-BL5NBKPH.mjs';
5
- import { extractScaffold, extractProjectOverview, extractFeatureStepsBatched, extractFeatureSteps, verifyProjectGraph, escalateAndMapConcepts, generateKnowledgeGraph, generateHybridGraph, createLlmClient, llmChatJson } from './chunk-CRN6D4HG.mjs';
5
+ import { extractScaffold, extractProjectOverview, extractFeatureStepsBatched, extractFeatureSteps, verifyProjectGraph, escalateAndMapConcepts, generateKnowledgeGraph, generateHybridGraph, createLlmClient, llmChatJson } from './chunk-HILSUZOF.mjs';
6
6
  import { parseSyllabus } from './chunk-T4Y2DE2W.mjs';
7
7
  import { resolveConcepts } from './chunk-KNDBODUQ.mjs';
8
8
  import { assembleRoadmap } from './chunk-ONQHJ4OH.mjs';
@@ -597,7 +597,7 @@ async function runDomainPipeline(options) {
597
597
  embeddings: options.embeddings,
598
598
  onProgress: options.onProgress
599
599
  });
600
- const { emitCurriculumFeed: emitCurriculumFeed2 } = await import('./curriculumFeedEmitter-E5DAJYUZ.mjs');
600
+ const { emitCurriculumFeed: emitCurriculumFeed2 } = await import('./curriculumFeedEmitter-6IK6PFDH.mjs');
601
601
  const curriculumFeed = emitCurriculumFeed2(projectResult.projectGraph, {
602
602
  warnings
603
603
  });
@@ -611,5 +611,5 @@ async function runDomainPipeline(options) {
611
611
  }
612
612
 
613
613
  export { runDomainPipeline, runHybridGraphPipeline, runKnowledgeGraphPipeline, runProjectGraphPipeline };
614
- //# sourceMappingURL=chunk-23TQPTHG.mjs.map
615
- //# sourceMappingURL=chunk-23TQPTHG.mjs.map
614
+ //# sourceMappingURL=chunk-LZQLLAYP.mjs.map
615
+ //# sourceMappingURL=chunk-LZQLLAYP.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/extractors/fileSelector.ts","../src/utils/fileUtils.ts","../src/pipeline/projectGraphPipeline.ts","../src/pipeline/knowledgeGraphPipeline.ts","../src/pipeline/hybridGraphPipeline.ts","../src/pipeline/domainRouter.ts"],"names":["relative","projectResult","emitCurriculumFeed"],"mappings":"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","file":"chunk-23TQPTHG.mjs","sourcesContent":["/**\n * LLM-based File Selector — sends file tree to LLM, asks it to pick\n * which files are most relevant to the project goal.\n *\n * This mirrors knowledge-tree's approach:\n * 1. git_tracker generates project_structure.txt (file tree)\n * 2. Agent/LLM reads tree → selects important files\n * 3. Only selected files are read for analysis\n */\n\nimport { createLlmClient, llmChatJson, type LlmClientConfig } from '../utils/llmClient';\n\nexport interface FileSelectionResult {\n selected: string[];\n reasoning: string;\n}\n\n/**\n * Ask LLM to select which files from the file tree are relevant to the goal.\n * Input: file tree (names only, very small) + goal\n * Output: list of file paths to analyze\n */\nexport async function selectFilesWithLlm(\n filePaths: string[],\n goal: string,\n techStack: string,\n llmConfig?: LlmClientConfig,\n): Promise<FileSelectionResult> {\n // If very few files, no need to filter\n if (filePaths.length <= 15) {\n return { selected: filePaths, reasoning: 'Too few files to filter' };\n }\n\n const client = createLlmClient(llmConfig);\n\n // Build file tree for LLM (just names, grouped by directory)\n const treeLines = buildFileTree(filePaths);\n\n const systemPrompt = (\n 'You are a software architect analyzing a project repository.\\n'\n + 'Given a file tree and a project goal, select which files are MOST IMPORTANT '\n + 'to read for understanding the project architecture and implementation.\\n\\n'\n + 'RULES:\\n'\n + '1. Prioritize source code files (Swift, TS, Python, C++) over config/docs\\n'\n + '2. Include entry points (App.swift, main.py, index.ts)\\n'\n + '3. Include core domain files (models, services, views, controllers)\\n'\n + '4. EXCLUDE test files, mock files, generated files\\n'\n + '5. EXCLUDE config files (package.json, Podfile, etc.) unless they reveal architecture\\n'\n + '6. Include files that directly implement the features mentioned in the goal\\n'\n + '7. Return 20-40 files maximum (fewer is better if the project is small)\\n\\n'\n + 'Return JSON: {\"selected\": [\"path/to/file1\", \"path/to/file2\"], \"reasoning\": \"brief explanation\"}'\n );\n\n const userPrompt = (\n `Project goal: ${goal}\\n`\n + `Tech stack: ${techStack}\\n\\n`\n + `FILE TREE (${filePaths.length} files):\\n${treeLines}\\n\\n`\n + 'Select the most important files to analyze. Return JSON.'\n );\n\n try {\n const result = await llmChatJson(client, systemPrompt, userPrompt, {\n temperature: 0.1,\n maxTokens: 4096,\n });\n\n const selected = Array.isArray(result.selected) ? result.selected as string[] : [];\n const reasoning = String(result.reasoning || '');\n\n // Validate: only keep files that exist in the original list\n const pathSet = new Set(filePaths);\n const validSelected = selected.filter(p => pathSet.has(p));\n\n if (validSelected.length === 0) {\n // LLM returned nothing valid — fallback to all files\n return { selected: filePaths, reasoning: 'LLM selection empty, using all files' };\n }\n\n return { selected: validSelected, reasoning };\n } catch (err) {\n console.warn(`[WARN] LLM file selection failed (${err}), using all files`);\n return { selected: filePaths, reasoning: `LLM failed: ${err}` };\n }\n}\n\n/**\n * Build a compact file tree string for LLM consumption.\n * Groups files by top-level directory, shows only filenames.\n */\nfunction buildFileTree(filePaths: string[]): string {\n const byDir = new Map<string, string[]>();\n\n for (const fp of filePaths) {\n const parts = fp.split('/');\n const dir = parts.length > 1 ? parts.slice(0, -1).join('/') : '(root)';\n const file = parts[parts.length - 1];\n if (!byDir.has(dir)) byDir.set(dir, []);\n byDir.get(dir)!.push(file);\n }\n\n const lines: string[] = [];\n for (const [dir, files] of byDir) {\n lines.push(`${dir}/`);\n for (const f of files.sort()) {\n lines.push(` ${f}`);\n }\n }\n\n return lines.join('\\n');\n}\n","/**\n * File I/O utilities for domain-kit pipeline.\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, statSync } from 'node:fs';\nimport { join, extname, relative, resolve } from 'node:path';\nimport { execSync } from 'node:child_process';\n\n/**\n * Read JSON file safely, returns null if not found or invalid.\n */\nexport function readJsonFile<T = unknown>(filePath: string): T | null {\n try {\n if (!existsSync(filePath)) return null;\n const content = readFileSync(filePath, 'utf-8');\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n\n/**\n * Write JSON file, creating parent directories if needed.\n */\nexport function writeJsonFile(filePath: string, data: unknown): void {\n mkdirSync(join(filePath, '..'), { recursive: true });\n writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');\n}\n\n/**\n * Read text file safely, returns null if not found.\n */\nexport function readTextFile(filePath: string): string | null {\n try {\n if (!existsSync(filePath)) return null;\n return readFileSync(filePath, 'utf-8');\n } catch {\n return null;\n }\n}\n\n/**\n * Collect source files from a directory, filtering by allowed extensions.\n */\nexport function collectSourceFiles(\n dir: string,\n options?: {\n allowedExtensions?: string[];\n skipDirs?: string[];\n maxFiles?: number;\n },\n): string[] {\n const allowedExts = options?.allowedExtensions || ['.swift', '.ts', '.tsx', '.js', '.jsx', '.py', '.ino', '.cpp', '.c', '.h', '.hpp'];\n const maxFiles = options?.maxFiles || 70;\n\n // Try git ls-files first — respects .gitignore, handles submodules, symlinks\n const gitFiles = collectViaGit(dir, allowedExts, maxFiles);\n if (gitFiles.length > 0) return gitFiles;\n\n // Fallback: filesystem walk (non-git directories)\n return collectViaFilesystem(dir, allowedExts, maxFiles, options?.skipDirs);\n}\n\n/**\n * Collect source files using `git ls-files`.\n * Respects .gitignore, handles symlinks, much faster than walk.\n */\nfunction collectViaGit(dir: string, allowedExts: string[], maxFiles: number): string[] {\n try {\n const raw = execSync('git ls-files --cached --others --exclude-standard', {\n cwd: dir,\n encoding: 'utf-8',\n timeout: 5000,\n maxBuffer: 1024 * 1024,\n });\n const extSet = new Set(allowedExts.map(e => e.toLowerCase()));\n return raw\n .split('\\n')\n .filter(line => line.length > 0)\n .filter(line => extSet.has(extname(line).toLowerCase()))\n .slice(0, maxFiles)\n .map(rel => join(dir, rel));\n } catch {\n // Not a git repo or git not available — fall through to filesystem walk\n return [];\n }\n}\n\n/**\n * Collect source files using recursive directory walk (non-git fallback).\n */\nfunction collectViaFilesystem(\n dir: string,\n allowedExts: string[],\n maxFiles: number,\n skipDirs?: string[],\n): string[] {\n const skipSet = new Set(skipDirs || [\n 'node_modules', '.build', 'Pods', '.git', '.venv', 'venv',\n '__pycache__', 'build', 'dist', '.idea', '.vscode',\n 'test', 'tests', 'demo', 'sample', 'example', 'playground',\n ]);\n const extSet = new Set(allowedExts.map(e => e.toLowerCase()));\n const result: string[] = [];\n\n function walk(currentDir: string) {\n if (result.length >= maxFiles) return;\n let entries;\n try {\n entries = readdirSync(currentDir, { withFileTypes: true });\n } catch {\n return; // permission error\n }\n for (const entry of entries) {\n if (result.length >= maxFiles) return;\n const fullPath = join(currentDir, entry.name);\n if (entry.isDirectory()) {\n if (!skipSet.has(entry.name)) {\n walk(fullPath);\n }\n } else if (entry.isFile()) {\n const ext = extname(entry.name).toLowerCase();\n if (extSet.has(ext)) {\n result.push(fullPath);\n }\n }\n }\n }\n\n walk(dir);\n return result;\n}\n\n/**\n * Collect file contents map (relative path → content).\n */\nexport function collectFileContents(\n dir: string,\n options?: {\n allowedExtensions?: string[];\n skipDirs?: string[];\n maxFiles?: number;\n maxChars?: number;\n },\n): { paths: string[]; contents: Map<string, string> } {\n const maxChars = options?.maxChars || 500000;\n const files = collectSourceFiles(dir, options);\n const contents = new Map<string, string>();\n let totalChars = 0;\n\n for (const filePath of files) {\n const relPath = relative(dir, filePath);\n try {\n const content = readFileSync(filePath, 'utf-8');\n if (totalChars + content.length > maxChars) {\n const remaining = maxChars - totalChars;\n if (remaining > 100) {\n contents.set(relPath, content.slice(0, remaining));\n totalChars += remaining;\n }\n break;\n }\n contents.set(relPath, content);\n totalChars += content.length;\n } catch {\n // Skip unreadable files\n }\n }\n\n return { paths: files.map(f => relative(dir, f)), contents };\n}\n\n/**\n * Read contents of SPECIFIC files (by relative path) — no directory scan.\n * Used for 2-pass approach: scan tree first, then read only selected files.\n */\nexport function collectSpecificFileContents(\n dir: string,\n relativePaths: string[],\n maxChars: number = 500000,\n): Map<string, string> {\n const contents = new Map<string, string>();\n let totalChars = 0;\n\n for (const relPath of relativePaths) {\n const fullPath = join(dir, relPath);\n try {\n const content = readFileSync(fullPath, 'utf-8');\n if (totalChars + content.length > maxChars) {\n const remaining = maxChars - totalChars;\n if (remaining > 100) {\n contents.set(relPath, content.slice(0, remaining));\n totalChars += remaining;\n }\n break;\n }\n contents.set(relPath, content);\n totalChars += content.length;\n } catch {\n // Skip unreadable files\n }\n }\n\n return contents;\n}\n\n/**\n * Detect primary language from file extensions.\n */\nexport function detectPrimaryLanguage(filePaths: string[]): string {\n const counts = new Map<string, number>();\n for (const fp of filePaths) {\n const ext = extname(fp).toLowerCase();\n let lang = 'unknown';\n if (ext === '.swift') lang = 'Swift';\n else if (ext === '.ts' || ext === '.tsx') lang = 'TypeScript';\n else if (ext === '.js' || ext === '.jsx') lang = 'JavaScript';\n else if (ext === '.py') lang = 'Python';\n else if (ext === '.ino' || ext === '.cpp' || ext === '.c' || ext === '.h') lang = 'C++';\n else if (ext === '.kt' || ext === '.kts') lang = 'Kotlin';\n counts.set(lang, (counts.get(lang) || 0) + 1);\n }\n\n let maxCount = 0;\n let primary = 'unknown';\n for (const [lang, count] of counts) {\n if (count > maxCount) {\n maxCount = count;\n primary = lang;\n }\n }\n return primary;\n}\n\n/**\n * Read README.md and extract project description.\n */\nexport function readReadmeDescription(repoDir: string): string | null {\n const readmePath = join(repoDir, 'README.md');\n if (!existsSync(readmePath)) return null;\n try {\n const content = readFileSync(readmePath, 'utf-8');\n const lines = content.split('\\n').map(l => l.trim()).filter(Boolean);\n // Skip patterns: badges, images, table of contents, HTML tags\n const skipPatterns = [/^\\[!/, /^<img/, /^<a /, /^#+\\s+Table of/i, /^---$/];\n let foundTitle = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line.startsWith('#') && !line.startsWith('##')) {\n foundTitle = true;\n continue;\n }\n if (!foundTitle) continue;\n // Skip empty lines, badges, images, TOC, horizontal rules\n if (skipPatterns.some(p => p.test(line))) continue;\n if (line.startsWith('#')) return null; // hit next heading — no description found\n if (line.startsWith('```')) return null; // code block\n if (line.startsWith('|')) return null; // table\n if (line.length > 15) return line;\n }\n return null;\n } catch {\n return null;\n }\n}\n","/**\n * Project Graph Pipeline — full orchestrator.\n *\n * Ported from knowledge-tree/generate_roadmap_v3.py PipelineOrchestrator\n * Coordinates: AST analysis → keyword extraction → LLM graph generation →\n * verification → concept escalation → concept resolution → assembly.\n */\n\nimport type { ProjectGraph, Feature } from '../schemas/projectGraphSchema';\nimport { parseSwiftFile, mergeSwiftResults, type SwiftParseResult } from '../parsers/swift';\nimport { parseTsFile, mergeTsResults, type TsParseResult } from '../parsers/typescript';\nimport { parsePythonFile, mergePythonResults, type PythonParseResult } from '../parsers/python';\nimport { parseCppFile, mergeCppResults, type CppParseResult } from '../parsers/cpp';\nimport { extractKeywords, type Keyword, type SourceContext } from '../extractors/keywordExtractor';\nimport { extractScaffold } from '../graph/scaffoldExtractor';\nimport { extractProjectOverview } from '../graph/overviewExtractor';\nimport { extractFeatureSteps, extractFeatureStepsBatched } from '../graph/stepExtractor';\nimport { verifyProjectGraph, type Hallucination } from '../graph/graphVerifier';\nimport { escalateAndMapConcepts, type ConceptMapping } from '../graph/conceptEscalator';\nimport { resolveConcepts, type ResolveConceptsResult } from '../concepts/conceptResolver';\nimport { assembleRoadmap, type AssembledRoadmap } from '../assembly/roadmapAssembler';\nimport { selectFilesWithLlm } from '../extractors/fileSelector';\nimport { collectSourceFiles, collectSpecificFileContents, detectPrimaryLanguage, readReadmeDescription } from '../utils/fileUtils';\nimport { relative } from 'node:path';\nimport { createLlmClient, type LlmClientConfig } from '../utils/llmClient';\n\nexport interface PipelineOptions {\n repoDir: string;\n goal: string;\n techStack: string;\n llmConfig?: LlmClientConfig;\n embeddings?: Record<string, { embedding?: number[]; name?: string; description?: string; keywords?: string }>;\n onProgress?: (step: string, message: string) => void;\n}\n\nexport interface PipelineResult {\n projectGraph: ProjectGraph;\n resolvedConcepts: ResolveConceptsResult;\n roadmap: AssembledRoadmap;\n hallucinations: Hallucination[];\n keywords: Keyword[];\n featureConcepts: Map<string, ConceptMapping[]>;\n}\n\n/**\n * Run the full project graph generation pipeline.\n */\nexport async function runProjectGraphPipeline(\n options: PipelineOptions,\n): Promise<PipelineResult> {\n const { repoDir, goal, techStack, llmConfig, embeddings, onProgress } = options;\n\n const log = (step: string, msg: string) => {\n console.log(`[${step}] ${msg}`);\n onProgress?.(step, msg);\n };\n\n // ─── STEP 1A: File Tree Scan (names only — no content reading) ─────────\n log('STEP_1', 'Scanning file tree (names only)...');\n\n const allFilePaths = collectSourceFiles(repoDir);\n const allRelPaths = allFilePaths.map(fp => relative(repoDir, fp));\n log('STEP_1', `Found ${allRelPaths.length} source files in repository`);\n\n // ─── STEP 1B: LLM File Selection (sends tiny file tree to LLM) ────────\n log('STEP_1', 'Asking LLM to select relevant files from file tree...');\n\n const { selected: selectedPaths, reasoning } = await selectFilesWithLlm(\n allRelPaths, goal, techStack, llmConfig,\n );\n log('STEP_1', `LLM selected ${selectedPaths.length}/${allRelPaths.length} files: ${reasoning.slice(0, 100)}`);\n\n // ─── STEP 1C: Read content only for LLM-selected files ─────────────────\n log('STEP_1', 'Reading content for selected files...');\n\n const fileContentsMap = collectSpecificFileContents(repoDir, selectedPaths);\n const filePaths = selectedPaths;\n const primaryLang = detectPrimaryLanguage(filePaths);\n log('STEP_1', `Primary language: ${primaryLang}, ${filePaths.length} files loaded (${fileContentsMap.size} with content)`);\n\n // Parse source files\n log('STEP_1', 'Parsing source files with AST-level analysis...');\n\n const allParseResults: SourceContext[] = [];\n for (const [relPath, content] of fileContentsMap) {\n const fullPath = relPath;\n if (fullPath.endsWith('.swift')) {\n allParseResults.push(parseSwiftFile(fullPath, content));\n } else if (fullPath.endsWith('.ts') || fullPath.endsWith('.tsx') || fullPath.endsWith('.js') || fullPath.endsWith('.jsx')) {\n allParseResults.push(parseTsFile(fullPath, content));\n } else if (fullPath.endsWith('.py')) {\n allParseResults.push(parsePythonFile(fullPath, content));\n } else if (fullPath.endsWith('.ino') || fullPath.endsWith('.cpp') || fullPath.endsWith('.c') || fullPath.endsWith('.h')) {\n allParseResults.push(parseCppFile(fullPath, content));\n }\n }\n\n // Merge parse results by language\n let mergedContext: SourceContext;\n if (primaryLang === 'Swift') {\n mergedContext = mergeSwiftResults(allParseResults.filter((r): r is SwiftParseResult => 'property_wrappers' in r));\n } else if (primaryLang === 'TypeScript' || primaryLang === 'JavaScript') {\n mergedContext = mergeTsResults(allParseResults.filter((r): r is TsParseResult => !('docstrings' in r) && !('property_wrappers' in r) && !('frameworks_used' in r)));\n } else if (primaryLang === 'Python') {\n mergedContext = mergePythonResults(allParseResults.filter((r): r is PythonParseResult => 'docstrings' in r));\n } else {\n mergedContext = mergeCppResults(allParseResults.filter((r): r is CppParseResult => 'error_handling' in r && !('docstrings' in r) && !('property_wrappers' in r)));\n }\n\n // ─── STEP 2: Keyword Extraction ──────────────────────────────────────────\n log('STEP_2', 'Extracting keywords from AST analysis...');\n\n const astKeywords = extractKeywords(mergedContext);\n log('STEP_2', `Extracted ${astKeywords.length} keywords`);\n\n // ─── STEP 3: Build SDK API Index (simplified — use AST keywords as proxy) ──\n log('STEP_3', 'Building SDK API index...');\n\n const sdkApiIndex = {\n sdk_apis: astKeywords.map(kw => ({\n name: kw.keyword,\n kind: kw.source,\n used_in_demo: true,\n })),\n };\n\n // ─── STEP 4: LLM Project Graph Generation ────────────────────────────────\n log('STEP_4', 'Generating project graph via LLM (C0: Scaffold, C1: Overview, C2: Steps)...');\n\n // C0: Scaffold (F0) — uses file list (names only, not content)\n log('STEP_4_C0', 'Extracting FOUNDATION & SETUP feature (F0)...');\n const scaffoldFeature = await extractScaffold({\n goal,\n techStack,\n fileList: filePaths,\n llmConfig,\n });\n\n // C1: Overview (features meta) — uses already-filtered fileContentsMap\n log('STEP_4_C1', 'Extracting project overview (features meta)...');\n const overview = await extractProjectOverview({\n goal,\n techStack,\n sdkApiIndex,\n fileContentsMap,\n astKeywords,\n llmConfig,\n });\n\n // Build PBL step (Design Thinking)\n const product = overview.product as Record<string, unknown> | undefined;\n const pblStep: Feature['steps'] extends (infer T)[] ? T : never = {\n id: 'F0-S1',\n sequence: 1,\n name: 'Frame the problem & understand user needs (Design Thinking)',\n description: 'BEFORE CODING — frame the problem and understand what the user needs',\n files: [],\n api_usage: [],\n keywords: ['Design Thinking', 'User Needs', 'Problem Statement', 'User Journey', 'PBL'],\n completion_level: 'base',\n platform: 'app',\n intent: 'Understand user needs and frame problem before writing code',\n outcome: { user_visible: 'Defined problem statement', technical: 'Problem frame context' },\n acceptance: ['Problem statement is clear', 'Primary users identified'],\n requirement_ids: [],\n concept_codes: [],\n effort: { estimated_minutes: 15, complexity: 'low' },\n };\n\n // Merge scaffold F0 with PBL step\n let featuresFull: Feature[] = [];\n if (scaffoldFeature) {\n const scaffoldSteps = [pblStep, ...(scaffoldFeature.steps || [])].map((s, i) => ({\n ...s,\n id: `F0-S${i + 1}`,\n sequence: i + 1,\n }));\n featuresFull.push({\n ...scaffoldFeature,\n id: 'F0',\n name: 'FOUNDATION & SETUP',\n steps: scaffoldSteps,\n });\n } else {\n featuresFull.push({\n id: 'F0',\n name: 'FOUNDATION & SETUP',\n description: 'Frame the problem, get familiar with the tools',\n steps: [pblStep],\n } as Feature);\n }\n\n // Add features from overview\n const overviewFeatures = (product?.features || []) as Feature[];\n featuresFull = [...featuresFull, ...overviewFeatures];\n\n // C2: Extract steps per feature\n log('STEP_4_C2', `Extracting steps for ${overviewFeatures.length} features...`);\n\n const nonF0Features = overviewFeatures.filter(f => f.id !== 'F0');\n if (nonF0Features.length > 0) {\n try {\n const batchedSteps = await extractFeatureStepsBatched(\n goal, techStack, sdkApiIndex, fileContentsMap, nonF0Features, llmConfig,\n );\n for (const feature of nonF0Features) {\n const steps = batchedSteps.get(feature.id || '');\n if (steps) feature.steps = steps;\n }\n } catch (err) {\n log('STEP_4_C2', `Batch extraction failed (${err}), falling back to per-feature...`);\n for (const feature of nonF0Features) {\n try {\n const steps = await extractFeatureSteps({\n goal, techStack, sdkApiIndex, fileContentsMap, feature, llmConfig,\n });\n feature.steps = steps;\n } catch (e) {\n log('STEP_4_C2', `Failed for ${feature.id}: ${e}`);\n }\n }\n }\n }\n\n // Build project graph\n const projectGraph: ProjectGraph = {\n schema_version: 3,\n project: {\n id: (overview.project as Record<string, unknown>)?.name?.toString().toLowerCase().replace(/\\s+/g, '-') || 'project',\n name: (overview.project as Record<string, unknown>)?.name?.toString() || 'Project',\n purpose: goal,\n version: '0.1.0',\n project_type: 'app',\n platform: ((overview.project as Record<string, unknown>)?.platforms as string[]) || ['ios'],\n tech_stack: techStack.split(',').reduce((acc, t) => {\n const key = t.trim().toLowerCase();\n if (key) acc[key] = [t.trim()];\n return acc;\n }, {} as Record<string, string[]>),\n architecture: (overview.architecture as Record<string, unknown>)?.layers as string[] || [],\n },\n product: {\n goals: (product?.goals as Array<{ id: string; description: string }>) || [],\n users: (product?.users as Array<{ id: string; goals: string[] }>) || [],\n journeys: (product?.user_journeys as Array<{ id: string; name: string; requirement_ids: string[]; steps: string[]; feature_ids: string[] }>) || [],\n requirements: [],\n development_stages: (product?.development_stages as Array<{ stage: string; product_state: string; need: string[]; learn: string[]; validation: string; cross_feature_value: string; temporary_approach: string }>) || [],\n purpose: String(product?.purpose || ''),\n problem_statement: String(product?.problem_statement || ''),\n primary_users: (product?.primary_users as string[]) || [],\n },\n features: featuresFull,\n capabilities: [],\n implementation: {\n tasks: [],\n },\n missing_gaps: [],\n tech_debt: [],\n };\n\n // ─── STEP 5: Verification ────────────────────────────────────────────────\n log('STEP_5', 'Verifying project graph against source code...');\n\n const { graph: verifiedGraph, hallucinations } = verifyProjectGraph(projectGraph, {\n repoDir,\n sdkApiIndex,\n fileContentsMap,\n });\n log('STEP_5', `Verification complete: ${hallucinations.length} hallucinations found`);\n\n // ─── STEP 6: Concept Escalation ──────────────────────────────────────────\n log('STEP_6', 'Escalating keywords to neutral concepts...');\n\n const featureConcepts = await escalateAndMapConcepts({\n projectGraph: verifiedGraph,\n fileContentsMap,\n llmConfig,\n });\n log('STEP_6', `Concept mapping complete: ${featureConcepts.size} features mapped`);\n\n // Propagate concept_codes back into verified graph steps\n for (const feature of verifiedGraph.features || []) {\n const fid = feature.id || '';\n const fConcepts = featureConcepts.get(fid) || [];\n for (const step of feature.steps || []) {\n const stepConcepts = fConcepts\n .filter(cm => {\n // Match concept to step: check if step contains the keyword\n const stepKws = [...(step.keywords || []), ...(step.api_usage || [])];\n return stepKws.some(k => k === cm.keyword);\n })\n .map(cm => cm.concept_code);\n // Merge with any existing concept_codes from LLM\n const existing = step.concept_codes || [];\n step.concept_codes = [...new Set([...existing, ...stepConcepts])];\n }\n }\n\n // ─── STEP 7: Concept Resolution ──────────────────────────────────────────\n log('STEP_7', 'Resolving keywords to Master Tree concepts...');\n\n // Collect LLM-generated keywords from verified graph (not just AST)\n const llmKeywords: Keyword[] = [];\n const seenKw = new Set<string>();\n for (const feature of verifiedGraph.features || []) {\n for (const step of feature.steps || []) {\n for (const kw of [...(step.keywords || []), ...(step.api_usage || [])]) {\n if (!seenKw.has(kw.toLowerCase())) {\n seenKw.add(kw.toLowerCase());\n llmKeywords.push({ keyword: kw, source: 'llm_step', platform: 'app', weight: 1.0, context: 'LLM-generated step keyword' });\n }\n }\n }\n }\n // Merge with AST keywords (AST takes precedence for source/weight)\n const astKwMap = new Map(astKeywords.map(k => [k.keyword.toLowerCase(), k]));\n const mergedKeywords: Keyword[] = [];\n const mergedSeen = new Set<string>();\n for (const kw of [...astKeywords, ...llmKeywords]) {\n const key = kw.keyword.toLowerCase();\n if (!mergedSeen.has(key)) {\n mergedSeen.add(key);\n mergedKeywords.push(astKwMap.get(key) || kw);\n }\n }\n\n // Build depth overrides from concept escalation\n const depthOverrides = new Map<string, 'ulo' | 'cio' | 'sio'>();\n for (const mappings of featureConcepts.values()) {\n for (const cm of mappings) {\n if (!depthOverrides.has(cm.keyword)) {\n depthOverrides.set(cm.keyword, cm.depth);\n }\n }\n }\n\n const resolvedConcepts = await resolveConcepts({\n keywords: mergedKeywords,\n goal,\n embeddings,\n depthOverrides,\n llmConfig,\n });\n log('STEP_7', `Resolved: ${resolvedConcepts.summary.resolved_count}, Proposed: ${resolvedConcepts.summary.proposed_count} (${resolvedConcepts.summary.search_mode})`);\n\n // ─── STEP 8: Assembly ────────────────────────────────────────────────────\n log('STEP_8', 'Assembling roadmap with keyword tracking...');\n\n const roadmap = assembleRoadmap({\n projectGraph: verifiedGraph,\n featureConcepts,\n sessionMinutes: 90,\n overheadFactor: 1.15,\n maxMilestoneMinutes: 120,\n });\n log('STEP_8', `Roadmap assembled: ${roadmap.phases.length} phases, ${roadmap.phases.reduce((s, p) => s + p.milestones.length, 0)} milestones`);\n\n return {\n projectGraph: verifiedGraph,\n resolvedConcepts,\n roadmap,\n hallucinations,\n keywords: astKeywords,\n featureConcepts,\n };\n}\n","/**\n * Knowledge Graph Pipeline Orchestrator.\n *\n * Runs: Syllabus Parsing -> Knowledge Graph Generation -> Verification -> CurriculumFeed v2 Emission.\n */\n\nimport { generateKnowledgeGraph, type KnowledgeGraphPipelineOptions } from '../graph/knowledgeGraphPipeline';\nimport { parseSyllabus, type ParsedSyllabus } from '../parsers/syllabusParser';\nimport { emitCurriculumFeed } from '../feed/curriculumFeedEmitter';\nimport type { KnowledgeGraph } from '../schemas/knowledgeGraphSchema';\nimport type { CurriculumFeed } from '../schemas/curriculumFeedSchema';\nimport type { KnowledgeGraphVerificationReport } from '../graph/knowledgeGraphVerifier';\n\nexport interface KnowledgePipelineOptions extends KnowledgeGraphPipelineOptions {}\n\nexport interface KnowledgePipelineResult {\n knowledgeGraph: KnowledgeGraph;\n parsedSyllabus?: ParsedSyllabus;\n curriculumFeed: CurriculumFeed;\n verificationReport?: KnowledgeGraphVerificationReport;\n warnings: string[];\n}\n\n/**\n * Run the full concept-driven knowledge graph pipeline.\n */\nexport async function runKnowledgeGraphPipeline(\n options: KnowledgePipelineOptions,\n): Promise<KnowledgePipelineResult> {\n const warnings: string[] = [];\n let parsedSyllabus = options.parsedSyllabus;\n\n if (!parsedSyllabus && options.syllabusText) {\n parsedSyllabus = parseSyllabus(options.syllabusText);\n }\n\n const effectiveSubject = options.subject || parsedSyllabus?.subject.title || 'Untitled Subject';\n const effectiveDomain = options.domain || parsedSyllabus?.subject.domain || 'other';\n const effectiveGradeBand = options.gradeBand || parsedSyllabus?.subject.gradeBand;\n const effectiveDesc = options.description || parsedSyllabus?.subject.description;\n\n const result = await generateKnowledgeGraph({\n ...options,\n subject: effectiveSubject,\n domain: effectiveDomain,\n gradeBand: effectiveGradeBand,\n description: effectiveDesc,\n parsedSyllabus,\n });\n\n warnings.push(...result.warnings);\n\n // Emit normalized CurriculumFeed v2\n const curriculumFeed = emitCurriculumFeed(result.knowledgeGraph, {\n warnings,\n });\n\n return {\n knowledgeGraph: result.knowledgeGraph,\n parsedSyllabus,\n curriculumFeed,\n verificationReport: result.verificationReport,\n warnings,\n };\n}\n","/**\n * Hybrid Graph Pipeline Orchestrator.\n *\n * Runs: Hybrid Graph Generation -> CurriculumFeed v2 Emission.\n */\n\nimport { generateHybridGraph, type HybridGraphPipelineOptions } from '../graph/hybridGraphPipeline';\nimport { emitCurriculumFeed } from '../feed/curriculumFeedEmitter';\nimport type { HybridGraph } from '../schemas/hybridGraphSchema';\nimport type { CurriculumFeed } from '../schemas/curriculumFeedSchema';\n\nexport interface HybridPipelineOptions extends HybridGraphPipelineOptions {}\n\nexport interface HybridPipelineResult {\n hybridGraph: HybridGraph;\n curriculumFeed: CurriculumFeed;\n warnings: string[];\n}\n\n/**\n * Run the hybrid graph generation and feed emission pipeline.\n */\nexport async function runHybridGraphPipeline(\n options: HybridPipelineOptions,\n): Promise<HybridPipelineResult> {\n const warnings: string[] = [];\n const result = await generateHybridGraph(options);\n warnings.push(...result.warnings);\n\n const curriculumFeed = emitCurriculumFeed(result.hybridGraph, {\n warnings,\n });\n\n return {\n hybridGraph: result.hybridGraph,\n curriculumFeed,\n warnings,\n };\n}\n","/**\n * Unified Domain Pipeline Router.\n *\n * Implements the 3-Layer Architecture from docs/ideas/2026-08-30-domain-detection-and-graph-types.md:\n * Layer 1: DOMAIN DETECTION (detectDomainProfile)\n * Layer 2: GRAPH ROUTER (routeDomain)\n * Layer 3: GRAPH GENERATION (runProjectGraphPipeline | runKnowledgeGraphPipeline | runHybridGraphPipeline)\n * Layer 4: NORMALIZED OUTPUT (CurriculumFeed v2)\n */\n\nimport { detectDomainProfile, type DetectDomainProfileOptions } from '../detector/domainProfileDetector';\nimport type { DomainProfile, GraphType } from '../schemas/domainProfileSchema';\nimport type { CurriculumFeed } from '../schemas/curriculumFeedSchema';\nimport { runProjectGraphPipeline, type PipelineOptions, type PipelineResult } from './projectGraphPipeline';\nimport { runKnowledgeGraphPipeline, type KnowledgePipelineOptions, type KnowledgePipelineResult } from './knowledgeGraphPipeline';\nimport { runHybridGraphPipeline, type HybridPipelineOptions, type HybridPipelineResult } from './hybridGraphPipeline';\nimport type { LlmClientConfig } from '../utils/llmClient';\nimport type { ParsedSyllabus } from '../parsers/syllabusParser';\n\nexport interface DomainPipelineOptions extends DetectDomainProfileOptions {\n subject?: string;\n llmConfig?: LlmClientConfig;\n onProgress?: (step: string, message: string) => void;\n parsedSyllabus?: ParsedSyllabus;\n knowledgeTreePath?: string;\n proposalsPath?: string;\n embeddings?: Record<string, { embedding?: number[]; name?: string; description?: string; keywords?: string }>;\n /** Override automatic learning mode detection */\n forcedLearningMode?: 'product' | 'concept' | 'hybrid';\n}\n\nexport interface DomainPipelineResult {\n domainProfile: DomainProfile;\n graphType: GraphType;\n curriculumFeed: CurriculumFeed;\n projectResult?: PipelineResult;\n knowledgeResult?: KnowledgePipelineResult;\n hybridResult?: HybridPipelineResult;\n warnings: string[];\n}\n\n/**\n * Route and execute the appropriate domain pipeline based on input context.\n */\nexport async function runDomainPipeline(\n options: DomainPipelineOptions,\n): Promise<DomainPipelineResult> {\n const warnings: string[] = [];\n const log = (step: string, msg: string) => {\n console.log(`[ROUTER-${step}] ${msg}`);\n options.onProgress?.(step, msg);\n };\n\n // ─── Layer 1: Domain Detection ───────────────────────────────────────────\n log('LAYER_1', 'Detecting domain profile...');\n const domainProfile = detectDomainProfile(options);\n\n const effectiveMode = options.forcedLearningMode || domainProfile.learningMode;\n log('LAYER_2', `Routing to pipeline for learning mode: ${effectiveMode} (graphType: ${domainProfile.graphType})`);\n\n // ─── Layer 3: Dispatch & Execute ─────────────────────────────────────────\n if (effectiveMode === 'concept') {\n log('LAYER_3', 'Executing Knowledge Graph Pipeline (Concept-driven)...');\n const knowledgeResult = await runKnowledgeGraphPipeline({\n subject: options.subject || domainProfile.detectedSubject || options.goal || options.description || 'General Subject',\n description: options.description,\n syllabusText: options.syllabusText,\n parsedSyllabus: options.parsedSyllabus,\n gradeBand: options.gradeBand,\n domain: domainProfile.domainCategory,\n techStack: options.techStack || domainProfile.detectedTechStack?.[0],\n llmConfig: options.llmConfig,\n onProgress: options.onProgress,\n knowledgeTreePath: options.knowledgeTreePath,\n proposalsPath: options.proposalsPath,\n });\n warnings.push(...knowledgeResult.warnings);\n\n return {\n domainProfile,\n graphType: 'knowledge_graph',\n curriculumFeed: knowledgeResult.curriculumFeed,\n knowledgeResult,\n warnings,\n };\n }\n\n if (effectiveMode === 'hybrid') {\n log('LAYER_3', 'Executing Hybrid Graph Pipeline...');\n if (options.repoDir) {\n const projectResult = await runProjectGraphPipeline({\n repoDir: options.repoDir,\n goal: options.goal || 'Build complete project',\n techStack: options.techStack || 'typescript',\n llmConfig: options.llmConfig,\n embeddings: options.embeddings,\n onProgress: options.onProgress,\n });\n\n const knowledgeResult = await runKnowledgeGraphPipeline({\n subject: options.subject || domainProfile.detectedSubject || options.goal || 'Subject Theory',\n description: options.description,\n syllabusText: options.syllabusText,\n parsedSyllabus: options.parsedSyllabus,\n domain: domainProfile.domainCategory,\n techStack: options.techStack,\n llmConfig: options.llmConfig,\n onProgress: options.onProgress,\n });\n\n const hybridResult = await runHybridGraphPipeline({\n projectGraph: projectResult.projectGraph,\n knowledgeGraph: knowledgeResult.knowledgeGraph,\n llmConfig: options.llmConfig,\n onProgress: options.onProgress,\n });\n\n warnings.push(...hybridResult.warnings);\n return {\n domainProfile,\n graphType: 'hybrid_graph',\n curriculumFeed: hybridResult.curriculumFeed,\n projectResult,\n knowledgeResult,\n hybridResult,\n warnings,\n };\n } else {\n warnings.push('Hybrid learning mode requested but repoDir was not provided — falling back to concept-driven knowledge graph pipeline');\n const knowledgeResult = await runKnowledgeGraphPipeline({\n subject: options.subject || domainProfile.detectedSubject || options.goal || 'Subject Theory',\n description: options.description,\n syllabusText: options.syllabusText,\n parsedSyllabus: options.parsedSyllabus,\n domain: domainProfile.domainCategory,\n techStack: options.techStack,\n llmConfig: options.llmConfig,\n onProgress: options.onProgress,\n });\n warnings.push(...knowledgeResult.warnings);\n\n return {\n domainProfile,\n graphType: 'knowledge_graph',\n curriculumFeed: knowledgeResult.curriculumFeed,\n knowledgeResult,\n warnings,\n };\n }\n }\n\n // Default: product-driven\n log('LAYER_3', 'Executing Project Graph Pipeline (Product-driven)...');\n if (!options.repoDir) {\n throw new Error('repoDir is required for product-driven project graph pipeline');\n }\n\n const projectResult = await runProjectGraphPipeline({\n repoDir: options.repoDir,\n goal: options.goal || 'Build complete project',\n techStack: options.techStack || domainProfile.detectedTechStack?.[0] || 'typescript',\n llmConfig: options.llmConfig,\n embeddings: options.embeddings,\n onProgress: options.onProgress,\n });\n\n // Emit curriculum feed from project graph\n const { emitCurriculumFeed } = await import('../feed/curriculumFeedEmitter');\n const curriculumFeed = emitCurriculumFeed(projectResult.projectGraph, {\n warnings,\n });\n\n return {\n domainProfile,\n graphType: 'project_graph',\n curriculumFeed,\n projectResult,\n warnings,\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/extractors/fileSelector.ts","../src/utils/fileUtils.ts","../src/pipeline/projectGraphPipeline.ts","../src/pipeline/knowledgeGraphPipeline.ts","../src/pipeline/hybridGraphPipeline.ts","../src/pipeline/domainRouter.ts"],"names":["relative","projectResult","emitCurriculumFeed"],"mappings":"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","file":"chunk-LZQLLAYP.mjs","sourcesContent":["/**\n * LLM-based File Selector — sends file tree to LLM, asks it to pick\n * which files are most relevant to the project goal.\n *\n * This mirrors knowledge-tree's approach:\n * 1. git_tracker generates project_structure.txt (file tree)\n * 2. Agent/LLM reads tree → selects important files\n * 3. Only selected files are read for analysis\n */\n\nimport { createLlmClient, llmChatJson, type LlmClientConfig } from '../utils/llmClient';\n\nexport interface FileSelectionResult {\n selected: string[];\n reasoning: string;\n}\n\n/**\n * Ask LLM to select which files from the file tree are relevant to the goal.\n * Input: file tree (names only, very small) + goal\n * Output: list of file paths to analyze\n */\nexport async function selectFilesWithLlm(\n filePaths: string[],\n goal: string,\n techStack: string,\n llmConfig?: LlmClientConfig,\n): Promise<FileSelectionResult> {\n // If very few files, no need to filter\n if (filePaths.length <= 15) {\n return { selected: filePaths, reasoning: 'Too few files to filter' };\n }\n\n const client = createLlmClient(llmConfig);\n\n // Build file tree for LLM (just names, grouped by directory)\n const treeLines = buildFileTree(filePaths);\n\n const systemPrompt = (\n 'You are a software architect analyzing a project repository.\\n'\n + 'Given a file tree and a project goal, select which files are MOST IMPORTANT '\n + 'to read for understanding the project architecture and implementation.\\n\\n'\n + 'RULES:\\n'\n + '1. Prioritize source code files (Swift, TS, Python, C++) over config/docs\\n'\n + '2. Include entry points (App.swift, main.py, index.ts)\\n'\n + '3. Include core domain files (models, services, views, controllers)\\n'\n + '4. EXCLUDE test files, mock files, generated files\\n'\n + '5. EXCLUDE config files (package.json, Podfile, etc.) unless they reveal architecture\\n'\n + '6. Include files that directly implement the features mentioned in the goal\\n'\n + '7. Return 20-40 files maximum (fewer is better if the project is small)\\n\\n'\n + 'Return JSON: {\"selected\": [\"path/to/file1\", \"path/to/file2\"], \"reasoning\": \"brief explanation\"}'\n );\n\n const userPrompt = (\n `Project goal: ${goal}\\n`\n + `Tech stack: ${techStack}\\n\\n`\n + `FILE TREE (${filePaths.length} files):\\n${treeLines}\\n\\n`\n + 'Select the most important files to analyze. Return JSON.'\n );\n\n try {\n const result = await llmChatJson(client, systemPrompt, userPrompt, {\n temperature: 0.1,\n maxTokens: 4096,\n });\n\n const selected = Array.isArray(result.selected) ? result.selected as string[] : [];\n const reasoning = String(result.reasoning || '');\n\n // Validate: only keep files that exist in the original list\n const pathSet = new Set(filePaths);\n const validSelected = selected.filter(p => pathSet.has(p));\n\n if (validSelected.length === 0) {\n // LLM returned nothing valid — fallback to all files\n return { selected: filePaths, reasoning: 'LLM selection empty, using all files' };\n }\n\n return { selected: validSelected, reasoning };\n } catch (err) {\n console.warn(`[WARN] LLM file selection failed (${err}), using all files`);\n return { selected: filePaths, reasoning: `LLM failed: ${err}` };\n }\n}\n\n/**\n * Build a compact file tree string for LLM consumption.\n * Groups files by top-level directory, shows only filenames.\n */\nfunction buildFileTree(filePaths: string[]): string {\n const byDir = new Map<string, string[]>();\n\n for (const fp of filePaths) {\n const parts = fp.split('/');\n const dir = parts.length > 1 ? parts.slice(0, -1).join('/') : '(root)';\n const file = parts[parts.length - 1];\n if (!byDir.has(dir)) byDir.set(dir, []);\n byDir.get(dir)!.push(file);\n }\n\n const lines: string[] = [];\n for (const [dir, files] of byDir) {\n lines.push(`${dir}/`);\n for (const f of files.sort()) {\n lines.push(` ${f}`);\n }\n }\n\n return lines.join('\\n');\n}\n","/**\n * File I/O utilities for domain-kit pipeline.\n */\n\nimport { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, statSync } from 'node:fs';\nimport { join, extname, relative, resolve } from 'node:path';\nimport { execSync } from 'node:child_process';\n\n/**\n * Read JSON file safely, returns null if not found or invalid.\n */\nexport function readJsonFile<T = unknown>(filePath: string): T | null {\n try {\n if (!existsSync(filePath)) return null;\n const content = readFileSync(filePath, 'utf-8');\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n\n/**\n * Write JSON file, creating parent directories if needed.\n */\nexport function writeJsonFile(filePath: string, data: unknown): void {\n mkdirSync(join(filePath, '..'), { recursive: true });\n writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8');\n}\n\n/**\n * Read text file safely, returns null if not found.\n */\nexport function readTextFile(filePath: string): string | null {\n try {\n if (!existsSync(filePath)) return null;\n return readFileSync(filePath, 'utf-8');\n } catch {\n return null;\n }\n}\n\n/**\n * Collect source files from a directory, filtering by allowed extensions.\n */\nexport function collectSourceFiles(\n dir: string,\n options?: {\n allowedExtensions?: string[];\n skipDirs?: string[];\n maxFiles?: number;\n },\n): string[] {\n const allowedExts = options?.allowedExtensions || ['.swift', '.ts', '.tsx', '.js', '.jsx', '.py', '.ino', '.cpp', '.c', '.h', '.hpp'];\n const maxFiles = options?.maxFiles || 70;\n\n // Try git ls-files first — respects .gitignore, handles submodules, symlinks\n const gitFiles = collectViaGit(dir, allowedExts, maxFiles);\n if (gitFiles.length > 0) return gitFiles;\n\n // Fallback: filesystem walk (non-git directories)\n return collectViaFilesystem(dir, allowedExts, maxFiles, options?.skipDirs);\n}\n\n/**\n * Collect source files using `git ls-files`.\n * Respects .gitignore, handles symlinks, much faster than walk.\n */\nfunction collectViaGit(dir: string, allowedExts: string[], maxFiles: number): string[] {\n try {\n const raw = execSync('git ls-files --cached --others --exclude-standard', {\n cwd: dir,\n encoding: 'utf-8',\n timeout: 5000,\n maxBuffer: 1024 * 1024,\n });\n const extSet = new Set(allowedExts.map(e => e.toLowerCase()));\n return raw\n .split('\\n')\n .filter(line => line.length > 0)\n .filter(line => extSet.has(extname(line).toLowerCase()))\n .slice(0, maxFiles)\n .map(rel => join(dir, rel));\n } catch {\n // Not a git repo or git not available — fall through to filesystem walk\n return [];\n }\n}\n\n/**\n * Collect source files using recursive directory walk (non-git fallback).\n */\nfunction collectViaFilesystem(\n dir: string,\n allowedExts: string[],\n maxFiles: number,\n skipDirs?: string[],\n): string[] {\n const skipSet = new Set(skipDirs || [\n 'node_modules', '.build', 'Pods', '.git', '.venv', 'venv',\n '__pycache__', 'build', 'dist', '.idea', '.vscode',\n 'test', 'tests', 'demo', 'sample', 'example', 'playground',\n ]);\n const extSet = new Set(allowedExts.map(e => e.toLowerCase()));\n const result: string[] = [];\n\n function walk(currentDir: string) {\n if (result.length >= maxFiles) return;\n let entries;\n try {\n entries = readdirSync(currentDir, { withFileTypes: true });\n } catch {\n return; // permission error\n }\n for (const entry of entries) {\n if (result.length >= maxFiles) return;\n const fullPath = join(currentDir, entry.name);\n if (entry.isDirectory()) {\n if (!skipSet.has(entry.name)) {\n walk(fullPath);\n }\n } else if (entry.isFile()) {\n const ext = extname(entry.name).toLowerCase();\n if (extSet.has(ext)) {\n result.push(fullPath);\n }\n }\n }\n }\n\n walk(dir);\n return result;\n}\n\n/**\n * Collect file contents map (relative path → content).\n */\nexport function collectFileContents(\n dir: string,\n options?: {\n allowedExtensions?: string[];\n skipDirs?: string[];\n maxFiles?: number;\n maxChars?: number;\n },\n): { paths: string[]; contents: Map<string, string> } {\n const maxChars = options?.maxChars || 500000;\n const files = collectSourceFiles(dir, options);\n const contents = new Map<string, string>();\n let totalChars = 0;\n\n for (const filePath of files) {\n const relPath = relative(dir, filePath);\n try {\n const content = readFileSync(filePath, 'utf-8');\n if (totalChars + content.length > maxChars) {\n const remaining = maxChars - totalChars;\n if (remaining > 100) {\n contents.set(relPath, content.slice(0, remaining));\n totalChars += remaining;\n }\n break;\n }\n contents.set(relPath, content);\n totalChars += content.length;\n } catch {\n // Skip unreadable files\n }\n }\n\n return { paths: files.map(f => relative(dir, f)), contents };\n}\n\n/**\n * Read contents of SPECIFIC files (by relative path) — no directory scan.\n * Used for 2-pass approach: scan tree first, then read only selected files.\n */\nexport function collectSpecificFileContents(\n dir: string,\n relativePaths: string[],\n maxChars: number = 500000,\n): Map<string, string> {\n const contents = new Map<string, string>();\n let totalChars = 0;\n\n for (const relPath of relativePaths) {\n const fullPath = join(dir, relPath);\n try {\n const content = readFileSync(fullPath, 'utf-8');\n if (totalChars + content.length > maxChars) {\n const remaining = maxChars - totalChars;\n if (remaining > 100) {\n contents.set(relPath, content.slice(0, remaining));\n totalChars += remaining;\n }\n break;\n }\n contents.set(relPath, content);\n totalChars += content.length;\n } catch {\n // Skip unreadable files\n }\n }\n\n return contents;\n}\n\n/**\n * Detect primary language from file extensions.\n */\nexport function detectPrimaryLanguage(filePaths: string[]): string {\n const counts = new Map<string, number>();\n for (const fp of filePaths) {\n const ext = extname(fp).toLowerCase();\n let lang = 'unknown';\n if (ext === '.swift') lang = 'Swift';\n else if (ext === '.ts' || ext === '.tsx') lang = 'TypeScript';\n else if (ext === '.js' || ext === '.jsx') lang = 'JavaScript';\n else if (ext === '.py') lang = 'Python';\n else if (ext === '.ino' || ext === '.cpp' || ext === '.c' || ext === '.h') lang = 'C++';\n else if (ext === '.kt' || ext === '.kts') lang = 'Kotlin';\n counts.set(lang, (counts.get(lang) || 0) + 1);\n }\n\n let maxCount = 0;\n let primary = 'unknown';\n for (const [lang, count] of counts) {\n if (count > maxCount) {\n maxCount = count;\n primary = lang;\n }\n }\n return primary;\n}\n\n/**\n * Read README.md and extract project description.\n */\nexport function readReadmeDescription(repoDir: string): string | null {\n const readmePath = join(repoDir, 'README.md');\n if (!existsSync(readmePath)) return null;\n try {\n const content = readFileSync(readmePath, 'utf-8');\n const lines = content.split('\\n').map(l => l.trim()).filter(Boolean);\n // Skip patterns: badges, images, table of contents, HTML tags\n const skipPatterns = [/^\\[!/, /^<img/, /^<a /, /^#+\\s+Table of/i, /^---$/];\n let foundTitle = false;\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line.startsWith('#') && !line.startsWith('##')) {\n foundTitle = true;\n continue;\n }\n if (!foundTitle) continue;\n // Skip empty lines, badges, images, TOC, horizontal rules\n if (skipPatterns.some(p => p.test(line))) continue;\n if (line.startsWith('#')) return null; // hit next heading — no description found\n if (line.startsWith('```')) return null; // code block\n if (line.startsWith('|')) return null; // table\n if (line.length > 15) return line;\n }\n return null;\n } catch {\n return null;\n }\n}\n","/**\n * Project Graph Pipeline — full orchestrator.\n *\n * Ported from knowledge-tree/generate_roadmap_v3.py PipelineOrchestrator\n * Coordinates: AST analysis → keyword extraction → LLM graph generation →\n * verification → concept escalation → concept resolution → assembly.\n */\n\nimport type { ProjectGraph, Feature } from '../schemas/projectGraphSchema';\nimport { parseSwiftFile, mergeSwiftResults, type SwiftParseResult } from '../parsers/swift';\nimport { parseTsFile, mergeTsResults, type TsParseResult } from '../parsers/typescript';\nimport { parsePythonFile, mergePythonResults, type PythonParseResult } from '../parsers/python';\nimport { parseCppFile, mergeCppResults, type CppParseResult } from '../parsers/cpp';\nimport { extractKeywords, type Keyword, type SourceContext } from '../extractors/keywordExtractor';\nimport { extractScaffold } from '../graph/scaffoldExtractor';\nimport { extractProjectOverview } from '../graph/overviewExtractor';\nimport { extractFeatureSteps, extractFeatureStepsBatched } from '../graph/stepExtractor';\nimport { verifyProjectGraph, type Hallucination } from '../graph/graphVerifier';\nimport { escalateAndMapConcepts, type ConceptMapping } from '../graph/conceptEscalator';\nimport { resolveConcepts, type ResolveConceptsResult } from '../concepts/conceptResolver';\nimport { assembleRoadmap, type AssembledRoadmap } from '../assembly/roadmapAssembler';\nimport { selectFilesWithLlm } from '../extractors/fileSelector';\nimport { collectSourceFiles, collectSpecificFileContents, detectPrimaryLanguage, readReadmeDescription } from '../utils/fileUtils';\nimport { relative } from 'node:path';\nimport { createLlmClient, type LlmClientConfig } from '../utils/llmClient';\n\nexport interface PipelineOptions {\n repoDir: string;\n goal: string;\n techStack: string;\n llmConfig?: LlmClientConfig;\n embeddings?: Record<string, { embedding?: number[]; name?: string; description?: string; keywords?: string }>;\n onProgress?: (step: string, message: string) => void;\n}\n\nexport interface PipelineResult {\n projectGraph: ProjectGraph;\n resolvedConcepts: ResolveConceptsResult;\n roadmap: AssembledRoadmap;\n hallucinations: Hallucination[];\n keywords: Keyword[];\n featureConcepts: Map<string, ConceptMapping[]>;\n}\n\n/**\n * Run the full project graph generation pipeline.\n */\nexport async function runProjectGraphPipeline(\n options: PipelineOptions,\n): Promise<PipelineResult> {\n const { repoDir, goal, techStack, llmConfig, embeddings, onProgress } = options;\n\n const log = (step: string, msg: string) => {\n console.log(`[${step}] ${msg}`);\n onProgress?.(step, msg);\n };\n\n // ─── STEP 1A: File Tree Scan (names only — no content reading) ─────────\n log('STEP_1', 'Scanning file tree (names only)...');\n\n const allFilePaths = collectSourceFiles(repoDir);\n const allRelPaths = allFilePaths.map(fp => relative(repoDir, fp));\n log('STEP_1', `Found ${allRelPaths.length} source files in repository`);\n\n // ─── STEP 1B: LLM File Selection (sends tiny file tree to LLM) ────────\n log('STEP_1', 'Asking LLM to select relevant files from file tree...');\n\n const { selected: selectedPaths, reasoning } = await selectFilesWithLlm(\n allRelPaths, goal, techStack, llmConfig,\n );\n log('STEP_1', `LLM selected ${selectedPaths.length}/${allRelPaths.length} files: ${reasoning.slice(0, 100)}`);\n\n // ─── STEP 1C: Read content only for LLM-selected files ─────────────────\n log('STEP_1', 'Reading content for selected files...');\n\n const fileContentsMap = collectSpecificFileContents(repoDir, selectedPaths);\n const filePaths = selectedPaths;\n const primaryLang = detectPrimaryLanguage(filePaths);\n log('STEP_1', `Primary language: ${primaryLang}, ${filePaths.length} files loaded (${fileContentsMap.size} with content)`);\n\n // Parse source files\n log('STEP_1', 'Parsing source files with AST-level analysis...');\n\n const allParseResults: SourceContext[] = [];\n for (const [relPath, content] of fileContentsMap) {\n const fullPath = relPath;\n if (fullPath.endsWith('.swift')) {\n allParseResults.push(parseSwiftFile(fullPath, content));\n } else if (fullPath.endsWith('.ts') || fullPath.endsWith('.tsx') || fullPath.endsWith('.js') || fullPath.endsWith('.jsx')) {\n allParseResults.push(parseTsFile(fullPath, content));\n } else if (fullPath.endsWith('.py')) {\n allParseResults.push(parsePythonFile(fullPath, content));\n } else if (fullPath.endsWith('.ino') || fullPath.endsWith('.cpp') || fullPath.endsWith('.c') || fullPath.endsWith('.h')) {\n allParseResults.push(parseCppFile(fullPath, content));\n }\n }\n\n // Merge parse results by language\n let mergedContext: SourceContext;\n if (primaryLang === 'Swift') {\n mergedContext = mergeSwiftResults(allParseResults.filter((r): r is SwiftParseResult => 'property_wrappers' in r));\n } else if (primaryLang === 'TypeScript' || primaryLang === 'JavaScript') {\n mergedContext = mergeTsResults(allParseResults.filter((r): r is TsParseResult => !('docstrings' in r) && !('property_wrappers' in r) && !('frameworks_used' in r)));\n } else if (primaryLang === 'Python') {\n mergedContext = mergePythonResults(allParseResults.filter((r): r is PythonParseResult => 'docstrings' in r));\n } else {\n mergedContext = mergeCppResults(allParseResults.filter((r): r is CppParseResult => 'error_handling' in r && !('docstrings' in r) && !('property_wrappers' in r)));\n }\n\n // ─── STEP 2: Keyword Extraction ──────────────────────────────────────────\n log('STEP_2', 'Extracting keywords from AST analysis...');\n\n const astKeywords = extractKeywords(mergedContext);\n log('STEP_2', `Extracted ${astKeywords.length} keywords`);\n\n // ─── STEP 3: Build SDK API Index (simplified — use AST keywords as proxy) ──\n log('STEP_3', 'Building SDK API index...');\n\n const sdkApiIndex = {\n sdk_apis: astKeywords.map(kw => ({\n name: kw.keyword,\n kind: kw.source,\n used_in_demo: true,\n })),\n };\n\n // ─── STEP 4: LLM Project Graph Generation ────────────────────────────────\n log('STEP_4', 'Generating project graph via LLM (C0: Scaffold, C1: Overview, C2: Steps)...');\n\n // C0: Scaffold (F0) — uses file list (names only, not content)\n log('STEP_4_C0', 'Extracting FOUNDATION & SETUP feature (F0)...');\n const scaffoldFeature = await extractScaffold({\n goal,\n techStack,\n fileList: filePaths,\n llmConfig,\n });\n\n // C1: Overview (features meta) — uses already-filtered fileContentsMap\n log('STEP_4_C1', 'Extracting project overview (features meta)...');\n const overview = await extractProjectOverview({\n goal,\n techStack,\n sdkApiIndex,\n fileContentsMap,\n astKeywords,\n llmConfig,\n });\n\n // Build PBL step (Design Thinking)\n const product = overview.product as Record<string, unknown> | undefined;\n const pblStep: Feature['steps'] extends (infer T)[] ? T : never = {\n id: 'F0-S1',\n sequence: 1,\n name: 'Frame the problem & understand user needs (Design Thinking)',\n description: 'BEFORE CODING — frame the problem and understand what the user needs',\n files: [],\n api_usage: [],\n keywords: ['Design Thinking', 'User Needs', 'Problem Statement', 'User Journey', 'PBL'],\n completion_level: 'base',\n platform: 'app',\n intent: 'Understand user needs and frame problem before writing code',\n outcome: { user_visible: 'Defined problem statement', technical: 'Problem frame context' },\n acceptance: ['Problem statement is clear', 'Primary users identified'],\n requirement_ids: [],\n concept_codes: [],\n effort: { estimated_minutes: 15, complexity: 'low' },\n };\n\n // Merge scaffold F0 with PBL step\n let featuresFull: Feature[] = [];\n if (scaffoldFeature) {\n const scaffoldSteps = [pblStep, ...(scaffoldFeature.steps || [])].map((s, i) => ({\n ...s,\n id: `F0-S${i + 1}`,\n sequence: i + 1,\n }));\n featuresFull.push({\n ...scaffoldFeature,\n id: 'F0',\n name: 'FOUNDATION & SETUP',\n steps: scaffoldSteps,\n });\n } else {\n featuresFull.push({\n id: 'F0',\n name: 'FOUNDATION & SETUP',\n description: 'Frame the problem, get familiar with the tools',\n steps: [pblStep],\n } as Feature);\n }\n\n // Add features from overview\n const overviewFeatures = (product?.features || []) as Feature[];\n featuresFull = [...featuresFull, ...overviewFeatures];\n\n // C2: Extract steps per feature\n log('STEP_4_C2', `Extracting steps for ${overviewFeatures.length} features...`);\n\n const nonF0Features = overviewFeatures.filter(f => f.id !== 'F0');\n if (nonF0Features.length > 0) {\n try {\n const batchedSteps = await extractFeatureStepsBatched(\n goal, techStack, sdkApiIndex, fileContentsMap, nonF0Features, llmConfig,\n );\n for (const feature of nonF0Features) {\n const steps = batchedSteps.get(feature.id || '');\n if (steps) feature.steps = steps;\n }\n } catch (err) {\n log('STEP_4_C2', `Batch extraction failed (${err}), falling back to per-feature...`);\n for (const feature of nonF0Features) {\n try {\n const steps = await extractFeatureSteps({\n goal, techStack, sdkApiIndex, fileContentsMap, feature, llmConfig,\n });\n feature.steps = steps;\n } catch (e) {\n log('STEP_4_C2', `Failed for ${feature.id}: ${e}`);\n }\n }\n }\n }\n\n // Build project graph\n const projectGraph: ProjectGraph = {\n schema_version: 3,\n project: {\n id: (overview.project as Record<string, unknown>)?.name?.toString().toLowerCase().replace(/\\s+/g, '-') || 'project',\n name: (overview.project as Record<string, unknown>)?.name?.toString() || 'Project',\n purpose: goal,\n version: '0.1.0',\n project_type: 'app',\n platform: ((overview.project as Record<string, unknown>)?.platforms as string[]) || ['ios'],\n tech_stack: techStack.split(',').reduce((acc, t) => {\n const key = t.trim().toLowerCase();\n if (key) acc[key] = [t.trim()];\n return acc;\n }, {} as Record<string, string[]>),\n architecture: (overview.architecture as Record<string, unknown>)?.layers as string[] || [],\n },\n product: {\n goals: (product?.goals as Array<{ id: string; description: string }>) || [],\n users: (product?.users as Array<{ id: string; goals: string[] }>) || [],\n journeys: (product?.user_journeys as Array<{ id: string; name: string; requirement_ids: string[]; steps: string[]; feature_ids: string[] }>) || [],\n requirements: [],\n development_stages: (product?.development_stages as Array<{ stage: string; product_state: string; need: string[]; learn: string[]; validation: string; cross_feature_value: string; temporary_approach: string }>) || [],\n purpose: String(product?.purpose || ''),\n problem_statement: String(product?.problem_statement || ''),\n primary_users: (product?.primary_users as string[]) || [],\n },\n features: featuresFull,\n capabilities: [],\n implementation: {\n tasks: [],\n },\n missing_gaps: [],\n tech_debt: [],\n };\n\n // ─── STEP 5: Verification ────────────────────────────────────────────────\n log('STEP_5', 'Verifying project graph against source code...');\n\n const { graph: verifiedGraph, hallucinations } = verifyProjectGraph(projectGraph, {\n repoDir,\n sdkApiIndex,\n fileContentsMap,\n });\n log('STEP_5', `Verification complete: ${hallucinations.length} hallucinations found`);\n\n // ─── STEP 6: Concept Escalation ──────────────────────────────────────────\n log('STEP_6', 'Escalating keywords to neutral concepts...');\n\n const featureConcepts = await escalateAndMapConcepts({\n projectGraph: verifiedGraph,\n fileContentsMap,\n llmConfig,\n });\n log('STEP_6', `Concept mapping complete: ${featureConcepts.size} features mapped`);\n\n // Propagate concept_codes back into verified graph steps\n for (const feature of verifiedGraph.features || []) {\n const fid = feature.id || '';\n const fConcepts = featureConcepts.get(fid) || [];\n for (const step of feature.steps || []) {\n const stepConcepts = fConcepts\n .filter(cm => {\n // Match concept to step: check if step contains the keyword\n const stepKws = [...(step.keywords || []), ...(step.api_usage || [])];\n return stepKws.some(k => k === cm.keyword);\n })\n .map(cm => cm.concept_code);\n // Merge with any existing concept_codes from LLM\n const existing = step.concept_codes || [];\n step.concept_codes = [...new Set([...existing, ...stepConcepts])];\n }\n }\n\n // ─── STEP 7: Concept Resolution ──────────────────────────────────────────\n log('STEP_7', 'Resolving keywords to Master Tree concepts...');\n\n // Collect LLM-generated keywords from verified graph (not just AST)\n const llmKeywords: Keyword[] = [];\n const seenKw = new Set<string>();\n for (const feature of verifiedGraph.features || []) {\n for (const step of feature.steps || []) {\n for (const kw of [...(step.keywords || []), ...(step.api_usage || [])]) {\n if (!seenKw.has(kw.toLowerCase())) {\n seenKw.add(kw.toLowerCase());\n llmKeywords.push({ keyword: kw, source: 'llm_step', platform: 'app', weight: 1.0, context: 'LLM-generated step keyword' });\n }\n }\n }\n }\n // Merge with AST keywords (AST takes precedence for source/weight)\n const astKwMap = new Map(astKeywords.map(k => [k.keyword.toLowerCase(), k]));\n const mergedKeywords: Keyword[] = [];\n const mergedSeen = new Set<string>();\n for (const kw of [...astKeywords, ...llmKeywords]) {\n const key = kw.keyword.toLowerCase();\n if (!mergedSeen.has(key)) {\n mergedSeen.add(key);\n mergedKeywords.push(astKwMap.get(key) || kw);\n }\n }\n\n // Build depth overrides from concept escalation\n const depthOverrides = new Map<string, 'ulo' | 'cio' | 'sio'>();\n for (const mappings of featureConcepts.values()) {\n for (const cm of mappings) {\n if (!depthOverrides.has(cm.keyword)) {\n depthOverrides.set(cm.keyword, cm.depth);\n }\n }\n }\n\n const resolvedConcepts = await resolveConcepts({\n keywords: mergedKeywords,\n goal,\n embeddings,\n depthOverrides,\n llmConfig,\n });\n log('STEP_7', `Resolved: ${resolvedConcepts.summary.resolved_count}, Proposed: ${resolvedConcepts.summary.proposed_count} (${resolvedConcepts.summary.search_mode})`);\n\n // ─── STEP 8: Assembly ────────────────────────────────────────────────────\n log('STEP_8', 'Assembling roadmap with keyword tracking...');\n\n const roadmap = assembleRoadmap({\n projectGraph: verifiedGraph,\n featureConcepts,\n sessionMinutes: 90,\n overheadFactor: 1.15,\n maxMilestoneMinutes: 120,\n });\n log('STEP_8', `Roadmap assembled: ${roadmap.phases.length} phases, ${roadmap.phases.reduce((s, p) => s + p.milestones.length, 0)} milestones`);\n\n return {\n projectGraph: verifiedGraph,\n resolvedConcepts,\n roadmap,\n hallucinations,\n keywords: astKeywords,\n featureConcepts,\n };\n}\n","/**\n * Knowledge Graph Pipeline Orchestrator.\n *\n * Runs: Syllabus Parsing -> Knowledge Graph Generation -> Verification -> CurriculumFeed v2 Emission.\n */\n\nimport { generateKnowledgeGraph, type KnowledgeGraphPipelineOptions } from '../graph/knowledgeGraphPipeline';\nimport { parseSyllabus, type ParsedSyllabus } from '../parsers/syllabusParser';\nimport { emitCurriculumFeed } from '../feed/curriculumFeedEmitter';\nimport type { KnowledgeGraph } from '../schemas/knowledgeGraphSchema';\nimport type { CurriculumFeed } from '../schemas/curriculumFeedSchema';\nimport type { KnowledgeGraphVerificationReport } from '../graph/knowledgeGraphVerifier';\n\nexport interface KnowledgePipelineOptions extends KnowledgeGraphPipelineOptions {}\n\nexport interface KnowledgePipelineResult {\n knowledgeGraph: KnowledgeGraph;\n parsedSyllabus?: ParsedSyllabus;\n curriculumFeed: CurriculumFeed;\n verificationReport?: KnowledgeGraphVerificationReport;\n warnings: string[];\n}\n\n/**\n * Run the full concept-driven knowledge graph pipeline.\n */\nexport async function runKnowledgeGraphPipeline(\n options: KnowledgePipelineOptions,\n): Promise<KnowledgePipelineResult> {\n const warnings: string[] = [];\n let parsedSyllabus = options.parsedSyllabus;\n\n if (!parsedSyllabus && options.syllabusText) {\n parsedSyllabus = parseSyllabus(options.syllabusText);\n }\n\n const effectiveSubject = options.subject || parsedSyllabus?.subject.title || 'Untitled Subject';\n const effectiveDomain = options.domain || parsedSyllabus?.subject.domain || 'other';\n const effectiveGradeBand = options.gradeBand || parsedSyllabus?.subject.gradeBand;\n const effectiveDesc = options.description || parsedSyllabus?.subject.description;\n\n const result = await generateKnowledgeGraph({\n ...options,\n subject: effectiveSubject,\n domain: effectiveDomain,\n gradeBand: effectiveGradeBand,\n description: effectiveDesc,\n parsedSyllabus,\n });\n\n warnings.push(...result.warnings);\n\n // Emit normalized CurriculumFeed v2\n const curriculumFeed = emitCurriculumFeed(result.knowledgeGraph, {\n warnings,\n });\n\n return {\n knowledgeGraph: result.knowledgeGraph,\n parsedSyllabus,\n curriculumFeed,\n verificationReport: result.verificationReport,\n warnings,\n };\n}\n","/**\n * Hybrid Graph Pipeline Orchestrator.\n *\n * Runs: Hybrid Graph Generation -> CurriculumFeed v2 Emission.\n */\n\nimport { generateHybridGraph, type HybridGraphPipelineOptions } from '../graph/hybridGraphPipeline';\nimport { emitCurriculumFeed } from '../feed/curriculumFeedEmitter';\nimport type { HybridGraph } from '../schemas/hybridGraphSchema';\nimport type { CurriculumFeed } from '../schemas/curriculumFeedSchema';\n\nexport interface HybridPipelineOptions extends HybridGraphPipelineOptions {}\n\nexport interface HybridPipelineResult {\n hybridGraph: HybridGraph;\n curriculumFeed: CurriculumFeed;\n warnings: string[];\n}\n\n/**\n * Run the hybrid graph generation and feed emission pipeline.\n */\nexport async function runHybridGraphPipeline(\n options: HybridPipelineOptions,\n): Promise<HybridPipelineResult> {\n const warnings: string[] = [];\n const result = await generateHybridGraph(options);\n warnings.push(...result.warnings);\n\n const curriculumFeed = emitCurriculumFeed(result.hybridGraph, {\n warnings,\n });\n\n return {\n hybridGraph: result.hybridGraph,\n curriculumFeed,\n warnings,\n };\n}\n","/**\n * Unified Domain Pipeline Router.\n *\n * Implements the 3-Layer Architecture from docs/ideas/2026-08-30-domain-detection-and-graph-types.md:\n * Layer 1: DOMAIN DETECTION (detectDomainProfile)\n * Layer 2: GRAPH ROUTER (routeDomain)\n * Layer 3: GRAPH GENERATION (runProjectGraphPipeline | runKnowledgeGraphPipeline | runHybridGraphPipeline)\n * Layer 4: NORMALIZED OUTPUT (CurriculumFeed v2)\n */\n\nimport { detectDomainProfile, type DetectDomainProfileOptions } from '../detector/domainProfileDetector';\nimport type { DomainProfile, GraphType } from '../schemas/domainProfileSchema';\nimport type { CurriculumFeed } from '../schemas/curriculumFeedSchema';\nimport { runProjectGraphPipeline, type PipelineOptions, type PipelineResult } from './projectGraphPipeline';\nimport { runKnowledgeGraphPipeline, type KnowledgePipelineOptions, type KnowledgePipelineResult } from './knowledgeGraphPipeline';\nimport { runHybridGraphPipeline, type HybridPipelineOptions, type HybridPipelineResult } from './hybridGraphPipeline';\nimport type { LlmClientConfig } from '../utils/llmClient';\nimport type { ParsedSyllabus } from '../parsers/syllabusParser';\n\nexport interface DomainPipelineOptions extends DetectDomainProfileOptions {\n subject?: string;\n llmConfig?: LlmClientConfig;\n onProgress?: (step: string, message: string) => void;\n parsedSyllabus?: ParsedSyllabus;\n knowledgeTreePath?: string;\n proposalsPath?: string;\n embeddings?: Record<string, { embedding?: number[]; name?: string; description?: string; keywords?: string }>;\n /** Override automatic learning mode detection */\n forcedLearningMode?: 'product' | 'concept' | 'hybrid';\n}\n\nexport interface DomainPipelineResult {\n domainProfile: DomainProfile;\n graphType: GraphType;\n curriculumFeed: CurriculumFeed;\n projectResult?: PipelineResult;\n knowledgeResult?: KnowledgePipelineResult;\n hybridResult?: HybridPipelineResult;\n warnings: string[];\n}\n\n/**\n * Route and execute the appropriate domain pipeline based on input context.\n */\nexport async function runDomainPipeline(\n options: DomainPipelineOptions,\n): Promise<DomainPipelineResult> {\n const warnings: string[] = [];\n const log = (step: string, msg: string) => {\n console.log(`[ROUTER-${step}] ${msg}`);\n options.onProgress?.(step, msg);\n };\n\n // ─── Layer 1: Domain Detection ───────────────────────────────────────────\n log('LAYER_1', 'Detecting domain profile...');\n const domainProfile = detectDomainProfile(options);\n\n const effectiveMode = options.forcedLearningMode || domainProfile.learningMode;\n log('LAYER_2', `Routing to pipeline for learning mode: ${effectiveMode} (graphType: ${domainProfile.graphType})`);\n\n // ─── Layer 3: Dispatch & Execute ─────────────────────────────────────────\n if (effectiveMode === 'concept') {\n log('LAYER_3', 'Executing Knowledge Graph Pipeline (Concept-driven)...');\n const knowledgeResult = await runKnowledgeGraphPipeline({\n subject: options.subject || domainProfile.detectedSubject || options.goal || options.description || 'General Subject',\n description: options.description,\n syllabusText: options.syllabusText,\n parsedSyllabus: options.parsedSyllabus,\n gradeBand: options.gradeBand,\n domain: domainProfile.domainCategory,\n techStack: options.techStack || domainProfile.detectedTechStack?.[0],\n llmConfig: options.llmConfig,\n onProgress: options.onProgress,\n knowledgeTreePath: options.knowledgeTreePath,\n proposalsPath: options.proposalsPath,\n });\n warnings.push(...knowledgeResult.warnings);\n\n return {\n domainProfile,\n graphType: 'knowledge_graph',\n curriculumFeed: knowledgeResult.curriculumFeed,\n knowledgeResult,\n warnings,\n };\n }\n\n if (effectiveMode === 'hybrid') {\n log('LAYER_3', 'Executing Hybrid Graph Pipeline...');\n if (options.repoDir) {\n const projectResult = await runProjectGraphPipeline({\n repoDir: options.repoDir,\n goal: options.goal || 'Build complete project',\n techStack: options.techStack || 'typescript',\n llmConfig: options.llmConfig,\n embeddings: options.embeddings,\n onProgress: options.onProgress,\n });\n\n const knowledgeResult = await runKnowledgeGraphPipeline({\n subject: options.subject || domainProfile.detectedSubject || options.goal || 'Subject Theory',\n description: options.description,\n syllabusText: options.syllabusText,\n parsedSyllabus: options.parsedSyllabus,\n domain: domainProfile.domainCategory,\n techStack: options.techStack,\n llmConfig: options.llmConfig,\n onProgress: options.onProgress,\n });\n\n const hybridResult = await runHybridGraphPipeline({\n projectGraph: projectResult.projectGraph,\n knowledgeGraph: knowledgeResult.knowledgeGraph,\n llmConfig: options.llmConfig,\n onProgress: options.onProgress,\n });\n\n warnings.push(...hybridResult.warnings);\n return {\n domainProfile,\n graphType: 'hybrid_graph',\n curriculumFeed: hybridResult.curriculumFeed,\n projectResult,\n knowledgeResult,\n hybridResult,\n warnings,\n };\n } else {\n warnings.push('Hybrid learning mode requested but repoDir was not provided — falling back to concept-driven knowledge graph pipeline');\n const knowledgeResult = await runKnowledgeGraphPipeline({\n subject: options.subject || domainProfile.detectedSubject || options.goal || 'Subject Theory',\n description: options.description,\n syllabusText: options.syllabusText,\n parsedSyllabus: options.parsedSyllabus,\n domain: domainProfile.domainCategory,\n techStack: options.techStack,\n llmConfig: options.llmConfig,\n onProgress: options.onProgress,\n });\n warnings.push(...knowledgeResult.warnings);\n\n return {\n domainProfile,\n graphType: 'knowledge_graph',\n curriculumFeed: knowledgeResult.curriculumFeed,\n knowledgeResult,\n warnings,\n };\n }\n }\n\n // Default: product-driven\n log('LAYER_3', 'Executing Project Graph Pipeline (Product-driven)...');\n if (!options.repoDir) {\n throw new Error('repoDir is required for product-driven project graph pipeline');\n }\n\n const projectResult = await runProjectGraphPipeline({\n repoDir: options.repoDir,\n goal: options.goal || 'Build complete project',\n techStack: options.techStack || domainProfile.detectedTechStack?.[0] || 'typescript',\n llmConfig: options.llmConfig,\n embeddings: options.embeddings,\n onProgress: options.onProgress,\n });\n\n // Emit curriculum feed from project graph\n const { emitCurriculumFeed } = await import('../feed/curriculumFeedEmitter');\n const curriculumFeed = emitCurriculumFeed(projectResult.projectGraph, {\n warnings,\n });\n\n return {\n domainProfile,\n graphType: 'project_graph',\n curriculumFeed,\n projectResult,\n warnings,\n };\n}\n"]}
@@ -29,11 +29,33 @@ var FeedNodeSchema = z.object({
29
29
  references: z.array(z.object({ file: z.string().min(1), evidence: z.string().default("") })).default([]),
30
30
  feature_id: z.string().nullable().default(null),
31
31
  concept_ref: z.string().nullable().default(null),
32
+ // P52/T2.1: outcome.user_visible projected from the ProjectGraph step — the
33
+ // tangible checkpoint the session-cutting planner aims for (empty when the
34
+ // step declares no user-visible result). Concepts carry '' by default.
35
+ user_visible_deliverable: z.string().default(""),
36
+ // P52/T3.1 — depth-reconcile inputs (optional/defaulted so old feeds
37
+ // validate unchanged):
38
+ // • depth_variants: minutes to teach this node at each depth level.
39
+ // ULO (know-it-exists) ≤ CIO (mechanism) ≤ SIO (implementation). All 3
40
+ // required so a downgrade never turns an anchor teach into a zero.
41
+ // • depth_scaffold_candidates: parallel to scaffold_candidates but
42
+ // acts on DEPTH (e.g. SIO→CIO) instead of lesson time.
43
+ // • is_core: concept is a Master-Tree core concept — reconciler must
44
+ // never downgrade it; escalate instead.
45
+ depth_variants: z.object({ ulo: z.number().int().nonnegative(), cio: z.number().int().nonnegative(), sio: z.number().int().nonnegative() }).optional(),
46
+ depth_scaffold_candidates: z.array(z.object({
47
+ from_depth: z.enum(["ulo", "cio", "sio"]),
48
+ to_depth: z.enum(["ulo", "cio", "sio"]),
49
+ minutes_saved: z.number().int().nonnegative(),
50
+ reason: z.string().default("")
51
+ })).optional(),
52
+ is_core: z.boolean().default(false),
32
53
  // Progressive-completion bookkeeping (feed v2, additive):
33
54
  // phase_id = development phase that introduces/uses this node;
34
- // introduce_aspect = how the phase teaches a concept node (first intro vs advanced revisit).
55
+ // introduce_aspect = how the phase teaches a concept node (first intro, advanced
56
+ // revisit, or preview — a light ULO awareness pass that is NOT the introduction).
35
57
  phase_id: z.string().default(""),
36
- introduce_aspect: z.enum(["new", "advanced"]).nullable().default(null)
58
+ introduce_aspect: z.enum(["new", "advanced", "preview"]).nullable().default(null)
37
59
  });
38
60
  var FeedEdgeSchema = z.object({
39
61
  from: z.string().min(1),
@@ -92,9 +114,25 @@ function validateCurriculumFeed(feed) {
92
114
  }
93
115
  const phaseIds = parsed.phases.map((p) => p.id);
94
116
  if (new Set(phaseIds).size !== phaseIds.length) throw new Error("curriculum feed contains duplicate phase ids");
117
+ if (parsed.phases.length > 0) {
118
+ const phaseIndexOf = /* @__PURE__ */ new Map();
119
+ parsed.phases.forEach((p, i) => {
120
+ for (const id of p.node_ids) phaseIndexOf.set(id, i);
121
+ });
122
+ for (const e of parsed.dependency_edges) {
123
+ const fromIdx = phaseIndexOf.get(e.from);
124
+ const toIdx = phaseIndexOf.get(e.to);
125
+ if (fromIdx === void 0 || toIdx === void 0) continue;
126
+ if (fromIdx > toIdx) {
127
+ throw new Error(
128
+ "curriculum feed teaching-order violation: prerequisite " + e.from + " (phase " + (fromIdx + 1) + ") is scheduled AFTER its consumer " + e.to + " (phase " + (toIdx + 1) + ")"
129
+ );
130
+ }
131
+ }
132
+ }
95
133
  return parsed;
96
134
  }
97
135
 
98
136
  export { CurriculumFeedSchema, FeedEdgeSchema, FeedGroupingSchema, FeedKeywordsSchema, FeedNodeSchema, FeedPhaseSchema, FeedScaffoldCandidateSchema, validateCurriculumFeed };
99
- //# sourceMappingURL=chunk-HH4UX65C.mjs.map
100
- //# sourceMappingURL=chunk-HH4UX65C.mjs.map
137
+ //# sourceMappingURL=chunk-PKUEOSZ3.mjs.map
138
+ //# sourceMappingURL=chunk-PKUEOSZ3.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schemas/curriculumFeedSchema.ts"],"names":[],"mappings":"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","file":"chunk-PKUEOSZ3.mjs","sourcesContent":["import { z } from 'zod';\n\n/**\n * CurriculumFeed v2 — normalized, planner-ready projection of a domain graph.\n * Consumers: curriculum-kit Curriculum Planner (see docs/ideas/2026-08-30-curriculum-feed-v2-output.md).\n * Guarantees enforced here: cycle-free is the CALLER's verifier job; the feed\n * itself guarantees resolution (edges/keywords reference emitted nodes) and\n * non-emptiness.\n */\n\nexport const FeedKeywordsSchema = z.object({\n all: z.array(z.string()).default([]),\n new: z.array(z.string()).default([]),\n prerequisite: z.array(z.string()).default([]),\n});\n\nexport const FeedScaffoldCandidateSchema = z.object({\n item: z.string(),\n reason: z.string().default(''),\n minutes_saved: z.number().int().nonnegative().default(0),\n suggest: z.enum(['provide_full', 'provide_partial', 'provide_reference']).default('provide_full'),\n});\n\nexport const FeedNodeSchema = z.object({\n id: z.string().min(1),\n kind: z.enum(['skill', 'concept', 'product_step']),\n name: z.string().min(1),\n concept_codes: z.array(z.string()).default([]),\n keywords: FeedKeywordsSchema,\n estimated_minutes: z.number().int().nonnegative(),\n bloom_hint: z.enum(['Remember', 'Understand', 'Apply', 'Analyze', 'Evaluate', 'Create']).nullable().default(null),\n depth_hint: z.enum(['ulo', 'cio', 'sio']).nullable().default(null),\n completion_level: z.enum(['mvp', 'standard', 'stretch']).default('standard'),\n scaffolding: z.object({\n scaffold_candidates: z.array(FeedScaffoldCandidateSchema).default([]),\n core_value_minutes: z.number().int().nonnegative().default(0),\n }).default({ scaffold_candidates: [], core_value_minutes: 0 }),\n references: z.array(z.object({ file: z.string().min(1), evidence: z.string().default('') })).default([]),\n feature_id: z.string().nullable().default(null),\n concept_ref: z.string().nullable().default(null),\n // P52/T2.1: outcome.user_visible projected from the ProjectGraph step — the\n // tangible checkpoint the session-cutting planner aims for (empty when the\n // step declares no user-visible result). Concepts carry '' by default.\n user_visible_deliverable: z.string().default(''),\n // P52/T3.1 — depth-reconcile inputs (optional/defaulted so old feeds\n // validate unchanged):\n // • depth_variants: minutes to teach this node at each depth level.\n // ULO (know-it-exists) ≤ CIO (mechanism) ≤ SIO (implementation). All 3\n // required so a downgrade never turns an anchor teach into a zero.\n // • depth_scaffold_candidates: parallel to scaffold_candidates but\n // acts on DEPTH (e.g. SIO→CIO) instead of lesson time.\n // • is_core: concept is a Master-Tree core concept — reconciler must\n // never downgrade it; escalate instead.\n depth_variants: z.object({ ulo: z.number().int().nonnegative(), cio: z.number().int().nonnegative(), sio: z.number().int().nonnegative() }).optional(),\n depth_scaffold_candidates: z.array(z.object({\n from_depth: z.enum(['ulo', 'cio', 'sio']),\n to_depth: z.enum(['ulo', 'cio', 'sio']),\n minutes_saved: z.number().int().nonnegative(),\n reason: z.string().default(''),\n })).optional(),\n is_core: z.boolean().default(false),\n // Progressive-completion bookkeeping (feed v2, additive):\n // phase_id = development phase that introduces/uses this node;\n // introduce_aspect = how the phase teaches a concept node (first intro, advanced\n // revisit, or preview — a light ULO awareness pass that is NOT the introduction).\n phase_id: z.string().default(''),\n introduce_aspect: z.enum(['new', 'advanced', 'preview']).nullable().default(null),\n});\n\nexport const FeedEdgeSchema = z.object({\n from: z.string().min(1),\n to: z.string().min(1),\n kind: z.enum(['knowledge', 'task']),\n reason: z.string().default(''),\n});\n\nexport const FeedGroupingSchema = z.object({\n id: z.string().min(1),\n name: z.string().min(1),\n node_ids: z.array(z.string()).min(1),\n rationale: z.string().default(''),\n});\n\nexport const FeedPhaseSchema = z.object({\n id: z.string().min(1),\n order: z.number().int().positive(),\n name: z.string().min(1),\n product_completion: z.string().min(1),\n node_ids: z.array(z.string()).min(1),\n});\nexport type FeedPhase = z.infer<typeof FeedPhaseSchema>;\n\nexport const CurriculumFeedSchema = z.object({\n schema_version: z.literal(2),\n source: z.object({\n graph_type: z.enum(['project_graph', 'knowledge_graph', 'hybrid_graph']),\n warnings: z.array(z.string()).default([]),\n hallucination_count: z.number().int().nonnegative().default(0),\n }),\n learning_nodes: z.array(FeedNodeSchema).min(1, 'curriculum feed must contain at least one learning node'),\n dependency_edges: z.array(FeedEdgeSchema).default([]),\n suggested_groupings: z.array(FeedGroupingSchema).default([]),\n // Progressive completion phases (cross-feature). When non-empty, these — not\n // suggested_groupings — define the teaching sequence and unit structure.\n phases: z.array(FeedPhaseSchema).default([]),\n});\n\nexport type CurriculumFeed = z.infer<typeof CurriculumFeedSchema>;\nexport type FeedNode = z.infer<typeof FeedNodeSchema>;\nexport type FeedEdge = z.infer<typeof FeedEdgeSchema>;\nexport type FeedGrouping = z.infer<typeof FeedGroupingSchema>;\n\n/** Strict pre-save resolution validation — fail-closed, no defaulted-empty graphs. */\nexport function validateCurriculumFeed(feed: unknown): CurriculumFeed {\n const parsed = CurriculumFeedSchema.parse(feed);\n const ids = new Set(parsed.learning_nodes.map((n) => n.id));\n if (ids.size !== parsed.learning_nodes.length) {\n throw new Error('curriculum feed contains duplicate node ids');\n }\n for (const e of parsed.dependency_edges) {\n if (!ids.has(e.from) || !ids.has(e.to)) {\n throw new Error('curriculum feed edge ' + e.from + ' -> ' + e.to + ' references unknown node');\n }\n if (e.from === e.to) throw new Error('curriculum feed self-loop edge on ' + e.from);\n }\n for (const g of parsed.suggested_groupings) {\n for (const id of g.node_ids) {\n if (!ids.has(id)) throw new Error('grouping ' + g.id + ' references unknown node ' + id);\n }\n }\n for (const ph of parsed.phases) {\n for (const id of ph.node_ids) {\n if (!ids.has(id)) throw new Error('phase ' + ph.id + ' references unknown node ' + id);\n }\n }\n const phaseIds = parsed.phases.map((p) => p.id);\n if (new Set(phaseIds).size !== phaseIds.length) throw new Error('curriculum feed contains duplicate phase ids');\n // Teaching-order invariant (2026-09-17 incident): when phases define the\n // teaching sequence, a prerequisite must live in the same or an EARLIER\n // phase than its consumer. Without this check a self-contradictory feed\n // (backwards phase-crossing edge) sailed through emission and only exploded\n // much later inside the planner as \"Teaching-order violation in session ...\"\n // — far from the constructor that produced the contradiction.\n if (parsed.phases.length > 0) {\n const phaseIndexOf = new Map<string, number>();\n parsed.phases.forEach((p, i) => {\n for (const id of p.node_ids) phaseIndexOf.set(id, i);\n });\n for (const e of parsed.dependency_edges) {\n const fromIdx = phaseIndexOf.get(e.from);\n const toIdx = phaseIndexOf.get(e.to);\n if (fromIdx === undefined || toIdx === undefined) continue; // node outside the phase sequence\n if (fromIdx > toIdx) {\n throw new Error(\n 'curriculum feed teaching-order violation: prerequisite ' + e.from +\n ' (phase ' + (fromIdx + 1) + ') is scheduled AFTER its consumer ' + e.to +\n ' (phase ' + (toIdx + 1) + ')',\n );\n }\n }\n }\n return parsed;\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { validateCurriculumFeed } from './chunk-HH4UX65C.mjs';
1
+ import { validateCurriculumFeed } from './chunk-PKUEOSZ3.mjs';
2
2
 
3
3
  // src/feed/curriculumFeedEmitter.ts
4
4
  var BLOOM_RANK = { Remember: 0, Understand: 1, Apply: 2, Analyze: 3, Evaluate: 4, Create: 5 };
@@ -11,6 +11,9 @@ function stepMinutes(step) {
11
11
  const effort = step.effort ?? {};
12
12
  return Math.max(0, Math.round(num(effort.estimated_minutes, num(step.estimated_minutes, 45))));
13
13
  }
14
+ function pushWarning(opts, message) {
15
+ (opts.warnings ?? (opts.warnings = [])).push(message);
16
+ }
14
17
  function newKeywordsInOrder(nodes) {
15
18
  const seen = /* @__PURE__ */ new Set();
16
19
  for (const n of nodes) {
@@ -40,6 +43,10 @@ function feedNodeFromStep(step, featureId) {
40
43
  references: arr(step.files).map((f) => ({ file: str(f), evidence: "step file" })).filter((f) => f.file),
41
44
  feature_id: featureId,
42
45
  concept_ref: null,
46
+ // P52/T2.1: carry the step's tangible outcome so the planner can cut
47
+ // sessions at user-visible checkpoints instead of raw minute counts.
48
+ user_visible_deliverable: str(step.outcome?.user_visible),
49
+ is_core: false,
43
50
  phase_id: "",
44
51
  introduce_aspect: null
45
52
  };
@@ -58,6 +65,20 @@ function deriveConceptDepthHint(concept) {
58
65
  if (str(concept.cio) || prereqs.length >= 1) return "cio";
59
66
  return "ulo";
60
67
  }
68
+ function deriveDepthInputs(minutes, depth) {
69
+ const ulo = Math.max(5, Math.round(minutes * 0.35));
70
+ const cio = Math.max(ulo + 5, Math.round(minutes * 0.65));
71
+ const sio = Math.max(cio + 5, minutes);
72
+ const variants = { ulo, cio, sio };
73
+ const candidates = [];
74
+ if (depth === "sio") {
75
+ candidates.push({ from_depth: "sio", to_depth: "cio", minutes_saved: sio - cio, reason: "SIO implementation practice deferred \u2014 CIO mechanism suffices for downstream consumers" });
76
+ }
77
+ if (depth === "cio" || depth === "sio") {
78
+ candidates.push({ from_depth: depth, to_depth: "ulo", minutes_saved: (depth === "sio" ? sio : cio) - ulo, reason: "Mechanism deferred \u2014 ULO awareness suffices (know-it-exists); never below the ULO floor" });
79
+ }
80
+ return { depth_variants: variants, depth_scaffold_candidates: candidates };
81
+ }
61
82
  function feedNodeFromConcept(concept) {
62
83
  const id = str(concept.id);
63
84
  const pts = arr(concept.problem_types).map((p) => str(p.bloom_level, "Understand")).filter((b) => b in BLOOM_RANK).sort((a, b) => BLOOM_RANK[a] - BLOOM_RANK[b]);
@@ -87,6 +108,10 @@ function feedNodeFromConcept(concept) {
87
108
  references,
88
109
  feature_id: null,
89
110
  concept_ref: id,
111
+ user_visible_deliverable: "",
112
+ // concepts are taught, not shipped — checkpoints live on product steps
113
+ ...deriveDepthInputs(Math.max(0, Math.round(num(concept.estimated_minutes, 15))), deriveConceptDepthHint(concept)),
114
+ is_core: false,
90
115
  phase_id: "",
91
116
  introduce_aspect: null
92
117
  };
@@ -147,6 +172,7 @@ function emitFromHybrid(hybrid, opts) {
147
172
  }
148
173
  const emitCtx = [];
149
174
  const emittedConcepts = /* @__PURE__ */ new Set();
175
+ const previewsEmitted = /* @__PURE__ */ new Set();
150
176
  const linkList = arr(hybrid.links);
151
177
  for (const rp of rawPhases) {
152
178
  const pid = str(rp.id);
@@ -155,7 +181,8 @@ function emitFromHybrid(hybrid, opts) {
155
181
  const intros = arr(rp.introduces);
156
182
  const news = intros.filter((i) => str(i.aspect, "new") === "new");
157
183
  const advanced = intros.filter((i) => str(i.aspect) === "advanced");
158
- for (const intro of [...news, ...advanced]) {
184
+ const previews = intros.filter((i) => str(i.aspect) === "preview");
185
+ for (const intro of [...news, ...advanced, ...previews]) {
159
186
  const cid = str(intro.concept_id);
160
187
  const c = conceptById.get(cid);
161
188
  if (!c) {
@@ -164,6 +191,39 @@ function emitFromHybrid(hybrid, opts) {
164
191
  if (str(intro.aspect, "new") === "advanced" && !emittedConcepts.has(cid)) {
165
192
  throw new Error("Phase " + pid + " advanced-revisits concept " + cid + " that was never emitted - fail-closed");
166
193
  }
194
+ if (str(intro.aspect, "new") === "preview") {
195
+ if (emittedConcepts.has(cid)) {
196
+ throw new Error("Phase " + pid + " previews concept " + cid + " that was already introduced - preview must precede the anchor teach - fail-closed");
197
+ }
198
+ if (previewsEmitted.has(cid)) {
199
+ throw new Error("Phase " + pid + " duplicate preview of concept " + cid + " - fail-closed");
200
+ }
201
+ const pidIdx = rawPhases.findIndex((rp2) => str(rp2.id) === pid);
202
+ const anchorIdx = rawPhases.findIndex((rp2) => arr(rp2.introduces).some((i2) => str(i2.concept_id) === cid && str(i2.aspect, "new") !== "preview"));
203
+ if (anchorIdx < 0) {
204
+ throw new Error("Phase " + pid + " previews concept " + cid + " that is never fully introduced in any phase - fail-closed");
205
+ }
206
+ if (pidIdx >= anchorIdx) {
207
+ throw new Error("Phase " + pid + " previews concept " + cid + " whose anchor introduction is not in a LATER phase - fail-closed");
208
+ }
209
+ previewsEmitted.add(cid);
210
+ const prevNode = feedNodeFromConcept(c);
211
+ prevNode.id = cid + "__PREV" + pad2(order);
212
+ prevNode.name = str(c.name, cid) + " (preview)";
213
+ prevNode.phase_id = pid;
214
+ prevNode.introduce_aspect = "preview";
215
+ prevNode.estimated_minutes = Math.max(5, Math.round(prevNode.estimated_minutes * 0.25));
216
+ prevNode.depth_hint = "ulo";
217
+ prevNode.bloom_hint = "Understand";
218
+ prevNode.concept_codes = [str(c.code) || cid];
219
+ prevNode.keywords = { all: strs(c.keywords), new: [], prerequisite: [] };
220
+ prevNode.scaffolding = { scaffold_candidates: [], core_value_minutes: 0 };
221
+ prevNode.depth_variants = { ulo: prevNode.estimated_minutes, cio: prevNode.estimated_minutes, sio: prevNode.estimated_minutes };
222
+ prevNode.depth_scaffold_candidates = [];
223
+ nodes.push(prevNode);
224
+ conceptOrder.push(prevNode.id);
225
+ continue;
226
+ }
167
227
  if (!emittedConcepts.has(cid)) {
168
228
  const node = feedNodeFromConcept(c);
169
229
  node.phase_id = pid;
@@ -184,6 +244,7 @@ function emitFromHybrid(hybrid, opts) {
184
244
  node.name = str(c.name, cid) + " (advanced)";
185
245
  node.phase_id = pid;
186
246
  node.introduce_aspect = "advanced";
247
+ node.depth_scaffold_candidates = [{ from_depth: "sio", to_depth: "cio", minutes_saved: Math.round(node.estimated_minutes * 0.3), reason: "advanced revisit may drop to CIO recap without breaking first-teach chain" }];
187
248
  node.estimated_minutes = Math.max(15, Math.round(node.estimated_minutes * 0.5));
188
249
  node.concept_codes = [str(c.code) || cid];
189
250
  edges.push({ from: cid, to: revisitId, kind: "knowledge", reason: "advanced revisit of " + cid + " at phase " + pid });
@@ -219,6 +280,17 @@ function emitFromHybrid(hybrid, opts) {
219
280
  }
220
281
  phaseNodeIds.push(ids);
221
282
  }
283
+ const placed = new Set(phaseNodeIds.flat());
284
+ const orderedNodes = [];
285
+ for (const ids of phaseNodeIds) {
286
+ for (const id of ids) {
287
+ const n = nodes.find((x) => x.id === id);
288
+ if (n) orderedNodes.push(n);
289
+ }
290
+ }
291
+ for (const n of nodes) if (!placed.has(n.id)) orderedNodes.push(n);
292
+ nodes.length = 0;
293
+ nodes.push(...orderedNodes);
222
294
  const edgeSeen = new Set(edges.map((e) => e.from + ">" + e.to));
223
295
  const pushEdge = (from, to, reason) => {
224
296
  const key = from + ">" + to;
@@ -233,6 +305,14 @@ function emitFromHybrid(hybrid, opts) {
233
305
  const firstStep = (stepIdsByFeature.get(fid) || [])[0];
234
306
  if (!firstStep) continue;
235
307
  const depth = str(l.depth, "cio");
308
+ const anchorNode = nodes.find((n2) => n2.kind === "concept" && n2.concept_ref === cid && n2.introduce_aspect === "new");
309
+ const stepNode = nodes.find((n2) => n2.id === firstStep);
310
+ const anchorPhaseIdx = anchorNode ? emitCtx.findIndex((c2) => c2.id === anchorNode.phase_id) : -1;
311
+ const stepPhaseIdx = stepNode ? emitCtx.findIndex((c2) => c2.id === stepNode.phase_id) : -1;
312
+ if (emitCtx.length > 0 && anchorPhaseIdx > stepPhaseIdx) {
313
+ pushWarning(opts, "hybrid link drift: concept " + cid + " is fully taught in a later phase than consumer " + firstStep + " (a preview covers the dependency)");
314
+ continue;
315
+ }
236
316
  pushEdge(cid, firstStep, str(l.relationship, "hybrid link") + " [" + depth + "]");
237
317
  for (const n of nodes) {
238
318
  if (n.kind === "concept" && n.concept_ref === cid && n.introduce_aspect === "advanced" && n.phase_id === str(l.phase_id)) {
@@ -251,6 +331,21 @@ function emitFromHybrid(hybrid, opts) {
251
331
  for (const k of n.keywords?.prerequisite ?? []) {
252
332
  const src = introducer.get(k.toLowerCase());
253
333
  if (!src || src === n.id) continue;
334
+ const srcNode = nodes.find((x) => x.id === src);
335
+ const phaseOf = (id) => {
336
+ const n2 = nodes.find((x) => x.id === id);
337
+ return n2 ? emitCtx.findIndex((c) => c.id === n2.phase_id) : -1;
338
+ };
339
+ const conceptOvertaken = n.kind === "concept" && srcNode?.kind === "product_step";
340
+ const fromPhase = phaseOf(src);
341
+ const toPhase = phaseOf(n.id);
342
+ if (conceptOvertaken || emitCtx.length > 0 && fromPhase > toPhase) {
343
+ pushWarning(
344
+ opts,
345
+ "keyword-order drift: introducer " + src + " sits in a later phase than consumer " + n.id + ' (keyword "' + k + '") \u2014 host should move the introducer earlier'
346
+ );
347
+ continue;
348
+ }
254
349
  if (feedOrder.get(src) < feedOrder.get(n.id)) pushEdge(src, n.id, "keyword prerequisite [" + k + "]");
255
350
  }
256
351
  }
@@ -370,5 +465,5 @@ function emitCurriculumFeed(graph, opts = {}) {
370
465
  }
371
466
 
372
467
  export { emitCurriculumFeed };
373
- //# sourceMappingURL=chunk-HUDFN4IX.mjs.map
374
- //# sourceMappingURL=chunk-HUDFN4IX.mjs.map
468
+ //# sourceMappingURL=chunk-QJF4QCBJ.mjs.map
469
+ //# sourceMappingURL=chunk-QJF4QCBJ.mjs.map