@happyvertical/smrt-core 0.36.5 → 0.36.6

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 (104) hide show
  1. package/dist/collection.d.ts +1 -1
  2. package/dist/config.d.ts +1 -1
  3. package/dist/config.d.ts.map +1 -1
  4. package/dist/config.js.map +1 -1
  5. package/dist/consumer-plugin/index.d.ts.map +1 -1
  6. package/dist/consumer-plugin/index.js +7 -3
  7. package/dist/consumer-plugin/index.js.map +1 -1
  8. package/dist/database.d.ts +3 -3
  9. package/dist/database.d.ts.map +1 -1
  10. package/dist/database.js.map +1 -1
  11. package/dist/embeddings/provider.d.ts +14 -2
  12. package/dist/embeddings/provider.d.ts.map +1 -1
  13. package/dist/embeddings/provider.js +3 -3
  14. package/dist/embeddings/provider.js.map +1 -1
  15. package/dist/embeddings/storage.js.map +1 -1
  16. package/dist/errors.d.ts +22 -22
  17. package/dist/errors.d.ts.map +1 -1
  18. package/dist/errors.js +5 -4
  19. package/dist/errors.js.map +1 -1
  20. package/dist/knowledge.d.ts +12 -1
  21. package/dist/knowledge.d.ts.map +1 -1
  22. package/dist/knowledge.js.map +1 -1
  23. package/dist/lazy-config.d.ts.map +1 -1
  24. package/dist/lazy-config.js.map +1 -1
  25. package/dist/manifest/generator.d.ts.map +1 -1
  26. package/dist/manifest/generator.js +14 -12
  27. package/dist/manifest/generator.js.map +1 -1
  28. package/dist/manifest/manager.d.ts +3 -3
  29. package/dist/manifest/manager.d.ts.map +1 -1
  30. package/dist/manifest/manager.js.map +1 -1
  31. package/dist/manifest/manifest-loader.d.ts +3 -2
  32. package/dist/manifest/manifest-loader.d.ts.map +1 -1
  33. package/dist/manifest/manifest-loader.js +3 -2
  34. package/dist/manifest/manifest-loader.js.map +1 -1
  35. package/dist/manifest/static-manifest.js +2 -2
  36. package/dist/manifest/static-manifest.js.map +1 -1
  37. package/dist/manifest/store.js +2 -2
  38. package/dist/manifest/test-manifest-stub.js +2 -2
  39. package/dist/manifest/test-manifest-stub.js.map +1 -1
  40. package/dist/manifest.json +2 -2
  41. package/dist/mcp-advisor/index.d.ts +1 -1
  42. package/dist/mcp-advisor/index.d.ts.map +1 -1
  43. package/dist/mcp-advisor/tools/get-object-config.d.ts.map +1 -1
  44. package/dist/mcp-advisor/types.d.ts +5 -5
  45. package/dist/mcp-advisor/types.d.ts.map +1 -1
  46. package/dist/migrations/differ.js.map +1 -1
  47. package/dist/scanner/manifest-generator.d.ts +11 -3
  48. package/dist/scanner/manifest-generator.d.ts.map +1 -1
  49. package/dist/scanner/manifest-generator.js +19 -15
  50. package/dist/scanner/manifest-generator.js.map +1 -1
  51. package/dist/scanner/types.d.ts +60 -6
  52. package/dist/scanner/types.d.ts.map +1 -1
  53. package/dist/schema/code-generator.d.ts.map +1 -1
  54. package/dist/schema/ddl/base-strategy.d.ts +2 -2
  55. package/dist/schema/ddl/base-strategy.d.ts.map +1 -1
  56. package/dist/schema/ddl/base-strategy.js.map +1 -1
  57. package/dist/schema/ddl/sqlite-strategy.d.ts +1 -1
  58. package/dist/schema/ddl/sqlite-strategy.d.ts.map +1 -1
  59. package/dist/schema/ddl/sqlite-strategy.js.map +1 -1
  60. package/dist/schema/ddl/types.d.ts +1 -1
  61. package/dist/schema/ddl/types.d.ts.map +1 -1
  62. package/dist/schema/generator.d.ts +27 -4
  63. package/dist/schema/generator.d.ts.map +1 -1
  64. package/dist/schema/generator.js +3 -2
  65. package/dist/schema/generator.js.map +1 -1
  66. package/dist/schema/override-system.d.ts +3 -3
  67. package/dist/schema/override-system.d.ts.map +1 -1
  68. package/dist/schema/schema-aggregator.d.ts.map +1 -1
  69. package/dist/schema/schema-manager.d.ts.map +1 -1
  70. package/dist/schema/schema-manager.js +12 -4
  71. package/dist/schema/schema-manager.js.map +1 -1
  72. package/dist/schema/types.d.ts +1 -1
  73. package/dist/schema/types.d.ts.map +1 -1
  74. package/dist/schema/utils.d.ts +6 -1
  75. package/dist/schema/utils.d.ts.map +1 -1
  76. package/dist/schema/utils.js +2 -1
  77. package/dist/schema/utils.js.map +1 -1
  78. package/dist/signals/sanitizer.d.ts +1 -1
  79. package/dist/signals/sanitizer.d.ts.map +1 -1
  80. package/dist/signals/sanitizer.js +12 -2
  81. package/dist/signals/sanitizer.js.map +1 -1
  82. package/dist/smrt-knowledge.json +4 -4
  83. package/dist/system/types.d.ts +2 -2
  84. package/dist/system/types.d.ts.map +1 -1
  85. package/dist/system-fields.d.ts +5 -43
  86. package/dist/system-fields.d.ts.map +1 -1
  87. package/dist/system-fields.js +2 -1
  88. package/dist/system-fields.js.map +1 -1
  89. package/dist/test-utils.d.ts +39 -13
  90. package/dist/test-utils.d.ts.map +1 -1
  91. package/dist/testing/database.d.ts.map +1 -1
  92. package/dist/testing/database.js.map +1 -1
  93. package/dist/utils/json.js.map +1 -1
  94. package/dist/utils.d.ts +16 -8
  95. package/dist/utils.d.ts.map +1 -1
  96. package/dist/utils.js.map +1 -1
  97. package/dist/vite-plugin/index.d.ts.map +1 -1
  98. package/dist/vite-plugin/index.js +9 -7
  99. package/dist/vite-plugin/index.js.map +1 -1
  100. package/dist/vite-plugin/sveltekit-generator.d.ts.map +1 -1
  101. package/dist/vite-plugin/sveltekit-generator.js +4 -3
  102. package/dist/vite-plugin/sveltekit-generator.js.map +1 -1
  103. package/dist/vite-plugin/templates/default-ui.ts +20 -6
  104. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"lazy-config.js","sources":["../src/lazy-config.ts"],"sourcesContent":["/**\n * Lazy / execute-time agent_config resolvers.\n *\n * Persisted agent configs (e.g. `_smrt_agent_schedules.agent_config`) freeze\n * any value resolved at sync time, including env-derived ones. When operators\n * rotate an env var the persisted snapshot goes stale until the schedule is\n * rewritten.\n *\n * To avoid that, callers can store **sentinel references** in the persisted\n * config and register matching resolvers that run at execute time. The\n * runtime walks the agent_config tree, replaces every recognised sentinel\n * with the resolver's current return value, and only then hands the config\n * to the agent.\n *\n * Two registration shapes are supported:\n *\n * 1. **Global named resolvers** — register a callback by name once at\n * application startup. Use this for shared resolvers like\n * `resolveSharedAssetStorage`.\n *\n * ```ts\n * import { registerConfigResolver } from '@happyvertical/smrt-agents';\n *\n * registerConfigResolver('sharedAssetStorage', () =>\n * resolveSharedAssetStorage(),\n * );\n * ```\n *\n * Then in the persisted agent_config:\n * ```jsonc\n * { \"assetStorage\": { \"$env\": \"sharedAssetStorage\" } }\n * ```\n *\n * 2. **Per-agent class resolvers** — declare them as a static\n * `configResolvers` map on the agent class. The runtime applies them on\n * top of the persisted config keyed by the same name as the resolver.\n *\n * ```ts\n * class Praeco extends Agent {\n * static configResolvers = {\n * assetStorage: () => resolveSharedAssetStorage(),\n * };\n * }\n * ```\n *\n * Both shapes can be combined freely. Global resolvers always take precedence\n * for `$env` sentinels; class resolvers fill in / override fields by name.\n *\n * @module\n */\n\n/**\n * A lazy resolver — synchronous or async. Return values are merged into the\n * config tree at execute time. Throwing is allowed but is treated as a\n * resolution failure (see {@link ResolveLazyConfigOptions.onError}).\n */\nexport type ConfigResolver = () => unknown | Promise<unknown>;\n\n/**\n * Sentinel object recognised inside agent_config to defer a value to a named\n * resolver. The runtime accepts both `$env` (preferred) and `$resolver` for\n * symmetry with similar systems.\n */\nexport interface LazyConfigSentinel {\n $env?: string;\n $resolver?: string;\n}\n\n/**\n * Options for resolving the lazy parts of a config tree.\n */\nexport interface ResolveLazyConfigOptions {\n /**\n * Per-class resolvers — typically the agent class's static\n * `configResolvers`. Applied as a key-by-key overlay on top of the\n * sentinel-resolved config.\n */\n classResolvers?: Record<string, ConfigResolver>;\n\n /**\n * Optional override for the global resolver registry. When omitted the\n * shared module-scoped registry is used. Useful for tests.\n */\n resolvers?: Map<string, ConfigResolver> | Record<string, ConfigResolver>;\n\n /**\n * What to do when a sentinel references a resolver that isn't registered,\n * or when a resolver throws.\n *\n * - `'leave'` (default): the sentinel is left in place verbatim. The\n * downstream consumer is responsible for handling it.\n * - `'omit'`: the sentinel key is removed from the parent object/array.\n * - `'throw'`: re-throw the underlying error (or throw a new one for\n * missing resolvers).\n */\n onError?: 'leave' | 'omit' | 'throw';\n}\n\nconst globalResolvers = new Map<string, ConfigResolver>();\n\n/**\n * Register a named resolver that participates in lazy config resolution.\n *\n * Calling this with the same name twice replaces the previous resolver — the\n * registry is intentionally last-write-wins so application boot ordering\n * doesn't have to be fragile.\n */\nexport function registerConfigResolver(\n name: string,\n resolver: ConfigResolver,\n): void {\n if (typeof name !== 'string' || name.length === 0) {\n throw new Error('registerConfigResolver: name must be a non-empty string');\n }\n if (typeof resolver !== 'function') {\n throw new Error('registerConfigResolver: resolver must be a function');\n }\n globalResolvers.set(name, resolver);\n}\n\n/**\n * Remove a previously registered resolver. Returns `true` if a resolver was\n * removed.\n */\nexport function unregisterConfigResolver(name: string): boolean {\n return globalResolvers.delete(name);\n}\n\n/**\n * Get the resolver registered under the given name, if any.\n */\nexport function getConfigResolver(name: string): ConfigResolver | undefined {\n return globalResolvers.get(name);\n}\n\n/**\n * List the names of all currently-registered global resolvers.\n */\nexport function listConfigResolvers(): string[] {\n return Array.from(globalResolvers.keys()).sort();\n}\n\n/**\n * Reset the global resolver registry. Primarily for tests.\n */\nexport function resetConfigResolvers(): void {\n globalResolvers.clear();\n}\n\n/**\n * Type guard that returns `true` if `value` is a lazy config sentinel.\n *\n * Recognises objects of the form `{ $env: string }` or\n * `{ $resolver: string }` exactly — extra keys disqualify the value so\n * arbitrary user data isn't accidentally treated as a sentinel.\n */\nexport function isLazyConfigSentinel(\n value: unknown,\n): value is LazyConfigSentinel {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return false;\n }\n const keys = Object.keys(value as Record<string, unknown>);\n if (keys.length !== 1) return false;\n const key = keys[0];\n if (key !== '$env' && key !== '$resolver') return false;\n const resolverName = (value as Record<string, unknown>)[key];\n return typeof resolverName === 'string' && resolverName.length > 0;\n}\n\n/**\n * Extract the resolver name from a sentinel.\n */\nfunction getSentinelName(sentinel: LazyConfigSentinel): string {\n return (sentinel.$env ?? sentinel.$resolver) as string;\n}\n\nfunction normalizeResolverMap(\n resolvers: Map<string, ConfigResolver> | Record<string, ConfigResolver>,\n): Map<string, ConfigResolver> {\n if (resolvers instanceof Map) return resolvers;\n return new Map(Object.entries(resolvers));\n}\n\nconst REMOVE = Symbol('LazyConfig.REMOVE');\n\n/**\n * Maximum traversal depth before {@link resolveValue} bails out. Real\n * `agent_config` payloads are shallow (2–3 levels); a high cap here exists\n * solely to prevent stack overflow from a malicious or buggy persisted\n * config without rejecting any legitimate input. When the cap is hit the\n * value is returned verbatim — same fail-soft as for a missing resolver.\n */\nconst MAX_DEPTH = 64;\n\ninterface ResolveContext {\n resolvers: Map<string, ConfigResolver>;\n onError: NonNullable<ResolveLazyConfigOptions['onError']>;\n /**\n * Map from input object/array to its resolved replacement. Serves two\n * purposes simultaneously:\n * 1. Cycle protection — without it, a self-referential config would\n * recurse forever.\n * 2. DAG fidelity — a sub-tree referenced from two places gets cloned\n * once and the same clone is reused for every reference, preserving\n * structure and ensuring sentinels under shared references are still\n * resolved.\n */\n resolved: WeakMap<object, unknown>;\n}\n\nasync function resolveValue(\n value: unknown,\n ctx: ResolveContext,\n depth: number,\n): Promise<unknown> {\n if (isLazyConfigSentinel(value)) {\n const name = getSentinelName(value);\n const resolver = ctx.resolvers.get(name);\n if (!resolver) {\n if (ctx.onError === 'throw') {\n throw new Error(\n `Lazy config sentinel references unknown resolver \"${name}\"`,\n );\n }\n if (ctx.onError === 'omit') return REMOVE;\n return value;\n }\n\n try {\n return await resolver();\n } catch (error) {\n if (ctx.onError === 'throw') throw error;\n if (ctx.onError === 'omit') return REMOVE;\n return value;\n }\n }\n\n if (depth > MAX_DEPTH) {\n // Defensive: refuse to recurse further. The original sub-tree is\n // returned as-is; sentinels beyond this point will stay unresolved.\n return value;\n }\n\n if (Array.isArray(value)) {\n const cached = ctx.resolved.get(value);\n if (cached !== undefined) return cached;\n const next: unknown[] = [];\n // Register the placeholder *before* descending so that a cycle pointing\n // back at this array sees the in-progress array (and stops recursing).\n ctx.resolved.set(value, next);\n for (const entry of value) {\n const resolved = await resolveValue(entry, ctx, depth + 1);\n if (resolved !== REMOVE) next.push(resolved);\n }\n return next;\n }\n\n if (value && typeof value === 'object') {\n const cached = ctx.resolved.get(value);\n if (cached !== undefined) return cached;\n const next: Record<string, unknown> = {};\n ctx.resolved.set(value, next);\n for (const [key, entry] of Object.entries(\n value as Record<string, unknown>,\n )) {\n const resolved = await resolveValue(entry, ctx, depth + 1);\n if (resolved !== REMOVE) next[key] = resolved;\n }\n return next;\n }\n\n return value;\n}\n\n/**\n * Resolve every lazy sentinel inside an `agent_config`-style record at\n * execute time. The input is not mutated; a new object is returned with\n * sentinel placeholders replaced by their resolver's current return value.\n *\n * Class-level resolvers from {@link ResolveLazyConfigOptions.classResolvers}\n * are applied as a final overlay so they always reflect the live value\n * regardless of what's persisted.\n *\n * @example Sentinel resolution\n * ```ts\n * registerConfigResolver('sharedAssetStorage', () => resolveStorage());\n *\n * const stored = { assetStorage: { $env: 'sharedAssetStorage' } };\n * const live = await resolveLazyConfig(stored);\n * // live.assetStorage === resolveStorage()\n * ```\n *\n * @example Class-level resolvers\n * ```ts\n * const live = await resolveLazyConfig(stored, {\n * classResolvers: { assetStorage: () => resolveStorage() },\n * });\n * ```\n */\nexport async function resolveLazyConfig<T extends Record<string, unknown>>(\n config: T,\n options: ResolveLazyConfigOptions = {},\n): Promise<T> {\n const onError = options.onError ?? 'leave';\n const resolvers = options.resolvers\n ? normalizeResolverMap(options.resolvers)\n : globalResolvers;\n\n const ctx: ResolveContext = {\n resolvers,\n onError,\n resolved: new WeakMap<object, unknown>(),\n };\n const sentinelResolved = (await resolveValue(config, ctx, 0)) as Record<\n string,\n unknown\n >;\n\n const result: Record<string, unknown> = { ...sentinelResolved };\n\n if (options.classResolvers) {\n for (const [key, resolver] of Object.entries(options.classResolvers)) {\n try {\n const value = await resolver();\n // Both `undefined` and `null` are treated as \"no overlay value\" —\n // the persisted record's existing value (if any) is preserved.\n // This matches the documented contract on `Agent.configResolvers`\n // and makes the common pattern `() => process.env.X ?? null` safe.\n if (value !== undefined && value !== null) {\n result[key] = value;\n }\n } catch (error) {\n if (onError === 'throw') throw error;\n if (onError === 'omit') {\n delete result[key];\n }\n // 'leave': preserve the existing (possibly persisted) value.\n }\n }\n }\n\n return result as T;\n}\n\n/**\n * Look up the static `configResolvers` map on a class (or any of its\n * ancestors). Returns `undefined` if none is declared.\n *\n * The lookup walks the prototype chain so a subclass can extend its parent's\n * resolvers without redeclaring them.\n */\nexport function getClassConfigResolvers(\n ctor: unknown,\n): Record<string, ConfigResolver> | undefined {\n if (typeof ctor !== 'function') return undefined;\n\n let current: any = ctor;\n let collected: Record<string, ConfigResolver> | undefined;\n\n while (current && current !== Function.prototype) {\n const resolvers = current.configResolvers;\n if (resolvers && typeof resolvers === 'object') {\n collected = {\n ...(resolvers as Record<string, ConfigResolver>),\n ...(collected ?? {}),\n };\n }\n current = Object.getPrototypeOf(current);\n }\n\n return collected;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lazy-config.js","sources":["../src/lazy-config.ts"],"sourcesContent":["/**\n * Lazy / execute-time agent_config resolvers.\n *\n * Persisted agent configs (e.g. `_smrt_agent_schedules.agent_config`) freeze\n * any value resolved at sync time, including env-derived ones. When operators\n * rotate an env var the persisted snapshot goes stale until the schedule is\n * rewritten.\n *\n * To avoid that, callers can store **sentinel references** in the persisted\n * config and register matching resolvers that run at execute time. The\n * runtime walks the agent_config tree, replaces every recognised sentinel\n * with the resolver's current return value, and only then hands the config\n * to the agent.\n *\n * Two registration shapes are supported:\n *\n * 1. **Global named resolvers** — register a callback by name once at\n * application startup. Use this for shared resolvers like\n * `resolveSharedAssetStorage`.\n *\n * ```ts\n * import { registerConfigResolver } from '@happyvertical/smrt-agents';\n *\n * registerConfigResolver('sharedAssetStorage', () =>\n * resolveSharedAssetStorage(),\n * );\n * ```\n *\n * Then in the persisted agent_config:\n * ```jsonc\n * { \"assetStorage\": { \"$env\": \"sharedAssetStorage\" } }\n * ```\n *\n * 2. **Per-agent class resolvers** — declare them as a static\n * `configResolvers` map on the agent class. The runtime applies them on\n * top of the persisted config keyed by the same name as the resolver.\n *\n * ```ts\n * class Praeco extends Agent {\n * static configResolvers = {\n * assetStorage: () => resolveSharedAssetStorage(),\n * };\n * }\n * ```\n *\n * Both shapes can be combined freely. Global resolvers always take precedence\n * for `$env` sentinels; class resolvers fill in / override fields by name.\n *\n * @module\n */\n\n/**\n * A lazy resolver — synchronous or async. Return values are merged into the\n * config tree at execute time. Throwing is allowed but is treated as a\n * resolution failure (see {@link ResolveLazyConfigOptions.onError}).\n */\nexport type ConfigResolver = () => unknown | Promise<unknown>;\n\n/**\n * Sentinel object recognised inside agent_config to defer a value to a named\n * resolver. The runtime accepts both `$env` (preferred) and `$resolver` for\n * symmetry with similar systems.\n */\nexport interface LazyConfigSentinel {\n $env?: string;\n $resolver?: string;\n}\n\n/**\n * Options for resolving the lazy parts of a config tree.\n */\nexport interface ResolveLazyConfigOptions {\n /**\n * Per-class resolvers — typically the agent class's static\n * `configResolvers`. Applied as a key-by-key overlay on top of the\n * sentinel-resolved config.\n */\n classResolvers?: Record<string, ConfigResolver>;\n\n /**\n * Optional override for the global resolver registry. When omitted the\n * shared module-scoped registry is used. Useful for tests.\n */\n resolvers?: Map<string, ConfigResolver> | Record<string, ConfigResolver>;\n\n /**\n * What to do when a sentinel references a resolver that isn't registered,\n * or when a resolver throws.\n *\n * - `'leave'` (default): the sentinel is left in place verbatim. The\n * downstream consumer is responsible for handling it.\n * - `'omit'`: the sentinel key is removed from the parent object/array.\n * - `'throw'`: re-throw the underlying error (or throw a new one for\n * missing resolvers).\n */\n onError?: 'leave' | 'omit' | 'throw';\n}\n\nconst globalResolvers = new Map<string, ConfigResolver>();\n\n/**\n * Register a named resolver that participates in lazy config resolution.\n *\n * Calling this with the same name twice replaces the previous resolver — the\n * registry is intentionally last-write-wins so application boot ordering\n * doesn't have to be fragile.\n */\nexport function registerConfigResolver(\n name: string,\n resolver: ConfigResolver,\n): void {\n if (typeof name !== 'string' || name.length === 0) {\n throw new Error('registerConfigResolver: name must be a non-empty string');\n }\n if (typeof resolver !== 'function') {\n throw new Error('registerConfigResolver: resolver must be a function');\n }\n globalResolvers.set(name, resolver);\n}\n\n/**\n * Remove a previously registered resolver. Returns `true` if a resolver was\n * removed.\n */\nexport function unregisterConfigResolver(name: string): boolean {\n return globalResolvers.delete(name);\n}\n\n/**\n * Get the resolver registered under the given name, if any.\n */\nexport function getConfigResolver(name: string): ConfigResolver | undefined {\n return globalResolvers.get(name);\n}\n\n/**\n * List the names of all currently-registered global resolvers.\n */\nexport function listConfigResolvers(): string[] {\n return Array.from(globalResolvers.keys()).sort();\n}\n\n/**\n * Reset the global resolver registry. Primarily for tests.\n */\nexport function resetConfigResolvers(): void {\n globalResolvers.clear();\n}\n\n/**\n * Type guard that returns `true` if `value` is a lazy config sentinel.\n *\n * Recognises objects of the form `{ $env: string }` or\n * `{ $resolver: string }` exactly — extra keys disqualify the value so\n * arbitrary user data isn't accidentally treated as a sentinel.\n */\nexport function isLazyConfigSentinel(\n value: unknown,\n): value is LazyConfigSentinel {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return false;\n }\n const keys = Object.keys(value as Record<string, unknown>);\n if (keys.length !== 1) return false;\n const key = keys[0];\n if (key !== '$env' && key !== '$resolver') return false;\n const resolverName = (value as Record<string, unknown>)[key];\n return typeof resolverName === 'string' && resolverName.length > 0;\n}\n\n/**\n * Extract the resolver name from a sentinel.\n */\nfunction getSentinelName(sentinel: LazyConfigSentinel): string {\n return (sentinel.$env ?? sentinel.$resolver) as string;\n}\n\nfunction normalizeResolverMap(\n resolvers: Map<string, ConfigResolver> | Record<string, ConfigResolver>,\n): Map<string, ConfigResolver> {\n if (resolvers instanceof Map) return resolvers;\n return new Map(Object.entries(resolvers));\n}\n\nconst REMOVE = Symbol('LazyConfig.REMOVE');\n\n/**\n * Maximum traversal depth before {@link resolveValue} bails out. Real\n * `agent_config` payloads are shallow (2–3 levels); a high cap here exists\n * solely to prevent stack overflow from a malicious or buggy persisted\n * config without rejecting any legitimate input. When the cap is hit the\n * value is returned verbatim — same fail-soft as for a missing resolver.\n */\nconst MAX_DEPTH = 64;\n\ninterface ResolveContext {\n resolvers: Map<string, ConfigResolver>;\n onError: NonNullable<ResolveLazyConfigOptions['onError']>;\n /**\n * Map from input object/array to its resolved replacement. Serves two\n * purposes simultaneously:\n * 1. Cycle protection — without it, a self-referential config would\n * recurse forever.\n * 2. DAG fidelity — a sub-tree referenced from two places gets cloned\n * once and the same clone is reused for every reference, preserving\n * structure and ensuring sentinels under shared references are still\n * resolved.\n */\n resolved: WeakMap<object, unknown>;\n}\n\nasync function resolveValue(\n value: unknown,\n ctx: ResolveContext,\n depth: number,\n): Promise<unknown> {\n if (isLazyConfigSentinel(value)) {\n const name = getSentinelName(value);\n const resolver = ctx.resolvers.get(name);\n if (!resolver) {\n if (ctx.onError === 'throw') {\n throw new Error(\n `Lazy config sentinel references unknown resolver \"${name}\"`,\n );\n }\n if (ctx.onError === 'omit') return REMOVE;\n return value;\n }\n\n try {\n return await resolver();\n } catch (error) {\n if (ctx.onError === 'throw') throw error;\n if (ctx.onError === 'omit') return REMOVE;\n return value;\n }\n }\n\n if (depth > MAX_DEPTH) {\n // Defensive: refuse to recurse further. The original sub-tree is\n // returned as-is; sentinels beyond this point will stay unresolved.\n return value;\n }\n\n if (Array.isArray(value)) {\n const cached = ctx.resolved.get(value);\n if (cached !== undefined) return cached;\n const next: unknown[] = [];\n // Register the placeholder *before* descending so that a cycle pointing\n // back at this array sees the in-progress array (and stops recursing).\n ctx.resolved.set(value, next);\n for (const entry of value) {\n const resolved = await resolveValue(entry, ctx, depth + 1);\n if (resolved !== REMOVE) next.push(resolved);\n }\n return next;\n }\n\n if (value && typeof value === 'object') {\n const cached = ctx.resolved.get(value);\n if (cached !== undefined) return cached;\n const next: Record<string, unknown> = {};\n ctx.resolved.set(value, next);\n for (const [key, entry] of Object.entries(\n value as Record<string, unknown>,\n )) {\n const resolved = await resolveValue(entry, ctx, depth + 1);\n if (resolved !== REMOVE) next[key] = resolved;\n }\n return next;\n }\n\n return value;\n}\n\n/**\n * Resolve every lazy sentinel inside an `agent_config`-style record at\n * execute time. The input is not mutated; a new object is returned with\n * sentinel placeholders replaced by their resolver's current return value.\n *\n * Class-level resolvers from {@link ResolveLazyConfigOptions.classResolvers}\n * are applied as a final overlay so they always reflect the live value\n * regardless of what's persisted.\n *\n * @example Sentinel resolution\n * ```ts\n * registerConfigResolver('sharedAssetStorage', () => resolveStorage());\n *\n * const stored = { assetStorage: { $env: 'sharedAssetStorage' } };\n * const live = await resolveLazyConfig(stored);\n * // live.assetStorage === resolveStorage()\n * ```\n *\n * @example Class-level resolvers\n * ```ts\n * const live = await resolveLazyConfig(stored, {\n * classResolvers: { assetStorage: () => resolveStorage() },\n * });\n * ```\n */\nexport async function resolveLazyConfig<T extends Record<string, unknown>>(\n config: T,\n options: ResolveLazyConfigOptions = {},\n): Promise<T> {\n const onError = options.onError ?? 'leave';\n const resolvers = options.resolvers\n ? normalizeResolverMap(options.resolvers)\n : globalResolvers;\n\n const ctx: ResolveContext = {\n resolvers,\n onError,\n resolved: new WeakMap<object, unknown>(),\n };\n const sentinelResolved = (await resolveValue(config, ctx, 0)) as Record<\n string,\n unknown\n >;\n\n const result: Record<string, unknown> = { ...sentinelResolved };\n\n if (options.classResolvers) {\n for (const [key, resolver] of Object.entries(options.classResolvers)) {\n try {\n const value = await resolver();\n // Both `undefined` and `null` are treated as \"no overlay value\" —\n // the persisted record's existing value (if any) is preserved.\n // This matches the documented contract on `Agent.configResolvers`\n // and makes the common pattern `() => process.env.X ?? null` safe.\n if (value !== undefined && value !== null) {\n result[key] = value;\n }\n } catch (error) {\n if (onError === 'throw') throw error;\n if (onError === 'omit') {\n delete result[key];\n }\n // 'leave': preserve the existing (possibly persisted) value.\n }\n }\n }\n\n return result as T;\n}\n\n/**\n * Look up the static `configResolvers` map on a class (or any of its\n * ancestors). Returns `undefined` if none is declared.\n *\n * The lookup walks the prototype chain so a subclass can extend its parent's\n * resolvers without redeclaring them.\n */\nexport function getClassConfigResolvers(\n ctor: unknown,\n): Record<string, ConfigResolver> | undefined {\n if (typeof ctor !== 'function') return undefined;\n\n let current: unknown = ctor;\n let collected: Record<string, ConfigResolver> | undefined;\n\n while (current && current !== Function.prototype) {\n // Each link in the prototype chain is an object/function; read its optional\n // static `configResolvers` map through a typed shape rather than `any`.\n const resolvers = (current as { configResolvers?: unknown })\n .configResolvers;\n if (resolvers && typeof resolvers === 'object') {\n collected = {\n ...(resolvers as Record<string, ConfigResolver>),\n ...(collected ?? {}),\n };\n }\n current = Object.getPrototypeOf(current);\n }\n\n return collected;\n}\n"],"names":[],"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;AAeD;;;;;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;IA4EvC;;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;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"}
