@happyvertical/smrt-workbench 0.46.0 → 0.47.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,6 +3,7 @@ import { existsSync, readFileSync } from "node:fs";
3
3
  import { createRequire } from "node:module";
4
4
  import { dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
5
5
  import { pathToFileURL } from "node:url";
6
+ import { createClassNamePredicate, resolveApiMethodExposure, resolveCustomActionMetadata, resolveEffectiveActionMetadata } from "@happyvertical/smrt-core/generators/custom-action";
6
7
  import fg from "fast-glob";
7
8
  //#region src/discovery.ts
8
9
  var require = createRequire(import.meta.url);
@@ -525,32 +526,61 @@ function publicCustomMethodNames(object) {
525
526
  return method.isPublic === true;
526
527
  }).map(([name]) => name).sort();
527
528
  }
528
- function enabledCustomActions(object, surface) {
529
- const surfaceConfig = configObject(object.decoratorConfig)[surface];
529
+ function enabledCustomActions(object, surface, isModelClassName) {
530
+ const decoratorConfig = configObject(object.decoratorConfig);
531
+ const surfaceConfig = decoratorConfig[surface];
530
532
  if (surfaceConfig === false) return [];
531
533
  const include = arrayOfStrings(configObject(surfaceConfig).include);
532
534
  const exclude = new Set(arrayOfStrings(configObject(surfaceConfig).exclude));
533
535
  const publicMethods = publicCustomMethodNames(object);
534
536
  if (surface === "mcp" && include.length > 0) return include.filter((name) => !CRUD_ACTIONS.includes(name)).filter((name) => publicMethods.includes(name)).filter((name) => !exclude.has(name));
535
- if (surface === "api") return publicMethods.filter((name) => include.length === 0 || include.includes(name)).filter((name) => !exclude.has(name));
537
+ if (surface === "api") {
538
+ const methods = configObject(object.methods);
539
+ const isCollectionClass = stringValue(object.extends) === "SmrtCollection" || object.extendsTypeArg !== void 0;
540
+ return Object.keys(methods).sort().filter((name) => resolveApiMethodExposure({
541
+ actionName: name,
542
+ method: configObject(methods[name]),
543
+ apiConfig: decoratorConfig.api,
544
+ isCollectionClass,
545
+ ...isModelClassName ? { isModelClassName } : {}
546
+ }).exposed);
547
+ }
536
548
  const customMethodsInInclude = include.filter((name) => !CRUD_ACTIONS.includes(name));
537
549
  return publicMethods.filter((name) => customMethodsInInclude.length === 0 || customMethodsInInclude.includes(name)).filter((name) => !exclude.has(name));
538
550
  }
539
- function routeOverrides(object) {
540
- const routes = configObject(configObject(configObject(object.decoratorConfig).api).routes);
541
- return Object.fromEntries(Object.entries(routes).filter((entry) => isRecord(entry[1])));
542
- }
543
551
  function methodDefinition(object, action) {
544
552
  return configObject(configObject(object.methods)[action]);
545
553
  }
554
+ function effectiveRoute(object, action) {
555
+ return resolveEffectiveActionMetadata({
556
+ actionName: action,
557
+ method: methodDefinition(object, action),
558
+ apiConfig: configObject(object.decoratorConfig).api
559
+ });
560
+ }
561
+ function customRouteMethod(object, action) {
562
+ return effectiveRoute(object, action).httpMethod || "POST";
563
+ }
564
+ function effectiveScope(object, action) {
565
+ const method = methodDefinition(object, action);
566
+ const defaultScope = stringValue(object.extends) === "SmrtCollection" || object.extendsTypeArg !== void 0 || method.isStatic === true ? "collection" : "item";
567
+ try {
568
+ return resolveCustomActionMetadata({
569
+ actionName: action,
570
+ method,
571
+ apiConfig: configObject(object.decoratorConfig).api,
572
+ defaultScope
573
+ }).scope;
574
+ } catch {
575
+ return defaultScope;
576
+ }
577
+ }
546
578
  function customRoutePath(object, action) {
547
579
  const collection = stringValue(object.collection) || stringValue(object.name) || action;
548
- const routeConfig = routeOverrides(object)[action] || {};
549
- const method = methodDefinition(object, action);
550
- const normalizedPath = (stringValue(routeConfig.path) || action).split("/").map((segment) => segment.trim()).filter(Boolean).join("/").replace(/\[([^\]]+)\]/g, "{$1}");
551
- return (stringValue(routeConfig.scope) || (method.isStatic === true ? "collection" : "item")) === "collection" ? `/api/v1/${collection}/${normalizedPath}` : `/api/v1/${collection}/{id}/${normalizedPath}`;
580
+ const normalizedPath = (effectiveRoute(object, action).path || action).split("/").map((segment) => segment.trim()).filter(Boolean).join("/").replace(/\[([^\]]+)\]/g, "{$1}");
581
+ return effectiveScope(object, action) === "collection" ? `/api/v1/${collection}/${normalizedPath}` : `/api/v1/${collection}/{id}/${normalizedPath}`;
552
582
  }
553
- function restEndpointsFrom(object) {
583
+ function restEndpointsFrom(object, isModelClassName) {
554
584
  const className = stringValue(object.className) || stringValue(object.name) || "Object";
555
585
  const collection = stringValue(object.collection) || className.toLowerCase();
556
586
  const apiConfig = configObject(object.decoratorConfig).api;
@@ -587,9 +617,8 @@ function restEndpointsFrom(object) {
587
617
  parameters: restCrudParameters(object, action, route[1])
588
618
  });
589
619
  }
