@happyvertical/smrt-core 0.36.8 → 0.37.1

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 (105) hide show
  1. package/dist/child-accessors.d.ts +1 -1
  2. package/dist/child-accessors.d.ts.map +1 -1
  3. package/dist/child-accessors.js +1 -1
  4. package/dist/child-accessors.js.map +1 -1
  5. package/dist/class.d.ts.map +1 -1
  6. package/dist/class.js +3 -1
  7. package/dist/class.js.map +1 -1
  8. package/dist/collection-cache.d.ts.map +1 -1
  9. package/dist/collection-cache.js +5 -3
  10. package/dist/collection-cache.js.map +1 -1
  11. package/dist/collection.d.ts +39 -16
  12. package/dist/collection.d.ts.map +1 -1
  13. package/dist/collection.js +40 -19
  14. package/dist/collection.js.map +1 -1
  15. package/dist/consumer-plugin/index.js.map +1 -1
  16. package/dist/decorators/compatibility.d.ts +1 -1
  17. package/dist/decorators/compatibility.d.ts.map +1 -1
  18. package/dist/decorators/compatibility.js.map +1 -1
  19. package/dist/decorators/index.d.ts +4 -4
  20. package/dist/decorators/index.d.ts.map +1 -1
  21. package/dist/decorators/index.js.map +1 -1
  22. package/dist/hierarchical.d.ts.map +1 -1
  23. package/dist/hierarchical.js.map +1 -1
  24. package/dist/junction.d.ts.map +1 -1
  25. package/dist/junction.js.map +1 -1
  26. package/dist/manifest/discover-smrt-packages.d.ts +10 -0
  27. package/dist/manifest/discover-smrt-packages.d.ts.map +1 -1
  28. package/dist/manifest/discover-smrt-packages.js.map +1 -1
  29. package/dist/manifest/generator.d.ts.map +1 -1
  30. package/dist/manifest/generator.js +34 -37
  31. package/dist/manifest/generator.js.map +1 -1
  32. package/dist/manifest/index.js +2 -2
  33. package/dist/manifest/index.js.map +1 -1
  34. package/dist/manifest/manifest-loader.d.ts +10 -0
  35. package/dist/manifest/manifest-loader.d.ts.map +1 -1
  36. package/dist/manifest/manifest-loader.js.map +1 -1
  37. package/dist/manifest/static-manifest.d.ts.map +1 -1
  38. package/dist/manifest/static-manifest.js +39 -20
  39. package/dist/manifest/static-manifest.js.map +1 -1
  40. package/dist/manifest/store.js +2 -2
  41. package/dist/manifest/store.js.map +1 -1
  42. package/dist/manifest/test-manifest-stub.d.ts.map +1 -1
  43. package/dist/manifest/test-manifest-stub.js +2301 -629
  44. package/dist/manifest/test-manifest-stub.js.map +1 -1
  45. package/dist/manifest.json +39 -20
  46. package/dist/migrations/differ.d.ts +104 -13
  47. package/dist/migrations/differ.d.ts.map +1 -1
  48. package/dist/migrations/differ.js +199 -26
  49. package/dist/migrations/differ.js.map +1 -1
  50. package/dist/node_modules/.pnpm/{minimatch@10.2.3 → minimatch@10.2.5}/node_modules/minimatch/dist/esm/assert-valid-pattern.js.map +1 -1
  51. package/dist/node_modules/.pnpm/{minimatch@10.2.3 → minimatch@10.2.5}/node_modules/minimatch/dist/esm/ast.js +1 -7
  52. package/dist/node_modules/.pnpm/minimatch@10.2.5/node_modules/minimatch/dist/esm/ast.js.map +1 -0
  53. package/dist/node_modules/.pnpm/{minimatch@10.2.3 → minimatch@10.2.5}/node_modules/minimatch/dist/esm/brace-expressions.js.map +1 -1
  54. package/dist/node_modules/.pnpm/{minimatch@10.2.3 → minimatch@10.2.5}/node_modules/minimatch/dist/esm/escape.js.map +1 -1
  55. package/dist/node_modules/.pnpm/{minimatch@10.2.3 → minimatch@10.2.5}/node_modules/minimatch/dist/esm/index.js +17 -14
  56. package/dist/node_modules/.pnpm/minimatch@10.2.5/node_modules/minimatch/dist/esm/index.js.map +1 -0
  57. package/dist/node_modules/.pnpm/minimatch@10.2.5/node_modules/minimatch/dist/esm/unescape.js +10 -0
  58. package/dist/node_modules/.pnpm/{minimatch@10.2.3 → minimatch@10.2.5}/node_modules/minimatch/dist/esm/unescape.js.map +1 -1
  59. package/dist/object.d.ts +64 -17
  60. package/dist/object.d.ts.map +1 -1
  61. package/dist/object.js +76 -30
  62. package/dist/object.js.map +1 -1
  63. package/dist/registry/class-registration.d.ts +3 -3
  64. package/dist/registry/class-registration.d.ts.map +1 -1
  65. package/dist/registry/class-registration.js +39 -42
  66. package/dist/registry/class-registration.js.map +1 -1
  67. package/dist/registry/inheritance-resolver.d.ts +17 -3
  68. package/dist/registry/inheritance-resolver.d.ts.map +1 -1
  69. package/dist/registry/inheritance-resolver.js +1 -1
  70. package/dist/registry/inheritance-resolver.js.map +1 -1
  71. package/dist/registry/manifest-field-merge.d.ts +17 -3
  72. package/dist/registry/manifest-field-merge.d.ts.map +1 -1
  73. package/dist/registry/manifest-field-merge.js +8 -6
  74. package/dist/registry/manifest-field-merge.js.map +1 -1
  75. package/dist/registry/schema-builder.d.ts +1 -1
  76. package/dist/registry/schema-builder.d.ts.map +1 -1
  77. package/dist/registry/schema-builder.js.map +1 -1
  78. package/dist/registry/shared-state.d.ts +3 -3
  79. package/dist/registry/shared-state.d.ts.map +1 -1
  80. package/dist/registry/shared-state.js.map +1 -1
  81. package/dist/registry/types.d.ts +78 -19
  82. package/dist/registry/types.d.ts.map +1 -1
  83. package/dist/registry/validator.d.ts +2 -1
  84. package/dist/registry/validator.d.ts.map +1 -1
  85. package/dist/registry/validator.js +38 -39
  86. package/dist/registry/validator.js.map +1 -1
  87. package/dist/registry.d.ts +84 -57
  88. package/dist/registry.d.ts.map +1 -1
  89. package/dist/registry.js +31 -25
  90. package/dist/registry.js.map +1 -1
  91. package/dist/scanner/manifest-generator.d.ts.map +1 -1
  92. package/dist/scanner/manifest-generator.js +22 -20
  93. package/dist/scanner/manifest-generator.js.map +1 -1
  94. package/dist/smrt-knowledge.json +8 -7
  95. package/dist/system-fields.d.ts +1 -1
  96. package/dist/system-fields.d.ts.map +1 -1
  97. package/dist/system-fields.js.map +1 -1
  98. package/dist/vite-plugin/index.js +1 -1
  99. package/package.json +7 -7
  100. package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/ast.js.map +0 -1
  101. package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/index.js.map +0 -1
  102. package/dist/node_modules/.pnpm/minimatch@10.2.3/node_modules/minimatch/dist/esm/unescape.js +0 -10
  103. /package/dist/node_modules/.pnpm/{minimatch@10.2.3 → minimatch@10.2.5}/node_modules/minimatch/dist/esm/assert-valid-pattern.js +0 -0
  104. /package/dist/node_modules/.pnpm/{minimatch@10.2.3 → minimatch@10.2.5}/node_modules/minimatch/dist/esm/brace-expressions.js +0 -0
  105. /package/dist/node_modules/.pnpm/{minimatch@10.2.3 → minimatch@10.2.5}/node_modules/minimatch/dist/esm/escape.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"discover-smrt-packages.js","sources":["../../src/manifest/discover-smrt-packages.ts"],"sourcesContent":["/**\n * SMRT Package Discovery\n *\n * Discovers all SMRT packages in node_modules by:\n * 1. Scanning node_modules directory for installed packages\n * 2. Following symlinks for workspace: dependencies\n * 3. Checking for a package manifest (`dist/manifest.json`,\n * `.smrt/manifest.json`, or `src/manifest/manifest.json`) with moduleType: \"smrt\"\n * 4. Caching results based on lockfile hash and manifest timestamps\n *\n * Cache Strategy:\n * - ENABLED by default (5-50x faster startup)\n * - Automatically invalidates when lockfile or any manifest.json changes\n * - Disable with SMRT_DISABLE_DISCOVERY_CACHE=true for debugging\n */\n\nimport { createHash } from 'node:crypto';\nimport {\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n realpathSync,\n statSync,\n writeFileSync,\n} from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { dirname, join } from 'node:path';\nimport { parse } from '../utils/json.js';\n\nconst CACHE_DIR = '.smrt';\nconst CACHE_FILE = 'discovery-cache.json';\nconst CACHE_VERSION = 4;\n\n/** Timing data for --timing flag */\ninterface TimingData {\n discovery?: number;\n cacheCheck?: number;\n total?: number;\n}\n\n/** Module-level timing storage */\nlet lastTimingData: TimingData = {};\n\n/**\n * Get timing data from last discovery operation\n */\nexport function getDiscoveryTiming(): TimingData {\n return { ...lastTimingData };\n}\n\n/**\n * Get hash of lockfile for cache invalidation\n */\nfunction getLockfileHash(baseDir: string): string | null {\n // Check for pnpm or npm lockfile\n const lockfile = existsSync(join(baseDir, 'pnpm-lock.yaml'))\n ? join(baseDir, 'pnpm-lock.yaml')\n : join(baseDir, 'package-lock.json');\n\n if (!existsSync(lockfile)) {\n return null;\n }\n\n const content = readFileSync(lockfile, 'utf-8');\n return createHash('sha256').update(content).digest('hex');\n}\n\n/**\n * Get hash of package.json for cache invalidation when a package workspace\n * changes its declared dependencies without a colocated lockfile.\n */\nfunction getPackageJsonHash(baseDir: string): string | null {\n const packageJsonPath = join(baseDir, 'package.json');\n\n if (!existsSync(packageJsonPath)) {\n return null;\n }\n\n const content = readFileSync(packageJsonPath, 'utf-8');\n return createHash('sha256').update(content).digest('hex');\n}\n\n/**\n * Get a hash of all manifest timestamps for cache invalidation\n * This catches changes to SMRT packages even when lockfile hasn't changed\n */\nfunction getManifestTimestampsHash(\n baseDir: string,\n packages: string[],\n): string {\n const timestamps: string[] = [];\n\n for (const pkgName of packages) {\n try {\n const manifestPath = resolveManifestPath(pkgName, baseDir);\n\n if (manifestPath && existsSync(manifestPath)) {\n const stats = statSync(manifestPath);\n timestamps.push(`${pkgName}:${stats.mtimeMs}`);\n }\n } catch {\n // Ignore errors, package may have been removed\n }\n }\n\n return createHash('sha256').update(timestamps.join('|')).digest('hex');\n}\n\ninterface DiscoveryCache {\n version: number;\n lockfileHash: string | null;\n packageJsonHash: string | null;\n manifestsHash: string;\n timestamp: number;\n packages: string[];\n}\n\nfunction findManifestPath(pkgPath: string): string | null {\n const candidates = [\n join(pkgPath, 'dist', 'manifest.json'),\n join(pkgPath, '.smrt', 'manifest.json'),\n join(pkgPath, 'src', 'manifest', 'manifest.json'),\n ];\n\n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n\n return null;\n}\n\nfunction normalizePackagePath(pkgPath: string): string {\n try {\n return realpathSync(pkgPath);\n } catch {\n return pkgPath;\n }\n}\n\nfunction resolvePackageDir(\n packageName: string,\n baseDir: string = process.cwd(),\n): string | null {\n try {\n const requireFromBase = createRequire(join(baseDir, 'package.json'));\n const packageEntry = requireFromBase.resolve(packageName);\n let currentDir = dirname(packageEntry);\n let resolvedPackageDir: string | null = null;\n\n for (let i = 0; i < 10; i++) {\n const packageJsonPath = join(currentDir, 'package.json');\n\n if (existsSync(packageJsonPath)) {\n const packageJson = parse<{ name?: string }>(\n readFileSync(packageJsonPath, 'utf-8'),\n );\n\n if (packageJson.name === packageName) {\n resolvedPackageDir = currentDir;\n }\n }\n\n const parentDir = dirname(currentDir);\n if (parentDir === currentDir) {\n break;\n }\n\n currentDir = parentDir;\n }\n\n if (resolvedPackageDir) {\n return normalizePackagePath(resolvedPackageDir);\n }\n } catch {\n // Fall through to direct node_modules lookup below.\n }\n\n const directPath = join(baseDir, 'node_modules', packageName);\n if (existsSync(directPath)) {\n return normalizePackagePath(directPath);\n }\n\n return null;\n}\n\nexport function resolveManifestPath(\n packageName: string,\n baseDir: string = process.cwd(),\n): string | null {\n const pkgPath = resolvePackageDir(packageName, baseDir);\n if (!pkgPath) {\n return null;\n }\n\n const manifestPath = findManifestPath(pkgPath);\n if (!manifestPath) {\n return null;\n }\n\n try {\n const manifest = parse<{ moduleType?: string }>(\n readFileSync(manifestPath, 'utf-8'),\n );\n\n return manifest.moduleType === 'smrt' ? manifestPath : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Load cached discovery results if valid\n * Cache is invalidated if:\n * - Lockfile hash changed (dependencies changed)\n * - Manifest timestamps hash changed (SMRT packages rebuilt)\n */\nfunction getCachedDiscovery(\n baseDir: string,\n verbose: boolean,\n): { packages: string[]; reason?: string } | null {\n const cachePath = join(baseDir, CACHE_DIR, CACHE_FILE);\n\n if (!existsSync(cachePath)) {\n return null;\n }\n\n try {\n const cache: DiscoveryCache = parse(readFileSync(cachePath, 'utf-8'));\n if (cache.version !== CACHE_VERSION) {\n if (verbose) {\n console.log('[discovery] Cache invalid: discovery version changed');\n }\n return null;\n }\n\n const currentLockfileHash = getLockfileHash(baseDir);\n const currentPackageJsonHash = getPackageJsonHash(baseDir);\n\n // Check lockfile hash\n if (cache.lockfileHash !== currentLockfileHash) {\n if (verbose) {\n console.log('[discovery] Cache invalid: lockfile changed');\n }\n return null;\n }\n\n if (cache.packageJsonHash !== currentPackageJsonHash) {\n if (verbose) {\n console.log('[discovery] Cache invalid: package.json changed');\n }\n return null;\n }\n\n // Check manifest timestamps (only if we have cached packages)\n if (cache.packages.length > 0) {\n const currentManifestsHash = getManifestTimestampsHash(\n baseDir,\n cache.packages,\n );\n if (cache.manifestsHash !== currentManifestsHash) {\n if (verbose) {\n console.log('[discovery] Cache invalid: manifest(s) changed');\n }\n return null;\n }\n }\n\n return { packages: cache.packages };\n } catch (error) {\n if (verbose) {\n console.warn(\n '[discovery] Failed to read cache:',\n (error as Error).message,\n );\n }\n return null;\n }\n}\n\n/**\n * Save discovery results to cache\n */\nfunction saveCachedDiscovery(\n baseDir: string,\n packages: string[],\n verbose: boolean,\n): void {\n const cache: DiscoveryCache = {\n version: CACHE_VERSION,\n lockfileHash: getLockfileHash(baseDir),\n packageJsonHash: getPackageJsonHash(baseDir),\n manifestsHash: getManifestTimestampsHash(baseDir, packages),\n timestamp: Date.now(),\n packages: packages,\n };\n\n try {\n mkdirSync(join(baseDir, CACHE_DIR), { recursive: true });\n writeFileSync(\n join(baseDir, CACHE_DIR, CACHE_FILE),\n JSON.stringify(cache, null, 2),\n );\n if (verbose) {\n console.log(`[discovery] Saved cache with ${packages.length} package(s)`);\n }\n } catch (error) {\n if (verbose) {\n console.warn(\n '[discovery] Failed to save cache:',\n (error as Error).message,\n );\n }\n }\n}\n\n/**\n * Check if a package provides a SMRT manifest\n *\n * Supports both regular npm dependencies and workspace: symlinks\n */\nfunction hasManifestExport(packageName: string, baseDir: string): boolean {\n return resolveManifestPath(packageName, baseDir) !== null;\n}\n\nfunction getDeclaredSmrtPackages(baseDir: string, verbose: boolean): string[] {\n const packageJsonPath = join(baseDir, 'package.json');\n if (!existsSync(packageJsonPath)) {\n return [];\n }\n\n try {\n const packageJson = parse<{\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n }>(readFileSync(packageJsonPath, 'utf-8'));\n\n const allDeps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n ...packageJson.peerDependencies,\n };\n\n return Object.keys(allDeps).filter((pkgName) => {\n if (!pkgName.startsWith('@happyvertical/smrt-')) {\n return false;\n }\n\n const hasManifest = hasManifestExport(pkgName, baseDir);\n if (verbose && hasManifest) {\n console.log(`[discovery] ✅ Found declared SMRT package: ${pkgName}`);\n }\n\n return hasManifest;\n });\n } catch (error) {\n if (verbose) {\n console.warn(\n '[discovery] Failed to read declared dependencies:',\n (error as Error).message,\n );\n }\n return [];\n }\n}\n\n/**\n * Scan node_modules recursively for packages\n */\nfunction* scanNodeModules(baseDir: string): Generator<string> {\n const nodeModulesPath = join(baseDir, 'node_modules');\n\n if (!existsSync(nodeModulesPath)) {\n return;\n }\n\n try {\n const entries = readdirSync(nodeModulesPath);\n\n for (const entry of entries) {\n if (entry === '.bin' || entry === '.pnpm' || entry === '.cache') {\n continue;\n }\n\n const entryPath = join(nodeModulesPath, entry);\n\n try {\n const stats = statSync(entryPath);\n\n if (stats.isDirectory() || stats.isSymbolicLink()) {\n // Scoped packages (e.g., @happyvertical/smrt-core)\n if (entry.startsWith('@')) {\n const scopeEntries = readdirSync(entryPath);\n for (const scopedPkg of scopeEntries) {\n yield `${entry}/${scopedPkg}`;\n }\n } else {\n // Regular packages\n yield entry;\n }\n }\n } catch {}\n }\n } catch (error) {\n // node_modules doesn't exist or can't be read\n return;\n }\n}\n\n/**\n * Perform fresh discovery of SMRT packages\n */\nfunction performDiscovery(baseDir: string, verbose: boolean): string[] {\n if (verbose) {\n console.log('[discovery] Scanning node_modules for SMRT packages...');\n }\n\n try {\n const smrtPackages = new Set<string>();\n\n // Scan node_modules for all packages\n for (const pkgName of scanNodeModules(baseDir)) {\n if (hasManifestExport(pkgName, baseDir)) {\n smrtPackages.add(pkgName);\n if (verbose) {\n console.log(`[discovery] ✅ Found SMRT package: ${pkgName}`);\n }\n }\n }\n\n for (const pkgName of getDeclaredSmrtPackages(baseDir, verbose)) {\n smrtPackages.add(pkgName);\n }\n\n if (verbose) {\n console.log(\n `[discovery] Discovered ${smrtPackages.size} SMRT package(s)`,\n );\n }\n\n return Array.from(smrtPackages);\n } catch (error) {\n console.error(\n '[discovery] Failed to discover packages:',\n (error as Error).message,\n );\n return [];\n }\n}\n\nexport interface DiscoveryOptions {\n /** Override project root for discovery/cache */\n baseDir?: string;\n /** Force fresh discovery, ignoring cache */\n noCache?: boolean;\n /** Show verbose output */\n verbose?: boolean;\n /** Record timing data */\n timing?: boolean;\n}\n\n/**\n * Main discovery function\n *\n * Cache ENABLED by default (5-50x faster startup)\n * - Automatically invalidates when lockfile changes (dependencies updated)\n * - Automatically invalidates when any manifest.json changes (packages rebuilt)\n *\n * Disable with SMRT_DISABLE_DISCOVERY_CACHE=true for debugging\n */\nexport function discoverSmrtPackages(options: DiscoveryOptions = {}): string[] {\n const startTime = options.timing ? performance.now() : 0;\n lastTimingData = {};\n const baseDir = options.baseDir || process.cwd();\n\n const cacheDisabled =\n options.noCache || process.env.SMRT_DISABLE_DISCOVERY_CACHE === 'true';\n\n const verbose: boolean =\n options.verbose === true ||\n process.env.SMRT_VERBOSE === 'true' ||\n !!process.env.DEBUG?.includes('smrt');\n\n if (cacheDisabled) {\n if (verbose) {\n console.log('[discovery] Cache disabled, performing fresh discovery...');\n }\n\n const packages = performDiscovery(baseDir, verbose);\n\n if (options.timing) {\n lastTimingData.discovery = performance.now() - startTime;\n lastTimingData.total = lastTimingData.discovery;\n }\n\n return packages;\n }\n\n // Try cache first\n const cacheCheckStart = options.timing ? performance.now() : 0;\n const cached = getCachedDiscovery(baseDir, verbose);\n\n if (options.timing) {\n lastTimingData.cacheCheck = performance.now() - cacheCheckStart;\n }\n\n if (cached) {\n if (verbose) {\n console.log(\n `[discovery] ✅ Using cached SMRT packages (${cached.packages.length} package(s))`,\n );\n }\n\n if (options.timing) {\n lastTimingData.total = performance.now() - startTime;\n }\n\n return cached.packages;\n }\n\n // No valid cache - perform fresh discovery\n if (verbose) {\n console.log('[discovery] Cache miss, performing discovery...');\n }\n\n const discoveryStart = options.timing ? performance.now() : 0;\n const packages = performDiscovery(baseDir, verbose);\n\n if (options.timing) {\n lastTimingData.discovery = performance.now() - discoveryStart;\n }\n\n // Save to cache\n saveCachedDiscovery(baseDir, packages, verbose);\n\n if (options.timing) {\n lastTimingData.total = performance.now() - startTime;\n }\n\n return packages;\n}\n\n// Run if called directly\nif (import.meta.url === `file://${process.argv[1]}`) {\n const noCache = process.argv.includes('--no-cache');\n const verbose =\n process.argv.includes('--verbose') || process.argv.includes('-v');\n const timing = process.argv.includes('--timing');\n\n const packages = discoverSmrtPackages({ noCache, verbose, timing });\n\n console.log('\\nDiscovered SMRT packages:');\n console.log(JSON.stringify(packages, null, 2));\n\n if (timing) {\n const timingData = getDiscoveryTiming();\n console.log('\\nTiming:');\n if (timingData.cacheCheck !== undefined) {\n console.log(` Cache check: ${timingData.cacheCheck.toFixed(2)}ms`);\n }\n if (timingData.discovery !== undefined) {\n console.log(` Discovery: ${timingData.discovery.toFixed(2)}ms`);\n }\n if (timingData.total !== undefined) {\n console.log(` Total: ${timingData.total.toFixed(2)}ms`);\n }\n }\n}\n"],"names":["packages"],"mappings":"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"}