@@ -142,8 +142,8 @@ class ManifestBuilder {
142
142
  const pkgPath = resolve(process.cwd(), "package.json");
143
143
  const pkgContent = readFileSync(pkgPath, "utf-8");
144
144
  packageJson = JSON.parse(pkgContent);
145
- packageName = packageJson.name || void 0;
146
- packageVersion = packageJson.version || void 0;
145
+ packageName = packageJson?.name || void 0;
146
+ packageVersion = packageJson?.version || void 0;
147
147
  } catch {
148
148
  }
149
149
  const adapter = new ManifestAdapter();
@@ -263,13 +263,12 @@ export default ${exportName};
263
263
  console.log("[smrt] No plugins found in vite config");
264
264
  return null;
265
265
  }
266
+ const plugins = loaded.config.plugins;
266
267
  console.log(
267
268
  "[smrt] Vite config loaded, plugins:",
268
- loaded.config.plugins.map((p) => p?.name)
269
- );
270
- const smrtPlugin = loaded.config.plugins.find(
271
- (p) => p?.name === "smrt-auto-service"
269
+ plugins.map((p) => p?.name)
272
270
  );
271
+ const smrtPlugin = plugins.find((p) => p?.name === "smrt-auto-service");
273
272
  if (!smrtPlugin) {
274
273
  console.log(
275
274
  "[smrt] smrt-auto-service plugin not found in plugins array"
@@ -277,11 +276,11 @@ export default ${exportName};
277
276
  return null;
278
277
  }
279
278
  console.log("[smrt] Found smrt-auto-service plugin");
280
- let opts = smrtPlugin.api?.options || smrtPlugin.options || smrtPlugin._options;
281
- if (!opts && typeof smrtPlugin.api === "function") {
279
+ const api = smrtPlugin.api;
280
+ let opts = (typeof api === "object" && api !== null ? api.options : void 0) || smrtPlugin.options || smrtPlugin._options;
281
+ if (!opts && typeof api === "function") {
282
282
  try {
283
- const api = smrtPlugin.api();
284
- opts = api.options;
283
+ opts = api().options;
285
284
  } catch (e) {
286
285
  console.log("[smrt] Could not call plugin.api()");
287
286
  }
@@ -299,7 +298,10 @@ export default ${exportName};
299
298
  console.log("[smrt] Could not access plugin options");
300
299
  return null;
301
300
  } catch (error) {
302
- console.log("[smrt] Error loading vite.config.ts:", error.message);
301
+ console.log(
302
+ "[smrt] Error loading vite.config.ts:",
303
+ error instanceof Error ? error.message : String(error)
304
+ );
303
305
  console.log("[smrt] Using default baseClasses");
304
306
  return null;
305
307
  }
@@ -331,7 +333,7 @@ export default ${exportName};
331
333
  );
332
334
  } catch (error) {
333
335
  console.log(
334
- `[smrt] ${pkgName}: manifest not found or invalid - ${error.message}`
336
+ `[smrt] ${pkgName}: manifest not found or invalid - ${error instanceof Error ? error.message : String(error)}`
335
337
  );
336
338
  }
