@happyvertical/smrt-dev-mcp 0.57.46 → 0.57.48

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.
@@ -107,7 +107,13 @@ async function performBoot(projectRoot, options) {
107
107
  if (typeof ObjectRegistry?.registerFromManifest !== "function" || typeof discoverSmrtPackages !== "function" || typeof resolveManifestPath !== "function") throw new ProjectRuntimeResolutionError("@happyvertical/smrt-core");
108
108
  const diagnostics = [];
109
109
  const manifests = [];
110
- const projectManifestPath = PROJECT_MANIFEST_CANDIDATES.map((candidate) => join(projectRoot, candidate)).find((path) => existsSync(path));
110
+ const existingManifestPaths = PROJECT_MANIFEST_CANDIDATES.map((candidate) => join(projectRoot, candidate)).filter((path) => existsSync(path));
111
+ const projectManifestPath = existingManifestPaths.find((path) => readManifest(path)?.artifactPurpose !== "test");
112
+ if (!projectManifestPath && existingManifestPaths.length > 0) diagnostics.push({
113
+ severity: "warning",
114
+ code: "project_manifest_test_artifact",
115
+ message: "The project manifest is a test artifact (artifactPurpose: test), not a build output; run the project build so the runtime manifest exists."
116
+ });
111
117
  const projectPackageName = readProjectPackageName(projectRoot);
112
118
  if (!projectManifestPath) diagnostics.push({
113
119
  severity: "warning",
@@ -383,4 +389,4 @@ var runtimeSchemaDiff = (args = {}) => withRuntimeSetup(() => runtimeSchemaDiffF
383
389
  //#endregion
384
390
  export { bootRuntime as a, runtimeSchemaDiff as i, runtimeObject as n, runtimeRegistry as r, observation_exports as t };
385
391
 
386
- //# sourceMappingURL=observation-CmDrAP9J.js.map
392
+ //# sourceMappingURL=observation-DbB4z-9t.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observation-DbB4z-9t.js","names":[],"sources":["../src/tools/runtime/boot.ts","../src/tools/runtime/observation.ts"],"sourcesContent":["/**\n * Confined runtime bootstrap for the Level 2 observation plane (#1831).\n *\n * \"Booting\" here means registering *manifests* into the in-process\n * `ObjectRegistry` — the project's own `.smrt/manifest.json` (or built\n * `dist/manifest.json`) plus every installed SMRT package manifest that the\n * project's dependency tree resolves to. No project source is imported, no\n * module is executed, no database is touched. That confinement is the safety\n * boundary: an observing agent sees what the runtime *would* register, never\n * what arbitrary project code does on import.\n *\n * The registry is a process-global singleton, so a process boots once. There\n * is deliberately no re-boot tool; restart the process to observe a rebuilt\n * manifest.\n */\n\nimport { existsSync, readFileSync, statSync } from 'node:fs';\nimport { basename, isAbsolute, join, relative, resolve, sep } from 'node:path';\nimport {\n importProjectRuntimeModule,\n loadProjectCore,\n ProjectRuntimeResolutionError,\n projectRuntimeRoot,\n resetProjectRuntimeForTests,\n} from './project-runtime.js';\n\n/** Provenance label for facts read from authored/installed manifests. */\nexport const DECLARED_PROVENANCE = 'declared (manifest)';\n\n/** Project manifest candidates, most authoritative first. */\nconst PROJECT_MANIFEST_CANDIDATES = [\n '.smrt/manifest.json',\n 'dist/manifest.json',\n] as const;\n\nexport interface BootDiagnostic {\n severity: 'info' | 'warning' | 'error';\n code: string;\n message: string;\n}\n\nexport interface BootedManifest {\n /** `project` for the project's own manifest, `dependency` for installed packages. */\n kind: 'project' | 'dependency';\n packageName: string | null;\n /** Path relative to the project root (never absolute). */\n path: string;\n objectCount: number;\n}\n\nexport interface RuntimeBoot {\n provenance: typeof DECLARED_PROVENANCE;\n bootedAt: string;\n /** Basename only; the absolute project root never leaves the process. */\n projectName: string;\n manifests: BootedManifest[];\n objectCount: number;\n diagnostics: BootDiagnostic[];\n}\n\ninterface ManifestLike {\n packageName?: unknown;\n moduleType?: unknown;\n artifactPurpose?: unknown;\n objects?: Record<string, unknown>;\n}\n\nfunction relativePath(projectRoot: string, path: string): string {\n const rel = relative(projectRoot, path);\n // Anything outside the root — the parent itself, a `..` walk, or a path on\n // another drive (Windows keeps those absolute) — is reduced to a basename.\n if (rel === '..' || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {\n return basename(path);\n }\n return rel.split(sep).join('/');\n}\n\nfunction readManifest(path: string): ManifestLike | null {\n try {\n const parsed = JSON.parse(readFileSync(path, 'utf8')) as unknown;\n return parsed && typeof parsed === 'object'\n ? (parsed as ManifestLike)\n : null;\n } catch {\n return null;\n }\n}\n\nfunction registerManifest(\n ObjectRegistry: typeof import('@happyvertical/smrt-core').ObjectRegistry,\n manifest: ManifestLike,\n fallbackPackageName: string | null,\n): number {\n const manifestPackageName =\n typeof manifest.packageName === 'string' && manifest.packageName\n ? manifest.packageName\n : (fallbackPackageName ?? undefined);\n let count = 0;\n for (const [name, definition] of Object.entries(manifest.objects ?? {})) {\n if (!definition || typeof definition !== 'object') continue;\n // An aggregate project manifest (consumer plugin output) carries\n // dependency objects that keep their own `packageName`; registering them\n // under the app's name would mint false `@app:Object` identities that\n // collide with the dependency's own manifest. Per-object ownership wins.\n const ownPackage = (definition as { packageName?: unknown }).packageName;\n ObjectRegistry.registerFromManifest(\n name,\n definition as Parameters<typeof ObjectRegistry.registerFromManifest>[1],\n typeof ownPackage === 'string' && ownPackage\n ? ownPackage\n : manifestPackageName,\n );\n count += 1;\n }\n return count;\n}\n\nlet booting: Promise<RuntimeBoot> | null = null;\nlet booted: RuntimeBoot | null = null;\nlet bootedProjectRoot: string | null = null;\nlet bootedProjectManifestPath: string | null = null;\nlet bootedProjectManifestMtimeMs: number | null = null;\n\n/**\n * Whether the project manifest on disk is newer than the one this process\n * booted. The registry is process-global and boots once, so this is the only\n * signal an agent has that a rebuild happened underneath it.\n */\nexport function getBootStaleness(): {\n stale: boolean;\n bootedAt: string | null;\n manifestModifiedAt: string | null;\n} {\n if (!booted || !bootedProjectManifestPath) {\n return {\n stale: false,\n bootedAt: booted?.bootedAt ?? null,\n manifestModifiedAt: null,\n };\n }\n try {\n const mtimeMs = statSync(bootedProjectManifestPath).mtimeMs;\n return {\n stale:\n bootedProjectManifestMtimeMs !== null &&\n mtimeMs > bootedProjectManifestMtimeMs,\n bootedAt: booted.bootedAt,\n manifestModifiedAt: new Date(mtimeMs).toISOString(),\n };\n } catch {\n return {\n stale: false,\n bootedAt: booted.bootedAt,\n manifestModifiedAt: null,\n };\n }\n}\n\n/** The boot record for this process, or `null` before {@link bootRuntime}. */\nexport function getRuntimeBoot(): RuntimeBoot | null {\n return booted;\n}\n\n/**\n * The resolved root the process booted from. Consumers must relativize\n * paths against *this* root, never a per-request argument, or a caller could\n * widen the root (e.g. `/`) and read the layout back through \"relative\" paths.\n */\nexport function getBootedProjectRoot(): string | null {\n return bootedProjectRoot;\n}\n\n/** Test seam: forget the boot record (the registry itself is cleared by the caller). */\nexport function resetRuntimeBootForTests(): void {\n resetProjectRuntimeForTests();\n booting = null;\n booted = null;\n bootedProjectRoot = null;\n bootedProjectManifestPath = null;\n bootedProjectManifestMtimeMs = null;\n}\n\nexport interface BootRuntimeOptions {\n projectRoot?: string;\n /** Clock for `bootedAt` (defaults to `new Date()`). */\n now?: Date;\n}\n\n/**\n * Boot the confined runtime once per process. A second call returns the\n * existing record without touching the registry.\n */\nexport async function bootRuntime(\n options: BootRuntimeOptions = {},\n): Promise<RuntimeBoot> {\n const projectRoot = resolve(options.projectRoot ?? process.cwd());\n if (\n bootedProjectRoot &&\n projectRuntimeRoot(bootedProjectRoot) !== projectRuntimeRoot(projectRoot)\n ) {\n throw new ProjectRuntimeResolutionError(\n '@happyvertical/smrt-core',\n 'runtime_project_mismatch',\n );\n }\n if (booted) return booted;\n if (booting) return booting;\n bootedProjectRoot = projectRoot;\n booting = performBoot(projectRoot, options).catch((error) => {\n booting = null;\n bootedProjectRoot = null;\n throw error;\n });\n return booting;\n}\n\nasync function performBoot(\n projectRoot: string,\n options: BootRuntimeOptions,\n): Promise<RuntimeBoot> {\n const { ObjectRegistry } = await loadProjectCore(projectRoot);\n const { discoverSmrtPackages, resolveManifestPath } =\n await importProjectRuntimeModule<\n typeof import('@happyvertical/smrt-core/manifest/discover-smrt-packages')\n >(projectRoot, '@happyvertical/smrt-core/manifest/discover-smrt-packages');\n if (\n typeof ObjectRegistry?.registerFromManifest !== 'function' ||\n typeof discoverSmrtPackages !== 'function' ||\n typeof resolveManifestPath !== 'function'\n ) {\n throw new ProjectRuntimeResolutionError('@happyvertical/smrt-core');\n }\n const diagnostics: BootDiagnostic[] = [];\n const manifests: BootedManifest[] = [];\n\n const existingManifestPaths = PROJECT_MANIFEST_CANDIDATES.map((candidate) =>\n join(projectRoot, candidate),\n ).filter((path) => existsSync(path));\n // A test run's manifest describes inline test fixtures, never the project's\n // runtime surface (#2760); skip it in favor of a build output.\n const projectManifestPath = existingManifestPaths.find(\n (path) => readManifest(path)?.artifactPurpose !== 'test',\n );\n if (!projectManifestPath && existingManifestPaths.length > 0) {\n diagnostics.push({\n severity: 'warning',\n code: 'project_manifest_test_artifact',\n message:\n 'The project manifest is a test artifact (artifactPurpose: test), not a build output; run the project build so the runtime manifest exists.',\n });\n }\n const projectPackageName = readProjectPackageName(projectRoot);\n\n if (!projectManifestPath) {\n diagnostics.push({\n severity: 'warning',\n code: 'project_manifest_missing',\n message:\n 'No project manifest found (.smrt/manifest.json or dist/manifest.json); run the project build so the runtime manifest exists.',\n });\n } else {\n const manifest = readManifest(projectManifestPath);\n if (!manifest) {\n diagnostics.push({\n severity: 'error',\n code: 'project_manifest_invalid',\n message: `Project manifest at ${relativePath(projectRoot, projectManifestPath)} is not valid JSON.`,\n });\n } else {\n manifests.push({\n kind: 'project',\n packageName:\n typeof manifest.packageName === 'string'\n ? manifest.packageName\n : projectPackageName,\n path: relativePath(projectRoot, projectManifestPath),\n objectCount: registerManifest(\n ObjectRegistry,\n manifest,\n projectPackageName,\n ),\n });\n }\n }\n\n let dependencyNames: string[] = [];\n try {\n // `noCache` keeps discovery from writing `.smrt/discovery-cache.json`:\n // observing a project must never dirty it.\n dependencyNames = discoverSmrtPackages({\n baseDir: projectRoot,\n noCache: true,\n });\n } catch (error) {\n diagnostics.push({\n severity: 'warning',\n code: 'dependency_discovery_failed',\n message: `Installed SMRT package discovery failed: ${error instanceof Error ? error.message : 'unknown error'}`,\n });\n }\n for (const dependency of dependencyNames.sort()) {\n const manifestPath = resolveManifestPath(dependency, projectRoot);\n if (!manifestPath) {\n diagnostics.push({\n severity: 'info',\n code: 'dependency_manifest_missing',\n message: `Installed SMRT package ${dependency} exposes no runtime manifest.`,\n });\n continue;\n }\n const manifest = readManifest(manifestPath);\n if (!manifest) {\n diagnostics.push({\n severity: 'warning',\n code: 'dependency_manifest_invalid',\n message: `Manifest for ${dependency} is not valid JSON.`,\n });\n continue;\n }\n manifests.push({\n kind: 'dependency',\n packageName: dependency,\n path: relativePath(projectRoot, manifestPath),\n objectCount: registerManifest(ObjectRegistry, manifest, dependency),\n });\n }\n\n bootedProjectRoot = projectRoot;\n if (projectManifestPath) {\n bootedProjectManifestPath = projectManifestPath;\n try {\n bootedProjectManifestMtimeMs = statSync(projectManifestPath).mtimeMs;\n } catch {\n bootedProjectManifestMtimeMs = null;\n }\n }\n booted = {\n provenance: DECLARED_PROVENANCE,\n bootedAt: (options.now ?? new Date()).toISOString(),\n projectName: projectPackageName ?? basename(projectRoot),\n manifests,\n objectCount: manifests.reduce((sum, m) => sum + m.objectCount, 0),\n diagnostics,\n };\n return booted;\n}\n\nfunction readProjectPackageName(projectRoot: string): string | null {\n try {\n const parsed = JSON.parse(\n readFileSync(join(projectRoot, 'package.json'), 'utf8'),\n ) as { name?: unknown };\n return typeof parsed.name === 'string' && parsed.name ? parsed.name : null;\n } catch {\n return null;\n }\n}\n","/**\n * Level 2 read-only observation tools over the booted runtime (#1831).\n *\n * Three facts planes, labelled separately in every envelope:\n * - `declared (manifest)`: what the confined boot registered ({@link bootRuntime});\n * - `booted (registry)`: the in-process `ObjectRegistry` projected through the\n * sanitized {@link snapshotRegistry} DTO;\n * - `runtime (live DB)`: the optional read-only connection, reused from Level 1.\n *\n * Nothing here mutates: no writes, no `do()`, no generated CRUD, no project\n * code execution. `runtime-schema-diff` only *introspects* the live schema.\n */\n\nimport type { RegistrySnapshotObject } from '@happyvertical/smrt-core';\nimport {\n bootRuntime,\n getBootedProjectRoot,\n getBootStaleness,\n type RuntimeBoot,\n} from './boot.js';\nimport type { RuntimeDatabaseArgs } from './connection.js';\nimport {\n importProjectRuntimeModule,\n loadProjectCore,\n ProjectRuntimeResolutionError,\n} from './project-runtime.js';\nimport {\n type RuntimeDiagnostic,\n type RuntimeToolEnvelope,\n withRuntimeConnection,\n withRuntimeSetup,\n} from './tools.js';\n\n/** Row budget for `runtime-schema-diff` change lists. */\nconst SCHEMA_DIFF_CHANGE_LIMIT = 200;\n\nexport interface RuntimeProjectArgs {\n /** Project root to boot from (defaults to the server's cwd). */\n projectPath?: string;\n}\n\nfunction bootDiagnostics(boot: RuntimeBoot): RuntimeDiagnostic[] {\n return boot.diagnostics\n .filter((d) => d.severity !== 'info')\n .map((d) => ({\n severity: d.severity === 'error' ? 'warning' : d.severity,\n code: `boot_${d.code}`,\n message: d.message,\n }));\n}\n\nlet bootPreambleSent = false;\n\n/**\n * The full manifest list is emitted once per process; later envelopes carry\n * only the identifying fields. Every runtime response re-embedding the same\n * multi-manifest block was pure repetition for an agent.\n */\nfunction bootSummary(boot: RuntimeBoot) {\n const compact = {\n provenance: boot.provenance,\n bootedAt: boot.bootedAt,\n projectName: boot.projectName,\n objectCount: boot.objectCount,\n manifestCount: boot.manifests.length,\n };\n if (bootPreambleSent) return compact;\n bootPreambleSent = true;\n return { ...compact, manifests: boot.manifests };\n}\n\n/** Test seam paired with `resetRuntimeBootForTests()`. */\nexport function resetBootPreambleForTests(): void {\n bootPreambleSent = false;\n}\n\nfunction stalenessDiagnostics(): RuntimeDiagnostic[] {\n const staleness = getBootStaleness();\n if (!staleness.stale) return [];\n return [\n {\n severity: 'warning',\n code: 'manifest_newer_than_boot',\n message: `The project manifest changed at ${staleness.manifestModifiedAt} after this process booted at ${staleness.bootedAt}; restart the server to observe the rebuilt registry.`,\n },\n ];\n}\n\nexport interface RuntimeRegistryArgs extends RuntimeProjectArgs {\n /** Restrict object detail to these simple or qualified names. */\n objects?: string[];\n /** Include field/method detail (default: only when `objects` is given). */\n detail?: boolean;\n /**\n * Resume after this object key: the qualified name when the object has\n * one, otherwise its simple name — exactly the value a previous response\n * returned as `page.nextCursor` (#2779). Objects are sorted by that key.\n */\n cursor?: string;\n /** Objects per page (default {@link REGISTRY_PAGE_LIMIT}, max 500). */\n limit?: number;\n}\n\n/** Default objects per `runtime-registry` page. */\nexport const REGISTRY_PAGE_LIMIT = 50;\n\nfunction objectKey(object: {\n qualifiedName: string | null;\n name: string;\n}): string {\n return object.qualifiedName ?? object.name;\n}\n\n/** `runtime-registry`: sanitized snapshot of the booted registry. */\nasync function runtimeRegistryFromProject(\n args: RuntimeRegistryArgs = {},\n): Promise<RuntimeToolEnvelope> {\n const boot = await bootRuntime({ projectRoot: args.projectPath });\n const { snapshotRegistry } = await loadProjectCore(args.projectPath);\n // Paths are relativized against the root the process actually booted from,\n // never the per-request argument (which is ignored after the first boot).\n if (typeof snapshotRegistry !== 'function')\n throw new ProjectRuntimeResolutionError('@happyvertical/smrt-core');\n const snapshot = snapshotRegistry({\n projectRoot: getBootedProjectRoot() ?? undefined,\n objects: args.objects,\n detail: args.detail ?? Boolean(args.objects?.length),\n });\n // Page the object list (summary stays global). A 76-object app answered in\n // 56 KB before paging; an agent hunting one class needs a cursor, not a cut.\n const limit = Math.min(\n Math.max(Math.floor(args.limit ?? REGISTRY_PAGE_LIMIT), 1),\n 500,\n );\n // The cursor is compared against the same key `page.nextCursor` carries.\n const cursor =\n typeof args.cursor === 'string' && args.cursor.length > 0\n ? args.cursor\n : null;\n const all = snapshot.objects;\n const afterCursor = cursor\n ? all.filter((object) => objectKey(object).localeCompare(cursor) > 0)\n : all;\n const objects = afterCursor.slice(0, limit);\n const nextCursor =\n afterCursor.length > objects.length && objects.length > 0\n ? objectKey(objects[objects.length - 1])\n : null;\n return {\n ok: true,\n coverage: null,\n diagnostics: [...bootDiagnostics(boot), ...stalenessDiagnostics()],\n data: {\n provenance: snapshot.provenance,\n boot: bootSummary(boot),\n page: {\n returned: objects.length,\n matched: all.length,\n limit,\n cursor,\n nextCursor,\n },\n snapshot: { ...snapshot, objects },\n },\n };\n}\n\nexport interface RuntimeObjectArgs extends RuntimeProjectArgs {\n /** Simple or qualified object name. */\n name: string;\n /** Engine for the generated DDL preview (default: the registry's default). */\n engine?: 'sqlite' | 'postgres' | 'duckdb';\n}\n\n/** `runtime-object`: one object's sanitized definition plus its generated DDL. */\nasync function runtimeObjectFromProject(\n args: RuntimeObjectArgs,\n): Promise<RuntimeToolEnvelope> {\n const boot = await bootRuntime({ projectRoot: args.projectPath });\n const { ObjectRegistry, snapshotRegistry } = await loadProjectCore(\n args.projectPath,\n );\n const name = typeof args.name === 'string' ? args.name.trim() : '';\n if (typeof snapshotRegistry !== 'function')\n throw new ProjectRuntimeResolutionError('@happyvertical/smrt-core');\n const snapshot = snapshotRegistry({\n projectRoot: getBootedProjectRoot() ?? undefined,\n objects: name ? [name] : [],\n detail: true,\n });\n const diagnostics = [...bootDiagnostics(boot), ...stalenessDiagnostics()];\n let object: RegistrySnapshotObject | null = snapshot.objects[0] ?? null;\n if (snapshot.objects.length > 1) {\n // Two packages registering the same simple name is legal; picking one\n // silently would misreport identity. Ask for the qualified name instead.\n object = null;\n diagnostics.push({\n severity: 'warning',\n code: 'object_ambiguous',\n message: `${name} is registered by several packages; pass a qualified name: ${snapshot.objects\n .map((candidate) => candidate.qualifiedName ?? candidate.name)\n .join(', ')}`,\n });\n } else if (!object) {\n diagnostics.push({\n severity: 'warning',\n code: 'object_not_found',\n message: name\n ? `No booted object named ${name}; use runtime-registry to list names.`\n : 'name is required.',\n });\n }\n let ddl: string | null = null;\n if (object) {\n try {\n // Resolve by qualified identity so a same-name class in another package\n // can never answer for this one.\n ddl =\n ObjectRegistry.getSchemaDDL(\n object.qualifiedName ?? object.name,\n args.engine,\n ) ?? null;\n } catch (error) {\n diagnostics.push({\n severity: 'warning',\n code: 'ddl_unavailable',\n message: `Generated DDL unavailable: ${error instanceof Error ? error.message : 'unknown error'}`,\n });\n }\n }\n return {\n ok: true,\n coverage: null,\n diagnostics,\n data: {\n provenance: snapshot.provenance,\n boot: bootSummary(boot),\n object,\n ddl,\n },\n };\n}\n\nexport interface RuntimeSchemaDiffArgs\n extends RuntimeDatabaseArgs,\n RuntimeProjectArgs {}\n\n/**\n * `runtime-schema-diff`: booted registry schemas versus the live database,\n * using the same comparer `db:diff`/`db:migrate` use. Introspection only —\n * drop/relax options are pinned off and nothing is executed.\n */\nasync function runtimeSchemaDiffFromProject(\n args: RuntimeSchemaDiffArgs = {},\n): Promise<RuntimeToolEnvelope> {\n const boot = await bootRuntime({ projectRoot: args.projectPath });\n const { ObjectRegistry } = await loadProjectCore(args.projectPath);\n const envelope = await withRuntimeConnection(\n args,\n async (db) => {\n const { SchemaComparer } = await importProjectRuntimeModule<\n typeof import('@happyvertical/smrt-core/migrations')\n >(args.projectPath, '@happyvertical/smrt-core/migrations');\n if (typeof SchemaComparer !== 'function')\n throw new ProjectRuntimeResolutionError(\n '@happyvertical/smrt-core/migrations',\n );\n const comparer = new SchemaComparer(\n db as ConstructorParameters<typeof SchemaComparer>[0],\n {\n includeDroppedTables: false,\n includeDroppedColumns: false,\n includeDroppedIndexes: false,\n relaxColumns: false,\n },\n );\n const diff = await comparer.compare(\n ObjectRegistry.getAllSchemasAsDefinitions(),\n );\n const byType: Record<string, number> = {};\n for (const change of diff.changes) {\n const type = String((change as { type?: unknown }).type ?? 'unknown');\n byType[type] = (byType[type] ?? 0) + 1;\n }\n // `hasChanges` covers table adds/drops too; count them so the two agree.\n const addedTables = diff.added_tables.map((t) => t.tableName);\n if (addedTables.length > 0) byType.add_table = addedTables.length;\n if (diff.dropped_tables.length > 0)\n byType.drop_table = diff.dropped_tables.length;\n const changeCount =\n diff.changes.length + addedTables.length + diff.dropped_tables.length;\n return {\n data: {\n boot: bootSummary(boot),\n hasChanges: diff.has_changes,\n addedTables,\n droppedTables: diff.dropped_tables,\n orphanTables: diff.orphan_tables ?? [],\n changeCount,\n columnChangeCount: diff.changes.length,\n changesByType: byType,\n changes: diff.changes.slice(0, SCHEMA_DIFF_CHANGE_LIMIT),\n truncated: diff.changes.length > SCHEMA_DIFF_CHANGE_LIMIT,\n },\n diagnostics: [],\n };\n },\n 'booted registry schemas only; connect a dev database to diff against live tables',\n );\n envelope.diagnostics = [\n ...bootDiagnostics(boot),\n ...stalenessDiagnostics(),\n ...envelope.diagnostics,\n ];\n return envelope;\n}\n\nexport const runtimeRegistry = (args: RuntimeRegistryArgs = {}) =>\n withRuntimeSetup(() => runtimeRegistryFromProject(args));\nexport const runtimeObject = (args: RuntimeObjectArgs) =>\n withRuntimeSetup(() => runtimeObjectFromProject(args));\nexport const runtimeSchemaDiff = (args: RuntimeSchemaDiffArgs = {}) =>\n withRuntimeSetup(() => runtimeSchemaDiffFromProject(args));\n"],"mappings":"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"}
package/dist/runtime.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { a as runtimeMigrationStatus, c as runtimeScheduleHealth, i as runtimeJobHealth, n as STATIC_PROVENANCE, o as runtimeRecentChanges, r as runtimeDispatchHealth, s as runtimeRegistryDrift, t as RUNTIME_PROVENANCE } from "./tools-B0uaPTz0.js";
2
- import { i as runtimeSchemaDiff, n as runtimeObject, r as runtimeRegistry } from "./observation-CmDrAP9J.js";
2
+ import { i as runtimeSchemaDiff, n as runtimeObject, r as runtimeRegistry } from "./observation-DbB4z-9t.js";
3
3
  //#region src/runtime.ts
4
4
  /** Name → handler for every Level 2 runtime tool. */
5
5
  var RUNTIME_TOOLS = {
@@ -1 +1 @@
1
- {"version":3,"file":"boot.d.ts","sourceRoot":"","sources":["../../../src/tools/runtime/boot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAYH,yEAAyE;AACzE,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AAQzD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,qFAAqF;IACrF,IAAI,EAAE,SAAS,GAAG,YAAY,CAAC;IAC/B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,OAAO,mBAAmB,CAAC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,cAAc,EAAE,CAAC;CAC/B;AAgED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC,CAwBA;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,IAAI,WAAW,GAAG,IAAI,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,GAAG,IAAI,CAEpD;AAED,wFAAwF;AACxF,wBAAgB,wBAAwB,IAAI,IAAI,CAO/C;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uDAAuD;IACvD,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,WAAW,CAAC,CAoBtB"}
1
+ {"version":3,"file":"boot.d.ts","sourceRoot":"","sources":["../../../src/tools/runtime/boot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAYH,yEAAyE;AACzE,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AAQzD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,qFAAqF;IACrF,IAAI,EAAE,SAAS,GAAG,YAAY,CAAC;IAC/B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,OAAO,mBAAmB,CAAC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,cAAc,EAAE,CAAC;CAC/B;AAiED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC,CAwBA;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,IAAI,WAAW,GAAG,IAAI,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,GAAG,IAAI,CAEpD;AAED,wFAAwF;AACxF,wBAAgB,wBAAwB,IAAI,IAAI,CAO/C;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uDAAuD;IACvD,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,WAAW,CAAC,CAoBtB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-dev-mcp",
3
- "version": "0.57.46",
3
+ "version": "0.57.48",
4
4
  "description": "Development MCP server for SMRT framework knowledge, review context, architecture context, and code generation",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -54,15 +54,15 @@
54
54
  "homepage": "https://github.com/happyvertical/smrt/tree/main/packages/smrt-dev-mcp#readme",
55
55
  "license": "MIT",
56
56
  "dependencies": {
57
- "@happyvertical/smrt-scanner": "0.57.46",
57
+ "@happyvertical/smrt-scanner": "0.57.48",
58
58
  "@modelcontextprotocol/node": "2.1.2",
59
59
  "@modelcontextprotocol/server": "2.3.1",
60
- "@happyvertical/smrt-types": "0.57.46"
60
+ "@happyvertical/smrt-types": "0.57.48"
61
61
  },
62
62
  "devDependencies": {
63
- "@happyvertical/smrt-config": "0.57.46",
64
- "@happyvertical/smrt-core": "0.57.46",
65
- "@happyvertical/sql": "^0.111.0",
63
+ "@happyvertical/smrt-config": "0.57.48",
64
+ "@happyvertical/smrt-core": "0.57.48",
65
+ "@happyvertical/sql": "^0.111.3",
66
66
  "@modelcontextprotocol/client": "2.3.1",
67
67
  "@modelcontextprotocol/conformance": "0.2.0-alpha.11",
68
68
  "@types/node": "24.13.6",
@@ -1 +0,0 @@
1
- {"version":3,"file":"introspect-project-D8bjCeZZ.js","names":[],"sources":["../src/tools/introspect-project.ts"],"sourcesContent":["/**\n * Project Introspection Tool\n * Returns a manifest-equivalent inventory of SMRT objects in a project.\n */\n\nimport { spawn } from 'node:child_process';\nimport type { Dirent } from 'node:fs';\nimport { access, readdir, readFile } from 'node:fs/promises';\nimport { isAbsolute, join, relative, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport type { ScanError } from '@happyvertical/smrt-scanner';\nimport { ManifestAdapter, OxcScanner } from '@happyvertical/smrt-scanner';\nimport {\n ProjectRuntimeResolutionError,\n resolveProjectRuntimeEntry,\n} from './runtime/project-runtime.js';\n\n/**\n * `summary` (default) returns one compact record per object; `full` returns the\n * verbose shape. A 42-object project produced 338,462 characters in the only\n * mode that used to exist, which put every call over tool-result budgets and\n * forced callers to write-to-file and `jq` (#2143).\n */\nexport type IntrospectDetail = 'summary' | 'full';\n\n/** Common shape both detail modes emit, so the two branches share a list. */\ntype IntrospectedObject = Record<string, unknown> & { className: string };\n\ninterface IntrospectProjectArgs {\n directory?: string;\n manifestPath?: string;\n includeFields?: boolean;\n includeRelationships?: boolean;\n includeMethods?: boolean;\n detail?: IntrospectDetail;\n /**\n * Overrides the default character budget for the serialized `objects` array.\n *\n * Project metadata and diagnostics are deliberately exempt: a diagnostic is\n * how discovery reports that it found nothing (#2143), so budgeting it away\n * would hide the very failure the caller needs to see. The full response is\n * therefore somewhat larger than this budget.\n */\n maxChars?: number;\n /**\n * Resume after this `className` (objects are sorted alphabetically). Pass\n * the `nextCursor` from a previous truncated response to read the next page\n * instead of raising `maxChars` (#2779).\n */\n cursor?: string;\n /** Maximum objects per page, applied before the character budget. */\n limit?: number;\n}\n\ntype DiagnosticSeverity = 'error' | 'warning' | 'info';\n\ninterface Diagnostic {\n severity: DiagnosticSeverity;\n message: string;\n filePath?: string;\n line?: number;\n column?: number;\n}\n\ninterface ManifestLike {\n version?: string;\n packageName?: string;\n packageVersion?: string;\n objects?: Record<string, ManifestObject>;\n}\n\ninterface ManifestObject {\n name?: string;\n className: string;\n qualifiedName?: string;\n collection?: string;\n filePath: string;\n packageName?: string;\n packageVersion?: string;\n importPath?: string;\n modulePath?: string;\n exportName?: string;\n collectionExportName?: string;\n fields?: Record<string, ManifestField>;\n methods?: Record<string, ManifestMethod>;\n decoratorConfig?: Record<string, unknown>;\n extends?: string;\n extendsTypeArg?: string;\n schema?: ManifestSchema;\n staticProperties?: Record<string, unknown>;\n validationRules?: Record<string, unknown>;\n}\n\ninterface ManifestField {\n type: string;\n required?: boolean;\n default?: unknown;\n related?: string;\n description?: string;\n _meta?: Record<string, unknown>;\n transient?: boolean;\n}\n\ninterface ManifestMethod {\n name?: string;\n async?: boolean;\n parameters?: Array<{\n name: string;\n type?: string;\n optional?: boolean;\n default?: unknown;\n }>;\n returnType?: string;\n description?: string;\n isStatic?: boolean;\n isPublic?: boolean;\n}\n\ninterface ManifestSchema {\n tableName?: string;\n ddl?: string;\n columns?: Record<string, unknown>;\n indexes?: Array<{\n name?: string;\n columns?: string[];\n unique?: boolean;\n where?: string;\n jsonPath?: unknown;\n }>;\n version?: string;\n}\n\ninterface PackageMetadata {\n name?: string;\n version?: string;\n json?: Record<string, unknown>;\n}\n\nconst DEFAULT_MANIFEST_PATHS = [\n '.smrt/manifest.json',\n 'dist/manifest.json',\n 'src/manifest/manifest.json',\n];\n\nconst SCAN_EXCLUDE = [\n '**/node_modules/**',\n '**/dist/**',\n '**/build/**',\n '**/.git/**',\n '**/.smrt/**',\n '**/*.d.ts',\n '**/*.test.ts',\n '**/*.spec.ts',\n '**/__tests__/**',\n];\n\nconst RELATIONSHIP_TYPES = new Set([\n 'foreignKey',\n 'crossPackageRef',\n 'oneToMany',\n 'manyToMany',\n]);\n\n/**\n * Response budget in characters. Generous enough that a 42-object summary never\n * truncates, while still capping a runaway payload instead of emitting one.\n */\nconst DEFAULT_MAX_CHARS = 50_000;\n\nconst DEFAULT_MCP_OPERATIONS = ['list', 'get', 'create', 'update', 'delete'];\n\nexport async function introspectProject(\n args: IntrospectProjectArgs,\n): Promise<string> {\n const {\n directory = process.cwd(),\n includeFields = true,\n includeRelationships = true,\n includeMethods = true,\n detail = 'summary',\n maxChars = DEFAULT_MAX_CHARS,\n cursor,\n limit,\n } = args;\n const projectPath = resolve(directory);\n\n const exists = await pathExists(projectPath);\n if (!exists) {\n return JSON.stringify(\n {\n projectPath,\n manifestSource: 'none',\n objectCount: 0,\n objects: [],\n diagnostics: [\n {\n severity: 'warning',\n message: `Project directory does not exist: ${projectPath}`,\n },\n ],\n },\n null,\n 2,\n );\n }\n\n const packageMetadata = await readPackageMetadata(projectPath);\n const tenantScopes = await scanTenantScopes(projectPath);\n const manifestResult =\n (await loadManifestArtifact(projectPath, args.manifestPath)) ??\n (await scanSourceManifest(projectPath, packageMetadata));\n\n const entries = Object.entries(manifestResult.manifest.objects ?? {});\n const objects: IntrospectedObject[] =\n detail === 'summary'\n ? entries.map(([manifestKey, object]) =>\n summarizeObject({\n manifestKey,\n object,\n projectPath,\n tenantScope: tenantScopes.get(object.className),\n }),\n )\n : entries.map(([manifestKey, object]) =>\n formatObject({\n manifestKey,\n object,\n projectPath,\n includeFields,\n includeRelationships,\n includeMethods,\n tenantScope: tenantScopes.get(object.className),\n }),\n );\n objects.sort((left, right) => left.className.localeCompare(right.className));\n // Paging: skip everything up to and including the cursor, then cap by\n // `limit` before the character budget trims further.\n const afterCursor =\n typeof cursor === 'string' && cursor.length > 0\n ? objects.filter((object) => object.className.localeCompare(cursor) > 0)\n : objects;\n const pageLimit =\n typeof limit === 'number' && Number.isFinite(limit) && limit >= 1\n ? Math.floor(limit)\n : undefined;\n const window =\n pageLimit !== undefined ? afterCursor.slice(0, pageLimit) : afterCursor;\n const { kept, omitted: budgetOmitted } = applyObjectBudget(window, maxChars);\n const omitted = afterCursor.length - kept.length;\n const nextCursor =\n omitted > 0 && kept.length > 0\n ? kept[kept.length - 1].className\n : undefined;\n\n const output = {\n projectPath,\n manifestSource: manifestResult.source,\n manifestPath:\n 'path' in manifestResult\n ? relative(projectPath, manifestResult.path)\n : undefined,\n packageName:\n manifestResult.manifest.packageName ?? packageMetadata.name ?? undefined,\n packageVersion:\n manifestResult.manifest.packageVersion ??\n packageMetadata.version ??\n undefined,\n detail,\n objectCount: objects.length,\n scannedFileCount: manifestResult.scannedFileCount,\n parseTimeMs: manifestResult.parseTimeMs,\n ...(cursor ? { cursor } : {}),\n ...(nextCursor ? { nextCursor } : {}),\n ...(omitted > 0\n ? {\n truncated: {\n returnedObjectCount: kept.length,\n omittedObjectCount: omitted,\n budgetChars: maxChars,\n ...(pageLimit !== undefined ? { limit: pageLimit } : {}),\n guidance:\n budgetOmitted > 0\n ? 'The object list hit its character budget; metadata and diagnostics are still complete. Pass `cursor: nextCursor` to read the next page, narrow the scan with `directory`, keep `detail: \"summary\"`, or raise `maxChars` deliberately. Objects are sorted alphabetically.'\n : 'More objects follow this page. Pass `cursor: nextCursor` to continue.',\n },\n }\n : {}),\n objects: kept,\n diagnostics: manifestResult.diagnostics,\n };\n\n return JSON.stringify(output, null, 2);\n}\n\n/**\n * Trims the object list to the character budget, always keeping at least one so\n * a caller sees the shape rather than an empty list.\n */\nfunction applyObjectBudget<T>(\n objects: T[],\n maxChars: number,\n): { kept: T[]; omitted: number } {\n const kept: T[] = [];\n let used = 0;\n\n for (const object of objects) {\n const size = JSON.stringify(object, null, 2).length + 2;\n if (used + size > maxChars && kept.length > 0) break;\n used += size;\n kept.push(object);\n }\n\n return { kept, omitted: objects.length - kept.length };\n}\n\nfunction summarizeObject({\n manifestKey,\n object,\n projectPath,\n tenantScope,\n}: {\n manifestKey: string;\n object: ManifestObject;\n projectPath: string;\n tenantScope?: Record<string, unknown>;\n}) {\n const fields = Object.entries(object.fields ?? {});\n const decoratorConfig = object.decoratorConfig ?? {};\n\n return compactObject({\n manifestKey,\n className: object.className,\n qualifiedName: object.qualifiedName,\n filePath: sanitizePath(projectPath, object.filePath),\n extends: object.extends,\n collection: object.collection,\n tableName:\n object.schema?.tableName ??\n stringFromConfig(decoratorConfig.tableName) ??\n object.collection,\n tenantScope:\n tenantScope ?? normalizeTenantScopedConfig(decoratorConfig.tenantScoped),\n fieldCount: fields.length,\n relationships:\n fields\n .filter(([, field]) => RELATIONSHIP_TYPES.has(field.type))\n .map(\n ([name, field]) =>\n `${name} -> ${field.related ?? ''} (${field.type})`,\n )\n .join(', ') || undefined,\n mcpOperations: mcpOperationsFromConfig(decoratorConfig.mcp),\n });\n}\n\n/**\n * An omitted `mcp` config means full CRUD, not a closed surface — the same rule\n * the knowledge index applies.\n */\nfunction mcpOperationsFromConfig(config: unknown): string[] {\n if (config === false) return [];\n if (typeof config !== 'object' || config === null || Array.isArray(config)) {\n return [...DEFAULT_MCP_OPERATIONS];\n }\n\n const record = config as Record<string, unknown>;\n const include = Array.isArray(record.include)\n ? record.include.filter((item): item is string => typeof item === 'string')\n : DEFAULT_MCP_OPERATIONS;\n const exclude = new Set(\n Array.isArray(record.exclude)\n ? record.exclude.filter(\n (item): item is string => typeof item === 'string',\n )\n : [],\n );\n\n return include.filter((operation) => !exclude.has(operation));\n}\n\nasync function loadManifestArtifact(\n projectPath: string,\n manifestPath: string | undefined,\n): Promise<\n | {\n source: 'manifest';\n path: string;\n manifest: ManifestLike;\n diagnostics: Diagnostic[];\n scannedFileCount?: number;\n parseTimeMs?: number;\n }\n | undefined\n> {\n const candidates = manifestPath\n ? [resolve(projectPath, manifestPath)]\n : DEFAULT_MANIFEST_PATHS.map((candidate) => join(projectPath, candidate));\n\n const diagnostics: Diagnostic[] = [];\n for (const candidate of candidates) {\n if (!(await pathExists(candidate))) {\n continue;\n }\n\n try {\n const parsed = JSON.parse(await readFile(candidate, 'utf-8')) as unknown;\n if (isManifestLike(parsed)) {\n return {\n source: 'manifest',\n path: candidate,\n manifest: parsed,\n diagnostics,\n };\n }\n\n diagnostics.push({\n severity: 'warning',\n filePath: candidate,\n message: 'Manifest artifact is present but does not contain objects.',\n });\n } catch (error) {\n diagnostics.push({\n severity: 'error',\n filePath: candidate,\n message: `Unable to parse manifest artifact: ${messageFromError(error)}`,\n });\n }\n }\n\n return manifestPath\n ? {\n source: 'manifest',\n path: resolve(projectPath, manifestPath),\n manifest: { objects: {} },\n diagnostics: [\n ...diagnostics,\n {\n severity: 'warning',\n filePath: resolve(projectPath, manifestPath),\n message: 'Requested manifest artifact was not found.',\n },\n ],\n }\n : undefined;\n}\n\nasync function scanSourceManifest(\n projectPath: string,\n packageMetadata: PackageMetadata,\n): Promise<{\n source: 'scanner';\n manifest: ManifestLike;\n diagnostics: Diagnostic[];\n scannedFileCount: number;\n parseTimeMs: number;\n}> {\n const scanner = new OxcScanner({\n cwd: projectPath,\n include: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],\n exclude: SCAN_EXCLUDE,\n });\n const { results, resolved } = await scanner.scanAndResolve();\n const adapter = new ManifestAdapter();\n const manifest = adapter.toManifest(\n resolved.filter((classDef) => classDef.hasSmartDecorator),\n {\n packageName: packageMetadata.name,\n packageVersion: packageMetadata.version,\n typeAliases: results.typeAliases,\n },\n ) as ManifestLike;\n await finalizeScannerManifest(manifest, packageMetadata, projectPath);\n\n return {\n source: 'scanner',\n manifest,\n diagnostics: results.errors.map(scanErrorToDiagnostic),\n scannedFileCount: results.fileCount,\n parseTimeMs: Math.round(results.totalParseTimeMs),\n };\n}\n\n/**\n * Enrichment executes only installed framework code in an isolated process.\n * Its stdout/stderr are captured, never forwarded onto the MCP protocol. This\n * also prevents the scanner's registry and config from contaminating the host.\n */\nasync function finalizeScannerManifest(\n manifest: ManifestLike,\n packageMetadata: PackageMetadata,\n projectPath: string,\n): Promise<void> {\n const specifier = '@happyvertical/smrt-core/scanner';\n const entry = resolveProjectRuntimeEntry(projectPath, specifier);\n const enriched = await new Promise<ManifestLike>(\n (resolveManifest, reject) => {\n const child = spawn(\n process.execPath,\n [\n '--input-type=module',\n '-e',\n `\n const answer = (result) => process.send(result, () => process.disconnect());\n process.once('message', async (workerData) => {\n let module;\n try { module = await import(workerData.entry); }\n catch { answer({ unavailable: true }); return; }\n if (typeof module.ManifestGenerator !== 'function') { answer({ unavailable: true }); return; }\n try {\n const generator = new module.ManifestGenerator();\n const manifest = workerData.manifest;\n generator.injectTenantScopedFields(manifest);\n generator.mergeInheritedFields(manifest);\n generator.generateValidationRules(manifest);\n generator.generateSchemas(manifest);\n generator.assertTenantScopedSchemaContract(manifest);\n generator.generateAgentManifests(manifest, workerData.name, workerData.packageJson);\n answer({ manifest });\n } catch { answer({ failed: true }); }\n });\n `,\n ],\n { cwd: projectPath, stdio: ['ignore', 'ignore', 'ignore', 'ipc'] },\n );\n child.send({\n entry: pathToFileURL(entry).href,\n manifest,\n name: packageMetadata.name,\n packageJson: packageMetadata.json,\n });\n const timeout = setTimeout(() => {\n child.kill('SIGKILL');\n reject(\n new Error(\n 'Project runtime manifest enrichment timed out; run the project build to diagnose it.',\n ),\n );\n }, 30_000);\n let answered = false;\n child.once('message', (message) => {\n const result = message as {\n unavailable?: boolean;\n failed?: boolean;\n manifest?: ManifestLike;\n };\n clearTimeout(timeout);\n answered = true;\n child.kill('SIGKILL');\n if (result.unavailable)\n reject(new ProjectRuntimeResolutionError(specifier));\n else if (result.failed)\n reject(\n new Error(\n 'Project runtime manifest enrichment failed. Run the project build to diagnose its manifest; no partial inventory was returned.',\n ),\n );\n else if (result.manifest) resolveManifest(result.manifest);\n else reject(new ProjectRuntimeResolutionError(specifier));\n });\n child.once('error', () => {\n clearTimeout(timeout);\n reject(new ProjectRuntimeResolutionError(specifier));\n });\n child.once('exit', () => {\n clearTimeout(timeout);\n if (!answered) reject(new ProjectRuntimeResolutionError(specifier));\n });\n },\n );\n Object.assign(manifest, enriched);\n}\n\nfunction formatObject({\n manifestKey,\n object,\n projectPath,\n includeFields,\n includeRelationships,\n includeMethods,\n tenantScope,\n}: {\n manifestKey: string;\n object: ManifestObject;\n projectPath: string;\n includeFields: boolean;\n includeRelationships: boolean;\n includeMethods: boolean;\n tenantScope?: Record<string, unknown>;\n}) {\n const fieldDetails = Object.entries(object.fields ?? {}).map(\n ([name, field]) => ({\n name,\n type: field.type,\n ...(field.required !== undefined ? { required: field.required } : {}),\n ...(field.default !== undefined ? { default: field.default } : {}),\n ...(field.related ? { related: field.related } : {}),\n ...(field.description ? { description: field.description } : {}),\n ...(field._meta ? { meta: field._meta } : {}),\n ...(field.transient !== undefined ? { transient: field.transient } : {}),\n }),\n );\n const relationshipDetails = fieldDetails\n .filter((field) => RELATIONSHIP_TYPES.has(field.type))\n .map((field) => ({\n field: field.name,\n relatedClass: field.related ?? '',\n type: field.type,\n ...(field.meta ? { meta: field.meta } : {}),\n }));\n const methodDetails = Object.entries(object.methods ?? {}).map(\n ([name, method]) => ({\n name: method.name ?? name,\n isAsync: method.async === true,\n isStatic: method.isStatic === true,\n isPublic: method.isPublic !== false,\n parameters: method.parameters ?? [],\n returnType: method.returnType ?? 'unknown',\n ...(method.description ? { description: method.description } : {}),\n }),\n );\n\n const decoratorConfig = object.decoratorConfig ?? {};\n const effectiveTenantScope =\n tenantScope ?? normalizeTenantScopedConfig(decoratorConfig.tenantScoped);\n const schema = object.schema;\n\n return compactObject({\n manifestKey,\n name: object.name,\n className: object.className,\n qualifiedName: object.qualifiedName,\n filePath: sanitizePath(projectPath, object.filePath),\n packageName: object.packageName,\n packageVersion: object.packageVersion,\n importPath: object.importPath,\n modulePath: object.modulePath,\n exportName: object.exportName,\n collectionExportName: object.collectionExportName,\n collection: object.collection,\n extends: object.extends,\n extendsTypeArg: object.extendsTypeArg,\n tableName:\n schema?.tableName ??\n stringFromConfig(decoratorConfig.tableName) ??\n object.collection,\n tableStrategy: stringFromConfig(decoratorConfig.tableStrategy) ?? 'cti',\n conflictColumns: arrayFromConfig(decoratorConfig.conflictColumns),\n tenantScope: effectiveTenantScope,\n decoratorConfig,\n schema: schema\n ? {\n tableName: schema.tableName,\n columns: schema.columns,\n indexes: schema.indexes ?? [],\n version: schema.version,\n }\n : undefined,\n indexes: schema?.indexes ?? [],\n staticProperties: object.staticProperties,\n validationRules: object.validationRules,\n ...(includeFields && {\n fields: fieldDetails\n .map((field) => `${field.name}: ${field.type}`)\n .join(', '),\n fieldDetails,\n }),\n ...(includeRelationships &&\n relationshipDetails.length > 0 && {\n relationships: relationshipDetails\n .map(\n (relationship) =>\n `${relationship.field} -> ${relationship.relatedClass} (${relationship.type})`,\n )\n .join(', '),\n relationshipDetails,\n }),\n ...(includeMethods &&\n methodDetails.length > 0 && {\n methods: methodDetails\n .map((method) => `${method.isAsync ? 'async ' : ''}${method.name}()`)\n .join(', '),\n methodDetails,\n }),\n });\n}\n\nasync function scanTenantScopes(\n projectPath: string,\n): Promise<Map<string, Record<string, unknown>>> {\n const files = await listSourceFiles(projectPath);\n const scopes = new Map<string, Record<string, unknown>>();\n\n await Promise.all(\n files.map(async (filePath) => {\n const content = await readFile(filePath, 'utf-8');\n const classMatches = content.matchAll(/class\\s+([A-Za-z_]\\w*)\\b/g);\n for (const match of classMatches) {\n const className = match[1];\n if (!className || match.index === undefined) continue;\n const prefix = content.slice(\n Math.max(0, match.index - 800),\n match.index,\n );\n const tenantMatches = Array.from(\n prefix.matchAll(/@TenantScoped\\s*\\(([\\s\\S]*?)\\)/g),\n );\n const tenantMatch = tenantMatches.at(-1);\n if (!tenantMatch) continue;\n scopes.set(className, {\n source: 'TenantScoped',\n ...parseTenantScopedOptions(tenantMatch[1]),\n });\n }\n }),\n );\n\n return scopes;\n}\n\nasync function listSourceFiles(projectPath: string): Promise<string[]> {\n const files: string[] = [];\n\n async function visit(dir: string): Promise<void> {\n let entries: Dirent[];\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n if (\n [\n 'node_modules',\n 'dist',\n 'build',\n '.git',\n '.smrt',\n '__tests__',\n ].includes(entry.name) ||\n entry.name.startsWith('.')\n ) {\n continue;\n }\n await visit(fullPath);\n continue;\n }\n\n if (\n entry.isFile() &&\n /\\.(tsx?|jsx?)$/.test(entry.name) &&\n !entry.name.endsWith('.d.ts') &&\n !entry.name.endsWith('.test.ts') &&\n !entry.name.endsWith('.spec.ts')\n ) {\n files.push(fullPath);\n }\n }\n }\n\n await visit(projectPath);\n return files;\n}\n\nfunction parseTenantScopedOptions(raw: string): Record<string, unknown> {\n const mode = raw.match(/mode\\s*:\\s*['\"`](required|optional)['\"`]/)?.[1];\n const field = raw.match(/field\\s*:\\s*['\"`]([A-Za-z_]\\w*)['\"`]/)?.[1];\n const allowSuperAdminBypass = raw.match(\n /allowSuperAdminBypass\\s*:\\s*(true|false)/,\n )?.[1];\n const autoFilter = raw.match(/autoFilter\\s*:\\s*(true|false)/)?.[1];\n const autoPopulate = raw.match(/autoPopulate\\s*:\\s*(true|false)/)?.[1];\n\n return compactObject({\n mode: mode ?? 'required',\n field: field ?? 'tenantId',\n autoFilter: autoFilter === undefined ? undefined : autoFilter === 'true',\n autoPopulate:\n autoPopulate === undefined ? undefined : autoPopulate === 'true',\n allowSuperAdminBypass:\n allowSuperAdminBypass === undefined\n ? undefined\n : allowSuperAdminBypass === 'true',\n });\n}\n\nfunction normalizeTenantScopedConfig(\n tenantScoped: unknown,\n): Record<string, unknown> | undefined {\n if (!tenantScoped) return undefined;\n const options =\n typeof tenantScoped === 'object' && !Array.isArray(tenantScoped)\n ? (tenantScoped as Record<string, unknown>)\n : {};\n return {\n source: 'smrt',\n mode: options.mode ?? 'required',\n field: options.field ?? 'tenantId',\n autoFilter: options.autoFilter ?? true,\n autoPopulate: options.autoPopulate ?? true,\n allowSuperAdminBypass: options.allowSuperAdminBypass ?? false,\n };\n}\n\nasync function readPackageMetadata(\n projectPath: string,\n): Promise<PackageMetadata> {\n const packageJsonPath = join(projectPath, 'package.json');\n if (!(await pathExists(packageJsonPath))) return {};\n\n try {\n const json = JSON.parse(await readFile(packageJsonPath, 'utf-8')) as Record<\n string,\n unknown\n >;\n return {\n name: typeof json.name === 'string' ? json.name : undefined,\n version: typeof json.version === 'string' ? json.version : undefined,\n json,\n };\n } catch {\n return {};\n }\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isManifestLike(value: unknown): value is ManifestLike {\n return (\n !!value &&\n typeof value === 'object' &&\n !!(value as ManifestLike).objects &&\n typeof (value as ManifestLike).objects === 'object'\n );\n}\n\nfunction scanErrorToDiagnostic(error: ScanError): Diagnostic {\n return {\n severity: error.severity,\n message: error.message,\n filePath: error.filePath,\n line: error.line,\n column: error.column,\n };\n}\n\nfunction sanitizePath(projectPath: string, filePath: string): string {\n const absolute = isAbsolute(filePath)\n ? filePath\n : resolve(projectPath, filePath);\n const relativePath = relative(projectPath, absolute);\n if (!relativePath.startsWith('..')) {\n return relativePath || filePath;\n }\n return filePath;\n}\n\nfunction stringFromConfig(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction arrayFromConfig(value: unknown): string[] | undefined {\n return Array.isArray(value)\n ? value.filter((item): item is string => typeof item === 'string')\n : undefined;\n}\n\nfunction compactObject<T extends Record<string, unknown>>(value: T): T {\n return Object.fromEntries(\n Object.entries(value).filter(([, entry]) => entry !== undefined),\n ) as T;\n}\n\nfunction messageFromError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"mappings":"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"}