1
+ {"version":3,"file":"discover-smrt-packages.js","sources":["../../src/manifest/discover-smrt-packages.ts"],"sourcesContent":["/**\n * SMRT Package Discovery\n *\n * Discovers all SMRT packages in node_modules by:\n * 1. Scanning node_modules directory for installed packages\n * 2. Following symlinks for workspace: dependencies\n * 3. Checking for a package manifest (`dist/manifest.json`,\n * `.smrt/manifest.json`, or `src/manifest/manifest.json`) with moduleType: \"smrt\"\n * 4. Caching results based on lockfile hash and manifest timestamps\n *\n * Cache Strategy:\n * - ENABLED by default (5-50x faster startup)\n * - Automatically invalidates when lockfile or any manifest.json changes\n * - Disable with SMRT_DISABLE_DISCOVERY_CACHE=true for debugging\n */\n\nimport { createHash } from 'node:crypto';\nimport {\n existsSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n realpathSync,\n statSync,\n writeFileSync,\n} from 'node:fs';\nimport { createRequire } from 'node:module';\nimport { dirname, join } from 'node:path';\nimport { parse } from '../utils/json.js';\n\nconst CACHE_DIR = '.smrt';\nconst CACHE_FILE = 'discovery-cache.json';\nconst CACHE_VERSION = 4;\n\n/** Timing data for --timing flag */\ninterface TimingData {\n discovery?: number;\n cacheCheck?: number;\n total?: number;\n}\n\n/** Module-level timing storage */\nlet lastTimingData: TimingData = {};\n\n/**\n * Get timing data from last discovery operation\n */\nexport function getDiscoveryTiming(): TimingData {\n return { ...lastTimingData };\n}\n\n/**\n * Get hash of lockfile for cache invalidation\n */\nfunction getLockfileHash(baseDir: string): string | null {\n // Check for pnpm or npm lockfile\n const lockfile = existsSync(join(baseDir, 'pnpm-lock.yaml'))\n ? join(baseDir, 'pnpm-lock.yaml')\n : join(baseDir, 'package-lock.json');\n\n if (!existsSync(lockfile)) {\n return null;\n }\n\n const content = readFileSync(lockfile, 'utf-8');\n return createHash('sha256').update(content).digest('hex');\n}\n\n/**\n * Get hash of package.json for cache invalidation when a package workspace\n * changes its declared dependencies without a colocated lockfile.\n */\nfunction getPackageJsonHash(baseDir: string): string | null {\n const packageJsonPath = join(baseDir, 'package.json');\n\n if (!existsSync(packageJsonPath)) {\n return null;\n }\n\n const content = readFileSync(packageJsonPath, 'utf-8');\n return createHash('sha256').update(content).digest('hex');\n}\n\n/**\n * Get a hash of all manifest timestamps for cache invalidation\n * This catches changes to SMRT packages even when lockfile hasn't changed\n */\nfunction getManifestTimestampsHash(\n baseDir: string,\n packages: string[],\n): string {\n const timestamps: string[] = [];\n\n for (const pkgName of packages) {\n try {\n const manifestPath = resolveManifestPath(pkgName, baseDir);\n\n if (manifestPath && existsSync(manifestPath)) {\n const stats = statSync(manifestPath);\n timestamps.push(`${pkgName}:${stats.mtimeMs}`);\n }\n } catch {\n // Ignore errors, package may have been removed\n }\n }\n\n return createHash('sha256').update(timestamps.join('|')).digest('hex');\n}\n\ninterface DiscoveryCache {\n version: number;\n lockfileHash: string | null;\n packageJsonHash: string | null;\n manifestsHash: string;\n timestamp: number;\n packages: string[];\n}\n\nfunction findManifestPath(pkgPath: string): string | null {\n const candidates = [\n join(pkgPath, 'dist', 'manifest.json'),\n join(pkgPath, '.smrt', 'manifest.json'),\n join(pkgPath, 'src', 'manifest', 'manifest.json'),\n ];\n\n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n\n return null;\n}\n\nfunction normalizePackagePath(pkgPath: string): string {\n try {\n return realpathSync(pkgPath);\n } catch {\n return pkgPath;\n }\n}\n\nfunction resolvePackageDir(\n packageName: string,\n baseDir: string = process.cwd(),\n): string | null {\n try {\n const requireFromBase = createRequire(join(baseDir, 'package.json'));\n const packageEntry = requireFromBase.resolve(packageName);\n let currentDir = dirname(packageEntry);\n let resolvedPackageDir: string | null = null;\n\n for (let i = 0; i < 10; i++) {\n const packageJsonPath = join(currentDir, 'package.json');\n\n if (existsSync(packageJsonPath)) {\n const packageJson = parse<{ name?: string }>(\n readFileSync(packageJsonPath, 'utf-8'),\n );\n\n if (packageJson.name === packageName) {\n resolvedPackageDir = currentDir;\n }\n }\n\n const parentDir = dirname(currentDir);\n if (parentDir === currentDir) {\n break;\n }\n\n currentDir = parentDir;\n }\n\n if (resolvedPackageDir) {\n return normalizePackagePath(resolvedPackageDir);\n }\n } catch {\n // Fall through to direct node_modules lookup below.\n }\n\n const directPath = join(baseDir, 'node_modules', packageName);\n if (existsSync(directPath)) {\n return normalizePackagePath(directPath);\n }\n\n return null;\n}\n\nexport function resolveManifestPath(\n packageName: string,\n baseDir: string = process.cwd(),\n): string | null {\n const pkgPath = resolvePackageDir(packageName, baseDir);\n if (!pkgPath) {\n return null;\n }\n\n const manifestPath = findManifestPath(pkgPath);\n if (!manifestPath) {\n return null;\n }\n\n try {\n const manifest = parse<{ moduleType?: string }>(\n readFileSync(manifestPath, 'utf-8'),\n );\n\n return manifest.moduleType === 'smrt' ? manifestPath : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Load cached discovery results if valid\n * Cache is invalidated if:\n * - Lockfile hash changed (dependencies changed)\n * - Manifest timestamps hash changed (SMRT packages rebuilt)\n */\nfunction getCachedDiscovery(\n baseDir: string,\n verbose: boolean,\n): { packages: string[]; reason?: string } | null {\n const cachePath = join(baseDir, CACHE_DIR, CACHE_FILE);\n\n if (!existsSync(cachePath)) {\n return null;\n }\n\n try {\n const cache: DiscoveryCache = parse(readFileSync(cachePath, 'utf-8'));\n if (cache.version !== CACHE_VERSION) {\n if (verbose) {\n console.log('[discovery] Cache invalid: discovery version changed');\n }\n return null;\n }\n\n const currentLockfileHash = getLockfileHash(baseDir);\n const currentPackageJsonHash = getPackageJsonHash(baseDir);\n\n // Check lockfile hash\n if (cache.lockfileHash !== currentLockfileHash) {\n if (verbose) {\n console.log('[discovery] Cache invalid: lockfile changed');\n }\n return null;\n }\n\n if (cache.packageJsonHash !== currentPackageJsonHash) {\n if (verbose) {\n console.log('[discovery] Cache invalid: package.json changed');\n }\n return null;\n }\n\n // Check manifest timestamps (only if we have cached packages)\n if (cache.packages.length > 0) {\n const currentManifestsHash = getManifestTimestampsHash(\n baseDir,\n cache.packages,\n );\n if (cache.manifestsHash !== currentManifestsHash) {\n if (verbose) {\n console.log('[discovery] Cache invalid: manifest(s) changed');\n }\n return null;\n }\n }\n\n return { packages: cache.packages };\n } catch (error) {\n if (verbose) {\n console.warn(\n '[discovery] Failed to read cache:',\n (error as Error).message,\n );\n }\n return null;\n }\n}\n\n/**\n * Save discovery results to cache\n */\nfunction saveCachedDiscovery(\n baseDir: string,\n packages: string[],\n verbose: boolean,\n): void {\n const cache: DiscoveryCache = {\n version: CACHE_VERSION,\n lockfileHash: getLockfileHash(baseDir),\n packageJsonHash: getPackageJsonHash(baseDir),\n manifestsHash: getManifestTimestampsHash(baseDir, packages),\n timestamp: Date.now(),\n packages: packages,\n };\n\n try {\n mkdirSync(join(baseDir, CACHE_DIR), { recursive: true });\n writeFileSync(\n join(baseDir, CACHE_DIR, CACHE_FILE),\n JSON.stringify(cache, null, 2),\n );\n if (verbose) {\n console.log(`[discovery] Saved cache with ${packages.length} package(s)`);\n }\n } catch (error) {\n if (verbose) {\n console.warn(\n '[discovery] Failed to save cache:',\n (error as Error).message,\n );\n }\n }\n}\n\n/**\n * Check if a package provides a SMRT manifest\n *\n * Supports both regular npm dependencies and workspace: symlinks\n */\nfunction hasManifestExport(packageName: string, baseDir: string): boolean {\n return resolveManifestPath(packageName, baseDir) !== null;\n}\n\nfunction getDeclaredSmrtPackages(baseDir: string, verbose: boolean): string[] {\n const packageJsonPath = join(baseDir, 'package.json');\n if (!existsSync(packageJsonPath)) {\n return [];\n }\n\n try {\n const packageJson = parse<{\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n }>(readFileSync(packageJsonPath, 'utf-8'));\n\n const allDeps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n ...packageJson.peerDependencies,\n };\n\n return Object.keys(allDeps).filter((pkgName) => {\n if (!pkgName.startsWith('@happyvertical/smrt-')) {\n return false;\n }\n\n const hasManifest = hasManifestExport(pkgName, baseDir);\n if (verbose && hasManifest) {\n console.log(`[discovery] ✅ Found declared SMRT package: ${pkgName}`);\n }\n\n return hasManifest;\n });\n } catch (error) {\n if (verbose) {\n console.warn(\n '[discovery] Failed to read declared dependencies:',\n (error as Error).message,\n );\n }\n return [];\n }\n}\n\n/**\n * Scan node_modules recursively for packages\n */\nfunction* scanNodeModules(baseDir: string): Generator<string> {\n const nodeModulesPath = join(baseDir, 'node_modules');\n\n if (!existsSync(nodeModulesPath)) {\n return;\n }\n\n try {\n const entries = readdirSync(nodeModulesPath);\n\n for (const entry of entries) {\n if (entry === '.bin' || entry === '.pnpm' || entry === '.cache') {\n continue;\n }\n\n const entryPath = join(nodeModulesPath, entry);\n\n try {\n const stats = statSync(entryPath);\n\n if (stats.isDirectory() || stats.isSymbolicLink()) {\n // Scoped packages (e.g., @happyvertical/smrt-core)\n if (entry.startsWith('@')) {\n const scopeEntries = readdirSync(entryPath);\n for (const scopedPkg of scopeEntries) {\n yield `${entry}/${scopedPkg}`;\n }\n } else {\n // Regular packages\n yield entry;\n }\n }\n } catch {}\n }\n } catch (error) {\n // node_modules doesn't exist or can't be read\n return;\n }\n}\n\n/**\n * Perform fresh discovery of SMRT packages\n */\nfunction performDiscovery(baseDir: string, verbose: boolean): string[] {\n if (verbose) {\n console.log('[discovery] Scanning node_modules for SMRT packages...');\n }\n\n try {\n const smrtPackages = new Set<string>();\n\n // Scan node_modules for all packages\n for (const pkgName of scanNodeModules(baseDir)) {\n if (hasManifestExport(pkgName, baseDir)) {\n smrtPackages.add(pkgName);\n if (verbose) {\n console.log(`[discovery] ✅ Found SMRT package: ${pkgName}`);\n }\n }\n }\n\n for (const pkgName of getDeclaredSmrtPackages(baseDir, verbose)) {\n smrtPackages.add(pkgName);\n }\n\n if (verbose) {\n console.log(\n `[discovery] Discovered ${smrtPackages.size} SMRT package(s)`,\n );\n }\n\n return Array.from(smrtPackages);\n } catch (error) {\n console.error(\n '[discovery] Failed to discover packages:',\n (error as Error).message,\n );\n return [];\n }\n}\n\nexport interface DiscoveryOptions {\n /** Override project root for discovery/cache */\n baseDir?: string;\n /** Force fresh discovery, ignoring cache */\n noCache?: boolean;\n /** Show verbose output */\n verbose?: boolean;\n /** Record timing data */\n timing?: boolean;\n}\n\n/**\n * Main discovery function\n *\n * Cache ENABLED by default (5-50x faster startup)\n * - Automatically invalidates when lockfile changes (dependencies updated)\n * - Automatically invalidates when any manifest.json changes (packages rebuilt)\n *\n * Disable with SMRT_DISABLE_DISCOVERY_CACHE=true for debugging\n *\n * Intentional split (#1579): this is the **build-time** discovery path —\n * synchronous, scans `node_modules` for `manifest.json` files with\n * `moduleType: \"smrt\"`, and caches by lockfile/manifest hash for fast manifest\n * generation. It is deliberately distinct from the consumer-plugin's\n * `discoverSmrtPackages(projectRoot)` (`src/consumer-plugin/index.ts`), which is\n * **async**, reads a downstream app's `package.json` dependency names with a\n * lightweight `@have/`/`smrt` heuristic, and runs inside the Vite consumer\n * plugin. Different inputs, contexts, and lifecycles — not duplicated logic to\n * consolidate.\n */\nexport function discoverSmrtPackages(options: DiscoveryOptions = {}): string[] {\n const startTime = options.timing ? performance.now() : 0;\n lastTimingData = {};\n const baseDir = options.baseDir || process.cwd();\n\n const cacheDisabled =\n options.noCache || process.env.SMRT_DISABLE_DISCOVERY_CACHE === 'true';\n\n const verbose: boolean =\n options.verbose === true ||\n process.env.SMRT_VERBOSE === 'true' ||\n !!process.env.DEBUG?.includes('smrt');\n\n if (cacheDisabled) {\n if (verbose) {\n console.log('[discovery] Cache disabled, performing fresh discovery...');\n }\n\n const packages = performDiscovery(baseDir, verbose);\n\n if (options.timing) {\n lastTimingData.discovery = performance.now() - startTime;\n lastTimingData.total = lastTimingData.discovery;\n }\n\n return packages;\n }\n\n // Try cache first\n const cacheCheckStart = options.timing ? performance.now() : 0;\n const cached = getCachedDiscovery(baseDir, verbose);\n\n if (options.timing) {\n lastTimingData.cacheCheck = performance.now() - cacheCheckStart;\n }\n\n if (cached) {\n if (verbose) {\n console.log(\n `[discovery] ✅ Using cached SMRT packages (${cached.packages.length} package(s))`,\n );\n }\n\n if (options.timing) {\n lastTimingData.total = performance.now() - startTime;\n }\n\n return cached.packages;\n }\n\n // No valid cache - perform fresh discovery\n if (verbose) {\n console.log('[discovery] Cache miss, performing discovery...');\n }\n\n const discoveryStart = options.timing ? performance.now() : 0;\n const packages = performDiscovery(baseDir, verbose);\n\n if (options.timing) {\n lastTimingData.discovery = performance.now() - discoveryStart;\n }\n\n // Save to cache\n saveCachedDiscovery(baseDir, packages, verbose);\n\n if (options.timing) {\n lastTimingData.total = performance.now() - startTime;\n }\n\n return packages;\n}\n\n// Run if called directly\nif (import.meta.url === `file://${process.argv[1]}`) {\n const noCache = process.argv.includes('--no-cache');\n const verbose =\n process.argv.includes('--verbose') || process.argv.includes('-v');\n const timing = process.argv.includes('--timing');\n\n const packages = discoverSmrtPackages({ noCache, verbose, timing });\n\n console.log('\\nDiscovered SMRT packages:');\n console.log(JSON.stringify(packages, null, 2));\n\n if (timing) {\n const timingData = getDiscoveryTiming();\n console.log('\\nTiming:');\n if (timingData.cacheCheck !== undefined) {\n console.log(` Cache check: ${timingData.cacheCheck.toFixed(2)}ms`);\n }\n if (timingData.discovery !== undefined) {\n console.log(` Discovery: ${timingData.discovery.toFixed(2)}ms`);\n }\n if (timingData.total !== undefined) {\n console.log(` Total: ${timingData.total.toFixed(2)}ms`);\n }\n }\n}\n"],"names":["packages"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/manifest/generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAkB/D;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IAErC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IAGxB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAG/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAGlB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAC;CACrC;AAuCD;;;;;GAKG;AACH,qBAAa,eAAe;IAC1B;;OAEG;IACG,QAAQ,CACZ,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC;IAkC/B,OAAO,CAAC,kBAAkB;IAa1B,OAAO,CAAC,iBAAiB;IAmBzB;;OAEG;IACH,OAAO,CAAC,aAAa;IAUrB;;OAEG;YACW,gBAAgB;IAoD9B;;;;;OAKG;YACW,oBAAoB;IAyDlC;;;;;;OAMG;IACH,OAAO,CAAC,cAAc;IAiCtB;;OAEG;YACW,WAAW;IAyCzB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAuCxB;;OAEG;YACW,yBAAyB;IAkFvC;;OAEG;YACW,uBAAuB;IAwCrC;;OAEG;IACH,OAAO,CAAC,eAAe;IAavB;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAuB5B"}
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/manifest/generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAuB/D;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IAErC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IAGxB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAG/B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAGlB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAC;CACrC;AAuCD;;;;;GAKG;AACH,qBAAa,eAAe;IAC1B;;OAEG;IACG,QAAQ,CACZ,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,mBAAmB,CAAC;IAkC/B,OAAO,CAAC,kBAAkB;IAa1B,OAAO,CAAC,iBAAiB;IAmBzB;;OAEG;IACH,OAAO,CAAC,aAAa;IAUrB;;OAEG;YACW,gBAAgB;IAoD9B;;;;;OAKG;YACW,oBAAoB;IAyDlC;;;;;;OAMG;IACH,OAAO,CAAC,cAAc;IAiCtB;;OAEG;YACW,WAAW;IAyCzB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAuCxB;;OAEG;YACW,yBAAyB;IA6EvC;;OAEG;YACW,uBAAuB;IAwCrC;;OAEG;IACH,OAAO,CAAC,eAAe;IAavB;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAuB5B"}
@@ -1,3 +1,4 @@
1
+ import { createLogger } from "@happyvertical/logger";
1
2
  import { existsSync, readFileSync, mkdirSync, writeFileSync } from "node:fs";
2
3
  import { isAbsolute, relative, resolve, dirname } from "node:path";
3
4
  import fg from "fast-glob";
@@ -5,6 +6,7 @@ import { ManifestGenerator } from "../scanner/manifest-generator.js";
5
6
  import { importWorkspaceModule } from "../utils/import-workspace-module.js";
6
7
  import { discoverSmrtPackages, resolveManifestPath } from "./discover-smrt-packages.js";
7
8
  import { ManifestManager } from "./manager.js";
9
+ const logger = createLogger({ level: "info" });
8
10
  async function importScanner() {
9
11
  return importWorkspaceModule({
10
12
  packageName: "@happyvertical/smrt-scanner",
@@ -20,10 +22,10 @@ class ManifestBuilder {
20
22
  async generate(options = {}) {
21
23
  const files = this.discoverFiles(options);
22
24
  if (files.length === 0) {
23
- console.log("[smrt] No source files found");
25
+ logger.info("[smrt] No source files found");
24
26
  return this.createEmptyManifest(options);
25
27
  }
26
- console.log(`[smrt] Scanning ${files.length} source file(s)...`);
28
+ logger.info(`[smrt] Scanning ${files.length} source file(s)...`);
27
29
  const scannerConfig = await this.configureScanner(options);
28
30
  const scannedManifest = await this.scanAndBuildManifest(
29
31
  scannerConfig,
@@ -86,26 +88,26 @@ class ManifestBuilder {
86
88
  const viteBaseClasses = await this.loadViteConfigBaseClasses();
87
89
  if (viteBaseClasses && viteBaseClasses.length > 0) {
88
90
  baseClasses = viteBaseClasses;
89
- console.log(
91
+ logger.info(
90
92
  `[smrt] Using baseClasses from vite.config.ts: ${baseClasses.join(", ")}`
91
93
  );
92
94
  }
93
95
  }
94
96
  let smrtDependencies = [];
95
97
  if (options.discoverExternalPackages) {
96
- console.log("[smrt] Discovering external SMRT packages...");
98
+ logger.info("[smrt] Discovering external SMRT packages...");
97
99
  smrtDependencies = discoverSmrtPackages();
98
- console.log(
100
+ logger.info(
99
101
  `[smrt] Found ${smrtDependencies.length} SMRT package(s): ${smrtDependencies.join(", ")}`
100
102
  );
101
103
  if (options.includeExternalBaseClasses) {
102
104
  const externalClasses = await this.loadExternalBaseClasses(smrtDependencies);
103
105
  if (externalClasses.length > 0) {
104
106
  baseClasses = [...baseClasses, ...externalClasses];
105
- console.log(
107
+ logger.info(
106
108
  `[smrt] Added ${externalClasses.length} external base class(es) to scanner`
107
109
  );
108
- console.log(`[smrt] Total baseClasses: ${baseClasses.length}`);
110
+ logger.info(`[smrt] Total baseClasses: ${baseClasses.length}`);
109
111
  }
110
112
  }
111
113
  }
@@ -180,9 +182,9 @@ class ManifestBuilder {
180
182
  const packageInfo = this.readPackageJson();
181
183
  if (packageInfo.name) {
182
184
  manifest.packageName = packageInfo.name;
183
- console.log(`[smrt] Injected package name: ${packageInfo.name}`);
185
+ logger.info(`[smrt] Injected package name: ${packageInfo.name}`);
184
186
  } else {
185
- console.warn(
187
+ logger.warn(
186
188
  "[smrt] Warning: Could not read package.json, packageName will be undefined"
187
189
  );
188
190
  }
@@ -212,8 +214,8 @@ class ManifestBuilder {
212
214
  writeFileSync(stubPath, tsContent);
213
215
  }
214
216
  const objectCount = Object.keys(manifest.objects).length;
215
- console.log(`[smrt] ✅ Generated manifest with ${objectCount} object(s)`);
216
- console.log(`[smrt] Unified: ${unifiedPath}`);
217
+ logger.info(`[smrt] ✅ Generated manifest with ${objectCount} object(s)`);
218
+ logger.info(`[smrt] Unified: ${unifiedPath}`);
217
219
  }
218
220
  /**
219
221
  * Generate TypeScript stub file with manifest constant
@@ -250,59 +252,54 @@ export default ${exportName};
250
252
  try {
251
253
  const viteConfigPath = resolve(process.cwd(), "vite.config.ts");
252
254
  if (!existsSync(viteConfigPath)) {
253
- console.log("[smrt] vite.config.ts not found");
255
+ logger.info("[smrt] vite.config.ts not found");
254
256
  return null;
255
257
  }
256
- console.log("[smrt] Found vite.config.ts, attempting to load...");
258
+ logger.info("[smrt] Found vite.config.ts, attempting to load...");
257
259
  const { loadConfigFromFile } = await import("vite");
258
260
  const loaded = await loadConfigFromFile(
259
261
  { command: "build", mode: "test" },
260
262
  viteConfigPath
261
263
  );
262
264
  if (!loaded?.config?.plugins) {
263
- console.log("[smrt] No plugins found in vite config");
265
+ logger.info("[smrt] No plugins found in vite config");
264
266
  return null;
265
267
  }
266
268
  const plugins = loaded.config.plugins;
267
- console.log(
268
- "[smrt] Vite config loaded, plugins:",
269
- plugins.map((p) => p?.name)
270
- );
269
+ logger.info("[smrt] Vite config loaded", {
270
+ plugins: plugins.map((p) => p?.name)
271
+ });
271
272
  const smrtPlugin = plugins.find((p) => p?.name === "smrt-auto-service");
272
273
  if (!smrtPlugin) {
273
- console.log(
274
+ logger.info(
274
275
  "[smrt] smrt-auto-service plugin not found in plugins array"
275
276
  );
276
277
  return null;
277
278
  }
278
- console.log("[smrt] Found smrt-auto-service plugin");
279
+ logger.info("[smrt] Found smrt-auto-service plugin");
279
280
  const api = smrtPlugin.api;
280
281
  let opts = (typeof api === "object" && api !== null ? api.options : void 0) || smrtPlugin.options || smrtPlugin._options;
281
282
  if (!opts && typeof api === "function") {
282
283
  try {
283
284
  opts = api().options;
284
285
  } catch (e) {
285
- console.log("[smrt] Could not call plugin.api()");
286
+ logger.info("[smrt] Could not call plugin.api()");
286
287
  }
287
288
  }
288
289
  if (opts?.baseClasses) {
289
- console.log(
290
- "[smrt] Plugin options:",
291
- JSON.stringify({
292
- baseClasses: opts.baseClasses,
293
- followImports: opts.followImports
294
- })
295
- );
290
+ logger.info("[smrt] Plugin options", {
291
+ baseClasses: opts.baseClasses,
292
+ followImports: opts.followImports
293
+ });
296
294
  return opts.baseClasses;
297
295
  }
298
- console.log("[smrt] Could not access plugin options");
296
+ logger.info("[smrt] Could not access plugin options");
299
297
  return null;
300
298
  } catch (error) {
301
- console.log(
302
- "[smrt] Error loading vite.config.ts:",
303
- error instanceof Error ? error.message : String(error)
304
- );
305
- console.log("[smrt] Using default baseClasses");
299
+ logger.warn("[smrt] Error loading vite.config.ts", {
300
+ error: error instanceof Error ? error.message : String(error)
301
+ });
302
+ logger.info("[smrt] Using default baseClasses");
306
303
  return null;
307
304
  }
308
305
  }
@@ -314,7 +311,7 @@ export default ${exportName};
314
311
  for (const pkgName of packages) {
315
312
  const manifestPath = resolveManifestPath(pkgName, process.cwd());
316
313
  if (!manifestPath) {
317
- console.log(`[smrt] ${pkgName}: no SMRT manifest resolved`);
314
+ logger.info(`[smrt] ${pkgName}: no SMRT manifest resolved`);
318
315
  continue;
319
316
  }
320
317
  try {
@@ -328,11 +325,11 @@ export default ${exportName};
328
325
  externalBaseClasses.push(className);
329
326
  }
330
327
  }
331
- console.log(
328
+ logger.info(
332
329
  `[smrt] ${pkgName}: found ${foundClassNames.length} class(es) - ${foundClassNames.join(", ")}`
333
330
  );
334
331
  } catch (error) {
335
- console.log(
332
+ logger.info(
336
333
  `[smrt] ${pkgName}: manifest not found or invalid - ${error instanceof Error ? error.message : String(error)}`
337
334
  );
338
335
  }
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","sources":["../../src/manifest/generator.ts"],"sourcesContent":["/**\n * Manifest generation orchestrator\n * Consolidates manifest generation logic for both build and test manifests\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, isAbsolute, relative, resolve } from 'node:path';\nimport fg from 'fast-glob';\nimport { ManifestGenerator } from '../scanner/manifest-generator.js';\nimport type { SmartObjectManifest } from '../scanner/types.js';\nimport { importWorkspaceModule } from '../utils/import-workspace-module.js';\nimport type { ScannerModule } from '../utils/scanner-module.js';\nimport {\n discoverSmrtPackages,\n resolveManifestPath,\n} from './discover-smrt-packages.js';\nimport { ManifestManager } from './manager.js';\n\nasync function importScanner() {\n return importWorkspaceModule<ScannerModule>({\n packageName: '@happyvertical/smrt-scanner',\n distEntry: 'packages/scanner/dist/index.js',\n sourceEntry: 'packages/scanner/src/index.ts',\n purpose: 'manifest generation',\n });\n}\n\n/**\n * Options for ManifestBuilder.generate()\n *\n * Controls file discovery, scanner configuration, output generation, and metadata injection\n */\nexport interface ManifestBuilderOptions {\n // File Discovery\n include?: string[];\n exclude?: string[];\n followImports?: boolean;\n\n // Scanner Configuration\n baseClasses?: string[];\n loadViteConfig?: boolean;\n discoverExternalPackages?: boolean;\n includeExternalBaseClasses?: boolean;\n includePrivateMethods?: boolean;\n includeStaticMethods?: boolean;\n\n // Output Configuration\n outputDir?: string;\n outputName?: string;\n generateTypeStub?: boolean;\n stubName?: string;\n\n // Metadata\n injectPackageInfo?: boolean;\n moduleType?: string;\n\n // Tree Shaking (External Object Filtering)\n /**\n * @deprecated Tree shaking is no longer needed. The AST scanner no longer includes external objects in the manifest by default.\n */\n treeShake?: boolean;\n\n /**\n * @deprecated Whitelists are no longer needed. The AST scanner no longer includes external objects in the manifest by default.\n */\n externalObjectsWhitelist?: string[];\n}\n\ninterface ScannerConfig {\n baseClasses: string[];\n includePrivateMethods: boolean;\n includeStaticMethods: boolean;\n followImports: boolean;\n smrtDependencies?: string[];\n}\n\ninterface PackageInfo {\n name?: string;\n version?: string;\n}\n\n/**\n * Subset of the smrt-auto-service Vite plugin options we probe when reading\n * baseClasses out of a project's vite.config.ts.\n */\ninterface VitePluginOptions {\n baseClasses?: string[];\n followImports?: boolean;\n}\n\n/**\n * Structural shape of a loaded Vite plugin entry as probed by\n * loadViteConfigBaseClasses(). The plugin may expose its options directly, on\n * `_options`, or via an `api` object/function — all optional and discovered at\n * runtime, so each is modeled as optional here.\n */\ninterface VitePluginProbe {\n name?: string;\n options?: VitePluginOptions;\n _options?: VitePluginOptions;\n api?:\n | { options?: VitePluginOptions }\n | (() => { options?: VitePluginOptions });\n}\n\n/**\n * Orchestrates manifest generation with configurable options\n *\n * Consolidates logic from generate-manifest.js and generate-test-manifest.js\n * into a single, testable, and maintainable service.\n */\nexport class ManifestBuilder {\n /**\n * Generate manifest with specified options\n */\n async generate(\n options: ManifestBuilderOptions = {},\n ): Promise<SmartObjectManifest> {\n // 1. Discover files to scan\n const files = this.discoverFiles(options);\n\n if (files.length === 0) {\n console.log('[smrt] No source files found');\n return this.createEmptyManifest(options);\n }\n\n console.log(`[smrt] Scanning ${files.length} source file(s)...`);\n\n // 2. Configure scanner (baseClasses, external packages, vite config)\n const scannerConfig = await this.configureScanner(options);\n\n // 3. Scan files with OXC scanner\n const scannedManifest = await this.scanAndBuildManifest(\n scannerConfig,\n options,\n );\n\n // 4. Enrich manifest with metadata (smrtDependencies, packageInfo)\n const manifest = this.enrichManifest(\n scannedManifest,\n options,\n scannerConfig,\n );\n\n // 5. Write output files\n this.normalizeFilePaths(manifest);\n await this.writeOutput(manifest, options);\n\n return manifest;\n }\n\n private normalizeFilePaths(manifest: SmartObjectManifest): void {\n const workspaceRoot = this.findWorkspaceRoot(process.cwd());\n\n for (const obj of Object.values(manifest.objects || {})) {\n if (obj.filePath && isAbsolute(obj.filePath)) {\n obj.filePath = relative(workspaceRoot, obj.filePath).replace(\n /\\\\/g,\n '/',\n );\n }\n }\n }\n\n private findWorkspaceRoot(startDir: string): string {\n let current = resolve(startDir);\n\n while (true) {\n if (\n existsSync(resolve(current, 'pnpm-workspace.yaml')) ||\n existsSync(resolve(current, '.git'))\n ) {\n return current;\n }\n\n const parent = dirname(current);\n if (parent === current) {\n return resolve(startDir);\n }\n current = parent;\n }\n }\n\n /**\n * Discover source files based on include/exclude patterns\n */\n private discoverFiles(options: ManifestBuilderOptions): string[] {\n const include = options.include || ['src/**/*.ts'];\n const exclude = options.exclude || ['src/**/*.d.ts', 'node_modules/**'];\n\n return fg.sync(include, {\n absolute: true,\n ignore: exclude,\n });\n }\n\n /**\n * Configure AST scanner with baseClasses, external packages, and vite config\n */\n private async configureScanner(\n options: ManifestBuilderOptions,\n ): Promise<ScannerConfig> {\n let baseClasses = options.baseClasses || [\n 'SmrtObject',\n 'SmrtClass',\n 'SmrtCollection',\n ];\n\n // Load from vite.config.ts if requested\n if (options.loadViteConfig) {\n const viteBaseClasses = await this.loadViteConfigBaseClasses();\n if (viteBaseClasses && viteBaseClasses.length > 0) {\n baseClasses = viteBaseClasses;\n console.log(\n `[smrt] Using baseClasses from vite.config.ts: ${baseClasses.join(', ')}`,\n );\n }\n }\n\n // Discover external SMRT packages\n let smrtDependencies: string[] = [];\n if (options.discoverExternalPackages) {\n console.log('[smrt] Discovering external SMRT packages...');\n smrtDependencies = discoverSmrtPackages();\n console.log(\n `[smrt] Found ${smrtDependencies.length} SMRT package(s): ${smrtDependencies.join(', ')}`,\n );\n\n // Optionally add external base classes\n if (options.includeExternalBaseClasses) {\n const externalClasses =\n await this.loadExternalBaseClasses(smrtDependencies);\n if (externalClasses.length > 0) {\n baseClasses = [...baseClasses, ...externalClasses];\n console.log(\n `[smrt] Added ${externalClasses.length} external base class(es) to scanner`,\n );\n console.log(`[smrt] Total baseClasses: ${baseClasses.length}`);\n }\n }\n }\n\n return {\n baseClasses,\n includePrivateMethods: options.includePrivateMethods ?? false,\n includeStaticMethods: options.includeStaticMethods ?? true,\n followImports: options.followImports ?? false,\n smrtDependencies,\n };\n }\n\n /**\n * Scan files using OxcScanner and build manifest via ManifestAdapter.\n *\n * This replaces the old ASTScanner-based scanFiles() method.\n * Uses the same OXC pipeline as the Vite plugin's scanWithOxc().\n */\n private async scanAndBuildManifest(\n config: ScannerConfig,\n options: ManifestBuilderOptions,\n ): Promise<SmartObjectManifest> {\n const { OxcScanner, ManifestAdapter } = await importScanner();\n\n const scanner = new OxcScanner({\n cwd: process.cwd(),\n include: options.include || ['src/**/*.ts'],\n exclude: options.exclude || ['src/**/*.d.ts', 'node_modules/**'],\n baseClasses: config.baseClasses,\n includePrivateMethods: config.includePrivateMethods,\n includeStaticMethods: config.includeStaticMethods,\n followImports: config.followImports,\n });\n\n const { results, resolved } = await scanner.scanAndResolve();\n\n // Read package.json for metadata\n let packageName: string | undefined;\n let packageVersion: string | undefined;\n let packageJson: { name?: string; version?: string } | undefined;\n try {\n const pkgPath = resolve(process.cwd(), 'package.json');\n const pkgContent = readFileSync(pkgPath, 'utf-8');\n packageJson = JSON.parse(pkgContent);\n packageName = packageJson?.name || undefined;\n packageVersion = packageJson?.version || undefined;\n } catch {\n // package.json not found - continue without packageName\n }\n\n // Convert to manifest format\n const adapter = new ManifestAdapter();\n const manifest = adapter.toManifest(resolved, {\n packageName,\n packageVersion,\n typeAliases: results.typeAliases,\n });\n\n // Set smrtDependencies BEFORE mergeInheritedFields so external packages can be loaded\n if (config.smrtDependencies && config.smrtDependencies.length > 0) {\n manifest.smrtDependencies = config.smrtDependencies;\n }\n\n // Run manifest generation passes (same as Vite plugin path)\n const manifestGen = new ManifestGenerator();\n manifestGen.injectTenantScopedFields(manifest);\n manifestGen.mergeInheritedFields(manifest);\n manifestGen.generateValidationRules(manifest);\n manifestGen.generateSchemas(manifest);\n manifestGen.assertTenantScopedSchemaContract(manifest);\n manifestGen.generateAgentManifests(manifest, packageName, packageJson);\n\n return manifest;\n }\n\n /**\n * Enrich manifest with metadata (moduleType, smrtDependencies, packageInfo).\n *\n * Note: As of Issue #1013, this method no longer merges external package\n * objects into the manifest. Dependencies are referenced via\n * `smrtDependencies` and resolved at runtime by manifest-loader.ts.\n */\n private enrichManifest(\n manifest: SmartObjectManifest,\n options: ManifestBuilderOptions,\n scannerConfig: ScannerConfig,\n ): SmartObjectManifest {\n // Add module type\n manifest.moduleType = options.moduleType || 'smrt';\n\n // Record dependency references (not their objects) so runtime\n // manifest-loader.ts can discover and load them on demand.\n if (\n scannerConfig.smrtDependencies &&\n scannerConfig.smrtDependencies.length > 0\n ) {\n manifest.smrtDependencies = scannerConfig.smrtDependencies;\n }\n\n // Inject package info\n if (options.injectPackageInfo) {\n const packageInfo = this.readPackageJson();\n if (packageInfo.name) {\n manifest.packageName = packageInfo.name;\n console.log(`[smrt] Injected package name: ${packageInfo.name}`);\n } else {\n console.warn(\n '[smrt] Warning: Could not read package.json, packageName will be undefined',\n );\n }\n }\n\n return manifest;\n }\n\n /**\n * Write manifest JSON and optional TypeScript stub\n */\n private async writeOutput(\n manifest: SmartObjectManifest,\n options: ManifestBuilderOptions,\n ): Promise<void> {\n const manager = new ManifestManager(process.cwd());\n const isTest =\n options.outputName?.includes('test') ||\n options.stubName?.includes('test');\n const mode = isTest ? 'dev' : 'build';\n\n // 1. Always write to the unified location via ManifestManager\n manager.write(manifest, mode);\n\n // 2. Legacy/Explicit Output (if requested or for stubs)\n const outputDir = options.outputDir || 'src/manifest';\n const outputName = options.outputName || 'manifest.json';\n\n // Ensure output directory exists for legacy/stubs\n mkdirSync(outputDir, { recursive: true });\n\n // Write JSON manifest to legacy location if different from unified path\n const manifestPath = resolve(outputDir, outputName);\n const unifiedPath = manager.getOutputPath(mode);\n\n if (resolve(manifestPath) !== resolve(unifiedPath)) {\n writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));\n }\n\n // Write TypeScript stub if requested\n if (options.generateTypeStub) {\n const stubName = options.stubName || 'manifest.ts';\n const tsContent = this.generateTypeStub(manifest, stubName);\n const stubPath = resolve(outputDir, stubName);\n writeFileSync(stubPath, tsContent);\n }\n\n const objectCount = Object.keys(manifest.objects).length;\n console.log(`[smrt] ✅ Generated manifest with ${objectCount} object(s)`);\n console.log(`[smrt] Unified: ${unifiedPath}`);\n }\n\n /**\n * Generate TypeScript stub file with manifest constant\n */\n private generateTypeStub(\n manifest: SmartObjectManifest,\n filename: string,\n ): string {\n const isTestManifest = filename.includes('test');\n\n const comment = isTestManifest\n ? `/**\n * Test manifest stub\n * This file is replaced by generate-test-manifest.js during pretest\n * If tests run without pretest, this empty manifest is used\n *\n * DO NOT EDIT MANUALLY - This file is automatically generated\n */`\n : `/**\n * Auto-generated static manifest\n * Generated at build time from SMRT object scanning\n * DO NOT EDIT - This file is automatically generated\n */`;\n\n const exportName = isTestManifest ? 'testManifest' : 'staticManifest';\n\n // Use relative import for core package (to avoid self-reference during build),\n // package import for all other packages\n const isCorePackage = manifest.packageName === '@happyvertical/smrt-core';\n const importPath = isCorePackage\n ? '../scanner/types.js'\n : '@happyvertical/smrt-core/scanner/types';\n\n return `${comment}\n\nimport type { SmartObjectManifest } from '${importPath}';\n\nexport const ${exportName}: SmartObjectManifest = ${JSON.stringify(manifest, null, 2)} as const;\n\nexport default ${exportName};\n`;\n }\n\n /**\n * Load baseClasses from vite.config.ts\n */\n private async loadViteConfigBaseClasses(): Promise<string[] | null> {\n try {\n const viteConfigPath = resolve(process.cwd(), 'vite.config.ts');\n if (!existsSync(viteConfigPath)) {\n console.log('[smrt] vite.config.ts not found');\n return null;\n }\n\n console.log('[smrt] Found vite.config.ts, attempting to load...');\n\n // Use vite to load config which handles TypeScript\n const { loadConfigFromFile } = await import('vite');\n const loaded = await loadConfigFromFile(\n { command: 'build', mode: 'test' },\n viteConfigPath,\n );\n\n if (!loaded?.config?.plugins) {\n console.log('[smrt] No plugins found in vite config');\n return null;\n }\n\n // Vite's loaded plugins are a recursive PluginOption[] (plugins, arrays,\n // falsy values, promises). We only probe a few optional fields, so model\n // them structurally and narrow defensively instead of using `any`.\n const plugins = loaded.config.plugins as readonly VitePluginProbe[];\n\n console.log(\n '[smrt] Vite config loaded, plugins:',\n plugins.map((p) => p?.name),\n );\n\n // Find smrtPlugin in plugins array\n const smrtPlugin = plugins.find((p) => p?.name === 'smrt-auto-service');\n\n if (!smrtPlugin) {\n console.log(\n '[smrt] smrt-auto-service plugin not found in plugins array',\n );\n return null;\n }\n\n console.log('[smrt] Found smrt-auto-service plugin');\n\n // Try different ways to access options\n const api = smrtPlugin.api;\n let opts: VitePluginOptions | undefined =\n (typeof api === 'object' && api !== null ? api.options : undefined) ||\n smrtPlugin.options ||\n smrtPlugin._options;\n\n if (!opts && typeof api === 'function') {\n try {\n opts = api().options;\n } catch (e) {\n console.log('[smrt] Could not call plugin.api()');\n }\n }\n\n if (opts?.baseClasses) {\n console.log(\n '[smrt] Plugin options:',\n JSON.stringify({\n baseClasses: opts.baseClasses,\n followImports: opts.followImports,\n }),\n );\n return opts.baseClasses;\n }\n\n console.log('[smrt] Could not access plugin options');\n return null;\n } catch (error) {\n console.log(\n '[smrt] Error loading vite.config.ts:',\n error instanceof Error ? error.message : String(error),\n );\n console.log('[smrt] Using default baseClasses');\n return null;\n }\n }\n\n /**\n * Load base classes from external SMRT package manifests\n */\n private async loadExternalBaseClasses(packages: string[]): Promise<string[]> {\n const externalBaseClasses: string[] = [];\n\n for (const pkgName of packages) {\n // Resolve the manifest the same way discovery does (honors `.smrt/` and\n // `src/manifest/`, not just `dist/`) so source-only workspace packages\n // still contribute base classes (#1378).\n const manifestPath = resolveManifestPath(pkgName, process.cwd());\n if (!manifestPath) {\n console.log(`[smrt] ${pkgName}: no SMRT manifest resolved`);\n continue;\n }\n\n try {\n const manifestContent = readFileSync(manifestPath, 'utf-8');\n const manifest: SmartObjectManifest = JSON.parse(manifestContent);\n\n // Extract all class names from this package\n const foundClassNames: string[] = [];\n for (const objDef of Object.values(manifest.objects)) {\n if (objDef.className) {\n const className = objDef.className;\n foundClassNames.push(className);\n externalBaseClasses.push(className);\n }\n }\n\n console.log(\n `[smrt] ${pkgName}: found ${foundClassNames.length} class(es) - ${foundClassNames.join(', ')}`,\n );\n } catch (error) {\n console.log(\n `[smrt] ${pkgName}: manifest not found or invalid - ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n return externalBaseClasses;\n }\n\n /**\n * Read package.json from current working directory\n */\n private readPackageJson(): PackageInfo {\n try {\n const packageJsonPath = resolve(process.cwd(), 'package.json');\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n return {\n name: packageJson.name,\n version: packageJson.version,\n };\n } catch (error) {\n return {};\n }\n }\n\n /**\n * Create empty manifest when no files found\n */\n private createEmptyManifest(\n options: ManifestBuilderOptions,\n ): SmartObjectManifest {\n const manifest: SmartObjectManifest = {\n version: '1.0.0',\n timestamp: Date.now(),\n objects: {},\n moduleType: options.moduleType || 'smrt',\n };\n\n if (options.discoverExternalPackages) {\n manifest.smrtDependencies = discoverSmrtPackages();\n }\n\n if (options.injectPackageInfo) {\n const packageInfo = this.readPackageJson();\n if (packageInfo.name) {\n manifest.packageName = packageInfo.name;\n }\n }\n\n return manifest;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generator.js","sources":["../../src/manifest/generator.ts"],"sourcesContent":["/**\n * Manifest generation orchestrator\n * Consolidates manifest generation logic for both build and test manifests\n */\n\nimport { createLogger } from '@happyvertical/logger';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, isAbsolute, relative, resolve } from 'node:path';\nimport fg from 'fast-glob';\nimport { ManifestGenerator } from '../scanner/manifest-generator.js';\nimport type { SmartObjectManifest } from '../scanner/types.js';\nimport { importWorkspaceModule } from '../utils/import-workspace-module.js';\nimport type { ScannerModule } from '../utils/scanner-module.js';\nimport {\n discoverSmrtPackages,\n resolveManifestPath,\n} from './discover-smrt-packages.js';\nimport { ManifestManager } from './manager.js';\n\n// Build-time manifest-generation diagnostics route through the shared logger\n// (S14 / dim-9, #1579) so consumers can control verbosity instead of receiving\n// unconditional stdout writes.\nconst logger = createLogger({ level: 'info' });\n\nasync function importScanner() {\n return importWorkspaceModule<ScannerModule>({\n packageName: '@happyvertical/smrt-scanner',\n distEntry: 'packages/scanner/dist/index.js',\n sourceEntry: 'packages/scanner/src/index.ts',\n purpose: 'manifest generation',\n });\n}\n\n/**\n * Options for ManifestBuilder.generate()\n *\n * Controls file discovery, scanner configuration, output generation, and metadata injection\n */\nexport interface ManifestBuilderOptions {\n // File Discovery\n include?: string[];\n exclude?: string[];\n followImports?: boolean;\n\n // Scanner Configuration\n baseClasses?: string[];\n loadViteConfig?: boolean;\n discoverExternalPackages?: boolean;\n includeExternalBaseClasses?: boolean;\n includePrivateMethods?: boolean;\n includeStaticMethods?: boolean;\n\n // Output Configuration\n outputDir?: string;\n outputName?: string;\n generateTypeStub?: boolean;\n stubName?: string;\n\n // Metadata\n injectPackageInfo?: boolean;\n moduleType?: string;\n\n // Tree Shaking (External Object Filtering)\n /**\n * @deprecated Tree shaking is no longer needed. The AST scanner no longer includes external objects in the manifest by default.\n */\n treeShake?: boolean;\n\n /**\n * @deprecated Whitelists are no longer needed. The AST scanner no longer includes external objects in the manifest by default.\n */\n externalObjectsWhitelist?: string[];\n}\n\ninterface ScannerConfig {\n baseClasses: string[];\n includePrivateMethods: boolean;\n includeStaticMethods: boolean;\n followImports: boolean;\n smrtDependencies?: string[];\n}\n\ninterface PackageInfo {\n name?: string;\n version?: string;\n}\n\n/**\n * Subset of the smrt-auto-service Vite plugin options we probe when reading\n * baseClasses out of a project's vite.config.ts.\n */\ninterface VitePluginOptions {\n baseClasses?: string[];\n followImports?: boolean;\n}\n\n/**\n * Structural shape of a loaded Vite plugin entry as probed by\n * loadViteConfigBaseClasses(). The plugin may expose its options directly, on\n * `_options`, or via an `api` object/function — all optional and discovered at\n * runtime, so each is modeled as optional here.\n */\ninterface VitePluginProbe {\n name?: string;\n options?: VitePluginOptions;\n _options?: VitePluginOptions;\n api?:\n | { options?: VitePluginOptions }\n | (() => { options?: VitePluginOptions });\n}\n\n/**\n * Orchestrates manifest generation with configurable options\n *\n * Consolidates logic from generate-manifest.js and generate-test-manifest.js\n * into a single, testable, and maintainable service.\n */\nexport class ManifestBuilder {\n /**\n * Generate manifest with specified options\n */\n async generate(\n options: ManifestBuilderOptions = {},\n ): Promise<SmartObjectManifest> {\n // 1. Discover files to scan\n const files = this.discoverFiles(options);\n\n if (files.length === 0) {\n logger.info('[smrt] No source files found');\n return this.createEmptyManifest(options);\n }\n\n logger.info(`[smrt] Scanning ${files.length} source file(s)...`);\n\n // 2. Configure scanner (baseClasses, external packages, vite config)\n const scannerConfig = await this.configureScanner(options);\n\n // 3. Scan files with OXC scanner\n const scannedManifest = await this.scanAndBuildManifest(\n scannerConfig,\n options,\n );\n\n // 4. Enrich manifest with metadata (smrtDependencies, packageInfo)\n const manifest = this.enrichManifest(\n scannedManifest,\n options,\n scannerConfig,\n );\n\n // 5. Write output files\n this.normalizeFilePaths(manifest);\n await this.writeOutput(manifest, options);\n\n return manifest;\n }\n\n private normalizeFilePaths(manifest: SmartObjectManifest): void {\n const workspaceRoot = this.findWorkspaceRoot(process.cwd());\n\n for (const obj of Object.values(manifest.objects || {})) {\n if (obj.filePath && isAbsolute(obj.filePath)) {\n obj.filePath = relative(workspaceRoot, obj.filePath).replace(\n /\\\\/g,\n '/',\n );\n }\n }\n }\n\n private findWorkspaceRoot(startDir: string): string {\n let current = resolve(startDir);\n\n while (true) {\n if (\n existsSync(resolve(current, 'pnpm-workspace.yaml')) ||\n existsSync(resolve(current, '.git'))\n ) {\n return current;\n }\n\n const parent = dirname(current);\n if (parent === current) {\n return resolve(startDir);\n }\n current = parent;\n }\n }\n\n /**\n * Discover source files based on include/exclude patterns\n */\n private discoverFiles(options: ManifestBuilderOptions): string[] {\n const include = options.include || ['src/**/*.ts'];\n const exclude = options.exclude || ['src/**/*.d.ts', 'node_modules/**'];\n\n return fg.sync(include, {\n absolute: true,\n ignore: exclude,\n });\n }\n\n /**\n * Configure AST scanner with baseClasses, external packages, and vite config\n */\n private async configureScanner(\n options: ManifestBuilderOptions,\n ): Promise<ScannerConfig> {\n let baseClasses = options.baseClasses || [\n 'SmrtObject',\n 'SmrtClass',\n 'SmrtCollection',\n ];\n\n // Load from vite.config.ts if requested\n if (options.loadViteConfig) {\n const viteBaseClasses = await this.loadViteConfigBaseClasses();\n if (viteBaseClasses && viteBaseClasses.length > 0) {\n baseClasses = viteBaseClasses;\n logger.info(\n `[smrt] Using baseClasses from vite.config.ts: ${baseClasses.join(', ')}`,\n );\n }\n }\n\n // Discover external SMRT packages\n let smrtDependencies: string[] = [];\n if (options.discoverExternalPackages) {\n logger.info('[smrt] Discovering external SMRT packages...');\n smrtDependencies = discoverSmrtPackages();\n logger.info(\n `[smrt] Found ${smrtDependencies.length} SMRT package(s): ${smrtDependencies.join(', ')}`,\n );\n\n // Optionally add external base classes\n if (options.includeExternalBaseClasses) {\n const externalClasses =\n await this.loadExternalBaseClasses(smrtDependencies);\n if (externalClasses.length > 0) {\n baseClasses = [...baseClasses, ...externalClasses];\n logger.info(\n `[smrt] Added ${externalClasses.length} external base class(es) to scanner`,\n );\n logger.info(`[smrt] Total baseClasses: ${baseClasses.length}`);\n }\n }\n }\n\n return {\n baseClasses,\n includePrivateMethods: options.includePrivateMethods ?? false,\n includeStaticMethods: options.includeStaticMethods ?? true,\n followImports: options.followImports ?? false,\n smrtDependencies,\n };\n }\n\n /**\n * Scan files using OxcScanner and build manifest via ManifestAdapter.\n *\n * This replaces the old ASTScanner-based scanFiles() method.\n * Uses the same OXC pipeline as the Vite plugin's scanWithOxc().\n */\n private async scanAndBuildManifest(\n config: ScannerConfig,\n options: ManifestBuilderOptions,\n ): Promise<SmartObjectManifest> {\n const { OxcScanner, ManifestAdapter } = await importScanner();\n\n const scanner = new OxcScanner({\n cwd: process.cwd(),\n include: options.include || ['src/**/*.ts'],\n exclude: options.exclude || ['src/**/*.d.ts', 'node_modules/**'],\n baseClasses: config.baseClasses,\n includePrivateMethods: config.includePrivateMethods,\n includeStaticMethods: config.includeStaticMethods,\n followImports: config.followImports,\n });\n\n const { results, resolved } = await scanner.scanAndResolve();\n\n // Read package.json for metadata\n let packageName: string | undefined;\n let packageVersion: string | undefined;\n let packageJson: { name?: string; version?: string } | undefined;\n try {\n const pkgPath = resolve(process.cwd(), 'package.json');\n const pkgContent = readFileSync(pkgPath, 'utf-8');\n packageJson = JSON.parse(pkgContent);\n packageName = packageJson?.name || undefined;\n packageVersion = packageJson?.version || undefined;\n } catch {\n // package.json not found - continue without packageName\n }\n\n // Convert to manifest format\n const adapter = new ManifestAdapter();\n const manifest = adapter.toManifest(resolved, {\n packageName,\n packageVersion,\n typeAliases: results.typeAliases,\n });\n\n // Set smrtDependencies BEFORE mergeInheritedFields so external packages can be loaded\n if (config.smrtDependencies && config.smrtDependencies.length > 0) {\n manifest.smrtDependencies = config.smrtDependencies;\n }\n\n // Run manifest generation passes (same as Vite plugin path)\n const manifestGen = new ManifestGenerator();\n manifestGen.injectTenantScopedFields(manifest);\n manifestGen.mergeInheritedFields(manifest);\n manifestGen.generateValidationRules(manifest);\n manifestGen.generateSchemas(manifest);\n manifestGen.assertTenantScopedSchemaContract(manifest);\n manifestGen.generateAgentManifests(manifest, packageName, packageJson);\n\n return manifest;\n }\n\n /**\n * Enrich manifest with metadata (moduleType, smrtDependencies, packageInfo).\n *\n * Note: As of Issue #1013, this method no longer merges external package\n * objects into the manifest. Dependencies are referenced via\n * `smrtDependencies` and resolved at runtime by manifest-loader.ts.\n */\n private enrichManifest(\n manifest: SmartObjectManifest,\n options: ManifestBuilderOptions,\n scannerConfig: ScannerConfig,\n ): SmartObjectManifest {\n // Add module type\n manifest.moduleType = options.moduleType || 'smrt';\n\n // Record dependency references (not their objects) so runtime\n // manifest-loader.ts can discover and load them on demand.\n if (\n scannerConfig.smrtDependencies &&\n scannerConfig.smrtDependencies.length > 0\n ) {\n manifest.smrtDependencies = scannerConfig.smrtDependencies;\n }\n\n // Inject package info\n if (options.injectPackageInfo) {\n const packageInfo = this.readPackageJson();\n if (packageInfo.name) {\n manifest.packageName = packageInfo.name;\n logger.info(`[smrt] Injected package name: ${packageInfo.name}`);\n } else {\n logger.warn(\n '[smrt] Warning: Could not read package.json, packageName will be undefined',\n );\n }\n }\n\n return manifest;\n }\n\n /**\n * Write manifest JSON and optional TypeScript stub\n */\n private async writeOutput(\n manifest: SmartObjectManifest,\n options: ManifestBuilderOptions,\n ): Promise<void> {\n const manager = new ManifestManager(process.cwd());\n const isTest =\n options.outputName?.includes('test') ||\n options.stubName?.includes('test');\n const mode = isTest ? 'dev' : 'build';\n\n // 1. Always write to the unified location via ManifestManager\n manager.write(manifest, mode);\n\n // 2. Legacy/Explicit Output (if requested or for stubs)\n const outputDir = options.outputDir || 'src/manifest';\n const outputName = options.outputName || 'manifest.json';\n\n // Ensure output directory exists for legacy/stubs\n mkdirSync(outputDir, { recursive: true });\n\n // Write JSON manifest to legacy location if different from unified path\n const manifestPath = resolve(outputDir, outputName);\n const unifiedPath = manager.getOutputPath(mode);\n\n if (resolve(manifestPath) !== resolve(unifiedPath)) {\n writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));\n }\n\n // Write TypeScript stub if requested\n if (options.generateTypeStub) {\n const stubName = options.stubName || 'manifest.ts';\n const tsContent = this.generateTypeStub(manifest, stubName);\n const stubPath = resolve(outputDir, stubName);\n writeFileSync(stubPath, tsContent);\n }\n\n const objectCount = Object.keys(manifest.objects).length;\n logger.info(`[smrt] ✅ Generated manifest with ${objectCount} object(s)`);\n logger.info(`[smrt] Unified: ${unifiedPath}`);\n }\n\n /**\n * Generate TypeScript stub file with manifest constant\n */\n private generateTypeStub(\n manifest: SmartObjectManifest,\n filename: string,\n ): string {\n const isTestManifest = filename.includes('test');\n\n const comment = isTestManifest\n ? `/**\n * Test manifest stub\n * This file is replaced by generate-test-manifest.js during pretest\n * If tests run without pretest, this empty manifest is used\n *\n * DO NOT EDIT MANUALLY - This file is automatically generated\n */`\n : `/**\n * Auto-generated static manifest\n * Generated at build time from SMRT object scanning\n * DO NOT EDIT - This file is automatically generated\n */`;\n\n const exportName = isTestManifest ? 'testManifest' : 'staticManifest';\n\n // Use relative import for core package (to avoid self-reference during build),\n // package import for all other packages\n const isCorePackage = manifest.packageName === '@happyvertical/smrt-core';\n const importPath = isCorePackage\n ? '../scanner/types.js'\n : '@happyvertical/smrt-core/scanner/types';\n\n return `${comment}\n\nimport type { SmartObjectManifest } from '${importPath}';\n\nexport const ${exportName}: SmartObjectManifest = ${JSON.stringify(manifest, null, 2)} as const;\n\nexport default ${exportName};\n`;\n }\n\n /**\n * Load baseClasses from vite.config.ts\n */\n private async loadViteConfigBaseClasses(): Promise<string[] | null> {\n try {\n const viteConfigPath = resolve(process.cwd(), 'vite.config.ts');\n if (!existsSync(viteConfigPath)) {\n logger.info('[smrt] vite.config.ts not found');\n return null;\n }\n\n logger.info('[smrt] Found vite.config.ts, attempting to load...');\n\n // Use vite to load config which handles TypeScript\n const { loadConfigFromFile } = await import('vite');\n const loaded = await loadConfigFromFile(\n { command: 'build', mode: 'test' },\n viteConfigPath,\n );\n\n if (!loaded?.config?.plugins) {\n logger.info('[smrt] No plugins found in vite config');\n return null;\n }\n\n // Vite's loaded plugins are a recursive PluginOption[] (plugins, arrays,\n // falsy values, promises). We only probe a few optional fields, so model\n // them structurally and narrow defensively instead of using `any`.\n const plugins = loaded.config.plugins as readonly VitePluginProbe[];\n\n logger.info('[smrt] Vite config loaded', {\n plugins: plugins.map((p) => p?.name),\n });\n\n // Find smrtPlugin in plugins array\n const smrtPlugin = plugins.find((p) => p?.name === 'smrt-auto-service');\n\n if (!smrtPlugin) {\n logger.info(\n '[smrt] smrt-auto-service plugin not found in plugins array',\n );\n return null;\n }\n\n logger.info('[smrt] Found smrt-auto-service plugin');\n\n // Try different ways to access options\n const api = smrtPlugin.api;\n let opts: VitePluginOptions | undefined =\n (typeof api === 'object' && api !== null ? api.options : undefined) ||\n smrtPlugin.options ||\n smrtPlugin._options;\n\n if (!opts && typeof api === 'function') {\n try {\n opts = api().options;\n } catch (e) {\n logger.info('[smrt] Could not call plugin.api()');\n }\n }\n\n if (opts?.baseClasses) {\n logger.info('[smrt] Plugin options', {\n baseClasses: opts.baseClasses,\n followImports: opts.followImports,\n });\n return opts.baseClasses;\n }\n\n logger.info('[smrt] Could not access plugin options');\n return null;\n } catch (error) {\n logger.warn('[smrt] Error loading vite.config.ts', {\n error: error instanceof Error ? error.message : String(error),\n });\n logger.info('[smrt] Using default baseClasses');\n return null;\n }\n }\n\n /**\n * Load base classes from external SMRT package manifests\n */\n private async loadExternalBaseClasses(packages: string[]): Promise<string[]> {\n const externalBaseClasses: string[] = [];\n\n for (const pkgName of packages) {\n // Resolve the manifest the same way discovery does (honors `.smrt/` and\n // `src/manifest/`, not just `dist/`) so source-only workspace packages\n // still contribute base classes (#1378).\n const manifestPath = resolveManifestPath(pkgName, process.cwd());\n if (!manifestPath) {\n logger.info(`[smrt] ${pkgName}: no SMRT manifest resolved`);\n continue;\n }\n\n try {\n const manifestContent = readFileSync(manifestPath, 'utf-8');\n const manifest: SmartObjectManifest = JSON.parse(manifestContent);\n\n // Extract all class names from this package\n const foundClassNames: string[] = [];\n for (const objDef of Object.values(manifest.objects)) {\n if (objDef.className) {\n const className = objDef.className;\n foundClassNames.push(className);\n externalBaseClasses.push(className);\n }\n }\n\n logger.info(\n `[smrt] ${pkgName}: found ${foundClassNames.length} class(es) - ${foundClassNames.join(', ')}`,\n );\n } catch (error) {\n logger.info(\n `[smrt] ${pkgName}: manifest not found or invalid - ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n return externalBaseClasses;\n }\n\n /**\n * Read package.json from current working directory\n */\n private readPackageJson(): PackageInfo {\n try {\n const packageJsonPath = resolve(process.cwd(), 'package.json');\n const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\n return {\n name: packageJson.name,\n version: packageJson.version,\n };\n } catch (error) {\n return {};\n }\n }\n\n /**\n * Create empty manifest when no files found\n */\n private createEmptyManifest(\n options: ManifestBuilderOptions,\n ): SmartObjectManifest {\n const manifest: SmartObjectManifest = {\n version: '1.0.0',\n timestamp: Date.now(),\n objects: {},\n moduleType: options.moduleType || 'smrt',\n };\n\n if (options.discoverExternalPackages) {\n manifest.smrtDependencies = discoverSmrtPackages();\n }\n\n if (options.injectPackageInfo) {\n const packageInfo = this.readPackageJson();\n if (packageInfo.name) {\n manifest.packageName = packageInfo.name;\n }\n }\n\n return manifest;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -2,8 +2,7 @@ import { existsSync, readFileSync } from "node:fs";
2
2
  import { dirname, join } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { ManifestGenerator } from "../scanner/manifest-generator.js";
5
- import "fast-glob";
6
- import "./discover-smrt-packages.js";
5
+ import { ManifestBuilder } from "./generator.js";
7
6
  import { ManifestManager } from "./manager.js";
8
7
  import { discoverManifestEntry, findManifestEntryByQualifiedName, loadExternalManifest, loadExternalManifestSync, loadLocalTestManifestSync, loadManifestFromPathSync } from "./manifest-loader.js";
9
8
  const EMPTY_STATIC_MANIFEST = {
@@ -36,6 +35,7 @@ function getManifest() {
36
35
  return Promise.resolve(manifest);
37
36
  }
38
37
  export {
38
+ ManifestBuilder,
39
39
  ManifestGenerator,
40
40
  ManifestManager,
41
41
  discoverManifestEntry,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/manifest/index.ts"],"sourcesContent":["/**\n * Static manifest module for runtime use\n * Uses pre-generated manifest from build time instead of runtime scanning\n */\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { SmartObjectManifest } from '../scanner/types';\n\n// Re-export utility functions that work with static manifest\nexport { ManifestGenerator } from '../scanner/manifest-generator';\nexport type {\n SmartObjectDefinition,\n SmartObjectManifest,\n} from '../scanner/types';\nexport type { ManifestBuilderOptions } from './generator';\nexport { ManifestBuilder } from './generator';\nexport { ManifestManager } from './manager';\nexport {\n discoverManifestEntry,\n findManifestEntryByQualifiedName,\n loadExternalManifest,\n loadExternalManifestSync,\n loadLocalTestManifestSync,\n loadManifestFromPathSync,\n} from './manifest-loader';\n\nconst EMPTY_STATIC_MANIFEST: SmartObjectManifest = {\n version: '1.0.0',\n timestamp: 0,\n objects: {},\n packageName: '@happyvertical/smrt-core',\n};\n\nfunction loadStaticManifest(): SmartObjectManifest {\n const currentDir = dirname(fileURLToPath(import.meta.url));\n const manifestCandidates = [\n join(currentDir, 'static-manifest.json'),\n join(currentDir, '..', 'manifest.json'),\n join(currentDir, '..', '..', 'dist', 'manifest.json'),\n ];\n\n for (const manifestPath of manifestCandidates) {\n if (!existsSync(manifestPath)) {\n continue;\n }\n\n try {\n return JSON.parse(readFileSync(manifestPath, 'utf-8'));\n } catch {\n // Fall through to the next candidate or the empty manifest.\n }\n }\n\n return EMPTY_STATIC_MANIFEST;\n}\n\nexport const manifest = loadStaticManifest();\nexport const staticManifest = manifest;\nexport default manifest;\n\n/**\n * Get manifest data (static at runtime)\n * No longer requires TypeScript compiler or file scanning.\n */\nexport function getManifest() {\n return Promise.resolve(manifest);\n}\n"],"names":[],"mappings":";;;;;;;;AA4BA,MAAM,wBAA6C;AAAA,EACjD,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS,CAAA;AAAA,EACT,aAAa;AACf;AAEA,SAAS,qBAA0C;AACjD,QAAM,aAAa,QAAQ,cAAc,YAAY,GAAG,CAAC;AACzD,QAAM,qBAAqB;AAAA,IACzB,KAAK,YAAY,sBAAsB;AAAA,IACvC,KAAK,YAAY,MAAM,eAAe;AAAA,IACtC,KAAK,YAAY,MAAM,MAAM,QAAQ,eAAe;AAAA,EAAA;AAGtD,aAAW,gBAAgB,oBAAoB;AAC7C,QAAI,CAAC,WAAW,YAAY,GAAG;AAC7B;AAAA,IACF;AAEA,QAAI;AACF,aAAO,KAAK,MAAM,aAAa,cAAc,OAAO,CAAC;AAAA,IACvD,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,SAAO;AACT;AAEO,MAAM,WAAW,mBAAA;AACjB,MAAM,iBAAiB;AAOvB,SAAS,cAAc;AAC5B,SAAO,QAAQ,QAAQ,QAAQ;AACjC;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/manifest/index.ts"],"sourcesContent":["/**\n * Static manifest module for runtime use\n * Uses pre-generated manifest from build time instead of runtime scanning\n */\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { SmartObjectManifest } from '../scanner/types';\n\n// Re-export utility functions that work with static manifest\nexport { ManifestGenerator } from '../scanner/manifest-generator';\nexport type {\n SmartObjectDefinition,\n SmartObjectManifest,\n} from '../scanner/types';\nexport type { ManifestBuilderOptions } from './generator';\nexport { ManifestBuilder } from './generator';\nexport { ManifestManager } from './manager';\nexport {\n discoverManifestEntry,\n findManifestEntryByQualifiedName,\n loadExternalManifest,\n loadExternalManifestSync,\n loadLocalTestManifestSync,\n loadManifestFromPathSync,\n} from './manifest-loader';\n\nconst EMPTY_STATIC_MANIFEST: SmartObjectManifest = {\n version: '1.0.0',\n timestamp: 0,\n objects: {},\n packageName: '@happyvertical/smrt-core',\n};\n\nfunction loadStaticManifest(): SmartObjectManifest {\n const currentDir = dirname(fileURLToPath(import.meta.url));\n const manifestCandidates = [\n join(currentDir, 'static-manifest.json'),\n join(currentDir, '..', 'manifest.json'),\n join(currentDir, '..', '..', 'dist', 'manifest.json'),\n ];\n\n for (const manifestPath of manifestCandidates) {\n if (!existsSync(manifestPath)) {\n continue;\n }\n\n try {\n return JSON.parse(readFileSync(manifestPath, 'utf-8'));\n } catch {\n // Fall through to the next candidate or the empty manifest.\n }\n }\n\n return EMPTY_STATIC_MANIFEST;\n}\n\nexport const manifest = loadStaticManifest();\nexport const staticManifest = manifest;\nexport default manifest;\n\n/**\n * Get manifest data (static at runtime)\n * No longer requires TypeScript compiler or file scanning.\n */\nexport function getManifest() {\n return Promise.resolve(manifest);\n}\n"],"names":[],"mappings":";;;;;;;AA4BA,MAAM,wBAA6C;AAAA,EACjD,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS,CAAA;AAAA,EACT,aAAa;AACf;AAEA,SAAS,qBAA0C;AACjD,QAAM,aAAa,QAAQ,cAAc,YAAY,GAAG,CAAC;AACzD,QAAM,qBAAqB;AAAA,IACzB,KAAK,YAAY,sBAAsB;AAAA,IACvC,KAAK,YAAY,MAAM,eAAe;AAAA,IACtC,KAAK,YAAY,MAAM,MAAM,QAAQ,eAAe;AAAA,EAAA;AAGtD,aAAW,gBAAgB,oBAAoB;AAC7C,QAAI,CAAC,WAAW,YAAY,GAAG;AAC7B;AAAA,IACF;AAEA,QAAI;AACF,aAAO,KAAK,MAAM,aAAa,cAAc,OAAO,CAAC;AAAA,IACvD,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,SAAO;AACT;AAEO,MAAM,WAAW,mBAAA;AACjB,MAAM,iBAAiB;AAOvB,SAAS,cAAc;AAC5B,SAAO,QAAQ,QAAQ,QAAQ;AACjC;"}
@@ -179,6 +179,16 @@ export declare function getLoadedManifests(): Array<[string, Manifest]>;
179
179
  *
180
180
  * @param collection - The collection/table name to find siblings for
181
181
  * @returns Array of manifest entries that share the same collection
182
+ *
183
+ * Known limitation (#1579, won't-fix): the per-collection result is cached on
184
+ * `globalThis.__smrtSTISiblingCache` after the first call and is not invalidated
185
+ * when a manifest is registered *afterwards* and isn't reachable via
186
+ * `smrtDependencies` (the Release-A self-register path). A sibling registered
187
+ * after first discovery for a given collection can therefore be missed until the
188
+ * cache is cleared. Accepted as low-risk: STI manifests are registered at
189
+ * startup before query traffic, and the few self-register flows that could hit
190
+ * it can reset the cache. Fixing it properly means a registration→cache
191
+ * invalidation hook, which is disproportionate to the exposure.
182
192
  */
183
193
  export declare function discoverSTISiblingsSync(collection: string): Array<{
184
194
  className: string;
@@ -1 +1 @@
1
- {"version":3,"file":"manifest-loader.d.ts","sourceRoot":"","sources":["../../src/manifest/manifest-loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manifest-loader.d.ts","sourceRoot":"","sources":["../../src/manifest/manifest-loader.ts"],"names":[],"mappings":"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"}