590
- const overrides = routeOverrides(object);
591
- for (const action of enabledCustomActions(object, "api")) {
592
- const method = stringValue((overrides[action] || {}).method) || "POST";
620
+ for (const action of enabledCustomActions(object, "api", isModelClassName)) {
621
+ const method = customRouteMethod(object, action);
593
622
  endpoints.push({
594
623
  objectName: className,
595
624
  action,
@@ -669,7 +698,12 @@ function readApiSummary(packageDir, rootDir, packageName, knowledge, routeFiles)
669
698
  };
670
699
  });
671
700
  const objectNames = objects.length > 0 ? objects.map((object) => object.qualifiedName || object.className || object.name).filter(Boolean).sort() : knowledge.objectNames;
672
- const restEndpoints = objectRecords.flatMap(restEndpointsFrom);
701
+ const isModelClassName = createClassNamePredicate(objectRecords.flatMap((record) => [
702
+ stringValue(record.className),
703
+ stringValue(record.name),
704
+ stringValue(record.qualifiedName)
705
+ ].filter((name) => Boolean(name))));
706
+ const restEndpoints = objectRecords.flatMap((record) => restEndpointsFrom(record, isModelClassName));
673
707
  return {
674
708
  objectNames,
675
709
  objects,
@@ -976,4 +1010,4 @@ function describeWorkbenchSource(target, cwd = process.cwd()) {
976
1010
  //#endregion
977
1011
  export { discoverWorkbenchTargets as a, findProjectRoot as c, importWorkbenchModule as d, resolveWorkbenchScope as f, discoverInstalledWorkbenches as i, findSmrtWorkbenchWorkspaceRoot as l, describeWorkbenchSource as n, discoverWorkspaceWorkbenches as o, detectWorkbenchMode as r, findPackageDir as s, buildWorkbenchProject as t, findWorkspaceRoot as u };
978
1012
 
979
- //# sourceMappingURL=discovery-G9-foyW8.js.map
1013
+ //# sourceMappingURL=discovery-BOoinKLR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery-BOoinKLR.js","names":["targets"],"sources":["../../src/discovery.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport {\n dirname,\n extname,\n isAbsolute,\n join,\n relative,\n resolve,\n} from 'node:path';\nimport { pathToFileURL } from 'node:url';\n// The leaf `/generators/custom-action` subpath — not the package root, and not\n// the `/generators` barrel, which value-re-exports `MCPGenerator` and so reaches\n// `SmrtCollection` -> `SmrtObject` -> `SmrtClass` and its module-scope\n// `@happyvertical/ai` / `@happyvertical/sql` imports. Measured over `dist`:\n// this subpath is 2 modules with no `@happyvertical` external, the barrel is\n// 109 with the full AI/SQL surface, the root 151. `custom-action`'s only runtime\n// import is `tools/tool-generator`, whose own imports are type-only, which is\n// what keeps it a leaf — a build-time discovery helper should load none of the\n// rest (#2686).\nimport {\n createClassNamePredicate,\n resolveApiMethodExposure,\n resolveCustomActionMetadata,\n resolveEffectiveActionMetadata,\n} from '@happyvertical/smrt-core/generators/custom-action';\nimport fg from 'fast-glob';\nimport { coerceWorkbenchModules } from './runtime.js';\nimport type {\n DiscoveredWorkbenchTarget,\n SmrtWorkbenchModule,\n SmrtWorkbenchProject,\n SmrtWorkbenchScopeMode,\n SmrtWorkbenchVitePluginOptions,\n WorkbenchApiObjectFieldSummary,\n WorkbenchApiObjectSummary,\n WorkbenchApiParameterLocation,\n WorkbenchApiParameterSummary,\n WorkbenchApiSummary,\n WorkbenchCliCommandSummary,\n WorkbenchDocumentSummary,\n WorkbenchExampleSummary,\n WorkbenchKnowledgeSummary,\n WorkbenchMcpToolSummary,\n WorkbenchPackageSummary,\n WorkbenchRestEndpointSummary,\n WorkbenchScopeResolution,\n} from './types.js';\nimport { commandIdForScript } from './utils.js';\n\nconst require = createRequire(import.meta.url);\nconst TS_SOURCE_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts']);\nconst DOCUMENT_LIMIT = 20_000;\nconst EXAMPLE_LIMIT = 8_000;\n\ninterface PackageJsonLike {\n name?: string;\n version?: string;\n description?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n exports?: unknown;\n packageManager?: string;\n}\n\ninterface WorkbenchPackageDir {\n packageDir: string;\n packageJson: PackageJsonLike;\n source: 'workspace' | 'package' | 'app';\n}\n\nexport function findWorkspaceRoot(startDir = process.cwd()): string | null {\n let current = resolve(startDir);\n\n while (true) {\n if (existsSync(join(current, 'pnpm-workspace.yaml'))) {\n return current;\n }\n\n const parent = dirname(current);\n if (parent === current) {\n return null;\n }\n current = parent;\n }\n}\n\nexport function findSmrtWorkbenchWorkspaceRoot(\n startDir = process.cwd(),\n): string | null {\n const workspaceRoot = findWorkspaceRoot(startDir);\n if (!workspaceRoot) {\n return null;\n }\n\n const hostPackageJsonPath = join(\n workspaceRoot,\n 'packages',\n 'smrt-workbench',\n 'host',\n 'package.json',\n );\n\n return existsSync(hostPackageJsonPath) ? workspaceRoot : null;\n}\n\nexport function findProjectRoot(startDir = process.cwd()): string {\n let current = resolve(startDir);\n\n while (true) {\n if (existsSync(join(current, 'package.json'))) {\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\nexport function findPackageDir(\n startDir = process.cwd(),\n workspaceRoot?: string,\n): string | null {\n let current = resolve(startDir);\n const boundary = workspaceRoot ? resolve(workspaceRoot) : null;\n\n while (true) {\n if (boundary && current === boundary) {\n return null;\n }\n\n const packageJsonPath = join(current, 'package.json');\n if (existsSync(packageJsonPath)) {\n return current;\n }\n\n const parent = dirname(current);\n if (parent === current) {\n return null;\n }\n current = parent;\n }\n}\n\nexport function detectWorkbenchMode(\n projectRoot = process.cwd(),\n): 'workspace' | 'consumer' {\n return findSmrtWorkbenchWorkspaceRoot(projectRoot) ? 'workspace' : 'consumer';\n}\n\nfunction readJson<T = Record<string, unknown>>(path: string): T {\n return JSON.parse(readFileSync(path, 'utf-8')) as T;\n}\n\nfunction readJsonIfExists<T = Record<string, unknown>>(path: string): T | null {\n return existsSync(path) ? readJson<T>(path) : null;\n}\n\nfunction detectPackageManager(projectRoot: string): 'pnpm' | 'yarn' | 'npm' {\n let current = resolve(projectRoot);\n\n while (true) {\n if (existsSync(join(current, 'pnpm-lock.yaml'))) return 'pnpm';\n if (existsSync(join(current, 'yarn.lock'))) return 'yarn';\n\n const packageManager = readJsonIfExists<PackageJsonLike>(\n join(current, 'package.json'),\n )?.packageManager;\n if (packageManager?.startsWith('pnpm@')) return 'pnpm';\n if (packageManager?.startsWith('yarn@')) return 'yarn';\n if (packageManager?.startsWith('npm@')) return 'npm';\n\n const parent = dirname(current);\n if (parent === current) return 'npm';\n current = parent;\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction stringRecord(value: unknown): Record<string, string> {\n if (!isRecord(value)) {\n return {};\n }\n\n return Object.fromEntries(\n Object.entries(value).filter(\n (entry): entry is [string, string] => typeof entry[1] === 'string',\n ),\n );\n}\n\nfunction countItems(value: unknown): number {\n if (Array.isArray(value)) {\n return value.length;\n }\n if (isRecord(value)) {\n return Object.keys(value).length;\n }\n return 0;\n}\n\nfunction truncate(\n value: string,\n limit: number,\n): {\n content: string;\n truncated: boolean;\n} {\n if (value.length <= limit) {\n return { content: value, truncated: false };\n }\n\n return { content: value.slice(0, limit), truncated: true };\n}\n\nfunction readDocument(\n packageDir: string,\n fileName: string,\n kind: WorkbenchDocumentSummary['kind'],\n): WorkbenchDocumentSummary | null {\n const path = join(packageDir, fileName);\n if (!existsSync(path)) {\n return null;\n }\n\n const { content, truncated } = truncate(\n readFileSync(path, 'utf-8'),\n DOCUMENT_LIMIT,\n );\n return {\n kind,\n title: fileName,\n path,\n content,\n truncated,\n };\n}\n\nfunction exportKeys(exportsField: unknown): string[] {\n if (!exportsField) {\n return [];\n }\n if (typeof exportsField === 'string') {\n return ['.'];\n }\n if (isRecord(exportsField)) {\n return Object.keys(exportsField).sort();\n }\n return [];\n}\n\nfunction dependencyNames(packageJson: PackageJsonLike): string[] {\n return Object.keys({\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n ...packageJson.peerDependencies,\n }).sort();\n}\n\nfunction smrtDependencyNames(packageJson: PackageJsonLike): string[] {\n return dependencyNames(packageJson).filter((name) =>\n name.startsWith('@happyvertical/smrt-'),\n );\n}\n\nfunction sdkDependencyNames(packageJson: PackageJsonLike): string[] {\n return dependencyNames(packageJson).filter(\n (name) =>\n name.startsWith('@happyvertical/') &&\n !name.startsWith('@happyvertical/smrt-'),\n );\n}\n\nfunction readKnowledgeSummary(packageDir: string): WorkbenchKnowledgeSummary {\n const knowledgeCandidates = [\n join(packageDir, '.smrt', 'smrt-knowledge.json'),\n join(packageDir, 'dist', 'smrt-knowledge.json'),\n ];\n const manifestCandidates = [\n join(packageDir, '.smrt', 'manifest.json'),\n join(packageDir, 'dist', 'manifest.json'),\n join(packageDir, 'src', 'manifest', 'manifest.json'),\n ];\n\n const knowledgePath = knowledgeCandidates.find((path) => existsSync(path));\n const manifestPath = manifestCandidates.find((path) => existsSync(path));\n const knowledge = knowledgePath\n ? readJsonIfExists<Record<string, unknown>>(knowledgePath)\n : null;\n const manifest = manifestPath\n ? readJsonIfExists<Record<string, unknown>>(manifestPath)\n : null;\n const knowledgeObjects = knowledge?.objects;\n const manifestObjects = manifest?.objects;\n const objects =\n countItems(knowledgeObjects) > 0 ? knowledgeObjects : manifestObjects;\n const objectNames = objectNamesFrom(objects);\n\n return {\n manifestPath,\n knowledgePath,\n objectCount: countItems(objects),\n relationshipCount:\n countItems(knowledge?.relationshipsV2) ||\n countItems(knowledge?.relationships),\n promptCount: countItems(knowledge?.prompts),\n mcpToolCount: countItems(knowledge?.mcpTools),\n surfaceCount: countItems(knowledge?.surfaces),\n tags: Array.isArray(knowledge?.tags)\n ? knowledge.tags.filter((tag): tag is string => typeof tag === 'string')\n : [],\n risks: Array.isArray(knowledge?.risks)\n ? knowledge.risks.filter(\n (risk): risk is string => typeof risk === 'string',\n )\n : [],\n objectNames,\n };\n}\n\nfunction objectNamesFrom(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value\n .map((item) => {\n if (!isRecord(item)) {\n return null;\n }\n return stringValue(item.qualifiedName) || stringValue(item.name);\n })\n .filter((name): name is string => Boolean(name))\n .sort();\n }\n\n if (isRecord(value)) {\n return Object.keys(value).sort();\n }\n\n return [];\n}\n\nfunction stringValue(value: unknown): string | null {\n return typeof value === 'string' && value.length > 0 ? value : null;\n}\n\nfunction booleanValue(value: unknown): boolean | undefined {\n return typeof value === 'boolean' ? value : undefined;\n}\n\nfunction objectRecordsFrom(value: unknown): Record<string, unknown>[] {\n if (Array.isArray(value)) {\n return value.filter(isRecord);\n }\n\n if (!isRecord(value)) {\n return [];\n }\n\n return Object.entries(value).map(([key, item]) => {\n if (isRecord(item)) {\n return {\n key,\n ...item,\n };\n }\n\n return {\n key,\n name: key,\n };\n });\n}\n\nfunction fieldSummariesFrom(value: unknown): WorkbenchApiObjectFieldSummary[] {\n if (Array.isArray(value)) {\n return value\n .filter(isRecord)\n .map((field) => ({\n name: stringValue(field.name) || 'unknown',\n type: stringValue(field.type) || undefined,\n required: booleanValue(field.required),\n related: stringValue(field.related) || undefined,\n }))\n .filter((field) => field.name !== 'unknown');\n }\n\n if (!isRecord(value)) {\n return [];\n }\n\n return Object.entries(value)\n .map(([name, field]) => {\n const fieldRecord = isRecord(field) ? field : {};\n return {\n name,\n type: stringValue(fieldRecord.type) || undefined,\n required: booleanValue(fieldRecord.required),\n related: stringValue(fieldRecord.related) || undefined,\n };\n })\n .sort((left, right) => left.name.localeCompare(right.name));\n}\n\nfunction resolveManifestSourcePath(\n rootDir: string,\n packageDir: string,\n sourcePath: string | null,\n): string | undefined {\n if (!sourcePath) {\n return undefined;\n }\n\n if (isAbsolute(sourcePath)) {\n return sourcePath;\n }\n\n const rootRelativePath = resolve(rootDir, sourcePath);\n if (existsSync(rootRelativePath)) {\n return rootRelativePath;\n }\n\n return resolve(packageDir, sourcePath);\n}\n\nfunction typedocPackageSlug(packageName: string | undefined): string | null {\n if (!packageName?.startsWith('@happyvertical/smrt-')) {\n return null;\n }\n\n return packageName.replace('@happyvertical/smrt-', '');\n}\n\nfunction findTypedocClassPath(\n rootDir: string,\n packageDir: string,\n packageName: string | undefined,\n className: string,\n): string | undefined {\n const slug = typedocPackageSlug(packageName);\n const candidates = [\n slug\n ? join(\n rootDir,\n 'docs',\n 'content',\n 'api',\n slug,\n 'classes',\n `${className}.md`,\n )\n : null,\n join(packageDir, 'docs', 'classes', `${className}.md`),\n join(packageDir, 'docs', `${className}.md`),\n ].filter((path): path is string => Boolean(path));\n\n return candidates.find((path) => existsSync(path));\n}\n\nfunction extractTypedocSummary(content: string): string | undefined {\n const lines = content.split(/\\r?\\n/);\n const summary: string[] = [];\n let hasSeenTitle = false;\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n if (!hasSeenTitle) {\n if (trimmed.startsWith('# ')) {\n hasSeenTitle = true;\n }\n continue;\n }\n\n if (!trimmed || trimmed.startsWith('Defined in:')) {\n continue;\n }\n if (trimmed.startsWith('## ')) {\n break;\n }\n if (trimmed.startsWith('> ')) {\n continue;\n }\n\n summary.push(trimmed);\n }\n\n const value = summary.join('\\n').trim();\n return value.length > 0 ? value : undefined;\n}\n\nfunction readTypedocSummary(path: string | undefined): string | undefined {\n if (!path) {\n return undefined;\n }\n\n return extractTypedocSummary(readFileSync(path, 'utf-8'));\n}\n\nconst CRUD_ACTIONS = ['list', 'get', 'create', 'update', 'delete'] as const;\nconst SERVER_MANAGED_FIELDS = new Set([\n 'id',\n 'tenantId',\n 'tenant_id',\n 'createdAt',\n 'created_at',\n 'updatedAt',\n 'updated_at',\n]);\n\nfunction arrayOfStrings(value: unknown): string[] {\n return Array.isArray(value)\n ? value.filter((item): item is string => typeof item === 'string')\n : [];\n}\n\nfunction configObject(value: unknown): Record<string, unknown> {\n return isRecord(value) ? value : {};\n}\n\nfunction parameterRequired(\n value: Record<string, unknown>,\n): boolean | undefined {\n if (typeof value.required === 'boolean') {\n return value.required;\n }\n\n const meta = configObject(value._meta);\n return typeof meta.required === 'boolean' ? meta.required : undefined;\n}\n\nfunction parameterDescription(\n value: Record<string, unknown>,\n): string | undefined {\n return (\n stringValue(value.description) ||\n stringValue(configObject(value._meta).description) ||\n undefined\n );\n}\n\nfunction parameterDefaultValue(\n value: Record<string, unknown>,\n): string | undefined {\n if (!Object.hasOwn(value, 'default')) {\n return undefined;\n }\n\n const defaultValue = value.default;\n if (\n typeof defaultValue === 'string' ||\n typeof defaultValue === 'number' ||\n typeof defaultValue === 'boolean'\n ) {\n return String(defaultValue);\n }\n\n if (defaultValue === null) {\n return 'null';\n }\n\n try {\n return JSON.stringify(defaultValue);\n } catch {\n return undefined;\n }\n}\n\nfunction fieldParameter(\n name: string,\n field: Record<string, unknown>,\n location: WorkbenchApiParameterLocation,\n requiredOverride?: boolean,\n): WorkbenchApiParameterSummary {\n return {\n name,\n type: stringValue(field.type) || undefined,\n required: requiredOverride ?? parameterRequired(field),\n location,\n description: parameterDescription(field),\n defaultValue: parameterDefaultValue(field),\n };\n}\n\nfunction writableFieldEntries(\n object: Record<string, unknown>,\n): Array<[string, Record<string, unknown>]> {\n const fields = configObject(object.fields);\n const apiConfig = configObject(configObject(object.decoratorConfig).api);\n const writableAllowlist = new Set(arrayOfStrings(apiConfig.writable));\n const hasWritableAllowlist = writableAllowlist.size > 0;\n\n return Object.entries(fields)\n .filter((entry): entry is [string, Record<string, unknown>] =>\n isRecord(entry[1]),\n )\n .filter(([name, field]) => {\n if (name.startsWith('_')) {\n return false;\n }\n if (SERVER_MANAGED_FIELDS.has(name)) {\n return false;\n }\n if (\n field.readonly === true ||\n configObject(field._meta).readonly === true\n ) {\n return false;\n }\n return !hasWritableAllowlist || writableAllowlist.has(name);\n })\n .sort(([left], [right]) => left.localeCompare(right));\n}\n\nfunction writableFieldParameters(\n object: Record<string, unknown>,\n location: WorkbenchApiParameterLocation,\n requiredMode: 'field' | 'optional',\n): WorkbenchApiParameterSummary[] {\n return writableFieldEntries(object).map(([name, field]) =>\n fieldParameter(\n name,\n field,\n location,\n requiredMode === 'field' ? parameterRequired(field) : false,\n ),\n );\n}\n\nfunction methodParameterSummaries(\n object: Record<string, unknown>,\n action: string,\n location: WorkbenchApiParameterLocation,\n): WorkbenchApiParameterSummary[] {\n const parameters = methodDefinition(object, action).parameters;\n if (!Array.isArray(parameters)) {\n return [];\n }\n\n return parameters.filter(isRecord).map((parameter) => ({\n name: stringValue(parameter.name) || 'parameter',\n type: stringValue(parameter.type) || undefined,\n required: parameter.optional !== true,\n location,\n description: parameterDescription(parameter),\n defaultValue: parameterDefaultValue(parameter),\n }));\n}\n\nfunction pathParameterNames(path: string): string[] {\n return Array.from(path.matchAll(/\\{([^}]+)\\}/g))\n .map((match) => match[1]?.trim())\n .filter((name): name is string => Boolean(name));\n}\n\nfunction pathParameters(path: string): WorkbenchApiParameterSummary[] {\n return pathParameterNames(path).map((name) => ({\n name,\n type: 'string',\n required: true,\n location: 'path',\n }));\n}\n\nfunction restCrudParameters(\n object: Record<string, unknown>,\n action: string,\n path: string,\n): WorkbenchApiParameterSummary[] {\n if (action === 'list') {\n return [\n {\n name: 'limit',\n type: 'integer',\n required: false,\n location: 'query',\n description: 'Maximum number of items to return.',\n defaultValue: '50',\n },\n {\n name: 'offset',\n type: 'integer',\n required: false,\n location: 'query',\n description: 'Number of items to skip.',\n defaultValue: '0',\n },\n ];\n }\n\n if (action === 'create') {\n return writableFieldParameters(object, 'body', 'field');\n }\n\n if (action === 'update') {\n return [\n ...pathParameters(path),\n ...writableFieldParameters(object, 'body', 'optional'),\n ];\n }\n\n return pathParameters(path);\n}\n\nfunction restCustomParameters(\n object: Record<string, unknown>,\n action: string,\n method: string,\n path: string,\n): WorkbenchApiParameterSummary[] {\n const pathParams = pathParameters(path);\n const pathParamNameSet = new Set(pathParams.map((param) => param.name));\n const bodyOrQueryParams = methodParameterSummaries(\n object,\n action,\n method === 'GET' ? 'query' : 'body',\n ).filter((param) => !pathParamNameSet.has(param.name));\n\n return [...pathParams, ...bodyOrQueryParams];\n}\n\nfunction cliCrudParameters(\n object: Record<string, unknown>,\n action: string,\n): WorkbenchApiParameterSummary[] {\n if (action === 'list') {\n return [\n {\n name: '--limit',\n type: 'integer',\n required: false,\n location: 'option',\n description: 'Maximum number of items to return.',\n defaultValue: '50',\n },\n {\n name: '--offset',\n type: 'integer',\n required: false,\n location: 'option',\n description: 'Number of items to skip.',\n defaultValue: '0',\n },\n {\n name: '--order-by',\n type: 'string',\n required: false,\n location: 'option',\n description: 'Ordering expression, for example \"created_at DESC\".',\n },\n {\n name: '--where',\n type: 'object',\n required: false,\n location: 'option',\n description: 'JSON filter conditions.',\n },\n ];\n }\n\n if (action === 'get' || action === 'delete') {\n return [\n {\n name: 'id',\n type: 'string',\n required: true,\n location: 'argument',\n description: 'Object ID. May also be passed as --id.',\n },\n ];\n }\n\n const bodyParameters = writableFieldParameters(\n object,\n 'option',\n action === 'create' ? 'field' : 'optional',\n ).map((param) => ({\n ...param,\n name: `--${param.name}`,\n }));\n\n if (action === 'create') {\n return [\n {\n name: '--from-file',\n type: 'path',\n required: false,\n location: 'option',\n description: 'Path to a JSON object payload.',\n },\n ...bodyParameters,\n ];\n }\n\n return [\n {\n name: 'id',\n type: 'string',\n required: true,\n location: 'argument',\n description: 'Object ID. May also be passed as --id.',\n },\n {\n name: '--from-file',\n type: 'path',\n required: false,\n location: 'option',\n description: 'Path to a JSON object payload.',\n },\n ...bodyParameters,\n ];\n}\n\nfunction cliCustomParameters(\n object: Record<string, unknown>,\n action: string,\n): WorkbenchApiParameterSummary[] {\n const params = methodParameterSummaries(object, action, 'option').map(\n (param) => ({\n ...param,\n name: `--${param.name}`,\n required: false,\n }),\n );\n\n return [\n {\n name: 'id',\n type: 'string',\n required: false,\n location: 'argument',\n description:\n 'Optional object ID for instance actions. May also be passed as --id.',\n },\n ...params,\n ];\n}\n\nfunction mcpCrudParameters(\n object: Record<string, unknown>,\n action: string,\n): WorkbenchApiParameterSummary[] {\n if (action === 'list') {\n return [\n {\n name: 'limit',\n type: 'integer',\n required: false,\n location: 'input',\n description: 'Maximum number of items to return.',\n defaultValue: '50',\n },\n {\n name: 'offset',\n type: 'integer',\n required: false,\n location: 'input',\n description: 'Number of items to skip.',\n defaultValue: '0',\n },\n {\n name: 'orderBy',\n type: 'string',\n required: false,\n location: 'input',\n description: 'Ordering expression, for example \"created_at DESC\".',\n },\n {\n name: 'where',\n type: 'object',\n required: false,\n location: 'input',\n description: 'Filter conditions as key-value pairs.',\n },\n ];\n }\n\n if (action === 'get') {\n return [\n {\n name: 'id',\n type: 'string',\n required: true,\n location: 'input',\n description: 'Unique identifier of the object.',\n },\n {\n name: 'slug',\n type: 'string',\n required: false,\n location: 'input',\n description: 'URL-friendly identifier of the object.',\n },\n ];\n }\n\n if (action === 'delete') {\n return [\n {\n name: 'id',\n type: 'string',\n required: true,\n location: 'input',\n description: 'ID of the object to delete.',\n },\n ];\n }\n\n if (action === 'create') {\n return writableFieldParameters(object, 'input', 'field');\n }\n\n return [\n {\n name: 'id',\n type: 'string',\n required: true,\n location: 'input',\n description: 'ID of the object to update.',\n },\n ...writableFieldParameters(object, 'input', 'optional'),\n ];\n}\n\nfunction mcpCustomParameters(\n _object: Record<string, unknown>,\n _action: string,\n): WorkbenchApiParameterSummary[] {\n return [\n {\n name: 'id',\n type: 'string',\n required: true,\n location: 'input',\n description: 'ID of the object to execute the action on.',\n },\n {\n name: 'options',\n type: 'object',\n required: false,\n location: 'input',\n description: 'Additional options for the custom action.',\n },\n ];\n}\n\nfunction enabledCrudActions(config: unknown): string[] {\n if (config === false) {\n return [];\n }\n\n const include = arrayOfStrings(configObject(config).include);\n const exclude = new Set(arrayOfStrings(configObject(config).exclude));\n const actions =\n include.length > 0\n ? include.filter((action) => CRUD_ACTIONS.includes(action as never))\n : [...CRUD_ACTIONS];\n\n return actions.filter((action) => !exclude.has(action));\n}\n\nfunction publicCustomMethodNames(object: Record<string, unknown>): string[] {\n return Object.entries(configObject(object.methods))\n .filter(([name, method]) => {\n if (CRUD_ACTIONS.includes(name as never) || !isRecord(method)) {\n return false;\n }\n return method.isPublic === true;\n })\n .map(([name]) => name)\n .sort();\n}\n\nfunction enabledCustomActions(\n object: Record<string, unknown>,\n surface: 'api' | 'cli' | 'mcp',\n isModelClassName?: (name: string) => boolean,\n): string[] {\n const decoratorConfig = configObject(object.decoratorConfig);\n const surfaceConfig = decoratorConfig[surface];\n if (surfaceConfig === false) {\n return [];\n }\n\n const include = arrayOfStrings(configObject(surfaceConfig).include);\n const exclude = new Set(arrayOfStrings(configObject(surfaceConfig).exclude));\n const publicMethods = publicCustomMethodNames(object);\n\n if (surface === 'mcp' && include.length > 0) {\n return include\n .filter((name) => !CRUD_ACTIONS.includes(name as never))\n .filter((name) => publicMethods.includes(name))\n .filter((name) => !exclude.has(name));\n }\n\n // `api` reads the framework's ONE exposure resolver rather than a local copy\n // of the include/exclude rule. This summary is an agent-facing discovery\n // artifact, so a stale copy advertises endpoints the route emitters never\n // wrote -- the wire-ability gate, the framework-lifecycle exclusion, and\n // `@method({ expose })` all decide here too (#2686). `cli`/`mcp` keep their\n // own projection; #2692 owns those defaults.\n if (surface === 'api') {\n const methods = configObject(object.methods);\n const isCollectionClass =\n stringValue(object.extends) === 'SmrtCollection' ||\n object.extendsTypeArg !== undefined;\n return Object.keys(methods)\n .sort()\n .filter(\n (name) =>\n resolveApiMethodExposure({\n actionName: name,\n method: configObject(methods[name]),\n apiConfig: decoratorConfig.api,\n isCollectionClass,\n ...(isModelClassName ? { isModelClassName } : {}),\n }).exposed,\n );\n }\n\n const customMethodsInInclude = include.filter(\n (name) => !CRUD_ACTIONS.includes(name as never),\n );\n return publicMethods\n .filter(\n (name) =>\n customMethodsInInclude.length === 0 ||\n customMethodsInInclude.includes(name),\n )\n .filter((name) => !exclude.has(name));\n}\n\nfunction methodDefinition(\n object: Record<string, unknown>,\n action: string,\n): Record<string, unknown> {\n return configObject(configObject(object.methods)[action]);\n}\n\n/**\n * The effective route metadata for one custom action: `@method()` wins field by\n * field over the class-level `api.routes` entry, exactly as the emitters and\n * the knowledge artifact resolve it. Reading the map alone printed the\n * pre-migration verb and path for a class that had moved to the decorator\n * (#2686).\n */\nfunction effectiveRoute(\n object: Record<string, unknown>,\n action: string,\n): { httpMethod?: string; path?: string; scope?: string } {\n return resolveEffectiveActionMetadata({\n actionName: action,\n method: methodDefinition(object, action),\n apiConfig: configObject(object.decoratorConfig).api,\n });\n}\n\nfunction customRouteMethod(\n object: Record<string, unknown>,\n action: string,\n): string {\n return effectiveRoute(object, action).httpMethod || 'POST';\n}\n\n/**\n * The scope the emitters will actually route under.\n *\n * NOT `resolveEffectiveActionMetadata(...).scope`, which returns the raw\n * declaration: a `scope` is a declaration about a method, never a relocation of\n * it, and `resolveCustomActionMetadata` is what collapses a contradicting one\n * back onto the executable receiver. Reading the raw value printed the\n * collection URL for a route emitted under `[id]` — and, with no declaration at\n * all, printed `{id}` for every instance action on a COLLECTION class, whose\n * host makes it collection-scoped (#2686).\n */\nfunction effectiveScope(\n object: Record<string, unknown>,\n action: string,\n): 'item' | 'collection' {\n const method = methodDefinition(object, action);\n const isCollectionClass =\n stringValue(object.extends) === 'SmrtCollection' ||\n object.extendsTypeArg !== undefined;\n const defaultScope: 'item' | 'collection' =\n isCollectionClass || method.isStatic === true ? 'collection' : 'item';\n try {\n return resolveCustomActionMetadata({\n actionName: action,\n method,\n apiConfig: configObject(object.decoratorConfig).api,\n defaultScope,\n }).scope;\n } catch {\n // The shared resolver validates as it resolves; one malformed action must\n // not fail a whole discovery pass, and a declaration cannot change the\n // receiver anyway.\n return defaultScope;\n }\n}\n\nfunction customRoutePath(\n object: Record<string, unknown>,\n action: string,\n): string {\n const collection =\n stringValue(object.collection) || stringValue(object.name) || action;\n const configuredPath = effectiveRoute(object, action).path || action;\n const normalizedPath = configuredPath\n .split('/')\n .map((segment) => segment.trim())\n .filter(Boolean)\n .join('/')\n .replace(/\\[([^\\]]+)\\]/g, '{$1}');\n\n return effectiveScope(object, action) === 'collection'\n ? `/api/v1/${collection}/${normalizedPath}`\n : `/api/v1/${collection}/{id}/${normalizedPath}`;\n}\n\n/**\n * Exported for the parity test that pins this summary against the framework's\n * own `resolveApiActionSet`. This is a published agent-facing discovery\n * artifact, so \"the workbench and the route emitters agree\" has to be a test,\n * not a convention (#2686).\n */\nexport function restEndpointsFrom(\n object: Record<string, unknown>,\n isModelClassName?: (name: string) => boolean,\n): WorkbenchRestEndpointSummary[] {\n const className =\n stringValue(object.className) || stringValue(object.name) || 'Object';\n const collection = stringValue(object.collection) || className.toLowerCase();\n const apiConfig = configObject(object.decoratorConfig).api;\n const endpoints: WorkbenchRestEndpointSummary[] = [];\n\n const crudActions =\n stringValue(object.extends) === 'SmrtCollection'\n ? []\n : enabledCrudActions(apiConfig);\n for (const action of crudActions) {\n const route =\n action === 'list'\n ? ['GET', `/api/v1/${collection}`, `List ${className} objects`]\n : action === 'create'\n ? ['POST', `/api/v1/${collection}`, `Create ${className}`]\n : action === 'get'\n ? ['GET', `/api/v1/${collection}/{id}`, `Get ${className} by ID`]\n : action === 'update'\n ? ['PUT', `/api/v1/${collection}/{id}`, `Update ${className}`]\n : ['DELETE', `/api/v1/${collection}/{id}`, `Delete ${className}`];\n\n endpoints.push({\n objectName: className,\n action,\n method: route[0],\n path: route[1],\n description: route[2],\n parameters: restCrudParameters(object, action, route[1]),\n });\n }\n\n for (const action of enabledCustomActions(object, 'api', isModelClassName)) {\n const method = customRouteMethod(object, action);\n endpoints.push({\n objectName: className,\n action,\n method,\n path: customRoutePath(object, action),\n description: `Run ${className}.${action}`,\n parameters: restCustomParameters(\n object,\n action,\n method,\n customRoutePath(object, action),\n ),\n });\n }\n\n return endpoints;\n}\n\nfunction cliCommandsFrom(\n object: Record<string, unknown>,\n): WorkbenchCliCommandSummary[] {\n const className =\n stringValue(object.className) || stringValue(object.name) || 'Object';\n const lowerName = className.toLowerCase();\n const cliConfig = configObject(object.decoratorConfig).cli;\n const commands: WorkbenchCliCommandSummary[] = [];\n\n for (const action of enabledCrudActions(cliConfig)) {\n const description =\n action === 'list'\n ? `List ${className} objects`\n : action === 'get'\n ? `Get ${className} by ID or slug`\n : action === 'create'\n ? `Create new ${className}`\n : action === 'update'\n ? `Update ${className}`\n : `Delete ${className}`;\n\n commands.push({\n objectName: className,\n action,\n command: `${lowerName}:${action}`,\n description,\n parameters: cliCrudParameters(object, action),\n });\n }\n\n for (const action of enabledCustomActions(object, 'cli')) {\n commands.push({\n objectName: className,\n action,\n command: `${lowerName}:${action}`,\n description: `Run ${className}.${action}`,\n parameters: cliCustomParameters(object, action),\n });\n }\n\n return commands;\n}\n\nfunction mcpToolsFrom(\n object: Record<string, unknown>,\n): WorkbenchMcpToolSummary[] {\n const className =\n stringValue(object.className) || stringValue(object.name) || 'Object';\n const lowerName = className.toLowerCase();\n const mcpConfig = configObject(object.decoratorConfig).mcp;\n const tools: WorkbenchMcpToolSummary[] = [];\n\n for (const action of enabledCrudActions(mcpConfig)) {\n const description =\n action === 'list'\n ? `List ${className} objects with optional filtering`\n : action === 'get'\n ? `Get a specific ${className} by ID or slug`\n : action === 'create'\n ? `Create a new ${className}`\n : action === 'update'\n ? `Update an existing ${className}`\n : `Delete a ${className} by ID`;\n\n tools.push({\n objectName: className,\n action,\n toolName: `${lowerName}_${action}`,\n description,\n parameters: mcpCrudParameters(object, action),\n });\n }\n\n for (const action of enabledCustomActions(object, 'mcp')) {\n tools.push({\n objectName: className,\n action,\n toolName: `${lowerName}_${action}`.toLowerCase(),\n description: `Execute ${action} action on ${className}`,\n parameters: mcpCustomParameters(object, action),\n });\n }\n\n return tools;\n}\n\nfunction readApiSummary(\n packageDir: string,\n rootDir: string,\n packageName: string,\n knowledge: WorkbenchKnowledgeSummary,\n routeFiles: string[],\n): WorkbenchApiSummary {\n const manifest = knowledge.manifestPath\n ? readJsonIfExists<Record<string, unknown>>(knowledge.manifestPath)\n : null;\n const objectRecords = objectRecordsFrom(manifest?.objects);\n\n const objects: WorkbenchApiObjectSummary[] = objectRecords.map((object) => {\n const name =\n stringValue(object.className) ||\n stringValue(object.name) ||\n stringValue(object.key) ||\n 'unknown';\n const className = stringValue(object.className) || name;\n const sourcePath = resolveManifestSourcePath(\n rootDir,\n packageDir,\n stringValue(object.filePath) || stringValue(object.sourcePath),\n );\n const typedocPath = findTypedocClassPath(\n rootDir,\n packageDir,\n packageName,\n className,\n );\n const fields = fieldSummariesFrom(object.fields);\n\n return {\n name,\n className,\n qualifiedName: stringValue(object.qualifiedName) || undefined,\n collection: stringValue(object.collection) || undefined,\n sourcePath,\n typedocPath,\n description: readTypedocSummary(typedocPath),\n fields,\n };\n });\n\n const objectNames =\n objects.length > 0\n ? objects\n .map(\n (object) => object.qualifiedName || object.className || object.name,\n )\n .filter(Boolean)\n .sort()\n : knowledge.objectNames;\n // The wire-ability gate needs a class inventory to tell a model instance from\n // an options interface. Without one it half-applies and this summary keeps\n // advertising the `addAsset(asset: Asset)` shape (#2686).\n const isModelClassName = createClassNamePredicate(\n objectRecords.flatMap((record) =>\n [\n stringValue(record.className),\n stringValue(record.name),\n stringValue(record.qualifiedName),\n ].filter((name): name is string => Boolean(name)),\n ),\n );\n const restEndpoints = objectRecords.flatMap((record) =>\n restEndpointsFrom(record, isModelClassName),\n );\n\n return {\n objectNames,\n objects,\n restEndpoints,\n cliCommands: objectRecords.flatMap(cliCommandsFrom),\n mcpTools: objectRecords.flatMap(mcpToolsFrom),\n endpointCount: restEndpoints.length,\n routeFiles,\n };\n}\n\nasync function collectRouteFiles(packageDir: string): Promise<string[]> {\n return fg(['src/routes/**/*.{ts,svelte}', 'routes/**/*.{ts,svelte}'], {\n cwd: packageDir,\n absolute: true,\n onlyFiles: true,\n ignore: ['**/node_modules/**', '**/.svelte-kit/**'],\n });\n}\n\nasync function collectMigrations(packageDir: string): Promise<string[]> {\n return fg(['migrations/**/*', 'src/migrations/**/*'], {\n cwd: packageDir,\n absolute: true,\n onlyFiles: true,\n ignore: ['**/node_modules/**'],\n });\n}\n\nasync function collectExamples(\n packageDir: string,\n docs: WorkbenchDocumentSummary[],\n): Promise<WorkbenchExampleSummary[]> {\n const fileMatches = await fg(\n [\n 'examples/**/*.{ts,tsx,svelte,md}',\n 'src/**/*.{example,stories}.{ts,tsx,svelte}',\n 'src/**/examples/**/*.{ts,tsx,svelte,md}',\n ],\n {\n cwd: packageDir,\n absolute: true,\n onlyFiles: true,\n ignore: ['**/node_modules/**', '**/dist/**', '**/.svelte-kit/**'],\n },\n );\n\n const fileExamples = fileMatches.slice(0, 16).map((path, index) => ({\n id: `file:${index}`,\n title: relative(packageDir, path),\n path,\n source: 'file' as const,\n }));\n\n const readme = docs.find((doc) => doc.kind === 'readme');\n const readmeExamples = readme?.content\n ? extractReadmeCodeBlocks(readme.content).slice(0, 8)\n : [];\n\n return [...fileExamples, ...readmeExamples];\n}\n\nfunction extractReadmeCodeBlocks(content: string): WorkbenchExampleSummary[] {\n const examples: WorkbenchExampleSummary[] = [];\n const blockPattern = /```([A-Za-z0-9_-]*)\\n([\\s\\S]*?)```/g;\n let index = 0;\n let match = blockPattern.exec(content);\n\n while (match) {\n const language = match[1] || undefined;\n const code = match[2] || '';\n if (!code.trim()) {\n match = blockPattern.exec(content);\n continue;\n }\n\n const { content: trimmedCode } = truncate(code, EXAMPLE_LIMIT);\n examples.push({\n id: `readme:${index}`,\n title: `README example ${index + 1}`,\n language,\n code: trimmedCode,\n source: 'readme',\n });\n index += 1;\n match = blockPattern.exec(content);\n }\n\n return examples;\n}\n\nasync function summarizePackage(\n input: WorkbenchPackageDir,\n rootDir: string,\n): Promise<WorkbenchPackageSummary> {\n const { packageDir, packageJson, source } = input;\n const packageName =\n packageJson.name || relative(rootDir, packageDir) || packageDir;\n const docs = [\n readDocument(packageDir, 'README.md', 'readme'),\n readDocument(packageDir, 'AGENTS.md', 'agents'),\n readDocument(packageDir, 'CHANGELOG.md', 'changelog'),\n ].filter((doc): doc is WorkbenchDocumentSummary => Boolean(doc));\n const examples = await collectExamples(packageDir, docs);\n const knowledge = readKnowledgeSummary(packageDir);\n const routeFiles = await collectRouteFiles(packageDir);\n const migrations = await collectMigrations(packageDir);\n const scripts = stringRecord(packageJson.scripts);\n const api = readApiSummary(\n packageDir,\n rootDir,\n packageName,\n knowledge,\n routeFiles,\n );\n\n return {\n name: packageName,\n version: packageJson.version,\n description: packageJson.description,\n source,\n directory: packageDir,\n relativeDirectory: relative(rootDir, packageDir) || '.',\n scripts,\n dependencies: stringRecord(packageJson.dependencies),\n devDependencies: stringRecord(packageJson.devDependencies),\n peerDependencies: stringRecord(packageJson.peerDependencies),\n smrtDependencies: smrtDependencyNames(packageJson),\n sdkDependencies: sdkDependencyNames(packageJson),\n exportKeys: exportKeys(packageJson.exports),\n docs,\n examples,\n knowledge,\n api,\n migrations,\n routeModuleCount: 0,\n routeCount: 0,\n playgroundEntryCount: 0,\n recommendedCommands: Object.keys(scripts)\n .filter((scriptName) =>\n ['test', 'typecheck', 'check', 'build', 'dev', 'workbench'].includes(\n scriptName,\n ),\n )\n .sort()\n .map((scriptName) => ({\n id: commandIdForScript(packageName, scriptName),\n label: scriptName,\n command: `pnpm --filter ${packageName} ${scriptName}`,\n })),\n };\n}\n\nasync function discoverWorkspacePackageDirs(\n workspaceRoot: string,\n): Promise<WorkbenchPackageDir[]> {\n const packageJsonPaths = await fg('packages/*/package.json', {\n cwd: workspaceRoot,\n absolute: true,\n onlyFiles: true,\n });\n\n return packageJsonPaths\n .map((packageJsonPath) => ({\n packageDir: dirname(packageJsonPath),\n packageJson: readJson<PackageJsonLike>(packageJsonPath),\n source: 'workspace' as const,\n }))\n .filter(\n (item) =>\n typeof item.packageJson.name === 'string' &&\n item.packageJson.name.startsWith('@happyvertical/smrt-'),\n )\n .sort((left, right) =>\n (left.packageJson.name || '').localeCompare(right.packageJson.name || ''),\n );\n}\n\nfunction resolveNodeModulePackageDir(\n projectRoot: string,\n packageName: string,\n): string | null {\n const packageJsonPath = join(\n projectRoot,\n 'node_modules',\n packageName,\n 'package.json',\n );\n return existsSync(packageJsonPath) ? dirname(packageJsonPath) : null;\n}\n\nasync function discoverConsumerPackageDirs(\n projectRoot: string,\n): Promise<WorkbenchPackageDir[]> {\n const packageJsonPath = join(projectRoot, 'package.json');\n if (!existsSync(packageJsonPath)) {\n return [];\n }\n\n const packageJson = readJson<PackageJsonLike>(packageJsonPath);\n const dependencies = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n ...packageJson.peerDependencies,\n };\n const packageDirs: WorkbenchPackageDir[] = [];\n\n packageDirs.push({\n packageDir: projectRoot,\n packageJson,\n source: packageJson.name?.startsWith('@happyvertical/smrt-')\n ? 'package'\n : 'app',\n });\n\n for (const dependencyName of Object.keys(dependencies).sort()) {\n if (\n !dependencyName.startsWith('@happyvertical/smrt-') ||\n dependencyName === '@happyvertical/smrt-workbench'\n ) {\n continue;\n }\n\n const packageDir = resolveNodeModulePackageDir(projectRoot, dependencyName);\n if (!packageDir) {\n continue;\n }\n\n packageDirs.push({\n packageDir,\n packageJson: readJson<PackageJsonLike>(join(packageDir, 'package.json')),\n source: 'package',\n });\n }\n\n return packageDirs;\n}\n\nfunction resolvePackageByName(\n workspaceRoot: string,\n packageName: string,\n): string | null {\n const packagesDir = join(workspaceRoot, 'packages');\n if (!existsSync(packagesDir)) {\n return null;\n }\n\n const packageJsonPaths = fg.sync('*/package.json', {\n cwd: packagesDir,\n absolute: true,\n onlyFiles: true,\n });\n\n for (const packageJsonPath of packageJsonPaths) {\n const packageJson = readJson<PackageJsonLike>(packageJsonPath);\n if (packageJson.name === packageName) {\n return dirname(packageJsonPath);\n }\n }\n\n return null;\n}\n\nexport function resolveWorkbenchScope(\n cwd = process.cwd(),\n options: Pick<\n SmrtWorkbenchVitePluginOptions,\n 'projectRoot' | 'workspaceRoot' | 'packageName'\n > = {},\n): WorkbenchScopeResolution {\n const resolvedCwd = resolve(cwd);\n const requestedProjectRoot = options.projectRoot\n ? resolve(options.projectRoot)\n : undefined;\n const workspaceRoot =\n options.workspaceRoot ||\n (requestedProjectRoot\n ? findSmrtWorkbenchWorkspaceRoot(requestedProjectRoot)\n : null) ||\n findSmrtWorkbenchWorkspaceRoot(resolvedCwd);\n\n if (workspaceRoot) {\n const packageDir =\n (options.packageName\n ? resolvePackageByName(workspaceRoot, options.packageName)\n : null) ||\n findPackageDir(resolvedCwd, workspaceRoot) ||\n undefined;\n const packageJson = packageDir\n ? readJsonIfExists<PackageJsonLike>(join(packageDir, 'package.json'))\n : null;\n const packageName = options.packageName || packageJson?.name;\n const mode: SmrtWorkbenchScopeMode = packageName ? 'package' : 'workspace';\n\n return {\n mode,\n cwd: resolvedCwd,\n projectRoot: workspaceRoot,\n workspaceRoot,\n packageName,\n packageDir,\n packageManager: 'pnpm',\n };\n }\n\n const projectRoot = requestedProjectRoot || findProjectRoot(resolvedCwd);\n return {\n mode: 'consumer',\n cwd: resolvedCwd,\n projectRoot,\n packageName: options.packageName,\n packageManager: detectPackageManager(projectRoot),\n };\n}\n\nexport async function buildWorkbenchProject(\n scope: WorkbenchScopeResolution,\n): Promise<SmrtWorkbenchProject> {\n const packageDirs =\n scope.mode === 'consumer'\n ? await discoverConsumerPackageDirs(scope.projectRoot)\n : await discoverWorkspacePackageDirs(scope.projectRoot);\n\n const filteredPackageDirs = scope.packageName\n ? packageDirs.filter((item) => item.packageJson.name === scope.packageName)\n : packageDirs;\n\n const packages = await Promise.all(\n filteredPackageDirs.map((item) =>\n summarizePackage(item, scope.projectRoot),\n ),\n );\n\n return {\n generatedAt: new Date().toISOString(),\n scope,\n packages,\n };\n}\n\nexport async function discoverWorkspaceWorkbenches(\n workspaceRoot: string,\n packagesPattern = 'packages/*/src/workbench.ts',\n): Promise<DiscoveredWorkbenchTarget[]> {\n const matches = await fg(packagesPattern, {\n cwd: workspaceRoot,\n absolute: true,\n onlyFiles: true,\n });\n\n return matches.sort().map((sourcePath) => {\n const packageDir = dirname(dirname(sourcePath));\n const packageJsonPath = join(packageDir, 'package.json');\n const packageJson = readJson<PackageJsonLike>(packageJsonPath);\n const runtimePath = join(packageDir, 'dist', 'workbench.js');\n\n return {\n packageName: packageJson.name,\n source: 'workspace' as const,\n sourcePath,\n runtimePath: existsSync(runtimePath) ? runtimePath : undefined,\n };\n });\n}\n\nexport async function discoverInstalledWorkbenches(\n projectRoot = process.cwd(),\n): Promise<DiscoveredWorkbenchTarget[]> {\n const packageJsonPath = join(projectRoot, 'package.json');\n if (!existsSync(packageJsonPath)) {\n return [];\n }\n\n const packageJson = readJson<PackageJsonLike>(packageJsonPath);\n const dependencies = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n ...packageJson.peerDependencies,\n };\n const discovered: DiscoveredWorkbenchTarget[] = [];\n\n for (const dependencyName of Object.keys(dependencies).sort()) {\n if (\n !dependencyName.startsWith('@happyvertical/smrt-') ||\n dependencyName === '@happyvertical/smrt-workbench'\n ) {\n continue;\n }\n\n const packageDir = resolveNodeModulePackageDir(projectRoot, dependencyName);\n if (!packageDir) {\n continue;\n }\n\n const dependencyPackageJson = readJson<PackageJsonLike>(\n join(packageDir, 'package.json'),\n );\n if (exportKeys(dependencyPackageJson.exports).includes('./workbench')) {\n discovered.push({\n packageName: dependencyName,\n source: 'package',\n importSpecifier: `${dependencyName}/workbench`,\n });\n }\n }\n\n return discovered;\n}\n\nexport async function discoverWorkbenchTargets(\n projectRoot = process.cwd(),\n mode: 'auto' | 'workspace' | 'consumer' = 'auto',\n localWorkbenchPath = 'src/workbench.ts',\n packageName?: string,\n packagesPattern = 'packages/*/src/workbench.ts',\n): Promise<DiscoveredWorkbenchTarget[]> {\n const effectiveMode =\n mode === 'auto' ? detectWorkbenchMode(projectRoot) : mode;\n\n if (effectiveMode === 'workspace') {\n const workspaceRoot =\n mode === 'workspace'\n ? findWorkspaceRoot(projectRoot)\n : findSmrtWorkbenchWorkspaceRoot(projectRoot);\n if (!workspaceRoot) {\n return [];\n }\n\n const targets = await discoverWorkspaceWorkbenches(\n workspaceRoot,\n packagesPattern,\n );\n return packageName\n ? targets.filter((target) => target.packageName === packageName)\n : targets;\n }\n\n const targets = await discoverInstalledWorkbenches(projectRoot);\n const localPath = resolve(projectRoot, localWorkbenchPath);\n if (existsSync(localPath)) {\n const localPackageJson = readJsonIfExists<PackageJsonLike>(\n join(projectRoot, 'package.json'),\n );\n targets.push({\n packageName: localPackageJson?.name,\n source: 'app',\n sourcePath: localPath,\n });\n }\n\n return packageName\n ? targets.filter((target) => target.packageName === packageName)\n : targets;\n}\n\nexport async function importWorkbenchModule(\n input: string,\n): Promise<SmrtWorkbenchModule[]> {\n const imported =\n isAbsolute(input) || input.startsWith('.')\n ? await importPathModule(resolve(input))\n : await import(/* @vite-ignore */ input);\n\n const module = imported.default ?? imported.workbench ?? imported;\n return module && typeof module === 'object'\n ? coerceWorkbenchModules(module as SmrtWorkbenchModule)\n : [];\n}\n\nasync function importPathModule(inputPath: string): Promise<unknown> {\n if (!TS_SOURCE_EXTENSIONS.has(extname(inputPath))) {\n return import(/* @vite-ignore */ pathToFileURL(inputPath).href);\n }\n\n let tsxApiPath: string;\n try {\n tsxApiPath = require.resolve('tsx/esm/api');\n } catch (tsxError) {\n throw new Error(\n `Failed to load workbench module from ${inputPath}: source workbench discovery requires the \"tsx\" package.`,\n { cause: tsxError },\n );\n }\n\n const { tsImport } = await import(\n /* @vite-ignore */ pathToFileURL(tsxApiPath).href\n );\n return tsImport(pathToFileURL(inputPath).href, {\n parentURL: import.meta.url,\n });\n}\n\nexport function describeWorkbenchSource(\n target: DiscoveredWorkbenchTarget,\n cwd = process.cwd(),\n): string {\n if (target.source === 'package') {\n return target.importSpecifier || target.packageName || 'installed package';\n }\n\n const path = target.sourcePath || target.runtimePath;\n return path ? relative(cwd, path) || '.' : target.source;\n}\n"],"mappings":"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AG,cACL;CAGF,OAAO;EACL;GACE,MAAM;GACN,MAAM;GACN,UAAU;GACV,UAAU;GACV,aAAa;EACf;EACA;GACE,MAAM;GACN,MAAM;GACN,UAAU;GACV,UAAU;GACV,aAAa;EACf;EACA,GAAG;CACL;AACF;AAEA,SAAS,oBACP,QACA,QACgC;CAShC,OAAO,CACL;EACE,MAAM;EACN,MAAM;EACN,UAAU;EACV,UAAU;EACV,aACE;CACJ,GACA,GAjBa,yBAAyB,QAAQ,QAAQ,QAAQ,CAAA,CAAE,KAC/D,WAAW;EACV,GAAG;EACH,MAAM,KAAK,MAAM;EACjB,UAAU;CACZ,EAYG,CACL;AACF;AAEA,SAAS,kBACP,QACA,QACgC;CAChC,IAAI,WAAW,QACb,OAAO;EACL;GACE,MAAM;GACN,MAAM;GACN,UAAU;GACV,UAAU;GACV,aAAa;GACb,cAAc;EAChB;EACA;GACE,MAAM;GACN,MAAM;GACN,UAAU;GACV,UAAU;GACV,aAAa;GACb,cAAc;EAChB;EACA;GACE,MAAM;GACN,MAAM;GACN,UAAU;GACV,UAAU;GACV,aAAa;EACf;EACA;GACE,MAAM;GACN,MAAM;GACN,UAAU;GACV,UAAU;GACV,aAAa;EACf;CACF;CAGF,IAAI,WAAW,OACb,OAAO,CACL;EACE,MAAM;EACN,MAAM;EACN,UAAU;EACV,UAAU;EACV,aAAa;CACf,GACA;EACE,MAAM;EACN,MAAM;EACN,UAAU;EACV,UAAU;EACV,aAAa;CACf,CACF;CAGF,IAAI,WAAW,UACb,OAAO,CACL;EACE,MAAM;EACN,MAAM;EACN,UAAU;EACV,UAAU;EACV,aAAa;CACf,CACF;CAGF,IAAI,WAAW,UACb,OAAO,wBAAwB,QAAQ,SAAS,OAAO;CAGzD,OAAO,CACL;EACE,MAAM;EACN,MAAM;EACN,UAAU;EACV,UAAU;EACV,aAAa;CACf,GACA,GAAG,wBAAwB,QAAQ,SAAS,UAAU,CACxD;AACF;AAEA,SAAS,oBACP,SACA,SACgC;CAChC,OAAO,CACL;EACE,MAAM;EACN,MAAM;EACN,UAAU;EACV,UAAU;EACV,aAAa;CACf,GACA;EACE,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"}
@@ -1,9 +1,16 @@
1
- import { DiscoveredWorkbenchTarget, SmrtWorkbenchModule, SmrtWorkbenchProject, SmrtWorkbenchVitePluginOptions, WorkbenchScopeResolution } from './types.js';
1
+ import { DiscoveredWorkbenchTarget, SmrtWorkbenchModule, SmrtWorkbenchProject, SmrtWorkbenchVitePluginOptions, WorkbenchRestEndpointSummary, WorkbenchScopeResolution } from './types.js';
2
2
  export declare function findWorkspaceRoot(startDir?: string): string | null;
3
3
  export declare function findSmrtWorkbenchWorkspaceRoot(startDir?: string): string | null;
4
4
  export declare function findProjectRoot(startDir?: string): string;
5
5
  export declare function findPackageDir(startDir?: string, workspaceRoot?: string): string | null;
6
6
  export declare function detectWorkbenchMode(projectRoot?: string): 'workspace' | 'consumer';
7
+ /**
8
+ * Exported for the parity test that pins this summary against the framework's
9
+ * own `resolveApiActionSet`. This is a published agent-facing discovery
10
+ * artifact, so "the workbench and the route emitters agree" has to be a test,
11
+ * not a convention (#2686).
12
+ */
13
+ export declare function restEndpointsFrom(object: Record<string, unknown>, isModelClassName?: (name: string) => boolean): WorkbenchRestEndpointSummary[];
7
14
  export declare function resolveWorkbenchScope(cwd?: string, options?: Pick<SmrtWorkbenchVitePluginOptions, 'projectRoot' | 'workspaceRoot' | 'packageName'>): WorkbenchScopeResolution;
8
15
  export declare function buildWorkbenchProject(scope: WorkbenchScopeResolution): Promise<SmrtWorkbenchProject>;
9
16
  export declare function discoverWorkspaceWorkbenches(workspaceRoot: string, packagesPattern?: string): Promise<DiscoveredWorkbenchTarget[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,yBAAyB,EACzB,mBAAmB,EACnB,oBAAoB,EAEpB,8BAA8B,EAa9B,wBAAwB,EACzB,MAAM,YAAY,CAAC;AA0BpB,wBAAgB,iBAAiB,CAAC,QAAQ,SAAgB,GAAG,MAAM,GAAG,IAAI,CAczE;AAED,wBAAgB,8BAA8B,CAC5C,QAAQ,SAAgB,GACvB,MAAM,GAAG,IAAI,CAef;AAED,wBAAgB,eAAe,CAAC,QAAQ,SAAgB,GAAG,MAAM,CAchE;AAED,wBAAgB,cAAc,CAC5B,QAAQ,SAAgB,EACxB,aAAa,CAAC,EAAE,MAAM,GACrB,MAAM,GAAG,IAAI,CAoBf;AAED,wBAAgB,mBAAmB,CACjC,WAAW,SAAgB,GAC1B,WAAW,GAAG,UAAU,CAE1B;AA01CD,wBAAgB,qBAAqB,CACnC,GAAG,SAAgB,EACnB,OAAO,GAAE,IAAI,CACX,8BAA8B,EAC9B,aAAa,GAAG,eAAe,GAAG,aAAa,CAC3C,GACL,wBAAwB,CA4C1B;AAED,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,oBAAoB,CAAC,CAqB/B;AAED,wBAAsB,4BAA4B,CAChD,aAAa,EAAE,MAAM,EACrB,eAAe,SAAgC,GAC9C,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAoBtC;AAED,wBAAsB,4BAA4B,CAChD,WAAW,SAAgB,GAC1B,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAwCtC;AAED,wBAAsB,wBAAwB,CAC5C,WAAW,SAAgB,EAC3B,IAAI,GAAE,MAAM,GAAG,WAAW,GAAG,UAAmB,EAChD,kBAAkB,SAAqB,EACvC,WAAW,CAAC,EAAE,MAAM,EACpB,eAAe,SAAgC,GAC9C,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAsCtC;AAED,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAUhC;AAyBD,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,yBAAyB,EACjC,GAAG,SAAgB,GAClB,MAAM,CAOR"}
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EACV,yBAAyB,EACzB,mBAAmB,EACnB,oBAAoB,EAEpB,8BAA8B,EAY9B,4BAA4B,EAC5B,wBAAwB,EACzB,MAAM,YAAY,CAAC;AA0BpB,wBAAgB,iBAAiB,CAAC,QAAQ,SAAgB,GAAG,MAAM,GAAG,IAAI,CAczE;AAED,wBAAgB,8BAA8B,CAC5C,QAAQ,SAAgB,GACvB,MAAM,GAAG,IAAI,CAef;AAED,wBAAgB,eAAe,CAAC,QAAQ,SAAgB,GAAG,MAAM,CAchE;AAED,wBAAgB,cAAc,CAC5B,QAAQ,SAAgB,EACxB,aAAa,CAAC,EAAE,MAAM,GACrB,MAAM,GAAG,IAAI,CAoBf;AAED,wBAAgB,mBAAmB,CACjC,WAAW,SAAgB,GAC1B,WAAW,GAAG,UAAU,CAE1B;AA48BD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GAC3C,4BAA4B,EAAE,CAmDhC;AAoaD,wBAAgB,qBAAqB,CACnC,GAAG,SAAgB,EACnB,OAAO,GAAE,IAAI,CACX,8BAA8B,EAC9B,aAAa,GAAG,eAAe,GAAG,aAAa,CAC3C,GACL,wBAAwB,CA4C1B;AAED,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,oBAAoB,CAAC,CAqB/B;AAED,wBAAsB,4BAA4B,CAChD,aAAa,EAAE,MAAM,EACrB,eAAe,SAAgC,GAC9C,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAoBtC;AAED,wBAAsB,4BAA4B,CAChD,WAAW,SAAgB,GAC1B,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAwCtC;AAED,wBAAsB,wBAAwB,CAC5C,WAAW,SAAgB,EAC3B,IAAI,GAAE,MAAM,GAAG,WAAW,GAAG,UAAmB,EAChD,kBAAkB,SAAqB,EACvC,WAAW,CAAC,EAAE,MAAM,EACpB,eAAe,SAAgC,GAC9C,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAsCtC;AAED,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAUhC;AAyBD,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,yBAAyB,EACjC,GAAG,SAAgB,GAClB,MAAM,CAOR"}
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import { a as normalizeWorkbenchModule, i as mergeWorkbenchModules, n as defineWorkbenchModule, o as qualifyWorkbenchRouteId, t as coerceWorkbenchModules } from "./chunks/runtime-BTiu5fuP.js";
2
- import { a as discoverWorkbenchTargets, c as findProjectRoot, d as importWorkbenchModule, f as resolveWorkbenchScope, i as discoverInstalledWorkbenches, l as findSmrtWorkbenchWorkspaceRoot, n as describeWorkbenchSource, o as discoverWorkspaceWorkbenches, r as detectWorkbenchMode, s as findPackageDir, t as buildWorkbenchProject, u as findWorkspaceRoot } from "./chunks/discovery-G9-foyW8.js";
2
+ import { a as discoverWorkbenchTargets, c as findProjectRoot, d as importWorkbenchModule, f as resolveWorkbenchScope, i as discoverInstalledWorkbenches, l as findSmrtWorkbenchWorkspaceRoot, n as describeWorkbenchSource, o as discoverWorkspaceWorkbenches, r as detectWorkbenchMode, s as findPackageDir, t as buildWorkbenchProject, u as findWorkspaceRoot } from "./chunks/discovery-BOoinKLR.js";
3
3
  export { buildWorkbenchProject, coerceWorkbenchModules, defineWorkbenchModule, describeWorkbenchSource, detectWorkbenchMode, discoverInstalledWorkbenches, discoverWorkbenchTargets, discoverWorkspaceWorkbenches, findPackageDir, findProjectRoot, findSmrtWorkbenchWorkspaceRoot, findWorkspaceRoot, importWorkbenchModule, mergeWorkbenchModules, normalizeWorkbenchModule, qualifyWorkbenchRouteId, resolveWorkbenchScope };
package/dist/vite.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as discoverWorkbenchTargets, f as resolveWorkbenchScope, r as detectWorkbenchMode, t as buildWorkbenchProject, u as findWorkspaceRoot } from "./chunks/discovery-G9-foyW8.js";
1
+ import { a as discoverWorkbenchTargets, f as resolveWorkbenchScope, r as detectWorkbenchMode, t as buildWorkbenchProject, u as findWorkspaceRoot } from "./chunks/discovery-BOoinKLR.js";
2
2
  import { existsSync, readFileSync } from "node:fs";
3
3
  import { dirname, isAbsolute, join, resolve } from "node:path";
4
4
  import fg from "fast-glob";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-workbench",
3
- "version": "0.46.0",
3
+ "version": "0.47.1",
4
4
  "smrtJsdoc": "strict",
5
5
  "description": "Shared SMRT package and project workbench",
6
6
  "type": "module",
@@ -42,16 +42,17 @@
42
42
  }
43
43
  },
44
44
  "dependencies": {
45
+ "@happyvertical/smrt-core": "0.47.1",
46
+ "@happyvertical/smrt-playground": "0.47.1",
47
+ "@happyvertical/smrt-svelte": "0.47.1",
48
+ "@happyvertical/smrt-ui": "0.47.1",
45
49
  "@sveltejs/adapter-static": "^3.0.10",
46
50
  "@sveltejs/kit": "^2.69.1",
47
51
  "@sveltejs/vite-plugin-svelte": "^7.1.2",
48
52
  "fast-glob": "3.3.3",
49
53
  "svelte": "^5.56.4",
50
54
  "tsx": "^4.23.0",
51
- "vite": "^8.1.3",
52
- "@happyvertical/smrt-playground": "0.46.0",
53
- "@happyvertical/smrt-svelte": "0.46.0",
54
- "@happyvertical/smrt-ui": "0.46.0"
55
+ "vite": "^8.1.3"
55
56
  },
56
57
  "peerDependencies": {
57
58
  "svelte": "^5.56.4",
package/src/discovery.ts CHANGED
@@ -9,6 +9,21 @@ import {
9
9
  resolve,
10
10
  } from 'node:path';
11
11
  import { pathToFileURL } from 'node:url';
12
+ // The leaf `/generators/custom-action` subpath — not the package root, and not
13
+ // the `/generators` barrel, which value-re-exports `MCPGenerator` and so reaches
14
+ // `SmrtCollection` -> `SmrtObject` -> `SmrtClass` and its module-scope
15
+ // `@happyvertical/ai` / `@happyvertical/sql` imports. Measured over `dist`:
16
+ // this subpath is 2 modules with no `@happyvertical` external, the barrel is
17
+ // 109 with the full AI/SQL surface, the root 151. `custom-action`'s only runtime
18
+ // import is `tools/tool-generator`, whose own imports are type-only, which is
19
+ // what keeps it a leaf — a build-time discovery helper should load none of the
20
+ // rest (#2686).
21
+ import {
22
+ createClassNamePredicate,
23
+ resolveApiMethodExposure,
24
+ resolveCustomActionMetadata,
25
+ resolveEffectiveActionMetadata,
26
+ } from '@happyvertical/smrt-core/generators/custom-action';
12
27
  import fg from 'fast-glob';
13
28
  import { coerceWorkbenchModules } from './runtime.js';
14
29
  import type {
@@ -965,6 +980,7 @@ function publicCustomMethodNames(object: Record<string, unknown>): string[] {
965
980
  function enabledCustomActions(
966
981
  object: Record<string, unknown>,
967
982
  surface: 'api' | 'cli' | 'mcp',
983
+ isModelClassName?: (name: string) => boolean,
968
984
  ): string[] {
969
985
  const decoratorConfig = configObject(object.decoratorConfig);
970
986
  const surfaceConfig = decoratorConfig[surface];
@@ -983,10 +999,29 @@ function enabledCustomActions(
983
999
  .filter((name) => !exclude.has(name));
984
1000
  }
985
1001
 
1002
+ // `api` reads the framework's ONE exposure resolver rather than a local copy
1003
+ // of the include/exclude rule. This summary is an agent-facing discovery
1004
+ // artifact, so a stale copy advertises endpoints the route emitters never
1005
+ // wrote -- the wire-ability gate, the framework-lifecycle exclusion, and
1006
+ // `@method({ expose })` all decide here too (#2686). `cli`/`mcp` keep their
1007
+ // own projection; #2692 owns those defaults.
986
1008
  if (surface === 'api') {
987
- return publicMethods
988
- .filter((name) => include.length === 0 || include.includes(name))
989
- .filter((name) => !exclude.has(name));
1009
+ const methods = configObject(object.methods);
1010
+ const isCollectionClass =
1011
+ stringValue(object.extends) === 'SmrtCollection' ||
1012
+ object.extendsTypeArg !== undefined;
1013
+ return Object.keys(methods)
1014
+ .sort()
1015
+ .filter(
1016
+ (name) =>
1017
+ resolveApiMethodExposure({
1018
+ actionName: name,
1019
+ method: configObject(methods[name]),
1020
+ apiConfig: decoratorConfig.api,
1021
+ isCollectionClass,
1022
+ ...(isModelClassName ? { isModelClassName } : {}),
1023
+ }).exposed,
1024
+ );
990
1025
  }
991
1026
 
992
1027
  const customMethodsInInclude = include.filter(
@@ -1001,24 +1036,72 @@ function enabledCustomActions(
1001
1036
  .filter((name) => !exclude.has(name));
1002
1037
  }
1003
1038
 
1004
- function routeOverrides(
1039
+ function methodDefinition(
1005
1040
  object: Record<string, unknown>,
1006
- ): Record<string, Record<string, unknown>> {
1007
- const apiConfig = configObject(configObject(object.decoratorConfig).api);
1008
- const routes = configObject(apiConfig.routes);
1041
+ action: string,
1042
+ ): Record<string, unknown> {
1043
+ return configObject(configObject(object.methods)[action]);
1044
+ }
1009
1045
 
1010
- return Object.fromEntries(
1011
- Object.entries(routes).filter(
1012
- (entry): entry is [string, Record<string, unknown>] => isRecord(entry[1]),
1013
- ),
1014
- );
1046
+ /**
1047
+ * The effective route metadata for one custom action: `@method()` wins field by
1048
+ * field over the class-level `api.routes` entry, exactly as the emitters and
1049
+ * the knowledge artifact resolve it. Reading the map alone printed the
1050
+ * pre-migration verb and path for a class that had moved to the decorator
1051
+ * (#2686).
1052
+ */
1053
+ function effectiveRoute(
1054
+ object: Record<string, unknown>,
1055
+ action: string,
1056
+ ): { httpMethod?: string; path?: string; scope?: string } {
1057
+ return resolveEffectiveActionMetadata({
1058
+ actionName: action,
1059
+ method: methodDefinition(object, action),
1060
+ apiConfig: configObject(object.decoratorConfig).api,
1061
+ });
1015
1062
  }
1016
1063
 
1017
- function methodDefinition(
1064
+ function customRouteMethod(
1018
1065
  object: Record<string, unknown>,
1019
1066
  action: string,
1020
- ): Record<string, unknown> {
1021
- return configObject(configObject(object.methods)[action]);
1067
+ ): string {
1068
+ return effectiveRoute(object, action).httpMethod || 'POST';
1069
+ }
1070
+
1071
+ /**
1072
+ * The scope the emitters will actually route under.
1073
+ *
1074
+ * NOT `resolveEffectiveActionMetadata(...).scope`, which returns the raw
1075
+ * declaration: a `scope` is a declaration about a method, never a relocation of
1076
+ * it, and `resolveCustomActionMetadata` is what collapses a contradicting one
1077
+ * back onto the executable receiver. Reading the raw value printed the
1078
+ * collection URL for a route emitted under `[id]` — and, with no declaration at
1079
+ * all, printed `{id}` for every instance action on a COLLECTION class, whose
1080
+ * host makes it collection-scoped (#2686).
1081
+ */
1082
+ function effectiveScope(
1083
+ object: Record<string, unknown>,
1084
+ action: string,
1085
+ ): 'item' | 'collection' {
1086
+ const method = methodDefinition(object, action);
1087
+ const isCollectionClass =
1088
+ stringValue(object.extends) === 'SmrtCollection' ||
1089
+ object.extendsTypeArg !== undefined;
1090
+ const defaultScope: 'item' | 'collection' =
1091
+ isCollectionClass || method.isStatic === true ? 'collection' : 'item';
1092
+ try {
1093
+ return resolveCustomActionMetadata({
1094
+ actionName: action,
1095
+ method,
1096
+ apiConfig: configObject(object.decoratorConfig).api,
1097
+ defaultScope,
1098
+ }).scope;
1099
+ } catch {
1100
+ // The shared resolver validates as it resolves; one malformed action must
1101
+ // not fail a whole discovery pass, and a declaration cannot change the
1102
+ // receiver anyway.
1103
+ return defaultScope;
1104
+ }
1022
1105
  }
1023
1106
 
1024
1107
  function customRoutePath(
@@ -1027,26 +1110,28 @@ function customRoutePath(
1027
1110
  ): string {
1028
1111
  const collection =
1029
1112
  stringValue(object.collection) || stringValue(object.name) || action;
1030
- const routeConfig = routeOverrides(object)[action] || {};
1031
- const method = methodDefinition(object, action);
1032
- const configuredPath = stringValue(routeConfig.path) || action;
1113
+ const configuredPath = effectiveRoute(object, action).path || action;
1033
1114
  const normalizedPath = configuredPath
1034
1115
  .split('/')
1035
1116
  .map((segment) => segment.trim())
1036
1117
  .filter(Boolean)
1037
1118
  .join('/')
1038
1119
  .replace(/\[([^\]]+)\]/g, '{$1}');
1039
- const scope =
1040
- stringValue(routeConfig.scope) ||
1041
- (method.isStatic === true ? 'collection' : 'item');
1042
1120
 
1043
- return scope === 'collection'
1121
+ return effectiveScope(object, action) === 'collection'
1044
1122
  ? `/api/v1/${collection}/${normalizedPath}`
1045
1123
  : `/api/v1/${collection}/{id}/${normalizedPath}`;
1046
1124
  }
1047
1125
 
1048
- function restEndpointsFrom(
1126
+ /**
1127
+ * Exported for the parity test that pins this summary against the framework's
1128
+ * own `resolveApiActionSet`. This is a published agent-facing discovery
1129
+ * artifact, so "the workbench and the route emitters agree" has to be a test,
1130
+ * not a convention (#2686).
1131
+ */
1132
+ export function restEndpointsFrom(
1049
1133
  object: Record<string, unknown>,
1134
+ isModelClassName?: (name: string) => boolean,
1050
1135
  ): WorkbenchRestEndpointSummary[] {
1051
1136
  const className =
1052
1137
  stringValue(object.className) || stringValue(object.name) || 'Object';
@@ -1080,10 +1165,8 @@ function restEndpointsFrom(
1080
1165
  });
1081
1166
  }
1082
1167
 
1083
- const overrides = routeOverrides(object);
1084
- for (const action of enabledCustomActions(object, 'api')) {
1085
- const routeConfig = overrides[action] || {};
1086
- const method = stringValue(routeConfig.method) || 'POST';
1168
+ for (const action of enabledCustomActions(object, 'api', isModelClassName)) {
1169
+ const method = customRouteMethod(object, action);
1087
1170
  endpoints.push({
1088
1171
  objectName: className,
1089
1172
  action,
@@ -1241,7 +1324,21 @@ function readApiSummary(
1241
1324
  .filter(Boolean)
1242
1325
  .sort()
1243
1326
  : knowledge.objectNames;
1244
- const restEndpoints = objectRecords.flatMap(restEndpointsFrom);
1327
+ // The wire-ability gate needs a class inventory to tell a model instance from
1328
+ // an options interface. Without one it half-applies and this summary keeps
1329
+ // advertising the `addAsset(asset: Asset)` shape (#2686).
1330
+ const isModelClassName = createClassNamePredicate(
1331
+ objectRecords.flatMap((record) =>
1332
+ [
1333
+ stringValue(record.className),
1334
+ stringValue(record.name),
1335
+ stringValue(record.qualifiedName),
1336
+ ].filter((name): name is string => Boolean(name)),
1337
+ ),
1338
+ );
1339
+ const restEndpoints = objectRecords.flatMap((record) =>
1340
+ restEndpointsFrom(record, isModelClassName),
1341
+ );
1245
1342
 
1246
1343
  return {
1247
1344
  objectNames,
@@ -1 +0,0 @@
1
- {"version":3,"file":"discovery-G9-foyW8.js","names":["targets"],"sources":["../../src/discovery.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { createRequire } from 'node:module';\nimport {\n dirname,\n extname,\n isAbsolute,\n join,\n relative,\n resolve,\n} from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport fg from 'fast-glob';\nimport { coerceWorkbenchModules } from './runtime.js';\nimport type {\n DiscoveredWorkbenchTarget,\n SmrtWorkbenchModule,\n SmrtWorkbenchProject,\n SmrtWorkbenchScopeMode,\n SmrtWorkbenchVitePluginOptions,\n WorkbenchApiObjectFieldSummary,\n WorkbenchApiObjectSummary,\n WorkbenchApiParameterLocation,\n WorkbenchApiParameterSummary,\n WorkbenchApiSummary,\n WorkbenchCliCommandSummary,\n WorkbenchDocumentSummary,\n WorkbenchExampleSummary,\n WorkbenchKnowledgeSummary,\n WorkbenchMcpToolSummary,\n WorkbenchPackageSummary,\n WorkbenchRestEndpointSummary,\n WorkbenchScopeResolution,\n} from './types.js';\nimport { commandIdForScript } from './utils.js';\n\nconst require = createRequire(import.meta.url);\nconst TS_SOURCE_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts']);\nconst DOCUMENT_LIMIT = 20_000;\nconst EXAMPLE_LIMIT = 8_000;\n\ninterface PackageJsonLike {\n name?: string;\n version?: string;\n description?: string;\n scripts?: Record<string, string>;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n exports?: unknown;\n packageManager?: string;\n}\n\ninterface WorkbenchPackageDir {\n packageDir: string;\n packageJson: PackageJsonLike;\n source: 'workspace' | 'package' | 'app';\n}\n\nexport function findWorkspaceRoot(startDir = process.cwd()): string | null {\n let current = resolve(startDir);\n\n while (true) {\n if (existsSync(join(current, 'pnpm-workspace.yaml'))) {\n return current;\n }\n\n const parent = dirname(current);\n if (parent === current) {\n return null;\n }\n current = parent;\n }\n}\n\nexport function findSmrtWorkbenchWorkspaceRoot(\n startDir = process.cwd(),\n): string | null {\n const workspaceRoot = findWorkspaceRoot(startDir);\n if (!workspaceRoot) {\n return null;\n }\n\n const hostPackageJsonPath = join(\n workspaceRoot,\n 'packages',\n 'smrt-workbench',\n 'host',\n 'package.json',\n );\n\n return existsSync(hostPackageJsonPath) ? workspaceRoot : null;\n}\n\nexport function findProjectRoot(startDir = process.cwd()): string {\n let current = resolve(startDir);\n\n while (true) {\n if (existsSync(join(current, 'package.json'))) {\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\nexport function findPackageDir(\n startDir = process.cwd(),\n workspaceRoot?: string,\n): string | null {\n let current = resolve(startDir);\n const boundary = workspaceRoot ? resolve(workspaceRoot) : null;\n\n while (true) {\n if (boundary && current === boundary) {\n return null;\n }\n\n const packageJsonPath = join(current, 'package.json');\n if (existsSync(packageJsonPath)) {\n return current;\n }\n\n const parent = dirname(current);\n if (parent === current) {\n return null;\n }\n current = parent;\n }\n}\n\nexport function detectWorkbenchMode(\n projectRoot = process.cwd(),\n): 'workspace' | 'consumer' {\n return findSmrtWorkbenchWorkspaceRoot(projectRoot) ? 'workspace' : 'consumer';\n}\n\nfunction readJson<T = Record<string, unknown>>(path: string): T {\n return JSON.parse(readFileSync(path, 'utf-8')) as T;\n}\n\nfunction readJsonIfExists<T = Record<string, unknown>>(path: string): T | null {\n return existsSync(path) ? readJson<T>(path) : null;\n}\n\nfunction detectPackageManager(projectRoot: string): 'pnpm' | 'yarn' | 'npm' {\n let current = resolve(projectRoot);\n\n while (true) {\n if (existsSync(join(current, 'pnpm-lock.yaml'))) return 'pnpm';\n if (existsSync(join(current, 'yarn.lock'))) return 'yarn';\n\n const packageManager = readJsonIfExists<PackageJsonLike>(\n join(current, 'package.json'),\n )?.packageManager;\n if (packageManager?.startsWith('pnpm@')) return 'pnpm';\n if (packageManager?.startsWith('yarn@')) return 'yarn';\n if (packageManager?.startsWith('npm@')) return 'npm';\n\n const parent = dirname(current);\n if (parent === current) return 'npm';\n current = parent;\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction stringRecord(value: unknown): Record<string, string> {\n if (!isRecord(value)) {\n return {};\n }\n\n return Object.fromEntries(\n Object.entries(value).filter(\n (entry): entry is [string, string] => typeof entry[1] === 'string',\n ),\n );\n}\n\nfunction countItems(value: unknown): number {\n if (Array.isArray(value)) {\n return value.length;\n }\n if (isRecord(value)) {\n return Object.keys(value).length;\n }\n return 0;\n}\n\nfunction truncate(\n value: string,\n limit: number,\n): {\n content: string;\n truncated: boolean;\n} {\n if (value.length <= limit) {\n return { content: value, truncated: false };\n }\n\n return { content: value.slice(0, limit), truncated: true };\n}\n\nfunction readDocument(\n packageDir: string,\n fileName: string,\n kind: WorkbenchDocumentSummary['kind'],\n): WorkbenchDocumentSummary | null {\n const path = join(packageDir, fileName);\n if (!existsSync(path)) {\n return null;\n }\n\n const { content, truncated } = truncate(\n readFileSync(path, 'utf-8'),\n DOCUMENT_LIMIT,\n );\n return {\n kind,\n title: fileName,\n path,\n content,\n truncated,\n };\n}\n\nfunction exportKeys(exportsField: unknown): string[] {\n if (!exportsField) {\n return [];\n }\n if (typeof exportsField === 'string') {\n return ['.'];\n }\n if (isRecord(exportsField)) {\n return Object.keys(exportsField).sort();\n }\n return [];\n}\n\nfunction dependencyNames(packageJson: PackageJsonLike): string[] {\n return Object.keys({\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n ...packageJson.peerDependencies,\n }).sort();\n}\n\nfunction smrtDependencyNames(packageJson: PackageJsonLike): string[] {\n return dependencyNames(packageJson).filter((name) =>\n name.startsWith('@happyvertical/smrt-'),\n );\n}\n\nfunction sdkDependencyNames(packageJson: PackageJsonLike): string[] {\n return dependencyNames(packageJson).filter(\n (name) =>\n name.startsWith('@happyvertical/') &&\n !name.startsWith('@happyvertical/smrt-'),\n );\n}\n\nfunction readKnowledgeSummary(packageDir: string): WorkbenchKnowledgeSummary {\n const knowledgeCandidates = [\n join(packageDir, '.smrt', 'smrt-knowledge.json'),\n join(packageDir, 'dist', 'smrt-knowledge.json'),\n ];\n const manifestCandidates = [\n join(packageDir, '.smrt', 'manifest.json'),\n join(packageDir, 'dist', 'manifest.json'),\n join(packageDir, 'src', 'manifest', 'manifest.json'),\n ];\n\n const knowledgePath = knowledgeCandidates.find((path) => existsSync(path));\n const manifestPath = manifestCandidates.find((path) => existsSync(path));\n const knowledge = knowledgePath\n ? readJsonIfExists<Record<string, unknown>>(knowledgePath)\n : null;\n const manifest = manifestPath\n ? readJsonIfExists<Record<string, unknown>>(manifestPath)\n : null;\n const knowledgeObjects = knowledge?.objects;\n const manifestObjects = manifest?.objects;\n const objects =\n countItems(knowledgeObjects) > 0 ? knowledgeObjects : manifestObjects;\n const objectNames = objectNamesFrom(objects);\n\n return {\n manifestPath,\n knowledgePath,\n objectCount: countItems(objects),\n relationshipCount:\n countItems(knowledge?.relationshipsV2) ||\n countItems(knowledge?.relationships),\n promptCount: countItems(knowledge?.prompts),\n mcpToolCount: countItems(knowledge?.mcpTools),\n surfaceCount: countItems(knowledge?.surfaces),\n tags: Array.isArray(knowledge?.tags)\n ? knowledge.tags.filter((tag): tag is string => typeof tag === 'string')\n : [],\n risks: Array.isArray(knowledge?.risks)\n ? knowledge.risks.filter(\n (risk): risk is string => typeof risk === 'string',\n )\n : [],\n objectNames,\n };\n}\n\nfunction objectNamesFrom(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value\n .map((item) => {\n if (!isRecord(item)) {\n return null;\n }\n return stringValue(item.qualifiedName) || stringValue(item.name);\n })\n .filter((name): name is string => Boolean(name))\n .sort();\n }\n\n if (isRecord(value)) {\n return Object.keys(value).sort();\n }\n\n return [];\n}\n\nfunction stringValue(value: unknown): string | null {\n return typeof value === 'string' && value.length > 0 ? value : null;\n}\n\nfunction booleanValue(value: unknown): boolean | undefined {\n return typeof value === 'boolean' ? value : undefined;\n}\n\nfunction objectRecordsFrom(value: unknown): Record<string, unknown>[] {\n if (Array.isArray(value)) {\n return value.filter(isRecord);\n }\n\n if (!isRecord(value)) {\n return [];\n }\n\n return Object.entries(value).map(([key, item]) => {\n if (isRecord(item)) {\n return {\n key,\n ...item,\n };\n }\n\n return {\n key,\n name: key,\n };\n });\n}\n\nfunction fieldSummariesFrom(value: unknown): WorkbenchApiObjectFieldSummary[] {\n if (Array.isArray(value)) {\n return value\n .filter(isRecord)\n .map((field) => ({\n name: stringValue(field.name) || 'unknown',\n type: stringValue(field.type) || undefined,\n required: booleanValue(field.required),\n related: stringValue(field.related) || undefined,\n }))\n .filter((field) => field.name !== 'unknown');\n }\n\n if (!isRecord(value)) {\n return [];\n }\n\n return Object.entries(value)\n .map(([name, field]) => {\n const fieldRecord = isRecord(field) ? field : {};\n return {\n name,\n type: stringValue(fieldRecord.type) || undefined,\n required: booleanValue(fieldRecord.required),\n related: stringValue(fieldRecord.related) || undefined,\n };\n })\n .sort((left, right) => left.name.localeCompare(right.name));\n}\n\nfunction resolveManifestSourcePath(\n rootDir: string,\n packageDir: string,\n sourcePath: string | null,\n): string | undefined {\n if (!sourcePath) {\n return undefined;\n }\n\n if (isAbsolute(sourcePath)) {\n return sourcePath;\n }\n\n const rootRelativePath = resolve(rootDir, sourcePath);\n if (existsSync(rootRelativePath)) {\n return rootRelativePath;\n }\n\n return resolve(packageDir, sourcePath);\n}\n\nfunction typedocPackageSlug(packageName: string | undefined): string | null {\n if (!packageName?.startsWith('@happyvertical/smrt-')) {\n return null;\n }\n\n return packageName.replace('@happyvertical/smrt-', '');\n}\n\nfunction findTypedocClassPath(\n rootDir: string,\n packageDir: string,\n packageName: string | undefined,\n className: string,\n): string | undefined {\n const slug = typedocPackageSlug(packageName);\n const candidates = [\n slug\n ? join(\n rootDir,\n 'docs',\n 'content',\n 'api',\n slug,\n 'classes',\n `${className}.md`,\n )\n : null,\n join(packageDir, 'docs', 'classes', `${className}.md`),\n join(packageDir, 'docs', `${className}.md`),\n ].filter((path): path is string => Boolean(path));\n\n return candidates.find((path) => existsSync(path));\n}\n\nfunction extractTypedocSummary(content: string): string | undefined {\n const lines = content.split(/\\r?\\n/);\n const summary: string[] = [];\n let hasSeenTitle = false;\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n if (!hasSeenTitle) {\n if (trimmed.startsWith('# ')) {\n hasSeenTitle = true;\n }\n continue;\n }\n\n if (!trimmed || trimmed.startsWith('Defined in:')) {\n continue;\n }\n if (trimmed.startsWith('## ')) {\n break;\n }\n if (trimmed.startsWith('> ')) {\n continue;\n }\n\n summary.push(trimmed);\n }\n\n const value = summary.join('\\n').trim();\n return value.length > 0 ? value : undefined;\n}\n\nfunction readTypedocSummary(path: string | undefined): string | undefined {\n if (!path) {\n return undefined;\n }\n\n return extractTypedocSummary(readFileSync(path, 'utf-8'));\n}\n\nconst CRUD_ACTIONS = ['list', 'get', 'create', 'update', 'delete'] as const;\nconst SERVER_MANAGED_FIELDS = new Set([\n 'id',\n 'tenantId',\n 'tenant_id',\n 'createdAt',\n 'created_at',\n 'updatedAt',\n 'updated_at',\n]);\n\nfunction arrayOfStrings(value: unknown): string[] {\n return Array.isArray(value)\n ? value.filter((item): item is string => typeof item === 'string')\n : [];\n}\n\nfunction configObject(value: unknown): Record<string, unknown> {\n return isRecord(value) ? value : {};\n}\n\nfunction parameterRequired(\n value: Record<string, unknown>,\n): boolean | undefined {\n if (typeof value.required === 'boolean') {\n return value.required;\n }\n\n const meta = configObject(value._meta);\n return typeof meta.required === 'boolean' ? meta.required : undefined;\n}\n\nfunction parameterDescription(\n value: Record<string, unknown>,\n): string | undefined {\n return (\n stringValue(value.description) ||\n stringValue(configObject(value._meta).description) ||\n undefined\n );\n}\n\nfunction parameterDefaultValue(\n value: Record<string, unknown>,\n): string | undefined {\n if (!Object.hasOwn(value, 'default')) {\n return undefined;\n }\n\n const defaultValue = value.default;\n if (\n typeof defaultValue === 'string' ||\n typeof defaultValue === 'number' ||\n typeof defaultValue === 'boolean'\n ) {\n return String(defaultValue);\n }\n\n if (defaultValue === null) {\n return 'null';\n }\n\n try {\n return JSON.stringify(defaultValue);\n } catch {\n return undefined;\n }\n}\n\nfunction fieldParameter(\n name: string,\n field: Record<string, unknown>,\n location: WorkbenchApiParameterLocation,\n requiredOverride?: boolean,\n): WorkbenchApiParameterSummary {\n return {\n name,\n type: stringValue(field.type) || undefined,\n required: requiredOverride ?? parameterRequired(field),\n location,\n description: parameterDescription(field),\n defaultValue: parameterDefaultValue(field),\n };\n}\n\nfunction writableFieldEntries(\n object: Record<string, unknown>,\n): Array<[string, Record<string, unknown>]> {\n const fields = configObject(object.fields);\n const apiConfig = configObject(configObject(object.decoratorConfig).api);\n const writableAllowlist = new Set(arrayOfStrings(apiConfig.writable));\n const hasWritableAllowlist = writableAllowlist.size > 0;\n\n return Object.entries(fields)\n .filter((entry): entry is [string, Record<string, unknown>] =>\n isRecord(entry[1]),\n )\n .filter(([name, field]) => {\n if (name.startsWith('_')) {\n return false;\n }\n if (SERVER_MANAGED_FIELDS.has(name)) {\n return false;\n }\n if (\n field.readonly === true ||\n configObject(field._meta).readonly === true\n ) {\n return false;\n }\n return !hasWritableAllowlist || writableAllowlist.has(name);\n })\n .sort(([left], [right]) => left.localeCompare(right));\n}\n\nfunction writableFieldParameters(\n object: Record<string, unknown>,\n location: WorkbenchApiParameterLocation,\n requiredMode: 'field' | 'optional',\n): WorkbenchApiParameterSummary[] {\n return writableFieldEntries(object).map(([name, field]) =>\n fieldParameter(\n name,\n field,\n location,\n requiredMode === 'field' ? parameterRequired(field) : false,\n ),\n );\n}\n\nfunction methodParameterSummaries(\n object: Record<string, unknown>,\n action: string,\n location: WorkbenchApiParameterLocation,\n): WorkbenchApiParameterSummary[] {\n const parameters = methodDefinition(object, action).parameters;\n if (!Array.isArray(parameters)) {\n return [];\n }\n\n return parameters.filter(isRecord).map((parameter) => ({\n name: stringValue(parameter.name) || 'parameter',\n type: stringValue(parameter.type) || undefined,\n required: parameter.optional !== true,\n location,\n description: parameterDescription(parameter),\n defaultValue: parameterDefaultValue(parameter),\n }));\n}\n\nfunction pathParameterNames(path: string): string[] {\n return Array.from(path.matchAll(/\\{([^}]+)\\}/g))\n .map((match) => match[1]?.trim())\n .filter((name): name is string => Boolean(name));\n}\n\nfunction pathParameters(path: string): WorkbenchApiParameterSummary[] {\n return pathParameterNames(path).map((name) => ({\n name,\n type: 'string',\n required: true,\n location: 'path',\n }));\n}\n\nfunction restCrudParameters(\n object: Record<string, unknown>,\n action: string,\n path: string,\n): WorkbenchApiParameterSummary[] {\n if (action === 'list') {\n return [\n {\n name: 'limit',\n type: 'integer',\n required: false,\n location: 'query',\n description: 'Maximum number of items to return.',\n defaultValue: '50',\n },\n {\n name: 'offset',\n type: 'integer',\n required: false,\n location: 'query',\n description: 'Number of items to skip.',\n defaultValue: '0',\n },\n ];\n }\n\n if (action === 'create') {\n return writableFieldParameters(object, 'body', 'field');\n }\n\n if (action === 'update') {\n return [\n ...pathParameters(path),\n ...writableFieldParameters(object, 'body', 'optional'),\n ];\n }\n\n return pathParameters(path);\n}\n\nfunction restCustomParameters(\n object: Record<string, unknown>,\n action: string,\n method: string,\n path: string,\n): WorkbenchApiParameterSummary[] {\n const pathParams = pathParameters(path);\n const pathParamNameSet = new Set(pathParams.map((param) => param.name));\n const bodyOrQueryParams = methodParameterSummaries(\n object,\n action,\n method === 'GET' ? 'query' : 'body',\n ).filter((param) => !pathParamNameSet.has(param.name));\n\n return [...pathParams, ...bodyOrQueryParams];\n}\n\nfunction cliCrudParameters(\n object: Record<string, unknown>,\n action: string,\n): WorkbenchApiParameterSummary[] {\n if (action === 'list') {\n return [\n {\n name: '--limit',\n type: 'integer',\n required: false,\n location: 'option',\n description: 'Maximum number of items to return.',\n defaultValue: '50',\n },\n {\n name: '--offset',\n type: 'integer',\n required: false,\n location: 'option',\n description: 'Number of items to skip.',\n defaultValue: '0',\n },\n {\n name: '--order-by',\n type: 'string',\n required: false,\n location: 'option',\n description: 'Ordering expression, for example \"created_at DESC\".',\n },\n {\n name: '--where',\n type: 'object',\n required: false,\n location: 'option',\n description: 'JSON filter conditions.',\n },\n ];\n }\n\n if (action === 'get' || action === 'delete') {\n return [\n {\n name: 'id',\n type: 'string',\n required: true,\n location: 'argument',\n description: 'Object ID. May also be passed as --id.',\n },\n ];\n }\n\n const bodyParameters = writableFieldParameters(\n object,\n 'option',\n action === 'create' ? 'field' : 'optional',\n ).map((param) => ({\n ...param,\n name: `--${param.name}`,\n }));\n\n if (action === 'create') {\n return [\n {\n name: '--from-file',\n type: 'path',\n required: false,\n location: 'option',\n description: 'Path to a JSON object payload.',\n },\n ...bodyParameters,\n ];\n }\n\n return [\n {\n name: 'id',\n type: 'string',\n required: true,\n location: 'argument',\n description: 'Object ID. May also be passed as --id.',\n },\n {\n name: '--from-file',\n type: 'path',\n required: false,\n location: 'option',\n description: 'Path to a JSON object payload.',\n },\n ...bodyParameters,\n ];\n}\n\nfunction cliCustomParameters(\n object: Record<string, unknown>,\n action: string,\n): WorkbenchApiParameterSummary[] {\n const params = methodParameterSummaries(object, action, 'option').map(\n (param) => ({\n ...param,\n name: `--${param.name}`,\n required: false,\n }),\n );\n\n return [\n {\n name: 'id',\n type: 'string',\n required: false,\n location: 'argument',\n description:\n 'Optional object ID for instance actions. May also be passed as --id.',\n },\n ...params,\n ];\n}\n\nfunction mcpCrudParameters(\n object: Record<string, unknown>,\n action: string,\n): WorkbenchApiParameterSummary[] {\n if (action === 'list') {\n return [\n {\n name: 'limit',\n type: 'integer',\n required: false,\n location: 'input',\n description: 'Maximum number of items to return.',\n defaultValue: '50',\n },\n {\n name: 'offset',\n type: 'integer',\n required: false,\n location: 'input',\n description: 'Number of items to skip.',\n defaultValue: '0',\n },\n {\n name: 'orderBy',\n type: 'string',\n required: false,\n location: 'input',\n description: 'Ordering expression, for example \"created_at DESC\".',\n },\n {\n name: 'where',\n type: 'object',\n required: false,\n location: 'input',\n description: 'Filter conditions as key-value pairs.',\n },\n ];\n }\n\n if (action === 'get') {\n return [\n {\n name: 'id',\n type: 'string',\n required: true,\n location: 'input',\n description: 'Unique identifier of the object.',\n },\n {\n name: 'slug',\n type: 'string',\n required: false,\n location: 'input',\n description: 'URL-friendly identifier of the object.',\n },\n ];\n }\n\n if (action === 'delete') {\n return [\n {\n name: 'id',\n type: 'string',\n required: true,\n location: 'input',\n description: 'ID of the object to delete.',\n },\n ];\n }\n\n if (action === 'create') {\n return writableFieldParameters(object, 'input', 'field');\n }\n\n return [\n {\n name: 'id',\n type: 'string',\n required: true,\n location: 'input',\n description: 'ID of the object to update.',\n },\n ...writableFieldParameters(object, 'input', 'optional'),\n ];\n}\n\nfunction mcpCustomParameters(\n _object: Record<string, unknown>,\n _action: string,\n): WorkbenchApiParameterSummary[] {\n return [\n {\n name: 'id',\n type: 'string',\n required: true,\n location: 'input',\n description: 'ID of the object to execute the action on.',\n },\n {\n name: 'options',\n type: 'object',\n required: false,\n location: 'input',\n description: 'Additional options for the custom action.',\n },\n ];\n}\n\nfunction enabledCrudActions(config: unknown): string[] {\n if (config === false) {\n return [];\n }\n\n const include = arrayOfStrings(configObject(config).include);\n const exclude = new Set(arrayOfStrings(configObject(config).exclude));\n const actions =\n include.length > 0\n ? include.filter((action) => CRUD_ACTIONS.includes(action as never))\n : [...CRUD_ACTIONS];\n\n return actions.filter((action) => !exclude.has(action));\n}\n\nfunction publicCustomMethodNames(object: Record<string, unknown>): string[] {\n return Object.entries(configObject(object.methods))\n .filter(([name, method]) => {\n if (CRUD_ACTIONS.includes(name as never) || !isRecord(method)) {\n return false;\n }\n return method.isPublic === true;\n })\n .map(([name]) => name)\n .sort();\n}\n\nfunction enabledCustomActions(\n object: Record<string, unknown>,\n surface: 'api' | 'cli' | 'mcp',\n): string[] {\n const decoratorConfig = configObject(object.decoratorConfig);\n const surfaceConfig = decoratorConfig[surface];\n if (surfaceConfig === false) {\n return [];\n }\n\n const include = arrayOfStrings(configObject(surfaceConfig).include);\n const exclude = new Set(arrayOfStrings(configObject(surfaceConfig).exclude));\n const publicMethods = publicCustomMethodNames(object);\n\n if (surface === 'mcp' && include.length > 0) {\n return include\n .filter((name) => !CRUD_ACTIONS.includes(name as never))\n .filter((name) => publicMethods.includes(name))\n .filter((name) => !exclude.has(name));\n }\n\n if (surface === 'api') {\n return publicMethods\n .filter((name) => include.length === 0 || include.includes(name))\n .filter((name) => !exclude.has(name));\n }\n\n const customMethodsInInclude = include.filter(\n (name) => !CRUD_ACTIONS.includes(name as never),\n );\n return publicMethods\n .filter(\n (name) =>\n customMethodsInInclude.length === 0 ||\n customMethodsInInclude.includes(name),\n )\n .filter((name) => !exclude.has(name));\n}\n\nfunction routeOverrides(\n object: Record<string, unknown>,\n): Record<string, Record<string, unknown>> {\n const apiConfig = configObject(configObject(object.decoratorConfig).api);\n const routes = configObject(apiConfig.routes);\n\n return Object.fromEntries(\n Object.entries(routes).filter(\n (entry): entry is [string, Record<string, unknown>] => isRecord(entry[1]),\n ),\n );\n}\n\nfunction methodDefinition(\n object: Record<string, unknown>,\n action: string,\n): Record<string, unknown> {\n return configObject(configObject(object.methods)[action]);\n}\n\nfunction customRoutePath(\n object: Record<string, unknown>,\n action: string,\n): string {\n const collection =\n stringValue(object.collection) || stringValue(object.name) || action;\n const routeConfig = routeOverrides(object)[action] || {};\n const method = methodDefinition(object, action);\n const configuredPath = stringValue(routeConfig.path) || action;\n const normalizedPath = configuredPath\n .split('/')\n .map((segment) => segment.trim())\n .filter(Boolean)\n .join('/')\n .replace(/\\[([^\\]]+)\\]/g, '{$1}');\n const scope =\n stringValue(routeConfig.scope) ||\n (method.isStatic === true ? 'collection' : 'item');\n\n return scope === 'collection'\n ? `/api/v1/${collection}/${normalizedPath}`\n : `/api/v1/${collection}/{id}/${normalizedPath}`;\n}\n\nfunction restEndpointsFrom(\n object: Record<string, unknown>,\n): WorkbenchRestEndpointSummary[] {\n const className =\n stringValue(object.className) || stringValue(object.name) || 'Object';\n const collection = stringValue(object.collection) || className.toLowerCase();\n const apiConfig = configObject(object.decoratorConfig).api;\n const endpoints: WorkbenchRestEndpointSummary[] = [];\n\n const crudActions =\n stringValue(object.extends) === 'SmrtCollection'\n ? []\n : enabledCrudActions(apiConfig);\n for (const action of crudActions) {\n const route =\n action === 'list'\n ? ['GET', `/api/v1/${collection}`, `List ${className} objects`]\n : action === 'create'\n ? ['POST', `/api/v1/${collection}`, `Create ${className}`]\n : action === 'get'\n ? ['GET', `/api/v1/${collection}/{id}`, `Get ${className} by ID`]\n : action === 'update'\n ? ['PUT', `/api/v1/${collection}/{id}`, `Update ${className}`]\n : ['DELETE', `/api/v1/${collection}/{id}`, `Delete ${className}`];\n\n endpoints.push({\n objectName: className,\n action,\n method: route[0],\n path: route[1],\n description: route[2],\n parameters: restCrudParameters(object, action, route[1]),\n });\n }\n\n const overrides = routeOverrides(object);\n for (const action of enabledCustomActions(object, 'api')) {\n const routeConfig = overrides[action] || {};\n const method = stringValue(routeConfig.method) || 'POST';\n endpoints.push({\n objectName: className,\n action,\n method,\n path: customRoutePath(object, action),\n description: `Run ${className}.${action}`,\n parameters: restCustomParameters(\n object,\n action,\n method,\n customRoutePath(object, action),\n ),\n });\n }\n\n return endpoints;\n}\n\nfunction cliCommandsFrom(\n object: Record<string, unknown>,\n): WorkbenchCliCommandSummary[] {\n const className =\n stringValue(object.className) || stringValue(object.name) || 'Object';\n const lowerName = className.toLowerCase();\n const cliConfig = configObject(object.decoratorConfig).cli;\n const commands: WorkbenchCliCommandSummary[] = [];\n\n for (const action of enabledCrudActions(cliConfig)) {\n const description =\n action === 'list'\n ? `List ${className} objects`\n : action === 'get'\n ? `Get ${className} by ID or slug`\n : action === 'create'\n ? `Create new ${className}`\n : action === 'update'\n ? `Update ${className}`\n : `Delete ${className}`;\n\n commands.push({\n objectName: className,\n action,\n command: `${lowerName}:${action}`,\n description,\n parameters: cliCrudParameters(object, action),\n });\n }\n\n for (const action of enabledCustomActions(object, 'cli')) {\n commands.push({\n objectName: className,\n action,\n command: `${lowerName}:${action}`,\n description: `Run ${className}.${action}`,\n parameters: cliCustomParameters(object, action),\n });\n }\n\n return commands;\n}\n\nfunction mcpToolsFrom(\n object: Record<string, unknown>,\n): WorkbenchMcpToolSummary[] {\n const className =\n stringValue(object.className) || stringValue(object.name) || 'Object';\n const lowerName = className.toLowerCase();\n const mcpConfig = configObject(object.decoratorConfig).mcp;\n const tools: WorkbenchMcpToolSummary[] = [];\n\n for (const action of enabledCrudActions(mcpConfig)) {\n const description =\n action === 'list'\n ? `List ${className} objects with optional filtering`\n : action === 'get'\n ? `Get a specific ${className} by ID or slug`\n : action === 'create'\n ? `Create a new ${className}`\n : action === 'update'\n ? `Update an existing ${className}`\n : `Delete a ${className} by ID`;\n\n tools.push({\n objectName: className,\n action,\n toolName: `${lowerName}_${action}`,\n description,\n parameters: mcpCrudParameters(object, action),\n });\n }\n\n for (const action of enabledCustomActions(object, 'mcp')) {\n tools.push({\n objectName: className,\n action,\n toolName: `${lowerName}_${action}`.toLowerCase(),\n description: `Execute ${action} action on ${className}`,\n parameters: mcpCustomParameters(object, action),\n });\n }\n\n return tools;\n}\n\nfunction readApiSummary(\n packageDir: string,\n rootDir: string,\n packageName: string,\n knowledge: WorkbenchKnowledgeSummary,\n routeFiles: string[],\n): WorkbenchApiSummary {\n const manifest = knowledge.manifestPath\n ? readJsonIfExists<Record<string, unknown>>(knowledge.manifestPath)\n : null;\n const objectRecords = objectRecordsFrom(manifest?.objects);\n\n const objects: WorkbenchApiObjectSummary[] = objectRecords.map((object) => {\n const name =\n stringValue(object.className) ||\n stringValue(object.name) ||\n stringValue(object.key) ||\n 'unknown';\n const className = stringValue(object.className) || name;\n const sourcePath = resolveManifestSourcePath(\n rootDir,\n packageDir,\n stringValue(object.filePath) || stringValue(object.sourcePath),\n );\n const typedocPath = findTypedocClassPath(\n rootDir,\n packageDir,\n packageName,\n className,\n );\n const fields = fieldSummariesFrom(object.fields);\n\n return {\n name,\n className,\n qualifiedName: stringValue(object.qualifiedName) || undefined,\n collection: stringValue(object.collection) || undefined,\n sourcePath,\n typedocPath,\n description: readTypedocSummary(typedocPath),\n fields,\n };\n });\n\n const objectNames =\n objects.length > 0\n ? objects\n .map(\n (object) => object.qualifiedName || object.className || object.name,\n )\n .filter(Boolean)\n .sort()\n : knowledge.objectNames;\n const restEndpoints = objectRecords.flatMap(restEndpointsFrom);\n\n return {\n objectNames,\n objects,\n restEndpoints,\n cliCommands: objectRecords.flatMap(cliCommandsFrom),\n mcpTools: objectRecords.flatMap(mcpToolsFrom),\n endpointCount: restEndpoints.length,\n routeFiles,\n };\n}\n\nasync function collectRouteFiles(packageDir: string): Promise<string[]> {\n return fg(['src/routes/**/*.{ts,svelte}', 'routes/**/*.{ts,svelte}'], {\n cwd: packageDir,\n absolute: true,\n onlyFiles: true,\n ignore: ['**/node_modules/**', '**/.svelte-kit/**'],\n });\n}\n\nasync function collectMigrations(packageDir: string): Promise<string[]> {\n return fg(['migrations/**/*', 'src/migrations/**/*'], {\n cwd: packageDir,\n absolute: true,\n onlyFiles: true,\n ignore: ['**/node_modules/**'],\n });\n}\n\nasync function collectExamples(\n packageDir: string,\n docs: WorkbenchDocumentSummary[],\n): Promise<WorkbenchExampleSummary[]> {\n const fileMatches = await fg(\n [\n 'examples/**/*.{ts,tsx,svelte,md}',\n 'src/**/*.{example,stories}.{ts,tsx,svelte}',\n 'src/**/examples/**/*.{ts,tsx,svelte,md}',\n ],\n {\n cwd: packageDir,\n absolute: true,\n onlyFiles: true,\n ignore: ['**/node_modules/**', '**/dist/**', '**/.svelte-kit/**'],\n },\n );\n\n const fileExamples = fileMatches.slice(0, 16).map((path, index) => ({\n id: `file:${index}`,\n title: relative(packageDir, path),\n path,\n source: 'file' as const,\n }));\n\n const readme = docs.find((doc) => doc.kind === 'readme');\n const readmeExamples = readme?.content\n ? extractReadmeCodeBlocks(readme.content).slice(0, 8)\n : [];\n\n return [...fileExamples, ...readmeExamples];\n}\n\nfunction extractReadmeCodeBlocks(content: string): WorkbenchExampleSummary[] {\n const examples: WorkbenchExampleSummary[] = [];\n const blockPattern = /```([A-Za-z0-9_-]*)\\n([\\s\\S]*?)```/g;\n let index = 0;\n let match = blockPattern.exec(content);\n\n while (match) {\n const language = match[1] || undefined;\n const code = match[2] || '';\n if (!code.trim()) {\n match = blockPattern.exec(content);\n continue;\n }\n\n const { content: trimmedCode } = truncate(code, EXAMPLE_LIMIT);\n examples.push({\n id: `readme:${index}`,\n title: `README example ${index + 1}`,\n language,\n code: trimmedCode,\n source: 'readme',\n });\n index += 1;\n match = blockPattern.exec(content);\n }\n\n return examples;\n}\n\nasync function summarizePackage(\n input: WorkbenchPackageDir,\n rootDir: string,\n): Promise<WorkbenchPackageSummary> {\n const { packageDir, packageJson, source } = input;\n const packageName =\n packageJson.name || relative(rootDir, packageDir) || packageDir;\n const docs = [\n readDocument(packageDir, 'README.md', 'readme'),\n readDocument(packageDir, 'AGENTS.md', 'agents'),\n readDocument(packageDir, 'CHANGELOG.md', 'changelog'),\n ].filter((doc): doc is WorkbenchDocumentSummary => Boolean(doc));\n const examples = await collectExamples(packageDir, docs);\n const knowledge = readKnowledgeSummary(packageDir);\n const routeFiles = await collectRouteFiles(packageDir);\n const migrations = await collectMigrations(packageDir);\n const scripts = stringRecord(packageJson.scripts);\n const api = readApiSummary(\n packageDir,\n rootDir,\n packageName,\n knowledge,\n routeFiles,\n );\n\n return {\n name: packageName,\n version: packageJson.version,\n description: packageJson.description,\n source,\n directory: packageDir,\n relativeDirectory: relative(rootDir, packageDir) || '.',\n scripts,\n dependencies: stringRecord(packageJson.dependencies),\n devDependencies: stringRecord(packageJson.devDependencies),\n peerDependencies: stringRecord(packageJson.peerDependencies),\n smrtDependencies: smrtDependencyNames(packageJson),\n sdkDependencies: sdkDependencyNames(packageJson),\n exportKeys: exportKeys(packageJson.exports),\n docs,\n examples,\n knowledge,\n api,\n migrations,\n routeModuleCount: 0,\n routeCount: 0,\n playgroundEntryCount: 0,\n recommendedCommands: Object.keys(scripts)\n .filter((scriptName) =>\n ['test', 'typecheck', 'check', 'build', 'dev', 'workbench'].includes(\n scriptName,\n ),\n )\n .sort()\n .map((scriptName) => ({\n id: commandIdForScript(packageName, scriptName),\n label: scriptName,\n command: `pnpm --filter ${packageName} ${scriptName}`,\n })),\n };\n}\n\nasync function discoverWorkspacePackageDirs(\n workspaceRoot: string,\n): Promise<WorkbenchPackageDir[]> {\n const packageJsonPaths = await fg('packages/*/package.json', {\n cwd: workspaceRoot,\n absolute: true,\n onlyFiles: true,\n });\n\n return packageJsonPaths\n .map((packageJsonPath) => ({\n packageDir: dirname(packageJsonPath),\n packageJson: readJson<PackageJsonLike>(packageJsonPath),\n source: 'workspace' as const,\n }))\n .filter(\n (item) =>\n typeof item.packageJson.name === 'string' &&\n item.packageJson.name.startsWith('@happyvertical/smrt-'),\n )\n .sort((left, right) =>\n (left.packageJson.name || '').localeCompare(right.packageJson.name || ''),\n );\n}\n\nfunction resolveNodeModulePackageDir(\n projectRoot: string,\n packageName: string,\n): string | null {\n const packageJsonPath = join(\n projectRoot,\n 'node_modules',\n packageName,\n 'package.json',\n );\n return existsSync(packageJsonPath) ? dirname(packageJsonPath) : null;\n}\n\nasync function discoverConsumerPackageDirs(\n projectRoot: string,\n): Promise<WorkbenchPackageDir[]> {\n const packageJsonPath = join(projectRoot, 'package.json');\n if (!existsSync(packageJsonPath)) {\n return [];\n }\n\n const packageJson = readJson<PackageJsonLike>(packageJsonPath);\n const dependencies = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n ...packageJson.peerDependencies,\n };\n const packageDirs: WorkbenchPackageDir[] = [];\n\n packageDirs.push({\n packageDir: projectRoot,\n packageJson,\n source: packageJson.name?.startsWith('@happyvertical/smrt-')\n ? 'package'\n : 'app',\n });\n\n for (const dependencyName of Object.keys(dependencies).sort()) {\n if (\n !dependencyName.startsWith('@happyvertical/smrt-') ||\n dependencyName === '@happyvertical/smrt-workbench'\n ) {\n continue;\n }\n\n const packageDir = resolveNodeModulePackageDir(projectRoot, dependencyName);\n if (!packageDir) {\n continue;\n }\n\n packageDirs.push({\n packageDir,\n packageJson: readJson<PackageJsonLike>(join(packageDir, 'package.json')),\n source: 'package',\n });\n }\n\n return packageDirs;\n}\n\nfunction resolvePackageByName(\n workspaceRoot: string,\n packageName: string,\n): string | null {\n const packagesDir = join(workspaceRoot, 'packages');\n if (!existsSync(packagesDir)) {\n return null;\n }\n\n const packageJsonPaths = fg.sync('*/package.json', {\n cwd: packagesDir,\n absolute: true,\n onlyFiles: true,\n });\n\n for (const packageJsonPath of packageJsonPaths) {\n const packageJson = readJson<PackageJsonLike>(packageJsonPath);\n if (packageJson.name === packageName) {\n return dirname(packageJsonPath);\n }\n }\n\n return null;\n}\n\nexport function resolveWorkbenchScope(\n cwd = process.cwd(),\n options: Pick<\n SmrtWorkbenchVitePluginOptions,\n 'projectRoot' | 'workspaceRoot' | 'packageName'\n > = {},\n): WorkbenchScopeResolution {\n const resolvedCwd = resolve(cwd);\n const requestedProjectRoot = options.projectRoot\n ? resolve(options.projectRoot)\n : undefined;\n const workspaceRoot =\n options.workspaceRoot ||\n (requestedProjectRoot\n ? findSmrtWorkbenchWorkspaceRoot(requestedProjectRoot)\n : null) ||\n findSmrtWorkbenchWorkspaceRoot(resolvedCwd);\n\n if (workspaceRoot) {\n const packageDir =\n (options.packageName\n ? resolvePackageByName(workspaceRoot, options.packageName)\n : null) ||\n findPackageDir(resolvedCwd, workspaceRoot) ||\n undefined;\n const packageJson = packageDir\n ? readJsonIfExists<PackageJsonLike>(join(packageDir, 'package.json'))\n : null;\n const packageName = options.packageName || packageJson?.name;\n const mode: SmrtWorkbenchScopeMode = packageName ? 'package' : 'workspace';\n\n return {\n mode,\n cwd: resolvedCwd,\n projectRoot: workspaceRoot,\n workspaceRoot,\n packageName,\n packageDir,\n packageManager: 'pnpm',\n };\n }\n\n const projectRoot = requestedProjectRoot || findProjectRoot(resolvedCwd);\n return {\n mode: 'consumer',\n cwd: resolvedCwd,\n projectRoot,\n packageName: options.packageName,\n packageManager: detectPackageManager(projectRoot),\n };\n}\n\nexport async function buildWorkbenchProject(\n scope: WorkbenchScopeResolution,\n): Promise<SmrtWorkbenchProject> {\n const packageDirs =\n scope.mode === 'consumer'\n ? await discoverConsumerPackageDirs(scope.projectRoot)\n : await discoverWorkspacePackageDirs(scope.projectRoot);\n\n const filteredPackageDirs = scope.packageName\n ? packageDirs.filter((item) => item.packageJson.name === scope.packageName)\n : packageDirs;\n\n const packages = await Promise.all(\n filteredPackageDirs.map((item) =>\n summarizePackage(item, scope.projectRoot),\n ),\n );\n\n return {\n generatedAt: new Date().toISOString(),\n scope,\n packages,\n };\n}\n\nexport async function discoverWorkspaceWorkbenches(\n workspaceRoot: string,\n packagesPattern = 'packages/*/src/workbench.ts',\n): Promise<DiscoveredWorkbenchTarget[]> {\n const matches = await fg(packagesPattern, {\n cwd: workspaceRoot,\n absolute: true,\n onlyFiles: true,\n });\n\n return matches.sort().map((sourcePath) => {\n const packageDir = dirname(dirname(sourcePath));\n const packageJsonPath = join(packageDir, 'package.json');\n const packageJson = readJson<PackageJsonLike>(packageJsonPath);\n const runtimePath = join(packageDir, 'dist', 'workbench.js');\n\n return {\n packageName: packageJson.name,\n source: 'workspace' as const,\n sourcePath,\n runtimePath: existsSync(runtimePath) ? runtimePath : undefined,\n };\n });\n}\n\nexport async function discoverInstalledWorkbenches(\n projectRoot = process.cwd(),\n): Promise<DiscoveredWorkbenchTarget[]> {\n const packageJsonPath = join(projectRoot, 'package.json');\n if (!existsSync(packageJsonPath)) {\n return [];\n }\n\n const packageJson = readJson<PackageJsonLike>(packageJsonPath);\n const dependencies = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n ...packageJson.peerDependencies,\n };\n const discovered: DiscoveredWorkbenchTarget[] = [];\n\n for (const dependencyName of Object.keys(dependencies).sort()) {\n if (\n !dependencyName.startsWith('@happyvertical/smrt-') ||\n dependencyName === '@happyvertical/smrt-workbench'\n ) {\n continue;\n }\n\n const packageDir = resolveNodeModulePackageDir(projectRoot, dependencyName);\n if (!packageDir) {\n continue;\n }\n\n const dependencyPackageJson = readJson<PackageJsonLike>(\n join(packageDir, 'package.json'),\n );\n if (exportKeys(dependencyPackageJson.exports).includes('./workbench')) {\n discovered.push({\n packageName: dependencyName,\n source: 'package',\n importSpecifier: `${dependencyName}/workbench`,\n });\n }\n }\n\n return discovered;\n}\n\nexport async function discoverWorkbenchTargets(\n projectRoot = process.cwd(),\n mode: 'auto' | 'workspace' | 'consumer' = 'auto',\n localWorkbenchPath = 'src/workbench.ts',\n packageName?: string,\n packagesPattern = 'packages/*/src/workbench.ts',\n): Promise<DiscoveredWorkbenchTarget[]> {\n const effectiveMode =\n mode === 'auto' ? detectWorkbenchMode(projectRoot) : mode;\n\n if (effectiveMode === 'workspace') {\n const workspaceRoot =\n mode === 'workspace'\n ? findWorkspaceRoot(projectRoot)\n : findSmrtWorkbenchWorkspaceRoot(projectRoot);\n if (!workspaceRoot) {\n return [];\n }\n\n const targets = await discoverWorkspaceWorkbenches(\n workspaceRoot,\n packagesPattern,\n );\n return packageName\n ? targets.filter((target) => target.packageName === packageName)\n : targets;\n }\n\n const targets = await discoverInstalledWorkbenches(projectRoot);\n const localPath = resolve(projectRoot, localWorkbenchPath);\n if (existsSync(localPath)) {\n const localPackageJson = readJsonIfExists<PackageJsonLike>(\n join(projectRoot, 'package.json'),\n );\n targets.push({\n packageName: localPackageJson?.name,\n source: 'app',\n sourcePath: localPath,\n });\n }\n\n return packageName\n ? targets.filter((target) => target.packageName === packageName)\n : targets;\n}\n\nexport async function importWorkbenchModule(\n input: string,\n): Promise<SmrtWorkbenchModule[]> {\n const imported =\n isAbsolute(input) || input.startsWith('.')\n ? await importPathModule(resolve(input))\n : await import(/* @vite-ignore */ input);\n\n const module = imported.default ?? imported.workbench ?? imported;\n return module && typeof module === 'object'\n ? coerceWorkbenchModules(module as SmrtWorkbenchModule)\n : [];\n}\n\nasync function importPathModule(inputPath: string): Promise<unknown> {\n if (!TS_SOURCE_EXTENSIONS.has(extname(inputPath))) {\n return import(/* @vite-ignore */ pathToFileURL(inputPath).href);\n }\n\n let tsxApiPath: string;\n try {\n tsxApiPath = require.resolve('tsx/esm/api');\n } catch (tsxError) {\n throw new Error(\n `Failed to load workbench module from ${inputPath}: source workbench discovery requires the \"tsx\" package.`,\n { cause: tsxError },\n );\n }\n\n const { tsImport } = await import(\n /* @vite-ignore */ pathToFileURL(tsxApiPath).href\n );\n return tsImport(pathToFileURL(inputPath).href, {\n parentURL: import.meta.url,\n });\n}\n\nexport function describeWorkbenchSource(\n target: DiscoveredWorkbenchTarget,\n cwd = process.cwd(),\n): string {\n if (target.source === 'package') {\n return target.importSpecifier || target.packageName || 'installed package';\n }\n\n const path = target.sourcePath || target.runtimePath;\n return path ? relative(cwd, path) || '.' : target.source;\n}\n"],"mappings":"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G,cACL;CAGF,OAAO;EACL;GACE,MAAM;GACN,MAAM;GACN,UAAU;GACV,UAAU;GACV,aAAa;EACf;EACA;GACE,MAAM;GACN,MAAM;GACN,UAAU;GACV,UAAU;GACV,aAAa;EACf;EACA,GAAG;CACL;AACF;AAEA,SAAS,oBACP,QACA,QACgC;CAShC,OAAO,CACL;EACE,MAAM;EACN,MAAM;EACN,UAAU;EACV,UAAU;EACV,aACE;CACJ,GACA,GAjBa,yBAAyB,QAAQ,QAAQ,QAAQ,CAAA,CAAE,KAC/D,WAAW;EACV,GAAG;EACH,MAAM,KAAK,MAAM;EACjB,UAAU;CACZ,EAYG,CACL;AACF;AAEA,SAAS,kBACP,QACA,QACgC;CAChC,IAAI,WAAW,QACb,OAAO;EACL;GACE,MAAM;GACN,MAAM;GACN,UAAU;GACV,UAAU;GACV,aAAa;GACb,cAAc;EAChB;EACA;GACE,MAAM;GACN,MAAM;GACN,UAAU;GACV,UAAU;GACV,aAAa;GACb,cAAc;EAChB;EACA;GACE,MAAM;GACN,MAAM;GACN,UAAU;GACV,UAAU;GACV,aAAa;EACf;EACA;GACE,MAAM;GACN,MAAM;GACN,UAAU;GACV,UAAU;GACV,aAAa;EACf;CACF;CAGF,IAAI,WAAW,OACb,OAAO,CACL;EACE,MAAM;EACN,MAAM;EACN,UAAU;EACV,UAAU;EACV,aAAa;CACf,GACA;EACE,MAAM;EACN,MAAM;EACN,UAAU;EACV,UAAU;EACV,aAAa;CACf,CACF;CAGF,IAAI,WAAW,UACb,OAAO,CACL;EACE,MAAM;EACN,MAAM;EACN,UAAU;EACV,UAAU;EACV,aAAa;CACf,CACF;CAGF,IAAI,WAAW,UACb,OAAO,wBAAwB,QAAQ,SAAS,OAAO;CAGzD,OAAO,CACL;EACE,MAAM;EACN,MAAM;EACN,UAAU;EACV,UAAU;EACV,aAAa;CACf,GACA,GAAG,wBAAwB,QAAQ,SAAS,UAAU,CACxD;AACF;AAEA,SAAS,oBACP,SACA,SACgC;CAChC,OAAO,CACL;EACE,MAAM;EACN,MAAM;EACN,UAAU;EACV,UAAU;EACV,aAAa;CACf,GACA;EACE,M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"}