@happyvertical/smrt-core 0.55.1 → 0.55.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/AGENTS.md +8 -0
  2. package/agents/build-knowledge.md +42 -0
  3. package/agents/generators.md +13 -0
  4. package/agents/recipes.md +150 -0
  5. package/dist/browser.d.ts +3 -0
  6. package/dist/browser.d.ts.map +1 -1
  7. package/dist/browser.js +4 -1
  8. package/dist/generators/mcp.d.ts.map +1 -1
  9. package/dist/generators/mcp.js +10 -6
  10. package/dist/generators/mcp.js.map +1 -1
  11. package/dist/generators/swagger.d.ts.map +1 -1
  12. package/dist/generators/swagger.js +3 -0
  13. package/dist/generators/swagger.js.map +1 -1
  14. package/dist/generators/tool-schema.d.ts +9 -0
  15. package/dist/generators/tool-schema.d.ts.map +1 -1
  16. package/dist/generators/tool-schema.js +10 -7
  17. package/dist/generators/tool-schema.js.map +1 -1
  18. package/dist/index.d.ts +3 -0
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +4 -1
  21. package/dist/knowledge.d.ts.map +1 -1
  22. package/dist/knowledge.js +13 -2
  23. package/dist/knowledge.js.map +1 -1
  24. package/dist/manifest/generator.d.ts.map +1 -1
  25. package/dist/manifest/generator.js +3 -1
  26. package/dist/manifest/generator.js.map +1 -1
  27. package/dist/manifest/static-manifest.js +1 -1
  28. package/dist/manifest/static-manifest.js.map +1 -1
  29. package/dist/manifest/store.js +1 -1
  30. package/dist/manifest.json +1 -1
  31. package/dist/object.d.ts.map +1 -1
  32. package/dist/object.js +9 -3
  33. package/dist/object.js.map +1 -1
  34. package/dist/prebuild/index.d.ts.map +1 -1
  35. package/dist/prebuild/index.js +1 -0
  36. package/dist/prebuild/index.js.map +1 -1
  37. package/dist/recipe-help.d.ts +186 -0
  38. package/dist/recipe-help.d.ts.map +1 -0
  39. package/dist/recipe-help.js +311 -0
  40. package/dist/recipe-help.js.map +1 -0
  41. package/dist/recipe.d.ts +83 -0
  42. package/dist/recipe.d.ts.map +1 -0
  43. package/dist/recipe.js +30 -0
  44. package/dist/recipe.js.map +1 -0
  45. package/dist/registry/manifest-field-merge.d.ts +6 -0
  46. package/dist/registry/manifest-field-merge.d.ts.map +1 -1
  47. package/dist/registry/manifest-field-merge.js +12 -1
  48. package/dist/registry/manifest-field-merge.js.map +1 -1
  49. package/dist/registry/types.d.ts +17 -0
  50. package/dist/registry/types.d.ts.map +1 -1
  51. package/dist/scanner/index.d.ts +1 -1
  52. package/dist/scanner/index.d.ts.map +1 -1
  53. package/dist/scanner/manifest-generator.d.ts +33 -0
  54. package/dist/scanner/manifest-generator.d.ts.map +1 -1
  55. package/dist/scanner/manifest-generator.js +124 -0
  56. package/dist/scanner/manifest-generator.js.map +1 -1
  57. package/dist/scanner/types.d.ts +47 -0
  58. package/dist/scanner/types.d.ts.map +1 -1
  59. package/dist/scanner/types.js.map +1 -1
  60. package/dist/smrt-knowledge.json +16 -9
  61. package/dist/ui-metadata.d.ts +60 -0
  62. package/dist/ui-metadata.d.ts.map +1 -0
  63. package/dist/ui-metadata.js +85 -0
  64. package/dist/ui-metadata.js.map +1 -0
  65. package/dist/utils/scanner-module.d.ts +18 -1
  66. package/dist/utils/scanner-module.d.ts.map +1 -1
  67. package/dist/vite-plugin/index.d.ts.map +1 -1
  68. package/dist/vite-plugin/index.js +4 -1
  69. package/dist/vite-plugin/index.js.map +1 -1
  70. package/dist/vite-plugin/web-collections.d.ts.map +1 -1
  71. package/dist/vite-plugin/web-collections.js +8 -3
  72. package/dist/vite-plugin/web-collections.js.map +1 -1
  73. package/package.json +15 -10
