@happyvertical/smrt-workbench 0.45.3 → 0.47.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/{discovery-G9-foyW8.js → discovery-BOoinKLR.js} +51 -17
- package/dist/chunks/discovery-BOoinKLR.js.map +1 -0
- package/dist/discovery.d.ts +8 -1
- package/dist/discovery.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/vite.js +1 -1
- package/package.json +6 -5
- package/src/discovery.ts +125 -28
- package/dist/chunks/discovery-G9-foyW8.js.map +0 -1
|
@@ -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
|
|
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")
|
|
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
|
|
549
|
-
|
|
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
|
|
591
|
-
|
|
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
|
|
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-
|
|
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,MAAM;EACN,MAAM;EACN,UAAU;EACV,UAAU;EACV,aAAa;CACf,CACF;AACF;AAEA,SAAS,mBAAmB,QAA2B;CACrD,IAAI,WAAW,OACb,OAAO,CAAC;CAGV,MAAM,UAAU,eAAe,aAAa,MAAM,CAAA,CAAE,OAAO;CAC3D,MAAM,UAAU,IAAI,IAAI,eAAe,aAAa,MAAM,CAAA,CAAE,OAAO,CAAC;CAMpE,QAJE,QAAQ,SAAS,IACb,QAAQ,QAAQ,WAAW,aAAa,SAAS,MAAe,CAAC,IACjE,CAAC,GAAG,YAAY,EAAA,CAEP,QAAQ,WAAW,CAAC,QAAQ,IAAI,MAAM,CAAC;AACxD;AAEA,SAAS,wBAAwB,QAA2C;CAC1E,OAAO,OAAO,QAAQ,aAAa,OAAO,OAAO,CAAC,CAAA,CAC/C,QAAQ,CAAC,MAAM,YAAY;EAC1B,IAAI,aAAa,SAAS,IAAa,KAAK,CAAC,SAAS,MAAM,GAC1D,OAAO;EAET,OAAO,OAAO,aAAa;CAC7B,CAAC,CAAA,CACA,KAAK,CAAC,UAAU,IAAI,CAAA,CACpB,KAAK;AACV;AAEA,SAAS,qBACP,QACA,SACA,kBACU;CACV,MAAM,kBAAkB,aAAa,OAAO,eAAe;CAC3D,MAAM,gBAAgB,gBAAgB;CACtC,IAAI,kBAAkB,OACpB,OAAO,CAAC;CAGV,MAAM,UAAU,eAAe,aAAa,aAAa,CAAA,CAAE,OAAO;CAClE,MAAM,UAAU,IAAI,IAAI,eAAe,aAAa,aAAa,CAAA,CAAE,OAAO,CAAC;CAC3E,MAAM,gBAAgB,wBAAwB,MAAM;CAEpD,IAAI,YAAY,SAAS,QAAQ,SAAS,GACxC,OAAO,QACJ,QAAQ,SAAS,CAAC,aAAa,SAAS,IAAa,CAAC,CAAA,CACtD,QAAQ,SAAS,cAAc,SAAS,IAAI,CAAC,CAAA,CAC7C,QAAQ,SAAS,CAAC,QAAQ,IAAI,IAAI,CAAC;CASxC,IAAI,YAAY,OAAO;EACrB,MAAM,UAAU,aAAa,OAAO,OAAO;EAC3C,MAAM,oBACJ,YAAY,OAAO,OAAO,MAAM,oBAChC,OAAO,mBAAmB,KAAA;EAC5B,OAAO,OAAO,KAAK,OAAO,CAAA,CACvB,KAAK,CAAA,CACL,QACE,SACC,yBAAyB;GACvB,YAAY;GACZ,QAAQ,aAAa,QAAQ,KAAK;GAClC,WAAW,gBAAgB;GAC3B;GACA,GAAI,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;EACjD,CAAC,CAAA,CAAE,OACP;CACJ;CAEA,MAAM,yBAAyB,QAAQ,QACpC,SAAS,CAAC,aAAa,SAAS,IAAa,CAChD;CACA,OAAO,cACJ,QACE,SACC,uBAAuB,WAAW,KAClC,uBAAuB,SAAS,IAAI,CACxC,CAAA,CACC,QAAQ,SAAS,CAAC,QAAQ,IAAI,IAAI,CAAC;AACxC;AAEA,SAAS,iBACP,QACA,QACyB;CACzB,OAAO,aAAa,aAAa,OAAO,OAAO,CAAA,CAAE,OAAO;AAC1D;AASA,SAAS,eACP,QACA,QACwD;CACxD,OAAO,+BAA+B;EACpC,YAAY;EACZ,QAAQ,iBAAiB,QAAQ,MAAM;EACvC,WAAW,aAAa,OAAO,eAAe,CAAA,CAAE;CAClD,CAAC;AACH;AAEA,SAAS,kBACP,QACA,QACQ;CACR,OAAO,eAAe,QAAQ,MAAM,CAAA,CAAE,cAAc;AACtD;AAaA,SAAS,eACP,QACA,QACuB;CACvB,MAAM,SAAS,iBAAiB,QAAQ,MAAM;CAI9C,MAAM,eAFJ,YAAY,OAAO,OAAO,MAAM,oBAChC,OAAO,mBAAmB,KAAA,KAEL,OAAO,aAAa,OAAO,eAAe;CACjE,IAAI;EACF,OAAO,4BAA4B;GACjC,YAAY;GACZ;GACA,WAAW,aAAa,OAAO,eAAe,CAAA,CAAE;GAChD;EACF,CAAC,CAAA,CAAE;CACL,QAAQ;EAIN,OAAO;CACT;AACF;AAEA,SAAS,gBACP,QACA,QACQ;CACR,MAAM,aACJ,YAAY,OAAO,UAAU,KAAK,YAAY,OAAO,IAAI,KAAK;CAEhE,MAAM,kBADiB,eAAe,QAAQ,MAAM,CAAA,CAAE,QAAQ,OAAA,CAE3D,MAAM,GAAG,CAAA,CACT,KAAK,YAAY,QAAQ,KAAK,CAAC,CAAA,CAC/B,OAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA,CACR,QAAQ,iBAAiB,MAAM;CAElC,OAAO,eAAe,QAAQ,MAAM,MAAM,eACtC,WAAW,WAAU,GAAI,mBACzB,WAAW,WAAU,QAAS;AACpC;AAQO,SAAS,kBACd,QACA,kBACgC;CAChC,MAAM,YACJ,YAAY,OAAO,SAAS,KAAK,YAAY,OAAO,IAAI,KAAK;CAC/D,MAAM,aAAa,YAAY,OAAO,UAAU,KAAK,UAAU,YAAY;CAC3E,MAAM,YAAY,aAAa,OAAO,eAAe,CAAA,CAAE;CACvD,MAAM,YAA4C,CAAC;CAEnD,MAAM,cACJ,YAAY,OAAO,OAAO,MAAM,mBAC5B,CAAC,IACD,mBAAmB,SAAS;CAClC,KAAA,MAAW,UAAU,aAAa;EAChC,MAAM,QACJ,WAAW,SACP;GAAC;GAAO,WAAW;GAAc,QAAQ,UAAS;EAAU,IAC5D,WAAW,WACT;GAAC;GAAQ,WAAW;GAAc,UAAU;EAAW,IACvD,WAAW,QACT;GAAC;GAAO,WAAW,WAAU;GAAS,OAAO,UAAS;EAAQ,IAC9D,WAAW,WACT;GAAC;GAAO,WAAW,WAAU;GAAS,UAAU;EAAW,IAC3D;GAAC;GAAU,WAAW,WAAU;GAAS,UAAU;EAAW;EAE1E,UAAU,KAAK;GACb,YAAY;GACZ;GACA,QAAQ,MAAM;GACd,MAAM,MAAM;GACZ,aAAa,MAAM;GACnB,YAAY,mBAAmB,QAAQ,QAAQ,MAAM,EAAE;EACzD,CAAC;CACH;CAEA,KAAA,MAAW,UAAU,qBAAqB,QAAQ,OAAO,gBAAgB,GAAG;EAC1E,MAAM,SAAS,kBAAkB,QAAQ,MAAM;EAC/C,UAAU,KAAK;GACb,YAAY;GACZ;GACA;GACA,MAAM,gBAAgB,QAAQ,MAAM;GACpC,aAAa,OAAO,UAAS,GAAI;GACjC,YAAY,qBACV,QACA,QACA,QACA,gBAAgB,QAAQ,MAAM,CAChC;EACF,CAAC;CACH;CAEA,OAAO;AACT;AAEA,SAAS,gBACP,QAC8B;CAC9B,MAAM,YACJ,YAAY,OAAO,SAAS,KAAK,YAAY,OAAO,IAAI,KAAK;CAC/D,MAAM,YAAY,UAAU,YAAY;CACxC,MAAM,YAAY,aAAa,OAAO,eAAe,CAAA,CAAE;CACvD,MAAM,WAAyC,CAAC;CAEhD,KAAA,MAAW,UAAU,mBAAmB,SAAS,GAAG;EAClD,MAAM,cACJ,WAAW,SACP,QAAQ,UAAS,YACjB,WAAW,QACT,OAAO,UAAS,kBAChB,WAAW,WACT,cAAc,cACd,WAAW,WACT,UAAU,cACV,UAAU;EAEtB,SAAS,KAAK;GACZ,YAAY;GACZ;GACA,SAAS,GAAG,UAAS,GAAI;GACzB;GACA,YAAY,kBAAkB,QAAQ,MAAM;EAC9C,CAAC;CACH;CAEA,KAAA,MAAW,UAAU,qBAAqB,QAAQ,KAAK,GACrD,SAAS,KAAK;EACZ,YAAY;EACZ;EACA,SAAS,GAAG,UAAS,GAAI;EACzB,aAAa,OAAO,UAAS,GAAI;EACjC,YAAY,oBAAoB,QAAQ,MAAM;CAChD,CAAC;CAGH,OAAO;AACT;AAEA,SAAS,aACP,QAC2B;CAC3B,MAAM,YACJ,YAAY,OAAO,SAAS,KAAK,YAAY,OAAO,IAAI,KAAK;CAC/D,MAAM,YAAY,UAAU,YAAY;CACxC,MAAM,YAAY,aAAa,OAAO,eAAe,CAAA,CAAE;CACvD,MAAM,QAAmC,CAAC;CAE1C,KAAA,MAAW,UAAU,mBAAmB,SAAS,GAAG;EAClD,MAAM,cACJ,WAAW,SACP,QAAQ,UAAS,oCACjB,WAAW,QACT,kBAAkB,UAAS,kBAC3B,WAAW,WACT,gBAAgB,cAChB,WAAW,WACT,sBAAsB,cACtB,YAAY,UAAS;EAEjC,MAAM,KAAK;GACT,YAAY;GACZ;GACA,UAAU,GAAG,UAAS,GAAI;GAC1B;GACA,YAAY,kBAAkB,QAAQ,MAAM;EAC9C,CAAC;CACH;CAEA,KAAA,MAAW,UAAU,qBAAqB,QAAQ,KAAK,GACrD,MAAM,KAAK;EACT,YAAY;EACZ;EACA,UAAU,GAAG,UAAS,GAAI,SAAS,YAAY;EAC/C,aAAa,WAAW,OAAM,aAAc;EAC5C,YAAY,oBAAoB,QAAQ,MAAM;CAChD,CAAC;CAGH,OAAO;AACT;AAEA,SAAS,eACP,YACA,SACA,aACA,WACA,YACqB;CAIrB,MAAM,gBAAgB,mBAHL,UAAU,eACvB,iBAA0C,UAAU,YAAY,IAChE,KAAA,EAC8C,OAAO;CAEzD,MAAM,UAAuC,cAAc,KAAK,WAAW;EACzE,MAAM,OACJ,YAAY,OAAO,SAAS,KAC5B,YAAY,OAAO,IAAI,KACvB,YAAY,OAAO,GAAG,KACtB;EACF,MAAM,YAAY,YAAY,OAAO,SAAS,KAAK;EACnD,MAAM,aAAa,0BACjB,SACA,YACA,YAAY,OAAO,QAAQ,KAAK,YAAY,OAAO,UAAU,CAC/D;EACA,MAAM,cAAc,qBAClB,SACA,YACA,aACA,SACF;EACA,MAAM,SAAS,mBAAmB,OAAO,MAAM;EAE/C,OAAO;GACL;GACA;GACA,eAAe,YAAY,OAAO,aAAa,KAAK,KAAA;GACpD,YAAY,YAAY,OAAO,UAAU,KAAK,KAAA;GAC9C;GACA;GACA,aAAa,mBAAmB,WAAW;GAC3C;EACF;CACF,CAAC;CAED,MAAM,cACJ,QAAQ,SAAS,IACb,QACG,KACE,WAAW,OAAO,iBAAiB,OAAO,aAAa,OAAO,IACjE,CAAA,CACC,OAAO,OAAO,CAAA,CACd,KAAK,IACR,UAAU;CAIhB,MAAM,mBAAmB,yBACvB,cAAc,SAAS,WACrB;EACE,YAAY,OAAO,SAAS;EAC5B,YAAY,OAAO,IAAI;EACvB,YAAY,OAAO,aAAa;CAClC,CAAA,CAAE,QAAQ,SAAyB,QAAQ,IAAI,CAAC,CAClD,CACF;CACA,MAAM,gBAAgB,cAAc,SAAS,WAC3C,kBAAkB,QAAQ,gBAAgB,CAC5C;CAEA,OAAO;EACL;EACA;EACA;EACA,aAAa,cAAc,QAAQ,eAAe;EAClD,UAAU,cAAc,QAAQ,YAAY;EAC5C,eAAe,cAAc;EAC7B;CACF;AACF;AAEA,eAAe,kBAAkB,YAAuC;CACtE,OAAO,GAAG,CAAC,+BAA+B,yBAAyB,GAAG;EACpE,KAAK;EACL,UAAU;EACV,WAAW;EACX,QAAQ,CAAC,sBAAsB,mBAAmB;CACpD,CAAC;AACH;AAEA,eAAe,kBAAkB,YAAuC;CACtE,OAAO,GAAG,CAAC,mBAAmB,qBAAqB,GAAG;EACpD,KAAK;EACL,UAAU;EACV,WAAW;EACX,QAAQ,CAAC,oBAAoB;CAC/B,CAAC;AACH;AAEA,eAAe,gBACb,YACA,MACoC;CAepC,MAAM,gBAAe,MAdK,GACxB;EACE;EACA;EACA;CACF,GACA;EACE,KAAK;EACL,UAAU;EACV,WAAW;EACX,QAAQ;GAAC;GAAsB;GAAc;EAAmB;CAClE,CACF,EAAA,CAEiC,MAAM,GAAG,EAAE,CAAA,CAAE,KAAK,MAAM,WAAW;EAClE,IAAI,QAAQ;EACZ,OAAO,SAAS,YAAY,IAAI;EAChC;EACA,QAAQ;CACV,EAAE;CAEF,MAAM,SAAS,KAAK,MAAM,QAAQ,IAAI,SAAS,QAAQ;CACvD,MAAM,iBAAiB,QAAQ,UAC3B,wBAAwB,OAAO,OAAO,CAAA,CAAE,MAAM,GAAG,CAAC,IAClD,CAAC;CAEL,OAAO,CAAC,GAAG,cAAc,GAAG,cAAc;AAC5C;AAEA,SAAS,wBAAwB,SAA4C;CAC3E,MAAM,WAAsC,CAAC;CAC7C,MAAM,eAAe;CACrB,IAAI,QAAQ;CACZ,IAAI,QAAQ,aAAa,KAAK,OAAO;CAErC,OAAO,OAAO;EACZ,MAAM,WAAW,MAAM,MAAM,KAAA;EAC7B,MAAM,OAAO,MAAM,MAAM;EACzB,IAAI,CAAC,KAAK,KAAK,GAAG;GAChB,QAAQ,aAAa,KAAK,OAAO;GACjC;EACF;EAEA,MAAM,EAAE,SAAS,gBAAgB,SAAS,MAAM,aAAa;EAC7D,SAAS,KAAK;GACZ,IAAI,UAAU;GACd,OAAO,kBAAkB,QAAQ;GACjC;GACA,MAAM;GACN,QAAQ;EACV,CAAC;EACD,SAAS;EACT,QAAQ,aAAa,KAAK,OAAO;CACnC;CAEA,OAAO;AACT;AAEA,eAAe,iBACb,OACA,SACkC;CAClC,MAAM,EAAE,YAAY,aAAa,WAAW;CAC5C,MAAM,cACJ,YAAY,QAAQ,SAAS,SAAS,UAAU,KAAK;CACvD,MAAM,OAAO;EACX,aAAa,YAAY,aAAa,QAAQ;EAC9C,aAAa,YAAY,aAAa,QAAQ;EAC9C,aAAa,YAAY,gBAAgB,WAAW;CACtD,CAAA,CAAE,QAAQ,QAAyC,QAAQ,GAAG,CAAC;CAC/D,MAAM,WAAW,MAAM,gBAAgB,YAAY,IAAI;CACvD,MAAM,YAAY,qBAAqB,UAAU;CACjD,MAAM,aAAa,MAAM,kBAAkB,UAAU;CACrD,MAAM,aAAa,MAAM,kBAAkB,UAAU;CACrD,MAAM,UAAU,aAAa,YAAY,OAAO;CAChD,MAAM,MAAM,eACV,YACA,SACA,aACA,WACA,UACF;CAEA,OAAO;EACL,MAAM;EACN,SAAS,YAAY;EACrB,aAAa,YAAY;EACzB;EACA,WAAW;EACX,mBAAmB,SAAS,SAAS,UAAU,KAAK;EACpD;EACA,cAAc,aAAa,YAAY,YAAY;EACnD,iBAAiB,aAAa,YAAY,eAAe;EACzD,kBAAkB,aAAa,YAAY,gBAAgB;EAC3D,kBAAkB,oBAAoB,WAAW;EACjD,iBAAiB,mBAAmB,WAAW;EAC/C,YAAY,WAAW,YAAY,OAAO;EAC1C;EACA;EACA;EACA;EACA;EACA,kBAAkB;EAClB,YAAY;EACZ,sBAAsB;EACtB,qBAAqB,OAAO,KAAK,OAAO,CAAA,CACrC,QAAQ,eACP;GAAC;GAAQ;GAAa;GAAS;GAAS;GAAO;EAAW,CAAA,CAAE,SAC1D,UACF,CACF,CAAA,CACC,KAAK,CAAA,CACL,KAAK,gBAAgB;GACpB,IAAI,mBAAmB,aAAa,UAAU;GAC9C,OAAO;GACP,SAAS,iBAAiB,YAAW,GAAI;EAC3C,EAAE;CACN;AACF;AAEA,eAAe,6BACb,eACgC;CAOhC,QAAO,MANwB,GAAG,2BAA2B;EAC3D,KAAK;EACL,UAAU;EACV,WAAW;CACb,CAAC,EAAA,CAGE,KAAK,qBAAqB;EACzB,YAAY,QAAQ,eAAe;EACnC,aAAa,SAA0B,eAAe;EACtD,QAAQ;CACV,EAAE,CAAA,CACD,QACE,SACC,OAAO,KAAK,YAAY,SAAS,YACjC,KAAK,YAAY,KAAK,WAAW,sBAAsB,CAC3D,CAAA,CACC,MAAM,MAAM,WACV,KAAK,YAAY,QAAQ,GAAA,CAAI,cAAc,MAAM,YAAY,QAAQ,EAAE,CAC1E;AACJ;AAEA,SAAS,4BACP,aACA,aACe;CACf,MAAM,kBAAkB,KACtB,aACA,gBACA,aACA,cACF;CACA,OAAO,WAAW,eAAe,IAAI,QAAQ,eAAe,IAAI;AAClE;AAEA,eAAe,4BACb,aACgC;CAChC,MAAM,kBAAkB,KAAK,aAAa,cAAc;CACxD,IAAI,CAAC,WAAW,eAAe,GAC7B,OAAO,CAAC;CAGV,MAAM,cAAc,SAA0B,eAAe;CAC7D,MAAM,eAAe;EACnB,GAAG,YAAY;EACf,GAAG,YAAY;EACf,GAAG,YAAY;CACjB;CACA,MAAM,cAAqC,CAAC;CAE5C,YAAY,KAAK;EACf,YAAY;EACZ;EACA,QAAQ,YAAY,MAAM,WAAW,sBAAsB,IACvD,YACA;CACN,CAAC;CAED,KAAA,MAAW,kBAAkB,OAAO,KAAK,YAAY,CAAA,CAAE,KAAK,GAAG;EAC7D,IACE,CAAC,eAAe,WAAW,sBAAsB,KACjD,mBAAmB,iCAEnB;EAGF,MAAM,aAAa,4BAA4B,aAAa,cAAc;EAC1E,IAAI,CAAC,YACH;EAGF,YAAY,KAAK;GACf;GACA,aAAa,SAA0B,KAAK,YAAY,cAAc,CAAC;GACvE,QAAQ;EACV,CAAC;CACH;CAEA,OAAO;AACT;AAEA,SAAS,qBACP,eACA,aACe;CACf,MAAM,cAAc,KAAK,eAAe,UAAU;CAClD,IAAI,CAAC,WAAW,WAAW,GACzB,OAAO;CAGT,MAAM,mBAAmB,GAAG,KAAK,kBAAkB;EACjD,KAAK;EACL,UAAU;EACV,WAAW;CACb,CAAC;CAED,KAAA,MAAW,mBAAmB,kBAE5B,IADoB,SAA0B,eAC1C,CAAA,CAAY,SAAS,aACvB,OAAO,QAAQ,eAAe;CAIlC,OAAO;AACT;AAEO,SAAS,sBACd,MAAM,QAAQ,IAAI,GAClB,UAGI,CAAC,GACqB;CAC1B,MAAM,cAAc,QAAQ,GAAG;CAC/B,MAAM,uBAAuB,QAAQ,cACjC,QAAQ,QAAQ,WAAW,IAC3B,KAAA;CACJ,MAAM,gBACJ,QAAQ,kBACP,uBACG,+BAA+B,oBAAoB,IACnD,SACJ,+BAA+B,WAAW;CAE5C,IAAI,eAAe;EACjB,MAAM,cACH,QAAQ,cACL,qBAAqB,eAAe,QAAQ,WAAW,IACvD,SACJ,eAAe,aAAa,aAAa,KACzC,KAAA;EACF,MAAM,cAAc,aAChB,iBAAkC,KAAK,YAAY,cAAc,CAAC,IAClE;EACJ,MAAM,cAAc,QAAQ,eAAe,aAAa;EAGxD,OAAO;GACL,MAHmC,cAAc,YAAY;GAI7D,KAAK;GACL,aAAa;GACb;GACA;GACA;GACA,gBAAgB;EAClB;CACF;CAEA,MAAM,cAAc,wBAAwB,gBAAgB,WAAW;CACvE,OAAO;EACL,MAAM;EACN,KAAK;EACL;EACA,aAAa,QAAQ;EACrB,gBAAgB,qBAAqB,WAAW;CAClD;AACF;AAEA,eAAsB,sBACpB,OAC+B;CAC/B,MAAM,cACJ,MAAM,SAAS,aACX,MAAM,4BAA4B,MAAM,WAAW,IACnD,MAAM,6BAA6B,MAAM,WAAW;CAE1D,MAAM,sBAAsB,MAAM,cAC9B,YAAY,QAAQ,SAAS,KAAK,YAAY,SAAS,MAAM,WAAW,IACxE;CAEJ,MAAM,WAAW,MAAM,QAAQ,IAC7B,oBAAoB,KAAK,SACvB,iBAAiB,MAAM,MAAM,WAAW,CAC1C,CACF;CAEA,OAAO;EACL,8BAAa,IAAI,KAAK,EAAA,CAAE,YAAY;EACpC;EACA;CACF;AACF;AAEA,eAAsB,6BACpB,eACA,kBAAkB,+BACoB;CAOtC,QAAO,MANe,GAAG,iBAAiB;EACxC,KAAK;EACL,UAAU;EACV,WAAW;CACb,CAAC,EAAA,CAEc,KAAK,CAAA,CAAE,KAAK,eAAe;EACxC,MAAM,aAAa,QAAQ,QAAQ,UAAU,CAAC;EAE9C,MAAM,cAAc,SADI,KAAK,YAAY,cACK,CAAe;EAC7D,MAAM,cAAc,KAAK,YAAY,QAAQ,cAAc;EAE3D,OAAO;GACL,aAAa,YAAY;GACzB,QAAQ;GACR;GACA,aAAa,WAAW,WAAW,IAAI,cAAc,KAAA;EACvD;CACF,CAAC;AACH;AAEA,eAAsB,6BACpB,cAAc,QAAQ,IAAI,GACY;CACtC,MAAM,kBAAkB,KAAK,aAAa,cAAc;CACxD,IAAI,CAAC,WAAW,eAAe,GAC7B,OAAO,CAAC;CAGV,MAAM,cAAc,SAA0B,eAAe;CAC7D,MAAM,eAAe;EACnB,GAAG,YAAY;EACf,GAAG,YAAY;EACf,GAAG,YAAY;CACjB;CACA,MAAM,aAA0C,CAAC;CAEjD,KAAA,MAAW,kBAAkB,OAAO,KAAK,YAAY,CAAA,CAAE,KAAK,GAAG;EAC7D,IACE,CAAC,eAAe,WAAW,sBAAsB,KACjD,mBAAmB,iCAEnB;EAGF,MAAM,aAAa,4BAA4B,aAAa,cAAc;EAC1E,IAAI,CAAC,YACH;EAMF,IAAI,WAH0B,SAC5B,KAAK,YAAY,cAAc,CAElB,CAAA,CAAsB,OAAO,CAAA,CAAE,SAAS,aAAa,GAClE,WAAW,KAAK;GACd,aAAa;GACb,QAAQ;GACR,iBAAiB,GAAG,eAAc;EACpC,CAAC;CAEL;CAEA,OAAO;AACT;AAEA,eAAsB,yBACpB,cAAc,QAAQ,IAAI,GAC1B,OAA0C,QAC1C,qBAAqB,oBACrB,aACA,kBAAkB,+BACoB;CAItC,KAFE,SAAS,SAAS,oBAAoB,WAAW,IAAI,UAEjC,aAAa;EACjC,MAAM,gBACJ,SAAS,cACL,kBAAkB,WAAW,IAC7B,+BAA+B,WAAW;EAChD,IAAI,CAAC,eACH,OAAO,CAAC;EAGV,MAAMA,WAAU,MAAM,6BACpB,eACA,eACF;EACA,OAAO,cACHA,SAAQ,QAAQ,WAAW,OAAO,gBAAgB,WAAW,IAC7DA;CACN;CAEA,MAAM,UAAU,MAAM,6BAA6B,WAAW;CAC9D,MAAM,YAAY,QAAQ,aAAa,kBAAkB;CACzD,IAAI,WAAW,SAAS,GAAG;EACzB,MAAM,mBAAmB,iBACvB,KAAK,aAAa,cAAc,CAClC;EACA,QAAQ,KAAK;GACX,aAAa,kBAAkB;GAC/B,QAAQ;GACR,YAAY;EACd,CAAC;CACH;CAEA,OAAO,cACH,QAAQ,QAAQ,WAAW,OAAO,gBAAgB,WAAW,IAC7D;AACN;AAEA,eAAsB,sBACpB,OACgC;CAChC,MAAM,WACJ,WAAW,KAAK,KAAK,MAAM,WAAW,GAAG,IACrC,MAAM,iBAAiB,QAAQ,KAAK,CAAC,IACrC,MAAM;;EAA0B;;CAEtC,MAAM,SAAS,SAAS,WAAW,SAAS,aAAa;CACzD,OAAO,UAAU,OAAO,WAAW,WAC/B,uBAAuB,MAA6B,IACpD,CAAC;AACP;AAEA,eAAe,iBAAiB,WAAqC;CACnE,IAAI,CAAC,qBAAqB,IAAI,QAAQ,SAAS,CAAC,GAC9C,OAAO;;EAA0B,cAAc,SAAS,CAAA,CAAE;;CAG5D,IAAI;CACJ,IAAI;EACF,aAAa,QAAQ,QAAQ,aAAa;CAC5C,SAAS,UAAU;EACjB,MAAM,IAAI,MACR,wCAAwC,UAAS,2DACjD,EAAE,OAAO,SAAS,CACpB;CACF;CAEA,MAAM,EAAE,aAAa,MAAM;;EACN,cAAc,UAAU,CAAA,CAAE;;CAE/C,OAAO,SAAS,cAAc,SAAS,CAAA,CAAE,MAAM,EAC7C,WAAW,OAAA,KAAY,IACzB,CAAC;AACH;AAEO,SAAS,wBACd,QACA,MAAM,QAAQ,IAAI,GACV;CACR,IAAI,OAAO,WAAW,WACpB,OAAO,OAAO,mBAAmB,OAAO,eAAe;CAGzD,MAAM,OAAO,OAAO,cAAc,OAAO;CACzC,OAAO,OAAO,SAAS,KAAK,IAAI,KAAK,MAAM,OAAO;AACpD"}
|
package/dist/discovery.d.ts
CHANGED
|
@@ -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[]>;
|
package/dist/discovery.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"
|
|
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-
|
|
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-
|
|
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.
|
|
3
|
+
"version": "0.47.0",
|
|
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.0",
|
|
46
|
+
"@happyvertical/smrt-playground": "0.47.0",
|
|
47
|
+
"@happyvertical/smrt-svelte": "0.47.0",
|
|
48
|
+
"@happyvertical/smrt-ui": "0.47.0",
|
|
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.45.3",
|
|
53
|
-
"@happyvertical/smrt-svelte": "0.45.3",
|
|
54
|
-
"@happyvertical/smrt-ui": "0.45.3"
|
|
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
|
-
|
|
988
|
-
|
|
989
|
-
.
|
|
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
|
|
1039
|
+
function methodDefinition(
|
|
1005
1040
|
object: Record<string, unknown>,
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1041
|
+
action: string,
|
|
1042
|
+
): Record<string, unknown> {
|
|
1043
|
+
return configObject(configObject(object.methods)[action]);
|
|
1044
|
+
}
|
|
1009
1045
|
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
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
|
|
1064
|
+
function customRouteMethod(
|
|
1018
1065
|
object: Record<string, unknown>,
|
|
1019
1066
|
action: string,
|
|
1020
|
-
):
|
|
1021
|
-
return
|
|
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
|
|
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
|
|
1121
|
+
return effectiveScope(object, action) === 'collection'
|
|
1044
1122
|
? `/api/v1/${collection}/${normalizedPath}`
|
|
1045
1123
|
: `/api/v1/${collection}/{id}/${normalizedPath}`;
|
|
1046
1124
|
}
|
|
1047
1125
|
|
|
1048
|
-
|
|
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
|
|
1084
|
-
|
|
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
|
-
|
|
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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"}
|