337
339
  }
@@ -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 * 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: any;\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 console.log(\n '[smrt] Vite config loaded, plugins:',\n loaded.config.plugins.map((p: any) => p?.name),\n );\n\n // Find smrtPlugin in plugins array\n const smrtPlugin = loaded.config.plugins.find(\n (p: any) => p?.name === 'smrt-auto-service',\n );\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 let opts =\n (smrtPlugin as any).api?.options ||\n (smrtPlugin as any).options ||\n (smrtPlugin as any)._options;\n\n if (!opts && typeof (smrtPlugin as any).api === 'function') {\n try {\n const api = (smrtPlugin as any).api();\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: any) {\n console.log('[smrt] Error loading vite.config.ts:', error.message);\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 = 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 as any).className) {\n const className = (objDef as any).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: any) {\n console.log(\n `[smrt] ${pkgName}: manifest not found or invalid - ${error.message}`,\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 { 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,4 +1,4 @@
1
- import { SmartObjectManifest } from '../scanner/types.js';
1
+ import { ScanResult, SmartObjectManifest } from '../scanner/types.js';
2
2
  /**
3
3
  * Reads, writes, and generates SMRT manifests for a project.
4
4
  *
@@ -40,11 +40,11 @@ export declare class ManifestManager {
40
40
  /**
41
41
  * Generates a manifest from scan results and writes it.
42
42
  */