@@ -1 +1 @@
1
- {"version":3,"file":"swagger.d.ts","sourceRoot":"","sources":["../../src/generators/swagger.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAUD,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE3C;;;GAGG;AACH,UAAU,UAAU;IAClB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACnD,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;CACpD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,GAAE,aAAkB,GAAG,WAAW,CAuD3E;AAsRD;;GAEG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,UAAU,EACf,IAAI,EAAE,WAAW,EACjB,IAAI,SAAU,QAwBf"}
1
+ {"version":3,"file":"swagger.d.ts","sourceRoot":"","sources":["../../src/generators/swagger.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAUD,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE3C;;;GAGG;AACH,UAAU,UAAU;IAClB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACnD,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;CACpD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,GAAE,aAAkB,GAAG,WAAW,CAuD3E;AAgSD;;GAEG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,UAAU,EACf,IAAI,EAAE,WAAW,EACjB,IAAI,SAAU,QAwBf"}
@@ -1,4 +1,5 @@
1
1
  import { __require } from "../_virtual/_rolldown/runtime.js";
2
+ import { readFieldEnum } from "../registry/manifest-field-merge.js";
2
3
  import { ObjectRegistry } from "../registry.js";
3
4
  //#region src/generators/swagger.ts
4
5
  /**
@@ -152,6 +153,8 @@ function fieldToOpenAPISchema(field) {
152
153
  default: schema.type = "string";
153
154
  }
154
155
  if (field._meta?.default !== void 0) schema.default = field._meta.default;
156
+ const allowed = readFieldEnum(field);
157
+ if (allowed && (field.type === "text" || field.type === "integer" || field.type === "decimal")) schema.enum = [...allowed];
155
158
  return schema;
156
159
  }
157
160
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"swagger.js","names":[],"sources":["../../src/generators/swagger.ts"],"sourcesContent":["/**\n * OpenAPI documentation generation for smrt APIs\n *\n * Lightweight implementation with optional Swagger UI\n */\n\nimport { ObjectRegistry } from '../registry';\nimport type { FieldDefinition } from '../scanner/types';\n\nexport interface OpenAPIConfig {\n title?: string;\n version?: string;\n description?: string;\n basePath?: string;\n serverUrl?: string;\n}\n\n/**\n * Loose structural types for the generated OpenAPI 3.0 document. The generator\n * builds these objects by progressively assigning heterogeneous spec fields, so\n * the value surface is intentionally open (`unknown`) rather than a fully-typed\n * OpenAPI model (no shared OpenAPI types are available in this package).\n */\ntype OpenAPISchemaObject = Record<string, unknown>;\ntype OpenAPIPathItem = Record<string, unknown>;\ntype OpenAPISpec = Record<string, unknown>;\n\n/**\n * Minimal Express-like surface consumed by {@link setupSwaggerUI}. Avoids a hard\n * dependency on Express types for what is an optional integration helper.\n */\ninterface SwaggerApp {\n use(path: string, ...handlers: unknown[]): unknown;\n get(path: string, ...handlers: unknown[]): unknown;\n}\n\n/**\n * Generate OpenAPI specification (tree-shakeable)\n */\nexport function generateOpenAPISpec(config: OpenAPIConfig = {}): OpenAPISpec {\n const {\n title = 'smrt API',\n version = '1.0.0',\n description = 'Auto-generated API from smrt objects',\n basePath = '/api/v1',\n serverUrl = 'http://localhost:3000',\n } = config;\n\n const spec = {\n openapi: '3.0.3',\n info: { title, version, description },\n servers: [{ url: serverUrl }],\n security: [{ bearerAuth: [] }],\n components: {\n securitySchemes: {\n bearerAuth: {\n type: 'http',\n scheme: 'bearer',\n bearerFormat: 'JWT',\n },\n },\n schemas: generateSchemas(),\n responses: {\n ValidationError: {\n description: 'Validation error',\n content: {\n 'application/json': {\n schema: {\n type: 'object',\n properties: {\n error: { type: 'string' },\n details: { type: 'string' },\n },\n },\n },\n },\n },\n NotFound: {\n description: 'Resource not found',\n content: {\n 'application/json': {\n schema: {\n type: 'object',\n properties: { error: { type: 'string' } },\n },\n },\n },\n },\n },\n },\n paths: generatePaths(basePath),\n };\n\n return spec;\n}\n\n/**\n * Generate schemas for all registered objects\n */\nfunction generateSchemas(): Record<string, OpenAPISchemaObject> {\n const schemas: Record<string, OpenAPISchemaObject> = {};\n const registeredClasses = ObjectRegistry.getAllClasses();\n\n for (const [key, classInfo] of registeredClasses) {\n // Issue #951: Use simple name for schema keys, not the qualified map key\n const name = classInfo.name || key;\n // `api: false` disables REST generation (see rest.ts) and is already\n // skipped in generatePaths(); mirror that here so component schemas don't\n // leak the field shape of a surface with no working handlers. Skip ONLY\n // when api is explicitly false — default (undefined) and\n // `{ include: [...] }` configs still publish their schema (#1540).\n if (ObjectRegistry.getConfig(name).api === false) {\n continue;\n }\n schemas[name] = generateObjectSchema(name);\n schemas[`${name}List`] = {\n type: 'object',\n properties: {\n data: {\n type: 'array',\n items: { $ref: `#/components/schemas/${name}` },\n },\n meta: {\n type: 'object',\n properties: {\n total: { type: 'integer' },\n limit: { type: 'integer' },\n offset: { type: 'integer' },\n count: { type: 'integer' },\n },\n },\n },\n };\n }\n\n return schemas;\n}\n\n/**\n * Generate schema for a specific object\n */\nfunction generateObjectSchema(objectName: string): OpenAPISchemaObject {\n const fields = ObjectRegistry.getFields(objectName);\n const properties: Record<string, OpenAPISchemaObject> = {\n id: { type: 'string', format: 'uuid' },\n slug: { type: 'string' },\n created_at: { type: 'string', format: 'date-time' },\n updated_at: { type: 'string', format: 'date-time' },\n };\n\n const required = ['id'];\n\n for (const [fieldName, field] of fields) {\n properties[fieldName] = fieldToOpenAPISchema(field);\n if (field._meta?.required) {\n required.push(fieldName);\n }\n }\n\n return { type: 'object', properties, required };\n}\n\n/**\n * Convert field to OpenAPI schema\n */\nfunction fieldToOpenAPISchema(field: FieldDefinition): OpenAPISchemaObject {\n const schema: OpenAPISchemaObject = {\n description: field._meta?.description || '',\n };\n\n switch (field.type) {\n case 'text':\n schema.type = 'string';\n if (field._meta?.maxLength) schema.maxLength = field._meta.maxLength;\n if (field._meta?.minLength) schema.minLength = field._meta.minLength;\n break;\n case 'integer':\n schema.type = 'integer';\n if (field._meta?.min !== undefined) schema.minimum = field._meta.min;\n if (field._meta?.max !== undefined) schema.maximum = field._meta.max;\n break;\n case 'decimal':\n schema.type = 'number';\n schema.format = 'float';\n if (field._meta?.min !== undefined) schema.minimum = field._meta.min;\n if (field._meta?.max !== undefined) schema.maximum = field._meta.max;\n break;\n case 'boolean':\n schema.type = 'boolean';\n break;\n case 'datetime':\n schema.type = 'string';\n schema.format = 'date-time';\n break;\n case 'json':\n schema.type = 'object';\n schema.additionalProperties = true;\n break;\n case 'foreignKey':\n schema.type = 'string';\n schema.format = 'uuid';\n break;\n default:\n schema.type = 'string';\n }\n\n if (field._meta?.default !== undefined) {\n schema.default = field._meta.default;\n }\n\n return schema;\n}\n\n/**\n * Generate API paths\n */\nfunction generatePaths(basePath: string): Record<string, OpenAPIPathItem> {\n const paths: Record<string, OpenAPIPathItem> = {};\n const registeredClasses = ObjectRegistry.getAllClasses();\n\n for (const [key, classInfo] of registeredClasses) {\n // Issue #951: Use simple name, not the qualified map key\n const name = classInfo.name || key;\n const pluralName = pluralize(name.toLowerCase());\n const objectPath = `${basePath}/${pluralName}`;\n\n const config = ObjectRegistry.getConfig(name);\n const apiConfig = config.api;\n // `api: false` disables REST generation (see rest.ts); don't advertise its\n // paths in the OpenAPI spec either, or the spec leaks the shape of a\n // surface that has no working handlers (#1540).\n if (apiConfig === false) {\n continue;\n }\n const excluded: string[] =\n typeof apiConfig === 'object' && apiConfig?.exclude\n ? apiConfig.exclude\n : [];\n const included: string[] | undefined =\n typeof apiConfig === 'object' ? apiConfig?.include : undefined;\n\n const shouldInclude = (\n endpoint: 'list' | 'get' | 'create' | 'update' | 'delete',\n ) => {\n if (included && !included.includes(endpoint)) return false;\n if (excluded.includes(endpoint)) return false;\n return true;\n };\n\n // Collection endpoints\n paths[objectPath] = {};\n\n if (shouldInclude('list')) {\n paths[objectPath].get = {\n summary: `List ${name} objects`,\n tags: [name],\n parameters: [\n {\n name: 'limit',\n in: 'query',\n schema: { type: 'integer', default: 50 },\n },\n {\n name: 'offset',\n in: 'query',\n schema: { type: 'integer', default: 0 },\n },\n ],\n responses: {\n '200': {\n description: 'Success',\n content: {\n 'application/json': {\n schema: { $ref: `#/components/schemas/${name}List` },\n },\n },\n },\n },\n };\n }\n\n if (shouldInclude('create')) {\n paths[objectPath].post = {\n summary: `Create ${name}`,\n tags: [name],\n requestBody: {\n required: true,\n content: {\n 'application/json': {\n schema: { $ref: `#/components/schemas/${name}` },\n },\n },\n },\n responses: {\n '201': { description: 'Created' },\n '400': { $ref: '#/components/responses/ValidationError' },\n },\n };\n }\n\n // Item endpoints\n paths[`${objectPath}/{id}`] = {};\n\n if (shouldInclude('get')) {\n paths[`${objectPath}/{id}`].get = {\n summary: `Get ${name} by ID`,\n tags: [name],\n parameters: [\n {\n name: 'id',\n in: 'path',\n required: true,\n schema: { type: 'string' },\n },\n ],\n responses: {\n '200': { description: 'Success' },\n '404': { $ref: '#/components/responses/NotFound' },\n },\n };\n }\n\n if (shouldInclude('update')) {\n paths[`${objectPath}/{id}`].put = {\n summary: `Update ${name}`,\n tags: [name],\n parameters: [\n {\n name: 'id',\n in: 'path',\n required: true,\n schema: { type: 'string' },\n },\n ],\n requestBody: {\n required: true,\n content: {\n 'application/json': {\n schema: { $ref: `#/components/schemas/${name}` },\n },\n },\n },\n responses: {\n '200': { description: 'Updated' },\n '404': { $ref: '#/components/responses/NotFound' },\n },\n };\n }\n\n if (shouldInclude('delete')) {\n paths[`${objectPath}/{id}`].delete = {\n summary: `Delete ${name}`,\n tags: [name],\n parameters: [\n {\n name: 'id',\n in: 'path',\n required: true,\n schema: { type: 'string' },\n },\n ],\n responses: {\n '204': { description: 'Deleted' },\n '404': { $ref: '#/components/responses/NotFound' },\n },\n };\n }\n }\n\n return paths;\n}\n\n/**\n * Setup Swagger UI (optional peer dependency)\n */\nexport function setupSwaggerUI(\n app: SwaggerApp,\n spec: OpenAPISpec,\n path = '/docs',\n) {\n try {\n const swaggerUi = require('swagger-ui-express');\n\n app.use(path, swaggerUi.serve);\n app.get(\n path,\n swaggerUi.setup(spec, {\n customCss: '.swagger-ui .topbar { display: none }',\n }),\n );\n\n app.get(\n `${path}/openapi.json`,\n (_req: unknown, res: { json(body: unknown): void }) => {\n res.json(spec);\n },\n );\n\n console.log(`📚 Swagger UI available at ${path}`);\n } catch (_error) {\n console.warn('Swagger UI not available (install swagger-ui-express)');\n }\n}\n\nfunction pluralize(word: string): string {\n if (word.endsWith('y')) return `${word.slice(0, -1)}ies`;\n if (\n word.endsWith('s') ||\n word.endsWith('x') ||\n word.endsWith('z') ||\n word.endsWith('ch') ||\n word.endsWith('sh')\n )\n return `${word}es`;\n return `${word}s`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"swagger.js","names":[],"sources":["../../src/generators/swagger.ts"],"sourcesContent":["/**\n * OpenAPI documentation generation for smrt APIs\n *\n * Lightweight implementation with optional Swagger UI\n */\n\nimport { ObjectRegistry } from '../registry';\nimport { readFieldEnum } from '../registry/manifest-field-merge.js';\nimport type { FieldDefinition } from '../scanner/types';\n\nexport interface OpenAPIConfig {\n title?: string;\n version?: string;\n description?: string;\n basePath?: string;\n serverUrl?: string;\n}\n\n/**\n * Loose structural types for the generated OpenAPI 3.0 document. The generator\n * builds these objects by progressively assigning heterogeneous spec fields, so\n * the value surface is intentionally open (`unknown`) rather than a fully-typed\n * OpenAPI model (no shared OpenAPI types are available in this package).\n */\ntype OpenAPISchemaObject = Record<string, unknown>;\ntype OpenAPIPathItem = Record<string, unknown>;\ntype OpenAPISpec = Record<string, unknown>;\n\n/**\n * Minimal Express-like surface consumed by {@link setupSwaggerUI}. Avoids a hard\n * dependency on Express types for what is an optional integration helper.\n */\ninterface SwaggerApp {\n use(path: string, ...handlers: unknown[]): unknown;\n get(path: string, ...handlers: unknown[]): unknown;\n}\n\n/**\n * Generate OpenAPI specification (tree-shakeable)\n */\nexport function generateOpenAPISpec(config: OpenAPIConfig = {}): OpenAPISpec {\n const {\n title = 'smrt API',\n version = '1.0.0',\n description = 'Auto-generated API from smrt objects',\n basePath = '/api/v1',\n serverUrl = 'http://localhost:3000',\n } = config;\n\n const spec = {\n openapi: '3.0.3',\n info: { title, version, description },\n servers: [{ url: serverUrl }],\n security: [{ bearerAuth: [] }],\n components: {\n securitySchemes: {\n bearerAuth: {\n type: 'http',\n scheme: 'bearer',\n bearerFormat: 'JWT',\n },\n },\n schemas: generateSchemas(),\n responses: {\n ValidationError: {\n description: 'Validation error',\n content: {\n 'application/json': {\n schema: {\n type: 'object',\n properties: {\n error: { type: 'string' },\n details: { type: 'string' },\n },\n },\n },\n },\n },\n NotFound: {\n description: 'Resource not found',\n content: {\n 'application/json': {\n schema: {\n type: 'object',\n properties: { error: { type: 'string' } },\n },\n },\n },\n },\n },\n },\n paths: generatePaths(basePath),\n };\n\n return spec;\n}\n\n/**\n * Generate schemas for all registered objects\n */\nfunction generateSchemas(): Record<string, OpenAPISchemaObject> {\n const schemas: Record<string, OpenAPISchemaObject> = {};\n const registeredClasses = ObjectRegistry.getAllClasses();\n\n for (const [key, classInfo] of registeredClasses) {\n // Issue #951: Use simple name for schema keys, not the qualified map key\n const name = classInfo.name || key;\n // `api: false` disables REST generation (see rest.ts) and is already\n // skipped in generatePaths(); mirror that here so component schemas don't\n // leak the field shape of a surface with no working handlers. Skip ONLY\n // when api is explicitly false — default (undefined) and\n // `{ include: [...] }` configs still publish their schema (#1540).\n if (ObjectRegistry.getConfig(name).api === false) {\n continue;\n }\n schemas[name] = generateObjectSchema(name);\n schemas[`${name}List`] = {\n type: 'object',\n properties: {\n data: {\n type: 'array',\n items: { $ref: `#/components/schemas/${name}` },\n },\n meta: {\n type: 'object',\n properties: {\n total: { type: 'integer' },\n limit: { type: 'integer' },\n offset: { type: 'integer' },\n count: { type: 'integer' },\n },\n },\n },\n };\n }\n\n return schemas;\n}\n\n/**\n * Generate schema for a specific object\n */\nfunction generateObjectSchema(objectName: string): OpenAPISchemaObject {\n const fields = ObjectRegistry.getFields(objectName);\n const properties: Record<string, OpenAPISchemaObject> = {\n id: { type: 'string', format: 'uuid' },\n slug: { type: 'string' },\n created_at: { type: 'string', format: 'date-time' },\n updated_at: { type: 'string', format: 'date-time' },\n };\n\n const required = ['id'];\n\n for (const [fieldName, field] of fields) {\n properties[fieldName] = fieldToOpenAPISchema(field);\n if (field._meta?.required) {\n required.push(fieldName);\n }\n }\n\n return { type: 'object', properties, required };\n}\n\n/**\n * Convert field to OpenAPI schema\n */\nfunction fieldToOpenAPISchema(field: FieldDefinition): OpenAPISchemaObject {\n const schema: OpenAPISchemaObject = {\n description: field._meta?.description || '',\n };\n\n switch (field.type) {\n case 'text':\n schema.type = 'string';\n if (field._meta?.maxLength) schema.maxLength = field._meta.maxLength;\n if (field._meta?.minLength) schema.minLength = field._meta.minLength;\n break;\n case 'integer':\n schema.type = 'integer';\n if (field._meta?.min !== undefined) schema.minimum = field._meta.min;\n if (field._meta?.max !== undefined) schema.maximum = field._meta.max;\n break;\n case 'decimal':\n schema.type = 'number';\n schema.format = 'float';\n if (field._meta?.min !== undefined) schema.minimum = field._meta.min;\n if (field._meta?.max !== undefined) schema.maximum = field._meta.max;\n break;\n case 'boolean':\n schema.type = 'boolean';\n break;\n case 'datetime':\n schema.type = 'string';\n schema.format = 'date-time';\n break;\n case 'json':\n schema.type = 'object';\n schema.additionalProperties = true;\n break;\n case 'foreignKey':\n schema.type = 'string';\n schema.format = 'uuid';\n break;\n default:\n schema.type = 'string';\n }\n\n if (field._meta?.default !== undefined) {\n schema.default = field._meta.default;\n }\n\n const allowed = readFieldEnum(field);\n if (\n allowed &&\n (field.type === 'text' ||\n field.type === 'integer' ||\n field.type === 'decimal')\n ) {\n schema.enum = [...allowed];\n }\n\n return schema;\n}\n\n/**\n * Generate API paths\n */\nfunction generatePaths(basePath: string): Record<string, OpenAPIPathItem> {\n const paths: Record<string, OpenAPIPathItem> = {};\n const registeredClasses = ObjectRegistry.getAllClasses();\n\n for (const [key, classInfo] of registeredClasses) {\n // Issue #951: Use simple name, not the qualified map key\n const name = classInfo.name || key;\n const pluralName = pluralize(name.toLowerCase());\n const objectPath = `${basePath}/${pluralName}`;\n\n const config = ObjectRegistry.getConfig(name);\n const apiConfig = config.api;\n // `api: false` disables REST generation (see rest.ts); don't advertise its\n // paths in the OpenAPI spec either, or the spec leaks the shape of a\n // surface that has no working handlers (#1540).\n if (apiConfig === false) {\n continue;\n }\n const excluded: string[] =\n typeof apiConfig === 'object' && apiConfig?.exclude\n ? apiConfig.exclude\n : [];\n const included: string[] | undefined =\n typeof apiConfig === 'object' ? apiConfig?.include : undefined;\n\n const shouldInclude = (\n endpoint: 'list' | 'get' | 'create' | 'update' | 'delete',\n ) => {\n if (included && !included.includes(endpoint)) return false;\n if (excluded.includes(endpoint)) return false;\n return true;\n };\n\n // Collection endpoints\n paths[objectPath] = {};\n\n if (shouldInclude('list')) {\n paths[objectPath].get = {\n summary: `List ${name} objects`,\n tags: [name],\n parameters: [\n {\n name: 'limit',\n in: 'query',\n schema: { type: 'integer', default: 50 },\n },\n {\n name: 'offset',\n in: 'query',\n schema: { type: 'integer', default: 0 },\n },\n ],\n responses: {\n '200': {\n description: 'Success',\n content: {\n 'application/json': {\n schema: { $ref: `#/components/schemas/${name}List` },\n },\n },\n },\n },\n };\n }\n\n if (shouldInclude('create')) {\n paths[objectPath].post = {\n summary: `Create ${name}`,\n tags: [name],\n requestBody: {\n required: true,\n content: {\n 'application/json': {\n schema: { $ref: `#/components/schemas/${name}` },\n },\n },\n },\n responses: {\n '201': { description: 'Created' },\n '400': { $ref: '#/components/responses/ValidationError' },\n },\n };\n }\n\n // Item endpoints\n paths[`${objectPath}/{id}`] = {};\n\n if (shouldInclude('get')) {\n paths[`${objectPath}/{id}`].get = {\n summary: `Get ${name} by ID`,\n tags: [name],\n parameters: [\n {\n name: 'id',\n in: 'path',\n required: true,\n schema: { type: 'string' },\n },\n ],\n responses: {\n '200': { description: 'Success' },\n '404': { $ref: '#/components/responses/NotFound' },\n },\n };\n }\n\n if (shouldInclude('update')) {\n paths[`${objectPath}/{id}`].put = {\n summary: `Update ${name}`,\n tags: [name],\n parameters: [\n {\n name: 'id',\n in: 'path',\n required: true,\n schema: { type: 'string' },\n },\n ],\n requestBody: {\n required: true,\n content: {\n 'application/json': {\n schema: { $ref: `#/components/schemas/${name}` },\n },\n },\n },\n responses: {\n '200': { description: 'Updated' },\n '404': { $ref: '#/components/responses/NotFound' },\n },\n };\n }\n\n if (shouldInclude('delete')) {\n paths[`${objectPath}/{id}`].delete = {\n summary: `Delete ${name}`,\n tags: [name],\n parameters: [\n {\n name: 'id',\n in: 'path',\n required: true,\n schema: { type: 'string' },\n },\n ],\n responses: {\n '204': { description: 'Deleted' },\n '404': { $ref: '#/components/responses/NotFound' },\n },\n };\n }\n }\n\n return paths;\n}\n\n/**\n * Setup Swagger UI (optional peer dependency)\n */\nexport function setupSwaggerUI(\n app: SwaggerApp,\n spec: OpenAPISpec,\n path = '/docs',\n) {\n try {\n const swaggerUi = require('swagger-ui-express');\n\n app.use(path, swaggerUi.serve);\n app.get(\n path,\n swaggerUi.setup(spec, {\n customCss: '.swagger-ui .topbar { display: none }',\n }),\n );\n\n app.get(\n `${path}/openapi.json`,\n (_req: unknown, res: { json(body: unknown): void }) => {\n res.json(spec);\n },\n );\n\n console.log(`📚 Swagger UI available at ${path}`);\n } catch (_error) {\n console.warn('Swagger UI not available (install swagger-ui-express)');\n }\n}\n\nfunction pluralize(word: string): string {\n if (word.endsWith('y')) return `${word.slice(0, -1)}ies`;\n if (\n word.endsWith('s') ||\n word.endsWith('x') ||\n word.endsWith('z') ||\n word.endsWith('ch') ||\n word.endsWith('sh')\n )\n return `${word}es`;\n return `${word}s`;\n}\n"],"mappings":"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"}
@@ -67,6 +67,8 @@ export interface ToolFieldMeta {
67
67
  minLength?: number;
68
68
  min?: number;
69
69
  max?: number;
70
+ /** Closed set of allowed values (enum / literal-union field, #3598). */
71
+ enum?: ReadonlyArray<string | number>;
70
72
  /** Field values may explicitly be null in the runtime/manifest contract. */
71
73
  nullable?: boolean;
72
74
  /** For `foreignKey`: the related class name, for the generated description. */
@@ -117,6 +119,11 @@ export declare function fieldTypeToJsonSchema(field: ToolFieldMeta): ToolJsonSch
117
119
  * custom method taking `{ id, options }`.
118
120
  */
119
121
  export declare function buildToolInputSchema(action: string, fields: ToolFieldMeta[], customAction?: CustomActionMetadata, idType?: ToolIdType): ToolJsonSchema;
122
+ /**
123
+ * Human-readable description for a tool, matching mcp.ts's phrasing so the Node
124
+ * MCP and WebMCP surfaces read identically.
125
+ */
126
+ export declare function describeAction(action: string, className: string, displayLabelField?: string): string;
120
127
  /**
121
128
  * Build the full descriptor set for a model. `toolPrefix` defaults to the
122
129
  * lowercased class name so tool ids match the existing Node MCP surface exactly
@@ -130,6 +137,8 @@ export declare function buildToolDescriptors(opts: {
130
137
  customActions?: Record<string, CustomActionMetadata>;
131
138
  toolPrefix?: string;
132
139
  idType?: ToolIdType;
140
+ /** The own field that labels a record (#3599), named in descriptions. */
141
+ displayLabelField?: string;
133
142
  }): ToolDescriptor[];
134
143
  /**
135
144
  * Resolve the one canonical capability classification used by generated MCP
@@ -1 +1 @@
1
- {"version":3,"file":"tool-schema.d.ts","sourceRoot":"","sources":["../../src/generators/tool-schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool-schema.d.ts","sourceRoot":"","sources":["../../src/generators/tool-schema.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { CRUD_OPERATIONS, buildCustomActionInputSchema } from "./custom-action.js";
2
+ import { describeDisplayLabel } from "../ui-metadata.js";
2
3
  //#region src/generators/tool-schema.ts
3
4
  /** The only JSON Schema dialect emitted by generated MCP and WebMCP tools. */
4
5
  var JSON_SCHEMA_2020_12 = "https://json-schema.org/draft/2020-12/schema";
@@ -102,6 +103,7 @@ function fieldTypeToJsonSchema(field) {
102
103
  default: schema.type = "string";
103
104
  }
104
105
  if (field.default !== void 0) schema.default = field.default;
106
+ if ((field.type === "text" || field.type === "integer" || field.type === "decimal") && field.enum && field.enum.length > 0) schema.enum = field.nullable ? [...field.enum, null] : [...field.enum];
105
107
  if (field.nullable && typeof schema.type === "string") schema.type = [schema.type, "null"];
106
108
  return schema;
107
109
  }
@@ -210,13 +212,14 @@ function buildToolInputSchema(action, fields, customAction, idType = "uuid") {
210
212
  * Human-readable description for a tool, matching mcp.ts's phrasing so the Node
211
213
  * MCP and WebMCP surfaces read identically.
212
214
  */
213
- function describeAction(action, className) {
215
+ function describeAction(action, className, displayLabelField) {
216
+ const label = describeDisplayLabel(displayLabelField);
214
217
  switch (action) {
215
- case "list": return `List ${className} objects with optional filtering`;
216
- case "get": return `Get a specific ${className} by ID or slug`;
218
+ case "list": return `List ${className} objects with optional filtering${label}`;
219
+ case "get": return `Get a specific ${className} by ID or slug${label}`;
217
220
  case "create": return `Create a new ${className}`;
218
- case "update": return `Update an existing ${className}`;
219
- case "delete": return `Delete a ${className} by ID`;
221
+ case "update": return `Update an existing ${className}${label}`;
222
+ case "delete": return `Delete a ${className} by ID${label}`;
220
223
  default: return `Execute ${action} action on ${className}`;
221
224
  }
222
225
  }
@@ -235,7 +238,7 @@ function buildToolDescriptors(opts) {
235
238
  return {
236
239
  action,
237
240
  name: `${prefix}_${action}`.toLowerCase(),
238
- description: describeAction(action, className),
241
+ description: describeAction(action, className, opts.displayLabelField),
239
242
  inputSchema: buildToolInputSchema(action, fields, customAction, opts.idType),
240
243
  readOnly: semantics.effect === "read",
241
244
  ...semantics
@@ -282,6 +285,6 @@ function isCrudAction(action) {
282
285
  return CRUD_ACTIONS.has(action);
283
286
  }
284
287
  //#endregion
285
- export { JSON_SCHEMA_2020_12, MCP_SCHEMA_LIMITS, assertMcpJsonSchemaSafety, buildToolDescriptors, buildToolInputSchema, fieldTypeToJsonSchema, finalizeMcpJsonSchema, isCrudAction, resolveToolSemantics };
288
+ export { JSON_SCHEMA_2020_12, MCP_SCHEMA_LIMITS, assertMcpJsonSchemaSafety, buildToolDescriptors, buildToolInputSchema, describeAction, fieldTypeToJsonSchema, finalizeMcpJsonSchema, isCrudAction, resolveToolSemantics };
286
289
 
287
290
  //# sourceMappingURL=tool-schema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool-schema.js","names":[],"sources":["../../src/generators/tool-schema.ts"],"sourcesContent":["import {\n buildCustomActionInputSchema,\n CRUD_OPERATIONS,\n type CustomActionMetadata,\n type ToolEffect,\n} from './custom-action.js';\n\n/**\n * Transport-agnostic tool-descriptor builder (#1812, tracer).\n *\n * The single source of truth for turning a model's fields + exposed actions into\n * MCP-shaped tool descriptors (`{ name, description, inputSchema }`). This is the\n * shape both the Model Context Protocol AND Chrome's WebMCP\n * (`document.modelContext.registerTool`) consume — see\n * https://developer.chrome.com/docs/ai/webmcp.\n *\n * It is deliberately pure and free of `ObjectRegistry` / manifest coupling: it\n * takes a normalized {@link ToolFieldMeta}[] so BOTH callers can share it —\n * - `MCPGenerator` (`src/generators/mcp.ts`) for the Node stdio server, and\n * - the web-collections emitter (`src/vite-plugin/web-collections.ts`) for the\n * browser client-data runtime's WebMCP descriptors.\n *\n * Keeping one implementation removes the field-mapping drift risk the\n * \"three emission sites must agree\" contract in web-collections.ts already warns\n * about. The `fieldTypeToJsonSchema` / per-action skeletons below are ported\n * verbatim from mcp.ts's `fieldToMCPSchema` + `generateObjectTools`, so wiring\n * mcp.ts to call this helper is a mechanical, behavior-preserving refactor.\n */\n\n/**\n * A JSON Schema fragment. Values vary by field kind, so this is only ever\n * serialized into tool descriptors, never read back structurally.\n */\nexport type ToolJsonSchema = Record<string, unknown>;\n\n/** The only JSON Schema dialect emitted by generated MCP and WebMCP tools. */\nexport const JSON_SCHEMA_2020_12 =\n 'https://json-schema.org/draft/2020-12/schema';\n\n/**\n * Bounds for generated schemas. Field metadata is authored input, so it must\n * not turn a tools/list response into an unbounded composition or validation\n * workload. These limits are deliberately far above normal SMRT objects while\n * still keeping schemas comfortably inside MCP transport budgets.\n */\nexport const MCP_SCHEMA_LIMITS = {\n maxDepth: 16,\n maxNodes: 2_048,\n maxSerializedBytes: 65_536,\n} as const;\n\n/**\n * Apply the draft-2020-12 dialect and reject schemas that violate MCP's\n * bounded-composition contract. Generated schemas only ever reference local\n * `$defs`; external refs are neither emitted nor followed.\n */\nexport function finalizeMcpJsonSchema(schema: ToolJsonSchema): ToolJsonSchema {\n const finalized = {\n ...schema,\n $schema: JSON_SCHEMA_2020_12,\n };\n assertMcpJsonSchemaSafety(finalized);\n return finalized;\n}\n\n/**\n * Validate the resource envelope of an emitted schema without resolving refs.\n * This is intentionally structural rather than a general JSON-Schema\n * evaluator: the server already owns every schema it emits, and this guard\n * exists to keep authored metadata from introducing hostile shape growth.\n */\nexport function assertMcpJsonSchemaSafety(schema: ToolJsonSchema): void {\n let nodes = 0;\n const ancestors = new WeakSet<object>();\n\n const visit = (value: unknown, depth: number, key?: string): void => {\n nodes += 1;\n if (nodes > MCP_SCHEMA_LIMITS.maxNodes) {\n throw new Error(\n `MCP JSON Schema exceeds ${MCP_SCHEMA_LIMITS.maxNodes} nodes`,\n );\n }\n if (depth > MCP_SCHEMA_LIMITS.maxDepth) {\n throw new Error(\n `MCP JSON Schema exceeds ${MCP_SCHEMA_LIMITS.maxDepth} levels of depth`,\n );\n }\n if (key === '$ref') {\n if (\n typeof value !== 'string' ||\n !value.startsWith('#/$defs/') ||\n value.includes('://')\n ) {\n throw new Error(\n 'MCP JSON Schema may only use local #/$defs/ references',\n );\n }\n return;\n }\n if (value === null || typeof value !== 'object') return;\n if (ancestors.has(value)) {\n throw new Error('MCP JSON Schema must not contain cyclic values');\n }\n\n ancestors.add(value);\n if (Array.isArray(value)) {\n for (const entry of value) visit(entry, depth + 1);\n } else {\n for (const [childKey, child] of Object.entries(value)) {\n visit(child, depth + 1, childKey);\n }\n }\n ancestors.delete(value);\n };\n\n visit(schema, 0);\n\n let serialized: string;\n try {\n serialized = JSON.stringify(schema);\n } catch {\n throw new Error('MCP JSON Schema must be JSON-serializable');\n }\n if (\n new TextEncoder().encode(serialized).byteLength >\n MCP_SCHEMA_LIMITS.maxSerializedBytes\n ) {\n throw new Error(\n `MCP JSON Schema exceeds ${MCP_SCHEMA_LIMITS.maxSerializedBytes} serialized bytes`,\n );\n }\n}\n\n/**\n * Normalized field metadata — the intersection of what the runtime registry\n * (`FieldDefinition._meta`) and the build-time manifest (`WebFieldDefinition`)\n * can each supply. Callers flatten their own field source into this shape.\n */\nexport interface ToolFieldMeta {\n name: string;\n /** Field kind: text | integer | decimal | boolean | datetime | json | foreignKey | … */\n type: string;\n required?: boolean;\n description?: string;\n default?: unknown;\n maxLength?: number;\n minLength?: number;\n min?: number;\n max?: number;\n /** Field values may explicitly be null in the runtime/manifest contract. */\n nullable?: boolean;\n /** For `foreignKey`: the related class name, for the generated description. */\n related?: string;\n}\n\n/** Storage contract for the synthetic primary identifier. */\nexport type ToolIdType = 'uuid' | 'text';\n\n/** The CRUD verbs with dedicated input-schema skeletons; anything else is custom. */\nconst CRUD_ACTIONS = new Set<string>(CRUD_OPERATIONS);\n\nexport interface ToolRouteDescriptor {\n /** HTTP method emitted for the route. */\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n /** Whether the route targets one item or the whole collection. */\n scope: 'item' | 'collection';\n /** Route segments below the collection endpoint. Dynamic segments use `[x]`. */\n path: string[];\n /** Transport names rewritten by the tool schema (e.g. `actionId` → `id`). */\n parameterAliases?: Record<string, string>;\n /** The generated method accepts one `options` bag as its sole argument. */\n optionsBag?: boolean;\n}\n\n/** A single generated tool descriptor — the WebMCP / MCP tool shape. */\nexport interface ToolDescriptor {\n /** The action this tool performs (`list` | `get` | … | a custom method name). */\n action: string;\n /** Tool id, `${toolPrefix}_${action}` (e.g. `product_list`). */\n name: string;\n description: string;\n inputSchema: ToolJsonSchema;\n /** True when the declared effect is `read` → WebMCP `annotations.readOnlyHint`. */\n readOnly: boolean;\n /** Capability effect used by browser-tool exposure policy. */\n effect: ToolEffect;\n /** Whether repeating this tool with the same arguments is safe. */\n idempotent: boolean;\n /** Whether the tool may interact outside the SMRT application. */\n openWorld: boolean;\n /** Generated custom-route transport metadata, when the action has a route. */\n route?: ToolRouteDescriptor;\n}\n\n/**\n * Map one normalized field to its JSON-Schema fragment. Ported from\n * `MCPGenerator.fieldToMCPSchema` (mcp.ts) — keep the two in lockstep until\n * mcp.ts is switched to call this.\n */\nexport function fieldTypeToJsonSchema(field: ToolFieldMeta): ToolJsonSchema {\n const schema: ToolJsonSchema = {\n description: field.description || `${field.type} field`,\n };\n\n switch (field.type) {\n case 'text':\n schema.type = 'string';\n if (field.maxLength !== undefined) schema.maxLength = field.maxLength;\n if (field.minLength !== undefined) schema.minLength = field.minLength;\n break;\n case 'integer':\n schema.type = 'integer';\n if (field.min !== undefined) schema.minimum = field.min;\n if (field.max !== undefined) schema.maximum = field.max;\n break;\n case 'decimal':\n schema.type = 'number';\n if (field.min !== undefined) schema.minimum = field.min;\n if (field.max !== undefined) schema.maximum = field.max;\n break;\n case 'boolean':\n schema.type = 'boolean';\n break;\n case 'datetime':\n schema.type = 'string';\n schema.format = 'date-time';\n break;\n case 'json':\n schema.type = 'object';\n break;\n case 'foreignKey':\n case 'crossPackageRef':\n schema.type = 'string';\n // The generic relation hint is a fallback only — an authored\n // `@field({ description })` wins (#2046 threads descriptions into web\n // tool descriptors; clobbering them here would strip the help text).\n if (!field.description) {\n schema.description = `ID of related ${field.related || 'object'}`;\n }\n break;\n default:\n schema.type = 'string';\n }\n\n if (field.default !== undefined) {\n schema.default = field.default;\n }\n\n if (field.nullable && typeof schema.type === 'string') {\n schema.type = [schema.type, 'null'];\n }\n\n return schema;\n}\n\nfunction buildFieldProperties(fields: ToolFieldMeta[]): {\n properties: Record<string, ToolJsonSchema>;\n defs: Record<string, ToolJsonSchema>;\n} {\n const properties: Record<string, ToolJsonSchema> = {};\n const defs: Record<string, ToolJsonSchema> = {};\n\n fields.forEach((field, index) => {\n // Numeric keys avoid JSON Pointer escaping and keep output deterministic\n // even for an authored field name containing `/` or `~`.\n const defKey = `field_${index}`;\n defs[defKey] = fieldTypeToJsonSchema(field);\n properties[field.name] = { $ref: `#/$defs/${defKey}` };\n });\n\n return { properties, defs };\n}\n\n/**\n * Build the `inputSchema` for one action. CRUD verbs get the fixed skeletons\n * ported from mcp.ts's `generateObjectTools`; any other action is treated as a\n * custom method taking `{ id, options }`.\n */\nexport function buildToolInputSchema(\n action: string,\n fields: ToolFieldMeta[],\n customAction?: CustomActionMetadata,\n idType: ToolIdType = 'uuid',\n): ToolJsonSchema {\n const identifierSchema = (description: string): ToolJsonSchema => ({\n type: 'string',\n ...(idType === 'uuid' ? { format: 'uuid' } : {}),\n description,\n });\n\n switch (action) {\n case 'list':\n return finalizeMcpJsonSchema({\n type: 'object',\n properties: {\n limit: {\n type: 'integer',\n description: 'Maximum number of items to return',\n default: 50,\n minimum: 1,\n maximum: 1000,\n },\n offset: {\n type: 'integer',\n description: 'Number of items to skip',\n default: 0,\n minimum: 0,\n },\n orderBy: {\n type: 'string',\n description: 'Field to order by (e.g., \"created_at DESC\")',\n },\n where: {\n type: 'object',\n description: 'Filter conditions as key-value pairs',\n additionalProperties: true,\n },\n },\n });\n\n case 'get':\n // Either `id` OR `slug` identifies the object (collection.get resolves\n // both). The schema must require one of them just as the handler does,\n // while still allowing slug-only lookups.\n return finalizeMcpJsonSchema({\n type: 'object',\n anyOf: [{ required: ['id'] }, { required: ['slug'] }],\n properties: {\n id: identifierSchema('Unique identifier of the object'),\n slug: {\n type: 'string',\n description: 'URL-friendly identifier of the object',\n },\n },\n });\n\n case 'create': {\n const { properties, defs } = buildFieldProperties(fields);\n const required: string[] = [];\n for (const field of fields) {\n if (field.required) required.push(field.name);\n }\n return finalizeMcpJsonSchema({\n type: 'object',\n properties,\n ...(required.length > 0 ? { required } : {}),\n ...(Object.keys(defs).length > 0 ? { $defs: defs } : {}),\n });\n }\n\n case 'update': {\n const { properties: fieldProperties, defs } =\n buildFieldProperties(fields);\n const properties: Record<string, ToolJsonSchema> = {\n id: identifierSchema('ID of the object to update'),\n ...fieldProperties,\n };\n return finalizeMcpJsonSchema({\n type: 'object',\n properties,\n required: ['id'],\n ...(Object.keys(defs).length > 0 ? { $defs: defs } : {}),\n });\n }\n\n case 'delete':\n return finalizeMcpJsonSchema({\n type: 'object',\n properties: {\n id: identifierSchema('ID of the object to delete'),\n },\n required: ['id'],\n });\n\n default:\n return finalizeMcpJsonSchema(\n buildCustomActionInputSchema(\n customAction ?? {\n scope: 'item',\n idRequired: true,\n isStatic: false,\n effect: 'destructive',\n idempotent: false,\n openWorld: true,\n },\n ),\n );\n }\n}\n\n/**\n * Human-readable description for a tool, matching mcp.ts's phrasing so the Node\n * MCP and WebMCP surfaces read identically.\n */\nfunction describeAction(action: string, className: string): string {\n switch (action) {\n case 'list':\n return `List ${className} objects with optional filtering`;\n case 'get':\n return `Get a specific ${className} by ID or slug`;\n case 'create':\n return `Create a new ${className}`;\n case 'update':\n return `Update an existing ${className}`;\n case 'delete':\n return `Delete a ${className} by ID`;\n default:\n return `Execute ${action} action on ${className}`;\n }\n}\n\n/**\n * Build the full descriptor set for a model. `toolPrefix` defaults to the\n * lowercased class name so tool ids match the existing Node MCP surface exactly\n * (`product_list`, `invoice_record_payment`), giving one stable tool vocabulary\n * across MCP and WebMCP.\n */\nexport function buildToolDescriptors(opts: {\n className: string;\n fields: ToolFieldMeta[];\n actions: string[];\n customActions?: Record<string, CustomActionMetadata>;\n toolPrefix?: string;\n idType?: ToolIdType;\n}): ToolDescriptor[] {\n const { className, fields, actions } = opts;\n const prefix = (opts.toolPrefix ?? className).toLowerCase();\n\n return actions.map((action) => {\n const customAction = opts.customActions?.[action];\n const semantics = resolveToolSemantics(action, customAction);\n return {\n action,\n // Custom method names can contain underscores; the runtime splits on the\n // FIRST underscore only (mcp.ts #1378), so a lowercased join is safe here.\n name: `${prefix}_${action}`.toLowerCase(),\n description: describeAction(action, className),\n inputSchema: buildToolInputSchema(\n action,\n fields,\n customAction,\n opts.idType,\n ),\n readOnly: semantics.effect === 'read',\n ...semantics,\n };\n });\n}\n\n/**\n * Resolve the one canonical capability classification used by generated MCP\n * and WebMCP descriptors. Consumers that author a tool outside a model must\n * declare this same shape rather than infer safety from a name or HTTP verb.\n */\nexport function resolveToolSemantics(\n action: string,\n customAction?: CustomActionMetadata,\n): Pick<ToolDescriptor, 'effect' | 'idempotent' | 'openWorld'> {\n switch (action) {\n case 'list':\n case 'get':\n return { effect: 'read', idempotent: true, openWorld: false };\n case 'create':\n return { effect: 'write', idempotent: false, openWorld: false };\n case 'update':\n return { effect: 'write', idempotent: true, openWorld: false };\n case 'delete':\n return { effect: 'destructive', idempotent: true, openWorld: false };\n default:\n return {\n effect: customAction?.effect ?? 'destructive',\n idempotent: customAction?.idempotent ?? false,\n openWorld: customAction?.openWorld ?? true,\n };\n }\n}\n\n/** True when `action` is one of the fixed CRUD verbs (vs. a custom method). */\nexport function isCrudAction(action: string): boolean {\n return CRUD_ACTIONS.has(action);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"tool-schema.js","names":[],"sources":["../../src/generators/tool-schema.ts"],"sourcesContent":["import { describeDisplayLabel } from '../ui-metadata.js';\nimport {\n buildCustomActionInputSchema,\n CRUD_OPERATIONS,\n type CustomActionMetadata,\n type ToolEffect,\n} from './custom-action.js';\n\n/**\n * Transport-agnostic tool-descriptor builder (#1812, tracer).\n *\n * The single source of truth for turning a model's fields + exposed actions into\n * MCP-shaped tool descriptors (`{ name, description, inputSchema }`). This is the\n * shape both the Model Context Protocol AND Chrome's WebMCP\n * (`document.modelContext.registerTool`) consume — see\n * https://developer.chrome.com/docs/ai/webmcp.\n *\n * It is deliberately pure and free of `ObjectRegistry` / manifest coupling: it\n * takes a normalized {@link ToolFieldMeta}[] so BOTH callers can share it —\n * - `MCPGenerator` (`src/generators/mcp.ts`) for the Node stdio server, and\n * - the web-collections emitter (`src/vite-plugin/web-collections.ts`) for the\n * browser client-data runtime's WebMCP descriptors.\n *\n * Keeping one implementation removes the field-mapping drift risk the\n * \"three emission sites must agree\" contract in web-collections.ts already warns\n * about. The `fieldTypeToJsonSchema` / per-action skeletons below are ported\n * verbatim from mcp.ts's `fieldToMCPSchema` + `generateObjectTools`, so wiring\n * mcp.ts to call this helper is a mechanical, behavior-preserving refactor.\n */\n\n/**\n * A JSON Schema fragment. Values vary by field kind, so this is only ever\n * serialized into tool descriptors, never read back structurally.\n */\nexport type ToolJsonSchema = Record<string, unknown>;\n\n/** The only JSON Schema dialect emitted by generated MCP and WebMCP tools. */\nexport const JSON_SCHEMA_2020_12 =\n 'https://json-schema.org/draft/2020-12/schema';\n\n/**\n * Bounds for generated schemas. Field metadata is authored input, so it must\n * not turn a tools/list response into an unbounded composition or validation\n * workload. These limits are deliberately far above normal SMRT objects while\n * still keeping schemas comfortably inside MCP transport budgets.\n */\nexport const MCP_SCHEMA_LIMITS = {\n maxDepth: 16,\n maxNodes: 2_048,\n maxSerializedBytes: 65_536,\n} as const;\n\n/**\n * Apply the draft-2020-12 dialect and reject schemas that violate MCP's\n * bounded-composition contract. Generated schemas only ever reference local\n * `$defs`; external refs are neither emitted nor followed.\n */\nexport function finalizeMcpJsonSchema(schema: ToolJsonSchema): ToolJsonSchema {\n const finalized = {\n ...schema,\n $schema: JSON_SCHEMA_2020_12,\n };\n assertMcpJsonSchemaSafety(finalized);\n return finalized;\n}\n\n/**\n * Validate the resource envelope of an emitted schema without resolving refs.\n * This is intentionally structural rather than a general JSON-Schema\n * evaluator: the server already owns every schema it emits, and this guard\n * exists to keep authored metadata from introducing hostile shape growth.\n */\nexport function assertMcpJsonSchemaSafety(schema: ToolJsonSchema): void {\n let nodes = 0;\n const ancestors = new WeakSet<object>();\n\n const visit = (value: unknown, depth: number, key?: string): void => {\n nodes += 1;\n if (nodes > MCP_SCHEMA_LIMITS.maxNodes) {\n throw new Error(\n `MCP JSON Schema exceeds ${MCP_SCHEMA_LIMITS.maxNodes} nodes`,\n );\n }\n if (depth > MCP_SCHEMA_LIMITS.maxDepth) {\n throw new Error(\n `MCP JSON Schema exceeds ${MCP_SCHEMA_LIMITS.maxDepth} levels of depth`,\n );\n }\n if (key === '$ref') {\n if (\n typeof value !== 'string' ||\n !value.startsWith('#/$defs/') ||\n value.includes('://')\n ) {\n throw new Error(\n 'MCP JSON Schema may only use local #/$defs/ references',\n );\n }\n return;\n }\n if (value === null || typeof value !== 'object') return;\n if (ancestors.has(value)) {\n throw new Error('MCP JSON Schema must not contain cyclic values');\n }\n\n ancestors.add(value);\n if (Array.isArray(value)) {\n for (const entry of value) visit(entry, depth + 1);\n } else {\n for (const [childKey, child] of Object.entries(value)) {\n visit(child, depth + 1, childKey);\n }\n }\n ancestors.delete(value);\n };\n\n visit(schema, 0);\n\n let serialized: string;\n try {\n serialized = JSON.stringify(schema);\n } catch {\n throw new Error('MCP JSON Schema must be JSON-serializable');\n }\n if (\n new TextEncoder().encode(serialized).byteLength >\n MCP_SCHEMA_LIMITS.maxSerializedBytes\n ) {\n throw new Error(\n `MCP JSON Schema exceeds ${MCP_SCHEMA_LIMITS.maxSerializedBytes} serialized bytes`,\n );\n }\n}\n\n/**\n * Normalized field metadata — the intersection of what the runtime registry\n * (`FieldDefinition._meta`) and the build-time manifest (`WebFieldDefinition`)\n * can each supply. Callers flatten their own field source into this shape.\n */\nexport interface ToolFieldMeta {\n name: string;\n /** Field kind: text | integer | decimal | boolean | datetime | json | foreignKey | … */\n type: string;\n required?: boolean;\n description?: string;\n default?: unknown;\n maxLength?: number;\n minLength?: number;\n min?: number;\n max?: number;\n /** Closed set of allowed values (enum / literal-union field, #3598). */\n enum?: ReadonlyArray<string | number>;\n /** Field values may explicitly be null in the runtime/manifest contract. */\n nullable?: boolean;\n /** For `foreignKey`: the related class name, for the generated description. */\n related?: string;\n}\n\n/** Storage contract for the synthetic primary identifier. */\nexport type ToolIdType = 'uuid' | 'text';\n\n/** The CRUD verbs with dedicated input-schema skeletons; anything else is custom. */\nconst CRUD_ACTIONS = new Set<string>(CRUD_OPERATIONS);\n\nexport interface ToolRouteDescriptor {\n /** HTTP method emitted for the route. */\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n /** Whether the route targets one item or the whole collection. */\n scope: 'item' | 'collection';\n /** Route segments below the collection endpoint. Dynamic segments use `[x]`. */\n path: string[];\n /** Transport names rewritten by the tool schema (e.g. `actionId` → `id`). */\n parameterAliases?: Record<string, string>;\n /** The generated method accepts one `options` bag as its sole argument. */\n optionsBag?: boolean;\n}\n\n/** A single generated tool descriptor — the WebMCP / MCP tool shape. */\nexport interface ToolDescriptor {\n /** The action this tool performs (`list` | `get` | … | a custom method name). */\n action: string;\n /** Tool id, `${toolPrefix}_${action}` (e.g. `product_list`). */\n name: string;\n description: string;\n inputSchema: ToolJsonSchema;\n /** True when the declared effect is `read` → WebMCP `annotations.readOnlyHint`. */\n readOnly: boolean;\n /** Capability effect used by browser-tool exposure policy. */\n effect: ToolEffect;\n /** Whether repeating this tool with the same arguments is safe. */\n idempotent: boolean;\n /** Whether the tool may interact outside the SMRT application. */\n openWorld: boolean;\n /** Generated custom-route transport metadata, when the action has a route. */\n route?: ToolRouteDescriptor;\n}\n\n/**\n * Map one normalized field to its JSON-Schema fragment. Ported from\n * `MCPGenerator.fieldToMCPSchema` (mcp.ts) — keep the two in lockstep until\n * mcp.ts is switched to call this.\n */\nexport function fieldTypeToJsonSchema(field: ToolFieldMeta): ToolJsonSchema {\n const schema: ToolJsonSchema = {\n description: field.description || `${field.type} field`,\n };\n\n switch (field.type) {\n case 'text':\n schema.type = 'string';\n if (field.maxLength !== undefined) schema.maxLength = field.maxLength;\n if (field.minLength !== undefined) schema.minLength = field.minLength;\n break;\n case 'integer':\n schema.type = 'integer';\n if (field.min !== undefined) schema.minimum = field.min;\n if (field.max !== undefined) schema.maximum = field.max;\n break;\n case 'decimal':\n schema.type = 'number';\n if (field.min !== undefined) schema.minimum = field.min;\n if (field.max !== undefined) schema.maximum = field.max;\n break;\n case 'boolean':\n schema.type = 'boolean';\n break;\n case 'datetime':\n schema.type = 'string';\n schema.format = 'date-time';\n break;\n case 'json':\n schema.type = 'object';\n break;\n case 'foreignKey':\n case 'crossPackageRef':\n schema.type = 'string';\n // The generic relation hint is a fallback only — an authored\n // `@field({ description })` wins (#2046 threads descriptions into web\n // tool descriptors; clobbering them here would strip the help text).\n if (!field.description) {\n schema.description = `ID of related ${field.related || 'object'}`;\n }\n break;\n default:\n schema.type = 'string';\n }\n\n if (field.default !== undefined) {\n schema.default = field.default;\n }\n\n // Only scalar kinds can be constrained by an enum; a value list on a json or\n // relationship field would describe the wrong thing.\n const constrained =\n field.type === 'text' ||\n field.type === 'integer' ||\n field.type === 'decimal';\n if (constrained && field.enum && field.enum.length > 0) {\n // A nullable field must still accept `null`, which `enum` would reject.\n schema.enum = field.nullable ? [...field.enum, null] : [...field.enum];\n }\n\n if (field.nullable && typeof schema.type === 'string') {\n schema.type = [schema.type, 'null'];\n }\n\n return schema;\n}\n\nfunction buildFieldProperties(fields: ToolFieldMeta[]): {\n properties: Record<string, ToolJsonSchema>;\n defs: Record<string, ToolJsonSchema>;\n} {\n const properties: Record<string, ToolJsonSchema> = {};\n const defs: Record<string, ToolJsonSchema> = {};\n\n fields.forEach((field, index) => {\n // Numeric keys avoid JSON Pointer escaping and keep output deterministic\n // even for an authored field name containing `/` or `~`.\n const defKey = `field_${index}`;\n defs[defKey] = fieldTypeToJsonSchema(field);\n properties[field.name] = { $ref: `#/$defs/${defKey}` };\n });\n\n return { properties, defs };\n}\n\n/**\n * Build the `inputSchema` for one action. CRUD verbs get the fixed skeletons\n * ported from mcp.ts's `generateObjectTools`; any other action is treated as a\n * custom method taking `{ id, options }`.\n */\nexport function buildToolInputSchema(\n action: string,\n fields: ToolFieldMeta[],\n customAction?: CustomActionMetadata,\n idType: ToolIdType = 'uuid',\n): ToolJsonSchema {\n const identifierSchema = (description: string): ToolJsonSchema => ({\n type: 'string',\n ...(idType === 'uuid' ? { format: 'uuid' } : {}),\n description,\n });\n\n switch (action) {\n case 'list':\n return finalizeMcpJsonSchema({\n type: 'object',\n properties: {\n limit: {\n type: 'integer',\n description: 'Maximum number of items to return',\n default: 50,\n minimum: 1,\n maximum: 1000,\n },\n offset: {\n type: 'integer',\n description: 'Number of items to skip',\n default: 0,\n minimum: 0,\n },\n orderBy: {\n type: 'string',\n description: 'Field to order by (e.g., \"created_at DESC\")',\n },\n where: {\n type: 'object',\n description: 'Filter conditions as key-value pairs',\n additionalProperties: true,\n },\n },\n });\n\n case 'get':\n // Either `id` OR `slug` identifies the object (collection.get resolves\n // both). The schema must require one of them just as the handler does,\n // while still allowing slug-only lookups.\n return finalizeMcpJsonSchema({\n type: 'object',\n anyOf: [{ required: ['id'] }, { required: ['slug'] }],\n properties: {\n id: identifierSchema('Unique identifier of the object'),\n slug: {\n type: 'string',\n description: 'URL-friendly identifier of the object',\n },\n },\n });\n\n case 'create': {\n const { properties, defs } = buildFieldProperties(fields);\n const required: string[] = [];\n for (const field of fields) {\n if (field.required) required.push(field.name);\n }\n return finalizeMcpJsonSchema({\n type: 'object',\n properties,\n ...(required.length > 0 ? { required } : {}),\n ...(Object.keys(defs).length > 0 ? { $defs: defs } : {}),\n });\n }\n\n case 'update': {\n const { properties: fieldProperties, defs } =\n buildFieldProperties(fields);\n const properties: Record<string, ToolJsonSchema> = {\n id: identifierSchema('ID of the object to update'),\n ...fieldProperties,\n };\n return finalizeMcpJsonSchema({\n type: 'object',\n properties,\n required: ['id'],\n ...(Object.keys(defs).length > 0 ? { $defs: defs } : {}),\n });\n }\n\n case 'delete':\n return finalizeMcpJsonSchema({\n type: 'object',\n properties: {\n id: identifierSchema('ID of the object to delete'),\n },\n required: ['id'],\n });\n\n default:\n return finalizeMcpJsonSchema(\n buildCustomActionInputSchema(\n customAction ?? {\n scope: 'item',\n idRequired: true,\n isStatic: false,\n effect: 'destructive',\n idempotent: false,\n openWorld: true,\n },\n ),\n );\n }\n}\n\n/**\n * Human-readable description for a tool, matching mcp.ts's phrasing so the Node\n * MCP and WebMCP surfaces read identically.\n */\nexport function describeAction(\n action: string,\n className: string,\n displayLabelField?: string,\n): string {\n // How to name a record (#3599): assistants resolve \"Acme\" to an id by\n // matching this field, so every verb that targets an existing record says so.\n const label = describeDisplayLabel(displayLabelField);\n switch (action) {\n case 'list':\n return `List ${className} objects with optional filtering${label}`;\n case 'get':\n return `Get a specific ${className} by ID or slug${label}`;\n case 'create':\n return `Create a new ${className}`;\n case 'update':\n return `Update an existing ${className}${label}`;\n case 'delete':\n return `Delete a ${className} by ID${label}`;\n default:\n return `Execute ${action} action on ${className}`;\n }\n}\n\n/**\n * Build the full descriptor set for a model. `toolPrefix` defaults to the\n * lowercased class name so tool ids match the existing Node MCP surface exactly\n * (`product_list`, `invoice_record_payment`), giving one stable tool vocabulary\n * across MCP and WebMCP.\n */\nexport function buildToolDescriptors(opts: {\n className: string;\n fields: ToolFieldMeta[];\n actions: string[];\n customActions?: Record<string, CustomActionMetadata>;\n toolPrefix?: string;\n idType?: ToolIdType;\n /** The own field that labels a record (#3599), named in descriptions. */\n displayLabelField?: string;\n}): ToolDescriptor[] {\n const { className, fields, actions } = opts;\n const prefix = (opts.toolPrefix ?? className).toLowerCase();\n\n return actions.map((action) => {\n const customAction = opts.customActions?.[action];\n const semantics = resolveToolSemantics(action, customAction);\n return {\n action,\n // Custom method names can contain underscores; the runtime splits on the\n // FIRST underscore only (mcp.ts #1378), so a lowercased join is safe here.\n name: `${prefix}_${action}`.toLowerCase(),\n description: describeAction(action, className, opts.displayLabelField),\n inputSchema: buildToolInputSchema(\n action,\n fields,\n customAction,\n opts.idType,\n ),\n readOnly: semantics.effect === 'read',\n ...semantics,\n };\n });\n}\n\n/**\n * Resolve the one canonical capability classification used by generated MCP\n * and WebMCP descriptors. Consumers that author a tool outside a model must\n * declare this same shape rather than infer safety from a name or HTTP verb.\n */\nexport function resolveToolSemantics(\n action: string,\n customAction?: CustomActionMetadata,\n): Pick<ToolDescriptor, 'effect' | 'idempotent' | 'openWorld'> {\n switch (action) {\n case 'list':\n case 'get':\n return { effect: 'read', idempotent: true, openWorld: false };\n case 'create':\n return { effect: 'write', idempotent: false, openWorld: false };\n case 'update':\n return { effect: 'write', idempotent: true, openWorld: false };\n case 'delete':\n return { effect: 'destructive', idempotent: true, openWorld: false };\n default:\n return {\n effect: customAction?.effect ?? 'destructive',\n idempotent: customAction?.idempotent ?? false,\n openWorld: customAction?.openWorld ?? true,\n };\n }\n}\n\n/** True when `action` is one of the fixed CRUD verbs (vs. a custom method). */\nexport function isCrudAction(action: string): boolean {\n return CRUD_ACTIONS.has(action);\n}\n"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -61,6 +61,8 @@ export { SmrtPolymorphicAssociation, type SmrtPolymorphicAssociationOptions, } f
61
61
  export { applyPostgresPermissions, type PostgresPermissionContract, type PostgresPermissionDiagnostic, type PostgresPermissionPlan, planPostgresPermissions, validatePostgresPermissionContract, } from './postgres-permissions.js';
62
62
  export { applyPostgresRuntimeTimeouts, DEFAULT_POSTGRES_TIMEOUTS, POSTGRES_TIMEOUT_ENV_VARS, type PostgresTimeoutConfig, type ResolvedPostgresTimeouts, resolvePostgresTimeouts, } from "./postgres-timeouts.js";
63
63
  export { buildDefaultListOrderBy, DEFAULT_LIST_LIMIT, DEFAULT_LIST_ORDER_BY, type ListBoundOptions, MAX_LIST_LIMIT, QueryBoundsError, QueryOrderByError, resolveListLimit, resolveListOffset, } from "./query-bounds.js";
64
+ export { SmrtRecipe, type SmrtRecipeModel, type SmrtRecipeModelOptions, type SmrtRecipeNavEntry, } from "./recipe.js";
65
+ export { buildConnectSection, buildGlossary, type ConnectSection, type ConnectSurface, createRecipeHelp, extractFieldRefs, findField, type GlossaryEntry, type HelpBlock, type HelpField, type HelpModel, helpToMarkdown, type Inline, parseHelp, type RecipeHelp, type RenderedHelp, type RenderHelpOptions, renderHelp, resolveHelp, validateHelp, } from "./recipe-help.js";
64
66
  export * from "./registry.js";
65
67
  export { smrt as smrtRegistry } from "./registry.js";
66
68
  export type { RuntimeRegistrationOverride } from "./registry/runtime-overrides.js";
@@ -80,6 +82,7 @@ export type { DiscoveryStrategy, ForgetOptions, ForgetScopeOptions, NoteMetadata
80
82
  export { resetVerifiedTables } from "./table-cache.js";
81
83
  export { getTestDatabase, type TestDatabaseOptions, } from "./testing/database.js";
82
84
  export * from "./tools/index.js";
85
+ export * from './ui-metadata.js';
83
86
  export { chunkArray, IN_LIST_CHUNK_SIZE } from "./utils/chunk.js";
84
87
  export { isSensitiveConnectionParam, redactDatabaseUrl, redactDatabaseUrlsInText, } from "./utils/database-url.js";
85
88
  export { clone, getAdapterInfo, isValid, type JSONAdapter, type ParseError, parse, type Result, type StringifyError, safeParse, safeStringify, stringify, } from "./utils/json.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -42,6 +42,8 @@ import { assertScopedPackageName, createQualifiedName, getClassName, getPackageF
42
42
  import { publishArtifactFiles, publishAtomicArtifact } from "./consumer-plugin/artifact-publication.js";
43
43
  import { convertTypeToJsonSchema, generateToolFromMethod, generateToolManifest, shouldIncludeMethod } from "./tools/tool-generator.js";
44
44
  import { CRUD_OPERATIONS, SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY, buildCustomActionInputSchema, buildCustomActionInvocationArgs, classifyMethodWireability, classifyParameterWireability, coerceCustomActionArgument, createClassNamePredicate, createManifestClassNamePredicate, customActionParameterInputName, declaredTypeAcceptsDate, declaresRuntimeRestRoute, declaresRuntimeRestRouteShape, isCrudOperation, isCrudToolAction, normalizeCustomActionFailure, queryStringDecoderFor, readMethodDecoratorConfig, resolveApiMethodExposure, resolveCustomActionMetadata, resolveDeclaredScopeMismatch, resolveEffectiveActionMetadata, toCustomActionBoolean, toCustomActionDate, toCustomActionNumber } from "./generators/custom-action.js";
45
+ import { buildConnectSection, buildGlossary, createRecipeHelp, extractFieldRefs, findField, helpToMarkdown, parseHelp, renderHelp, resolveHelp, validateHelp } from "./recipe-help.js";
46
+ import { DEFAULT_DISPLAY_LABEL_FIELDS, FIELD_UI_WIDGETS, FIELD_UI_WIDGET_TYPES, describeDisplayLabel, displayLabelFieldProblem, findSelectorFor, isFieldUIWidget, resolveDisplayLabelField } from "./ui-metadata.js";
45
47
  import { ManifestGenerator } from "./scanner/manifest-generator.js";
46
48
  import { ManifestManager } from "./manifest/manager.js";
47
49
  import { discoverManifestEntry, findManifestEntryByQualifiedName, loadExternalManifest, loadExternalManifestSync, loadLocalTestManifestSync, loadManifestFromPathSync } from "./manifest/manifest-loader.js";
@@ -91,6 +93,7 @@ import { planForeignKeyCreation } from "./schema/foreign-key-planner.js";
91
93
  import { SchemaComparer, generateSchemaDiff, getSQLFromDiff, hasActionableChanges, isAdvisoryOnlyChange, isManualOrAdvisoryChange } from "./migrations/differ.js";
92
94
  import { SmrtPolymorphicAssociation } from "./polymorphic-association.js";
93
95
  import { applyPostgresPermissions, planPostgresPermissions, validatePostgresPermissionContract } from "./postgres-permissions.js";
96
+ import { SmrtRecipe } from "./recipe.js";
94
97
  import { deriveRunOnceClaimKey, digestRunOnceContent, resolveExistingRunOnceClaim, runOnce } from "./run-once.js";
95
98
  import { createSmrtClient } from "./runtime/client.js";
96
99
  import { SmrtMCPServer, createMCPServer } from "./runtime/mcp.js";
@@ -106,4 +109,4 @@ import "./system/index.js";
106
109
  import { getTestDatabase } from "./testing/database.js";
107
110
  import "./tools/index.js";
108
111
  import { smrtPlugin } from "./vite-plugin/index.js";
109
- export { AGENT_SURFACE_HASH_PREFIX, AIError, APIGenerator, AiUsageCollector, AiUsagePersistenceHandler, BOOTED_PROVENANCE, CACHE_INVALIDATION_CHANNEL, CHANGE_FEED_CREDENTIAL_TABLES, CHANGE_FEED_INTERCEPTOR_NAME, CHANGE_FEED_TABLE, CHANGE_SIGNAL_CHANNEL, CRUD_OPERATIONS, ConfigurationError, ContentHasher, CosineSimilarity, DEFAULT_AI_COST_RATES, DEFAULT_CHANGES_LIMIT, DEFAULT_DATA_QUERY_PAGE_LIMIT, DEFAULT_DATA_QUERY_RESULT_BYTES, DEFAULT_EMBEDDING_CONFIG, DEFAULT_EVENTS_HEARTBEAT_MS, DEFAULT_EVENTS_MAX_SUBSCRIBERS, DEFAULT_EVENTS_RETRY_AFTER_SECONDS, DEFAULT_FACET_LIMIT, DEFAULT_LEARNING_CONFIG, DEFAULT_LIST_LIMIT, DEFAULT_LIST_ORDER_BY, DEFAULT_POSTGRES_TIMEOUTS, DEFAULT_RETENTION_POLICY, DIAGNOSTICS_DEFAULT_LIMIT, DataQueryValidationError, DatabaseError, Dispatch, DispatchBus, DispatchCollection, DispatchSubscription, DispatchSubscriptionCollection, EmbeddingProvider, EmbeddingStorage, EmbeddingUnavailableError, ErrorUtils, FilesystemError, GlobalInterceptors, IN_LIST_CHUNK_SIZE, LearningMemory, LiveSchemaParityError, MAX_CHANGES_LIMIT, MAX_DATA_QUERY_CURSOR_LENGTH, MAX_DATA_QUERY_FACETS, MAX_DATA_QUERY_FILTERS, MAX_DATA_QUERY_FILTER_DEPTH, MAX_DATA_QUERY_IN_VALUES, MAX_DATA_QUERY_OFFSET, MAX_DATA_QUERY_PAGE_LIMIT, MAX_DATA_QUERY_REQUEST_BYTES, MAX_DATA_QUERY_RESULT_BYTES, MAX_DATA_QUERY_WARNINGS, MAX_FACET_FIELDS, MAX_FACET_LIMIT, MAX_LIST_LIMIT, MAX_STI_READ_SCOPE_TYPES, MAX_SYNC_APPLY_BATCH_SIZE, MCPGenerator, MCP_STABLE_CATALOG_TTL_MS, MODULE_DOC_HASH_PREFIX, ManifestBuilder, ManifestGenerator, ManifestManager, MetricsAdapter, NetworkError, ObjectRegistry, PLAYBOOK_PREFLIGHT_CAPABILITY, PLAYBOOK_PREFLIGHT_ROUTE_SEGMENT, POSTGRES_REVISION_GUARD_EXPRESSION, POSTGRES_TIMEOUT_ENV_VARS, PRIVATE_READ_CACHE_CONTROL, PubSubAdapter, QueryBoundsError, QueryOrderByError, RUN_ONCE_CLAIMS_TABLE, RunOnceClaimError, RuntimeError, SMRT_COLLECTION_BASE_NAMES, SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY, SMRT_SCHEMA_VERSION, SYNC_APPLY_ROUTE_SEGMENTS, SYNC_APPLY_UUID_PATTERN, SYSTEM_DIAGNOSTICS_TABLES, SYSTEM_TABLE_NAMES, SchemaComparer, SignalBus, SignalSanitizer, SmrtClass, SmrtCollection, SmrtError, SmrtHierarchical, SmrtJunction, SmrtJunctionBase, SmrtMCPServer, SmrtObject, SmrtPolymorphicAssociation, TenantIsolationError, ValidationError, ValidationReport, ValidationUtils, appendChange, appendChanges, applyOneToManyChildAccessors, applyPendingDecoratorRegistrations, applyPostgresPermissions, applyPostgresRuntimeTimeouts, applySyncWritablePolicy, assertPlainJson, assertPostgresSystemTimestampsCurrent, assertScopedPackageName, auditChanges, auditSnapshot, broadcastCacheInvalidation, buildCascadePlan, buildChangeEventStream, buildCustomActionInputSchema, buildCustomActionInvocationArgs, buildDefaultListOrderBy, buildDomainKnowledgeManifest, buildKnowledgeGraph, bumpChangeFeed, canonicalReadRepresentation, canonicalizeDataQuery, cascadeReferencesTo, changeEventSubscribersAtCapacity, checkKnowledgeGraphFreshness, checkLiveSchemaParity, childAccessorName, chunkArray, classifyDatabaseError, classifyDialectMessage, classifyMethodWireability, classifyParameterWireability, clearRetentionTasks, clone, coerceCustomActionArgument, collectForeignKeyOrphanCounts, computeBodyEtag, computeRuntimeWebManifestHash, computeTableVersionEtag, conditionalJsonResponse, config, convertTypeToJsonSchema, createClassNamePredicate, createDataQueryFingerprint, createDispatchBus, createFilesystemAdapter, createGeneratedCollectionAccess, createInterceptorContext, createMCPServer, createManifestClassNamePredicate, createQualifiedName, createRestServer, createSmrtClient, createSmrtServer, crossPackageRef, customActionParameterInputName, declareChangeFeedSensitiveTable, declaredTypeAcceptsDate, declaresRuntimeRestRoute, declaresRuntimeRestRouteShape, deriveRunOnceClaimKey, detectEngine, digestRunOnceContent, discoverKnowledgeArtifactPaths, discoverManifestEntry, discoverScopedPackageDirectories, drainChangeFeed, ensureBootstrapSystemTableCompatibility, ensureCacheInvalidationListener, ensureChangeFeedTable, ensureDeferredSystemTableCompatibility, ensureDispatchSubscriptionsSystemTableCompatibility, ensureDispatchSystemTableCompatibility, ensureJobEventsSystemTableCompatibility, ensureJobsSystemTableCompatibility, ensureLegacySystemTableCompatibility, ensureSystemTables, estimateAiUsageCost, eventStreamCapacityExceededResponse, executeCollectionReadPlan, executeDecision, executeToolCall, executeToolCalls, field, filterVisibleChangeFeedEntries, findManifestEntryByQualifiedName, foreignKey, formatToolResults, generateDDLForEngine, generateOpenAPISpec, generateSchemaDiff, generateToolFromMethod, generateToolManifest, getActiveAuditOptions, getAdapterInfo, getAuthorizedChangesSince, getAuthorizedTenantScopedChangesSince, getCacheGeneration, getChangeFeedSensitiveTables, getChangesSince, getClassConfigResolvers, getClassName, getConfigResolver, getDatabaseEngine, getManifest, getPackageFromQualifiedName, getRetentionTasks, getSQLFromDiff, getSystemTableShapes, getTableVersion, getTenantScopedChangesSince, getTestDatabase, handlePlaybookPreflightRoute, hasActionableChanges, hasChangeFeedEntryVisibilityHook, hasChangeFeedTableAuthorizerHook, ifNoneMatchHasConcreteMatch, ifNoneMatchSatisfied, importOptionalDependency, invalidateCollectionCache, isAbortedTransactionError, isAdvisoryOnlyChange, isApiActionEnabledForObject, isAudited, isChangeFeedDenyAll, isChangeFeedEntryVisible, isChangeFeedSensitiveTable, isCrudOperation, isCrudToolAction, isDatabaseInterface, isDeterministicDatabaseError, isEmbeddedDatabase, isFrameworkBaseClass, isFromPackage, isLazyConfigSentinel, isManualOrAdvisoryChange, isNotNullViolationError, isPostgresDatabase, isQualifiedName, isRestActionRoutable, isRestRoutePublic, isScopedPackageName, isSensitiveConnectionParam, isSmrtCollectionExtendsName, isStaleWrite, isTenantScopedClassResolved, isTransientDatabaseError, isType, isUniqueViolationError, isValid, listConfigResolvers, loadExternalManifest, loadExternalManifestSync, loadLocalTestManifestSync, loadManifestFromPathSync, manifest, manyToMany, meta, method, migratePostgresSystemTimestamps, normalizeCustomActionFailure, normalizeDataQueryRequest, normalizeDataQueryResult, normalizeDataQuerySchema, normalizeEventsMaxSubscribers, normalizeOnDelete, normalizeTypedHttpError, oneToMany, parse, parseQualifiedName, parseSyncApplyBatch, payloadMatchesRow, planForeignKeyCreation, planPostgresPermissions, planPostgresSystemTimestampMigrations, postgresRevisionCandidates, postgresRevisionCondition, processSyncApplyBatch, pruneAiUsage, pruneChangeFeed, pruneExpiredContexts, pruneRunOnceClaims, publishArtifactFiles, publishAtomicArtifact, qualifiedNamesEqual, queryStringDecoderFor, readAgentModuleDocs, readDispatchHealth, readJobHealth, readMethodDecoratorConfig, readMigrationStatus, readPackageAgentDoc, readRecentChanges, readRegistryDrift, readScheduleHealth, readSystemDiagnostics, redactDatabaseUrl, redactDatabaseUrlsInText, registerChangeFeedWriter, registerCompatibleFieldDecorator, registerCompatibleMethodDecorator, registerConfigResolver, registerFilesystemAdapterFactory, registerOptionalDependency, registerRetentionTask, requireAuditOptions, resetChangeFeedWarnings, resetChangeSignals, resetCollectionCache, resetConfigResolvers, resetVerifiedTables, resolveAgentModuleDocPaths, resolveApiMethodExposure, resolveAuthorizedChangeFeedTables, resolveCustomActionMetadata, resolveDatabase, resolveDbCacheKey, resolveDeclaredScopeMismatch, resolveDispatchTenantId, resolveDispatchTenantScope, resolveEffectiveActionMetadata, resolveExistingRunOnceClaim, resolveFileKnowledgeConfig, resolveGetStringFilter, resolveLazyConfig, resolveListLimit, resolveListOffset, resolveMCPToolListCacheHint, resolvePostgresTimeouts, resolveReadCacheControl, resolveRegisteredObjectName, resolveTenantEtagDiscriminator, restFieldReadPermissions, restMethodForApiAction, runCascadeDelete, runOnce, runRetentionSweep, runWithTenantGate, safeParse, safeStringify, sanitizeMessagePaths, setChangeFeedAuthorizer, setChangeFeedEntryVisibility, setDispatchTenantResolver, setTenantEntryPointRunner, setTenantScopedClassResolver, setupSwaggerUI, shouldIncludeMethod, signalVisibleToTenant, smrt, smrtPlugin, smrt as smrtRegistry, snapshotRegistry, sortMCPTools, stableStringify, startRestServer, staticManifest, stopCacheInvalidationListeners, stopChangeSignalListeners, stringify, subscribeToChangeSignals, tableExists, toCustomActionBoolean, toCustomActionDate, toCustomActionNumber, toSnakeCase, tryReserveChangeEventSubscriberSlot, unregisterChangeFeedWriter, unregisterConfigResolver, unregisterRetentionTask, usesEmbeddedRevisionFallback, validatePostgresPermissionContract, validateSyncApplyItem, validateToolCall, versionConditionalResponse, warnIfSharedCacheNeutralized, withAuditContext, withEmbeddedWriteQueue, withEmbeddedWriteTransaction, writeAudit };
112
+ export { AGENT_SURFACE_HASH_PREFIX, AIError, APIGenerator, AiUsageCollector, AiUsagePersistenceHandler, BOOTED_PROVENANCE, CACHE_INVALIDATION_CHANNEL, CHANGE_FEED_CREDENTIAL_TABLES, CHANGE_FEED_INTERCEPTOR_NAME, CHANGE_FEED_TABLE, CHANGE_SIGNAL_CHANNEL, CRUD_OPERATIONS, ConfigurationError, ContentHasher, CosineSimilarity, DEFAULT_AI_COST_RATES, DEFAULT_CHANGES_LIMIT, DEFAULT_DATA_QUERY_PAGE_LIMIT, DEFAULT_DATA_QUERY_RESULT_BYTES, DEFAULT_DISPLAY_LABEL_FIELDS, DEFAULT_EMBEDDING_CONFIG, DEFAULT_EVENTS_HEARTBEAT_MS, DEFAULT_EVENTS_MAX_SUBSCRIBERS, DEFAULT_EVENTS_RETRY_AFTER_SECONDS, DEFAULT_FACET_LIMIT, DEFAULT_LEARNING_CONFIG, DEFAULT_LIST_LIMIT, DEFAULT_LIST_ORDER_BY, DEFAULT_POSTGRES_TIMEOUTS, DEFAULT_RETENTION_POLICY, DIAGNOSTICS_DEFAULT_LIMIT, DataQueryValidationError, DatabaseError, Dispatch, DispatchBus, DispatchCollection, DispatchSubscription, DispatchSubscriptionCollection, EmbeddingProvider, EmbeddingStorage, EmbeddingUnavailableError, ErrorUtils, FIELD_UI_WIDGETS, FIELD_UI_WIDGET_TYPES, FilesystemError, GlobalInterceptors, IN_LIST_CHUNK_SIZE, LearningMemory, LiveSchemaParityError, MAX_CHANGES_LIMIT, MAX_DATA_QUERY_CURSOR_LENGTH, MAX_DATA_QUERY_FACETS, MAX_DATA_QUERY_FILTERS, MAX_DATA_QUERY_FILTER_DEPTH, MAX_DATA_QUERY_IN_VALUES, MAX_DATA_QUERY_OFFSET, MAX_DATA_QUERY_PAGE_LIMIT, MAX_DATA_QUERY_REQUEST_BYTES, MAX_DATA_QUERY_RESULT_BYTES, MAX_DATA_QUERY_WARNINGS, MAX_FACET_FIELDS, MAX_FACET_LIMIT, MAX_LIST_LIMIT, MAX_STI_READ_SCOPE_TYPES, MAX_SYNC_APPLY_BATCH_SIZE, MCPGenerator, MCP_STABLE_CATALOG_TTL_MS, MODULE_DOC_HASH_PREFIX, ManifestBuilder, ManifestGenerator, ManifestManager, MetricsAdapter, NetworkError, ObjectRegistry, PLAYBOOK_PREFLIGHT_CAPABILITY, PLAYBOOK_PREFLIGHT_ROUTE_SEGMENT, POSTGRES_REVISION_GUARD_EXPRESSION, POSTGRES_TIMEOUT_ENV_VARS, PRIVATE_READ_CACHE_CONTROL, PubSubAdapter, QueryBoundsError, QueryOrderByError, RUN_ONCE_CLAIMS_TABLE, RunOnceClaimError, RuntimeError, SMRT_COLLECTION_BASE_NAMES, SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY, SMRT_SCHEMA_VERSION, SYNC_APPLY_ROUTE_SEGMENTS, SYNC_APPLY_UUID_PATTERN, SYSTEM_DIAGNOSTICS_TABLES, SYSTEM_TABLE_NAMES, SchemaComparer, SignalBus, SignalSanitizer, SmrtClass, SmrtCollection, SmrtError, SmrtHierarchical, SmrtJunction, SmrtJunctionBase, SmrtMCPServer, SmrtObject, SmrtPolymorphicAssociation, SmrtRecipe, TenantIsolationError, ValidationError, ValidationReport, ValidationUtils, appendChange, appendChanges, applyOneToManyChildAccessors, applyPendingDecoratorRegistrations, applyPostgresPermissions, applyPostgresRuntimeTimeouts, applySyncWritablePolicy, assertPlainJson, assertPostgresSystemTimestampsCurrent, assertScopedPackageName, auditChanges, auditSnapshot, broadcastCacheInvalidation, buildCascadePlan, buildChangeEventStream, buildConnectSection, buildCustomActionInputSchema, buildCustomActionInvocationArgs, buildDefaultListOrderBy, buildDomainKnowledgeManifest, buildGlossary, buildKnowledgeGraph, bumpChangeFeed, canonicalReadRepresentation, canonicalizeDataQuery, cascadeReferencesTo, changeEventSubscribersAtCapacity, checkKnowledgeGraphFreshness, checkLiveSchemaParity, childAccessorName, chunkArray, classifyDatabaseError, classifyDialectMessage, classifyMethodWireability, classifyParameterWireability, clearRetentionTasks, clone, coerceCustomActionArgument, collectForeignKeyOrphanCounts, computeBodyEtag, computeRuntimeWebManifestHash, computeTableVersionEtag, conditionalJsonResponse, config, convertTypeToJsonSchema, createClassNamePredicate, createDataQueryFingerprint, createDispatchBus, createFilesystemAdapter, createGeneratedCollectionAccess, createInterceptorContext, createMCPServer, createManifestClassNamePredicate, createQualifiedName, createRecipeHelp, createRestServer, createSmrtClient, createSmrtServer, crossPackageRef, customActionParameterInputName, declareChangeFeedSensitiveTable, declaredTypeAcceptsDate, declaresRuntimeRestRoute, declaresRuntimeRestRouteShape, deriveRunOnceClaimKey, describeDisplayLabel, detectEngine, digestRunOnceContent, discoverKnowledgeArtifactPaths, discoverManifestEntry, discoverScopedPackageDirectories, displayLabelFieldProblem, drainChangeFeed, ensureBootstrapSystemTableCompatibility, ensureCacheInvalidationListener, ensureChangeFeedTable, ensureDeferredSystemTableCompatibility, ensureDispatchSubscriptionsSystemTableCompatibility, ensureDispatchSystemTableCompatibility, ensureJobEventsSystemTableCompatibility, ensureJobsSystemTableCompatibility, ensureLegacySystemTableCompatibility, ensureSystemTables, estimateAiUsageCost, eventStreamCapacityExceededResponse, executeCollectionReadPlan, executeDecision, executeToolCall, executeToolCalls, extractFieldRefs, field, filterVisibleChangeFeedEntries, findField, findManifestEntryByQualifiedName, findSelectorFor, foreignKey, formatToolResults, generateDDLForEngine, generateOpenAPISpec, generateSchemaDiff, generateToolFromMethod, generateToolManifest, getActiveAuditOptions, getAdapterInfo, getAuthorizedChangesSince, getAuthorizedTenantScopedChangesSince, getCacheGeneration, getChangeFeedSensitiveTables, getChangesSince, getClassConfigResolvers, getClassName, getConfigResolver, getDatabaseEngine, getManifest, getPackageFromQualifiedName, getRetentionTasks, getSQLFromDiff, getSystemTableShapes, getTableVersion, getTenantScopedChangesSince, getTestDatabase, handlePlaybookPreflightRoute, hasActionableChanges, hasChangeFeedEntryVisibilityHook, hasChangeFeedTableAuthorizerHook, helpToMarkdown, ifNoneMatchHasConcreteMatch, ifNoneMatchSatisfied, importOptionalDependency, invalidateCollectionCache, isAbortedTransactionError, isAdvisoryOnlyChange, isApiActionEnabledForObject, isAudited, isChangeFeedDenyAll, isChangeFeedEntryVisible, isChangeFeedSensitiveTable, isCrudOperation, isCrudToolAction, isDatabaseInterface, isDeterministicDatabaseError, isEmbeddedDatabase, isFieldUIWidget, isFrameworkBaseClass, isFromPackage, isLazyConfigSentinel, isManualOrAdvisoryChange, isNotNullViolationError, isPostgresDatabase, isQualifiedName, isRestActionRoutable, isRestRoutePublic, isScopedPackageName, isSensitiveConnectionParam, isSmrtCollectionExtendsName, isStaleWrite, isTenantScopedClassResolved, isTransientDatabaseError, isType, isUniqueViolationError, isValid, listConfigResolvers, loadExternalManifest, loadExternalManifestSync, loadLocalTestManifestSync, loadManifestFromPathSync, manifest, manyToMany, meta, method, migratePostgresSystemTimestamps, normalizeCustomActionFailure, normalizeDataQueryRequest, normalizeDataQueryResult, normalizeDataQuerySchema, normalizeEventsMaxSubscribers, normalizeOnDelete, normalizeTypedHttpError, oneToMany, parse, parseHelp, parseQualifiedName, parseSyncApplyBatch, payloadMatchesRow, planForeignKeyCreation, planPostgresPermissions, planPostgresSystemTimestampMigrations, postgresRevisionCandidates, postgresRevisionCondition, processSyncApplyBatch, pruneAiUsage, pruneChangeFeed, pruneExpiredContexts, pruneRunOnceClaims, publishArtifactFiles, publishAtomicArtifact, qualifiedNamesEqual, queryStringDecoderFor, readAgentModuleDocs, readDispatchHealth, readJobHealth, readMethodDecoratorConfig, readMigrationStatus, readPackageAgentDoc, readRecentChanges, readRegistryDrift, readScheduleHealth, readSystemDiagnostics, redactDatabaseUrl, redactDatabaseUrlsInText, registerChangeFeedWriter, registerCompatibleFieldDecorator, registerCompatibleMethodDecorator, registerConfigResolver, registerFilesystemAdapterFactory, registerOptionalDependency, registerRetentionTask, renderHelp, requireAuditOptions, resetChangeFeedWarnings, resetChangeSignals, resetCollectionCache, resetConfigResolvers, resetVerifiedTables, resolveAgentModuleDocPaths, resolveApiMethodExposure, resolveAuthorizedChangeFeedTables, resolveCustomActionMetadata, resolveDatabase, resolveDbCacheKey, resolveDeclaredScopeMismatch, resolveDispatchTenantId, resolveDispatchTenantScope, resolveDisplayLabelField, resolveEffectiveActionMetadata, resolveExistingRunOnceClaim, resolveFileKnowledgeConfig, resolveGetStringFilter, resolveHelp, resolveLazyConfig, resolveListLimit, resolveListOffset, resolveMCPToolListCacheHint, resolvePostgresTimeouts, resolveReadCacheControl, resolveRegisteredObjectName, resolveTenantEtagDiscriminator, restFieldReadPermissions, restMethodForApiAction, runCascadeDelete, runOnce, runRetentionSweep, runWithTenantGate, safeParse, safeStringify, sanitizeMessagePaths, setChangeFeedAuthorizer, setChangeFeedEntryVisibility, setDispatchTenantResolver, setTenantEntryPointRunner, setTenantScopedClassResolver, setupSwaggerUI, shouldIncludeMethod, signalVisibleToTenant, smrt, smrtPlugin, smrt as smrtRegistry, snapshotRegistry, sortMCPTools, stableStringify, startRestServer, staticManifest, stopCacheInvalidationListeners, stopChangeSignalListeners, stringify, subscribeToChangeSignals, tableExists, toCustomActionBoolean, toCustomActionDate, toCustomActionNumber, toSnakeCase, tryReserveChangeEventSubscriberSlot, unregisterChangeFeedWriter, unregisterConfigResolver, unregisterRetentionTask, usesEmbeddedRevisionFallback, validateHelp, validatePostgresPermissionContract, validateSyncApplyItem, validateToolCall, versionConditionalResponse, warnIfSharedCacheNeutralized, withAuditContext, withEmbeddedWriteQueue, withEmbeddedWriteTransaction, writeAudit };
@@ -1 +1 @@
1
- {"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../src/knowledge.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,mBAAmB,EACnB,0BAA0B,EAC3B,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EACL,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EACL,gCAAgC,EAChC,mBAAmB,EACnB,KAAK,sBAAsB,GAC5B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,mBAAmB,EACnB,4BAA4B,EAC5B,8BAA8B,EAC9B,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACvB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,mBAAmB,EACnB,0BAA0B,GAC3B,CAAC;AAKF,OAAO,KAAK,EACV,2BAA2B,EAC3B,qBAAqB,EAGrB,uBAAuB,EAMxB,MAAM,2BAA2B,CAAC;AAanC,OAAO,KAAK,EAEV,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAI5B;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,2BAA2B,CAAC;CAC5C;AA0CD,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,2BAA2B,GACnC,uBAAuB,CA0FzB"}
1
+ {"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../src/knowledge.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,mBAAmB,EACnB,0BAA0B,EAC3B,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EACL,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EACL,gCAAgC,EAChC,mBAAmB,EACnB,KAAK,sBAAsB,GAC5B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,mBAAmB,EACnB,4BAA4B,EAC5B,8BAA8B,EAC9B,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACvB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,mBAAmB,EACnB,0BAA0B,GAC3B,CAAC;AAKF,OAAO,KAAK,EACV,2BAA2B,EAC3B,qBAAqB,EAGrB,uBAAuB,EAMxB,MAAM,2BAA2B,CAAC;AAanC,OAAO,KAAK,EAEV,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAI5B;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,2BAA2B,CAAC;CAC5C;AA0CD,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,2BAA2B,GACnC,uBAAuB,CA6FzB"}
package/dist/knowledge.js CHANGED
@@ -101,7 +101,8 @@ function buildDomainKnowledgeManifest(options) {
101
101
  relationshipsV2,
102
102
  agentDoc,
103
103
  moduleDocs: includeDocs && moduleDocPaths.length > 0 ? readAgentModuleDocs(rootDir, agentDocContent) : void 0,
104
- agentSurface
104
+ agentSurface,
105
+ ...options.manifest.recipes && options.manifest.recipes.length > 0 ? { recipes: options.manifest.recipes } : {}
105
106
  };
106
107
  }
107
108
  /**
@@ -139,7 +140,8 @@ function buildKnowledgeObject(object, manifest) {
139
140
  ...defaultValue.present ? { default: defaultValue.value } : {},
140
141
  constraints: fieldConstraints(field),
141
142
  readonly: field.readonly === true || field._meta?.readonly === true ? true : void 0,
142
- transient: field.transient === true || field._meta?.transient === true ? true : void 0
143
+ transient: field.transient === true || field._meta?.transient === true ? true : void 0,
144
+ description: fieldDescription(field)
143
145
  };
144
146
  });
145
147
  const sensitiveIdentifiers = sensitiveFieldIdentifiers(object.fields);
@@ -157,6 +159,7 @@ function buildKnowledgeObject(object, manifest) {
157
159
  name: object.className,
158
160
  qualifiedName: object.qualifiedName,
159
161
  ...previousQualifiedNames.length > 0 ? { previousQualifiedNames } : {},
162
+ ...object.displayLabelField ? { displayLabelField: object.displayLabelField } : {},
160
163
  collection: object.collection,
161
164
  tableName: object.schema?.tableName,
162
165
  packageName: object.packageName,
@@ -177,6 +180,14 @@ function buildKnowledgeObject(object, manifest) {
177
180
  risks: knowledge.risks ?? []
178
181
  };
179
182
  }
183
+ /**
184
+ * The developer-authored `@field({ description })` (#3591). Scanner manifests
185
+ * expose it top-level; runtime-registry entries under `_meta`.
186
+ */
187
+ function fieldDescription(field) {
188
+ const text = field.description ?? field._meta?.description;
189
+ return typeof text === "string" && text.trim() !== "" ? text : void 0;
190
+ }
180
191
  function isSensitiveField(field) {
181
192
  return field.sensitive === true || field._meta?.sensitive === true;
182
193
  }