43
- generateFromScanResults(scanResults: any[], options: {
43
+ generateFromScanResults(scanResults: ScanResult[], options: {
44
44
  mode: 'dev' | 'build';
45
45
  packageName?: string;
46
46
  packageVersion?: string;
47
- packageJson?: any;
47
+ packageJson?: Record<string, unknown>;
48
48
  smrtDependencies?: string[];
49
49
  }): Promise<SmartObjectManifest>;
50
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/manifest/manager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAI/D;;;;;;;;;;GAUG;AACH,qBAAa,eAAe;IACd,OAAO,CAAC,WAAW;gBAAX,WAAW,EAAE,MAAM;IAEvC;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM;IAUvD;;;OAGG;IACH,SAAS,IAAI,mBAAmB,GAAG,IAAI;IAQvC;;;;;;;;OAQG;IACH,sBAAsB,IAAI,mBAAmB,GAAG,IAAI;IAQpD,OAAO,CAAC,cAAc;IAiBtB;;OAEG;IACH,KAAK,CAAC,QAAQ,EAAE,mBAAmB,EAAE,IAAI,GAAE,KAAK,GAAG,OAAe,GAAG,IAAI;IAWzE;;OAEG;IACG,uBAAuB,CAC3B,WAAW,EAAE,GAAG,EAAE,EAClB,OAAO,EAAE;QACP,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,WAAW,CAAC,EAAE,GAAG,CAAC;QAClB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC7B,GACA,OAAO,CAAC,mBAAmB,CAAC;CAMhC"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/manifest/manager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAI3E;;;;;;;;;;GAUG;AACH,qBAAa,eAAe;IACd,OAAO,CAAC,WAAW;gBAAX,WAAW,EAAE,MAAM;IAEvC;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM;IAUvD;;;OAGG;IACH,SAAS,IAAI,mBAAmB,GAAG,IAAI;IAQvC;;;;;;;;OAQG;IACH,sBAAsB,IAAI,mBAAmB,GAAG,IAAI;IAQpD,OAAO,CAAC,cAAc;IAiBtB;;OAEG;IACH,KAAK,CAAC,QAAQ,EAAE,mBAAmB,EAAE,IAAI,GAAE,KAAK,GAAG,OAAe,GAAG,IAAI;IAWzE;;OAEG;IACG,uBAAuB,CAC3B,WAAW,EAAE,UAAU,EAAE,EACzB,OAAO,EAAE;QACP,IAAI,EAAE,KAAK,GAAG,OAAO,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACtC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;KAC7B,GACA,OAAO,CAAC,mBAAmB,CAAC;CAMhC"}
@@ -1 +1 @@
1
- {"version":3,"file":"manager.js","sources":["../../src/manifest/manager.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { createLogger } from '@happyvertical/logger';\nimport { ManifestGenerator } from '../scanner/manifest-generator.js';\nimport type { SmartObjectManifest } from '../scanner/types.js';\n\nconst logger = createLogger({ level: 'info' });\n\n/**\n * Reads, writes, and generates SMRT manifests for a project.\n *\n * @remarks\n * Manifests are JSON files containing class/field metadata produced by the AST scanner.\n * Dev manifests live at `.smrt/manifest.json`; build manifests at `dist/manifest.json`.\n * Workspace packages may also provide a checked-in source manifest at\n * `src/manifest/manifest.json`. When loading a local project, the dev path takes\n * priority; for external packages (dependencies), the build path takes priority\n * to avoid pulling in test objects.\n */\nexport class ManifestManager {\n constructor(private projectRoot: string) {}\n\n /**\n * Get the standard output path for the manifest based on mode.\n */\n getOutputPath(mode: 'dev' | 'build' | 'source'): string {\n if (mode === 'dev') {\n return join(this.projectRoot, '.smrt/manifest.json');\n }\n if (mode === 'source') {\n return join(this.projectRoot, 'src/manifest/manifest.json');\n }\n return join(this.projectRoot, 'dist/manifest.json');\n }\n\n /**\n * Loads the local manifest from the standard locations.\n * Priority: .smrt/manifest.json -> dist/manifest.json -> src/manifest/manifest.json\n */\n loadLocal(): SmartObjectManifest | null {\n return this._loadFromPaths([\n this.getOutputPath('dev'),\n this.getOutputPath('build'),\n this.getOutputPath('source'),\n ]);\n }\n\n /**\n * Loads the manifest for an external package (dependency).\n * Priority: dist/manifest.json -> .smrt/manifest.json -> src/manifest/manifest.json\n *\n * External packages should prefer their production (dist) manifest\n * over the dev/test (.smrt) manifest to avoid pulling in test objects\n * and transitive dependencies. In a workspace, the checked-in source manifest\n * provides the same package metadata even when the sibling package has not been built yet.\n */\n loadForExternalPackage(): SmartObjectManifest | null {\n return this._loadFromPaths([\n this.getOutputPath('build'),\n this.getOutputPath('dev'),\n this.getOutputPath('source'),\n ]);\n }\n\n private _loadFromPaths(paths: string[]): SmartObjectManifest | null {\n for (const path of paths) {\n if (existsSync(path)) {\n try {\n const content = readFileSync(path, 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n logger.error(`[ManifestManager] Failed to read manifest at ${path}`, {\n error,\n });\n }\n }\n }\n\n return null;\n }\n\n /**\n * Writes a manifest to the standard location.\n */\n write(manifest: SmartObjectManifest, mode: 'dev' | 'build' = 'dev'): void {\n const outputPath = this.getOutputPath(mode);\n const outputDir = dirname(outputPath);\n\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n\n writeFileSync(outputPath, JSON.stringify(manifest, null, 2));\n }\n\n /**\n * Generates a manifest from scan results and writes it.\n */\n async generateFromScanResults(\n scanResults: any[],\n options: {\n mode: 'dev' | 'build';\n packageName?: string;\n packageVersion?: string;\n packageJson?: any;\n smrtDependencies?: string[];\n },\n ): Promise<SmartObjectManifest> {\n const generator = new ManifestGenerator();\n const manifest = generator.generateManifest(scanResults, options);\n this.write(manifest, options.mode);\n return manifest;\n }\n}\n"],"names":[],"mappings":";;;;AAMA,MAAM,SAAS,aAAa,EAAE,OAAO,QAAQ;AAatC,MAAM,gBAAgB;AAAA,EAC3B,YAAoB,aAAqB;AAArB,SAAA,cAAA;AAAA,EAAsB;AAAA,EAAtB;AAAA;AAAA;AAAA;AAAA,EAKpB,cAAc,MAA0C;AACtD,QAAI,SAAS,OAAO;AAClB,aAAO,KAAK,KAAK,aAAa,qBAAqB;AAAA,IACrD;AACA,QAAI,SAAS,UAAU;AACrB,aAAO,KAAK,KAAK,aAAa,4BAA4B;AAAA,IAC5D;AACA,WAAO,KAAK,KAAK,aAAa,oBAAoB;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAwC;AACtC,WAAO,KAAK,eAAe;AAAA,MACzB,KAAK,cAAc,KAAK;AAAA,MACxB,KAAK,cAAc,OAAO;AAAA,MAC1B,KAAK,cAAc,QAAQ;AAAA,IAAA,CAC5B;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,yBAAqD;AACnD,WAAO,KAAK,eAAe;AAAA,MACzB,KAAK,cAAc,OAAO;AAAA,MAC1B,KAAK,cAAc,KAAK;AAAA,MACxB,KAAK,cAAc,QAAQ;AAAA,IAAA,CAC5B;AAAA,EACH;AAAA,EAEQ,eAAe,OAA6C;AAClE,eAAW,QAAQ,OAAO;AACxB,UAAI,WAAW,IAAI,GAAG;AACpB,YAAI;AACF,gBAAM,UAAU,aAAa,MAAM,OAAO;AAC1C,iBAAO,KAAK,MAAM,OAAO;AAAA,QAC3B,SAAS,OAAO;AACd,iBAAO,MAAM,gDAAgD,IAAI,IAAI;AAAA,YACnE;AAAA,UAAA,CACD;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAA+B,OAAwB,OAAa;AACxE,UAAM,aAAa,KAAK,cAAc,IAAI;AAC1C,UAAM,YAAY,QAAQ,UAAU;AAEpC,QAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,gBAAU,WAAW,EAAE,WAAW,KAAA,CAAM;AAAA,IAC1C;AAEA,kBAAc,YAAY,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,wBACJ,aACA,SAO8B;AAC9B,UAAM,YAAY,IAAI,kBAAA;AACtB,UAAM,WAAW,UAAU,iBAAiB,aAAa,OAAO;AAChE,SAAK,MAAM,UAAU,QAAQ,IAAI;AACjC,WAAO;AAAA,EACT;AACF;"}
1
+ {"version":3,"file":"manager.js","sources":["../../src/manifest/manager.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { createLogger } from '@happyvertical/logger';\nimport { ManifestGenerator } from '../scanner/manifest-generator.js';\nimport type { ScanResult, SmartObjectManifest } from '../scanner/types.js';\n\nconst logger = createLogger({ level: 'info' });\n\n/**\n * Reads, writes, and generates SMRT manifests for a project.\n *\n * @remarks\n * Manifests are JSON files containing class/field metadata produced by the AST scanner.\n * Dev manifests live at `.smrt/manifest.json`; build manifests at `dist/manifest.json`.\n * Workspace packages may also provide a checked-in source manifest at\n * `src/manifest/manifest.json`. When loading a local project, the dev path takes\n * priority; for external packages (dependencies), the build path takes priority\n * to avoid pulling in test objects.\n */\nexport class ManifestManager {\n constructor(private projectRoot: string) {}\n\n /**\n * Get the standard output path for the manifest based on mode.\n */\n getOutputPath(mode: 'dev' | 'build' | 'source'): string {\n if (mode === 'dev') {\n return join(this.projectRoot, '.smrt/manifest.json');\n }\n if (mode === 'source') {\n return join(this.projectRoot, 'src/manifest/manifest.json');\n }\n return join(this.projectRoot, 'dist/manifest.json');\n }\n\n /**\n * Loads the local manifest from the standard locations.\n * Priority: .smrt/manifest.json -> dist/manifest.json -> src/manifest/manifest.json\n */\n loadLocal(): SmartObjectManifest | null {\n return this._loadFromPaths([\n this.getOutputPath('dev'),\n this.getOutputPath('build'),\n this.getOutputPath('source'),\n ]);\n }\n\n /**\n * Loads the manifest for an external package (dependency).\n * Priority: dist/manifest.json -> .smrt/manifest.json -> src/manifest/manifest.json\n *\n * External packages should prefer their production (dist) manifest\n * over the dev/test (.smrt) manifest to avoid pulling in test objects\n * and transitive dependencies. In a workspace, the checked-in source manifest\n * provides the same package metadata even when the sibling package has not been built yet.\n */\n loadForExternalPackage(): SmartObjectManifest | null {\n return this._loadFromPaths([\n this.getOutputPath('build'),\n this.getOutputPath('dev'),\n this.getOutputPath('source'),\n ]);\n }\n\n private _loadFromPaths(paths: string[]): SmartObjectManifest | null {\n for (const path of paths) {\n if (existsSync(path)) {\n try {\n const content = readFileSync(path, 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n logger.error(`[ManifestManager] Failed to read manifest at ${path}`, {\n error,\n });\n }\n }\n }\n\n return null;\n }\n\n /**\n * Writes a manifest to the standard location.\n */\n write(manifest: SmartObjectManifest, mode: 'dev' | 'build' = 'dev'): void {\n const outputPath = this.getOutputPath(mode);\n const outputDir = dirname(outputPath);\n\n if (!existsSync(outputDir)) {\n mkdirSync(outputDir, { recursive: true });\n }\n\n writeFileSync(outputPath, JSON.stringify(manifest, null, 2));\n }\n\n /**\n * Generates a manifest from scan results and writes it.\n */\n async generateFromScanResults(\n scanResults: ScanResult[],\n options: {\n mode: 'dev' | 'build';\n packageName?: string;\n packageVersion?: string;\n packageJson?: Record<string, unknown>;\n smrtDependencies?: string[];\n },\n ): Promise<SmartObjectManifest> {\n const generator = new ManifestGenerator();\n const manifest = generator.generateManifest(scanResults, options);\n this.write(manifest, options.mode);\n return manifest;\n }\n}\n"],"names":[],"mappings":";;;;AAMA,MAAM,SAAS,aAAa,EAAE,OAAO,QAAQ;AAatC,MAAM,gBAAgB;AAAA,EAC3B,YAAoB,aAAqB;AAArB,SAAA,cAAA;AAAA,EAAsB;AAAA,EAAtB;AAAA;AAAA;AAAA;AAAA,EAKpB,cAAc,MAA0C;AACtD,QAAI,SAAS,OAAO;AAClB,aAAO,KAAK,KAAK,aAAa,qBAAqB;AAAA,IACrD;AACA,QAAI,SAAS,UAAU;AACrB,aAAO,KAAK,KAAK,aAAa,4BAA4B;AAAA,IAC5D;AACA,WAAO,KAAK,KAAK,aAAa,oBAAoB;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAwC;AACtC,WAAO,KAAK,eAAe;AAAA,MACzB,KAAK,cAAc,KAAK;AAAA,MACxB,KAAK,cAAc,OAAO;AAAA,MAC1B,KAAK,cAAc,QAAQ;AAAA,IAAA,CAC5B;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,yBAAqD;AACnD,WAAO,KAAK,eAAe;AAAA,MACzB,KAAK,cAAc,OAAO;AAAA,MAC1B,KAAK,cAAc,KAAK;AAAA,MACxB,KAAK,cAAc,QAAQ;AAAA,IAAA,CAC5B;AAAA,EACH;AAAA,EAEQ,eAAe,OAA6C;AAClE,eAAW,QAAQ,OAAO;AACxB,UAAI,WAAW,IAAI,GAAG;AACpB,YAAI;AACF,gBAAM,UAAU,aAAa,MAAM,OAAO;AAC1C,iBAAO,KAAK,MAAM,OAAO;AAAA,QAC3B,SAAS,OAAO;AACd,iBAAO,MAAM,gDAAgD,IAAI,IAAI;AAAA,YACnE;AAAA,UAAA,CACD;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAA+B,OAAwB,OAAa;AACxE,UAAM,aAAa,KAAK,cAAc,IAAI;AAC1C,UAAM,YAAY,QAAQ,UAAU;AAEpC,QAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,gBAAU,WAAW,EAAE,WAAW,KAAA,CAAM;AAAA,IAC1C;AAEA,kBAAc,YAAY,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,wBACJ,aACA,SAO8B;AAC9B,UAAM,YAAY,IAAI,kBAAA;AACtB,UAAM,WAAW,UAAU,iBAAiB,aAAa,OAAO;AAChE,SAAK,MAAM,UAAU,QAAQ,IAAI;AACjC,WAAO;AAAA,EACT;AACF;"}
@@ -1,3 +1,4 @@
1
+ import { SmrtObjectConstructor } from '../registry/types.js';
1
2
  import { FieldDefinition, MethodDefinition, SmartObjectDefinition, SmartObjectManifest } from '../scanner/types.js';
2
3
  /**
3
4
  * Extend globalThis to include manifest loader state.
@@ -56,7 +57,7 @@ export declare function loadLocalTestManifestSync(): Manifest | null | undefined
56
57
  * @param skipRegistry - If true, skip checking ObjectRegistry (used during initial registration to avoid circular dependency)
57
58
  * @returns Package name (e.g., '@happyvertical/smrt-places') or null
58
59
  */
59
- export declare function getPackageName(ctor: new (...args: any[]) => any, skipRegistry?: boolean): string | null;
60
+ export declare function getPackageName(ctor: SmrtObjectConstructor, skipRegistry?: boolean): string | null;
60
61
  interface ManifestLoadOptions {
61
62
  warn?: boolean;
62
63
  }
@@ -137,7 +138,7 @@ export declare function findManifestEntryByQualifiedName(qualifiedName: string):
137
138
  * @returns ManifestEntry or undefined if not found
138
139
  * @throws {Error} If class name collision detected across different packages
139
140
  */
140
- export declare function discoverManifestEntry(ctor: new (...args: any[]) => any, className: string): Promise<ManifestEntry | undefined>;
141
+ export declare function discoverManifestEntry(ctor: SmrtObjectConstructor, className: string): Promise<ManifestEntry | undefined>;
141
142
  /**
142
143
  * Get all detected manifest collisions
143
144
  *
@@ -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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"}
@@ -225,8 +225,9 @@ function getPackageName(ctor, skipRegistry = false) {
225
225
  }
226
226
  }
227
227
  }
228
- if (ctor.__package__) {
229
- return ctor.__package__;
228
+ const packageMeta = ctor.__package__;
229
+ if (packageMeta) {
230
+ return packageMeta;
230
231
  }
231
232
  try {
232
233
  const error2 = new Error();