@happyvertical/smrt-core 0.47.0 → 0.47.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 (84) hide show
  1. package/AGENTS.md +2 -0
  2. package/agents/generators.md +19 -5
  3. package/agents/registry-snapshot.md +28 -0
  4. package/agents/schema-paths.md +12 -0
  5. package/agents/system-diagnostics.md +43 -0
  6. package/dist/browser.js +4 -2
  7. package/dist/change-feed.d.ts +8 -0
  8. package/dist/change-feed.d.ts.map +1 -1
  9. package/dist/change-feed.js +1 -1
  10. package/dist/change-feed.js.map +1 -1
  11. package/dist/index.d.ts +1 -0
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +5 -2
  14. package/dist/manifest/static-manifest.js +1 -1
  15. package/dist/manifest/static-manifest.js.map +1 -1
  16. package/dist/manifest/store.js +1 -1
  17. package/dist/manifest.json +1 -1
  18. package/dist/migrations/differ.d.ts +78 -0
  19. package/dist/migrations/differ.d.ts.map +1 -1
  20. package/dist/migrations/differ.js +191 -1
  21. package/dist/migrations/differ.js.map +1 -1
  22. package/dist/migrations/generator.d.ts.map +1 -1
  23. package/dist/migrations/generator.js +2 -1
  24. package/dist/migrations/generator.js.map +1 -1
  25. package/dist/postgres-permissions.d.ts +3 -0
  26. package/dist/postgres-permissions.d.ts.map +1 -1
  27. package/dist/postgres-permissions.js +49 -6
  28. package/dist/postgres-permissions.js.map +1 -1
  29. package/dist/prebuild/index.d.ts.map +1 -1
  30. package/dist/prebuild/index.js +4 -3
  31. package/dist/prebuild/index.js.map +1 -1
  32. package/dist/registry/class-registration.d.ts.map +1 -1
  33. package/dist/registry/class-registration.js +3 -1
  34. package/dist/registry/class-registration.js.map +1 -1
  35. package/dist/registry/schema-builder.js +1 -1
  36. package/dist/registry.js +1 -1
  37. package/dist/scanner/manifest-generator.d.ts.map +1 -1
  38. package/dist/scanner/manifest-generator.js +22 -1
  39. package/dist/scanner/manifest-generator.js.map +1 -1
  40. package/dist/schema/foreign-key-ddl.d.ts +18 -0
  41. package/dist/schema/foreign-key-ddl.d.ts.map +1 -1
  42. package/dist/schema/foreign-key-ddl.js +15 -2
  43. package/dist/schema/foreign-key-ddl.js.map +1 -1
  44. package/dist/schema/foreign-key-orphan-report.d.ts +57 -0
  45. package/dist/schema/foreign-key-orphan-report.d.ts.map +1 -0
  46. package/dist/schema/foreign-key-orphan-report.js +142 -0
  47. package/dist/schema/foreign-key-orphan-report.js.map +1 -0
  48. package/dist/schema/index.d.ts +1 -0
  49. package/dist/schema/index.d.ts.map +1 -1
  50. package/dist/schema/index.js +2 -1
  51. package/dist/schema/live-parity.d.ts +8 -1
  52. package/dist/schema/live-parity.d.ts.map +1 -1
  53. package/dist/schema/live-parity.js +98 -2
  54. package/dist/schema/live-parity.js.map +1 -1
  55. package/dist/schema/types.d.ts +11 -1
  56. package/dist/schema/types.d.ts.map +1 -1
  57. package/dist/schema.js +2 -1
  58. package/dist/smrt-knowledge.json +22 -10
  59. package/dist/system/diagnostics.d.ts +299 -0
  60. package/dist/system/diagnostics.d.ts.map +1 -0
  61. package/dist/system/diagnostics.js +530 -0
  62. package/dist/system/diagnostics.js.map +1 -0
  63. package/dist/system/index.d.ts +2 -0
  64. package/dist/system/index.d.ts.map +1 -1
  65. package/dist/system/index.js +3 -1
  66. package/dist/system/registry-snapshot.d.ts +112 -0
  67. package/dist/system/registry-snapshot.d.ts.map +1 -0
  68. package/dist/system/registry-snapshot.js +171 -0
  69. package/dist/system/registry-snapshot.js.map +1 -0
  70. package/dist/testing/database.d.ts.map +1 -1
  71. package/dist/testing/database.js +10 -2
  72. package/dist/testing/database.js.map +1 -1
  73. package/dist/utils/scanner-module.d.ts +16 -0
  74. package/dist/utils/scanner-module.d.ts.map +1 -1
  75. package/dist/vite-plugin/index.d.ts +34 -1
  76. package/dist/vite-plugin/index.d.ts.map +1 -1
  77. package/dist/vite-plugin/index.js +85 -5
  78. package/dist/vite-plugin/index.js.map +1 -1
  79. package/dist/vite-plugin/web-collections.d.ts +6 -0
  80. package/dist/vite-plugin/web-collections.d.ts.map +1 -1
  81. package/dist/vite-plugin/web-collections.js +9 -4
  82. package/dist/vite-plugin/web-collections.js.map +1 -1
  83. package/dist/vite-plugin.js +2 -2
  84. package/package.json +10 -10
@@ -1,6 +1,6 @@
1
1
  import { DETERMINISTIC_GENERATED_AT } from "../scanner/types.js";
2
2
  import { findCliApiCoherenceViolations, generateSvelteKitRoutes, methodNameToKebab, resolveApiActionRouteConfig, resolveApiActionSet, validateCliIncludeAgainstApi } from "./sveltekit-generator.js";
3
- import { buildWebCollectionDefinition, buildWebMcpToolDefinitions, buildWebToolDescriptors, computeWebManifestHash, selectWebCollectionEntries } from "./web-collections.js";
3
+ import { buildWebCollectionDefinition, buildWebMcpToolDefinitions, buildWebToolDescriptors, compareText, computeWebManifestHash, selectWebCollectionEntries } from "./web-collections.js";
4
4
  import { buildDomainKnowledgeManifest } from "../knowledge.js";
5
5
  import { importWorkspaceModule } from "../utils/import-workspace-module.js";
6
6
  import { discoverSmrtPackages } from "../manifest/discover-smrt-packages.js";
@@ -68,6 +68,70 @@ function reportAgentSurfaceDiagnostics(surface) {
68
68
  console.warn(` ${where} — ${diagnostic.message}`);
69
69
  }
70
70
  }
71
+ /**
72
+ * Compare the emitted intents against the tool names this build will really
73
+ * register, and project the result into the knowledge-artifact shape (#2725).
74
+ *
75
+ * The rule lives in the scanner, which owns the tool-name derivation. The INPUT
76
+ * lives here, because only core resolves the exposure policy:
77
+ * {@link buildWebMcpToolDefinitions} is the function that emits the runtime
78
+ * `webMcpToolDefinitions`, so its output is the set that actually registers.
79
+ * Handing the scanner every verb a class COULD expose would report collisions
80
+ * with tools nobody mounts.
81
+ *
82
+ * The check is passed in rather than imported: core reaches the scanner through
83
+ * {@link importScanner}, which resolves src or dist depending on how core itself
84
+ * was built, and a static import here would defeat that.
85
+ *
86
+ * `declaredBy` is `Class.action` — the same identity `smrt doctor` prints beside
87
+ * a generated model tool — so a reader can find the other side of the collision
88
+ * without cross-referencing anything.
89
+ */
90
+ function collectAgentSurfaceToolNameCollisions(input) {
91
+ return input.checkAgentSurfaceToolNames(input.surface, {
92
+ generatedToolNames: buildWebMcpToolDefinitions(input.manifest, { kebabRoutes: input.kebabRoutes ?? false }).map((definition) => ({
93
+ name: definition.name,
94
+ declaredBy: `${definition.className}.${definition.action}`
95
+ })),
96
+ ...input.uiToolPrefixes ? { uiToolPrefixes: input.uiToolPrefixes } : {}
97
+ }).map(({ filePath, ...rest }) => ({
98
+ ...rest,
99
+ sourceFile: filePath
100
+ }));
101
+ }
102
+ /**
103
+ * Print every emitted intent whose WebMCP tool name something else also claims
104
+ * (#2725).
105
+ *
106
+ * "Also claims", not "is already taken", for the same reason `smrt doctor`'s
107
+ * header says so: a build cannot see the provider's WebMCP `namespace` or
108
+ * `effects` policy, either of which separates the pair outright. This line runs
109
+ * on every build and every watch rebuild, so it is the surface an author sees
110
+ * most; each message beneath states the condition, and the header must not
111
+ * assert past it.
112
+ *
113
+ * Separate from {@link reportAgentSurfaceDiagnostics} because it says
114
+ * something different: those declarations were EXCLUDED, these are emitted and
115
+ * merely at risk. Folding them into that header would tell an author their
116
+ * intent had been dropped when it had not.
117
+ */
118
+ function reportAgentSurfaceToolNameCollisions(diagnostics) {
119
+ if (diagnostics.length === 0) return;
120
+ console.warn(`[smrt] ⚠️ ${diagnostics.length} declared intent(s) derive a WebMCP tool name something else also claims:`);
121
+ for (const diagnostic of diagnostics) {
122
+ const where = diagnostic.line ? `${diagnostic.sourceFile}:${diagnostic.line}` : diagnostic.sourceFile;
123
+ console.warn(` ${where} — ${diagnostic.message}`);
124
+ }
125
+ }
126
+ /**
127
+ * Order the emitted diagnostics the way the scanner's own merge does, so
128
+ * appending the manifest-derived collisions cannot make the artifact depend on
129
+ * when they were computed.
130
+ */
131
+ function sortKnowledgeAgentSurfaceDiagnostics(diagnostics) {
132
+ const compare = (a, b) => a < b ? -1 : a > b ? 1 : 0;
133
+ return [...diagnostics].sort((a, b) => compare(a.sourceFile, b.sourceFile) || (a.line ?? 0) - (b.line ?? 0) || (a.column ?? 0) - (b.column ?? 0) || compare(a.code, b.code) || compare(a.message, b.message));
134
+ }
71
135
  async function importScanner() {
72
136
  return importWorkspaceModule({
73
137
  packageName: "@happyvertical/smrt-scanner",
@@ -578,7 +642,8 @@ function smrtPlugin(options = {}) {
578
642
  async function scanWithOxc(rootDir) {
579
643
  const startTime = performance.now();
580
644
  try {
581
- const { OxcScanner, ManifestAdapter } = await importScanner();
645
+ const scannerModule = await importScanner();
646
+ const { OxcScanner, ManifestAdapter } = scannerModule;
582
647
  console.log(`[smrt] Using experimental OXC scanner for faster builds`);
583
648
  const safeExclude = [...exclude || [], "**/*.svelte"];
584
649
  const { results, resolved } = await new OxcScanner({
@@ -626,6 +691,20 @@ function smrtPlugin(options = {}) {
626
691
  packageName,
627
692
  packageJson
628
693
  });
694
+ if (agentSurface && results.agentSurface) try {
695
+ const collisions = collectAgentSurfaceToolNameCollisions({
696
+ surface: results.agentSurface,
697
+ manifest: newManifest,
698
+ checkAgentSurfaceToolNames: scannerModule.checkAgentSurfaceToolNames,
699
+ kebabRoutes: svelteKit.kebabRoutes ?? false
700
+ });
701
+ if (collisions.length > 0) {
702
+ reportAgentSurfaceToolNameCollisions(collisions);
703
+ agentSurface.diagnostics = sortKnowledgeAgentSurfaceDiagnostics([...agentSurface.diagnostics, ...collisions]);
704
+ }
705
+ } catch (error) {
706
+ console.warn("[smrt] Skipped the agent-surface tool-name collision check:", error);
707
+ }
629
708
  const elapsed = performance.now() - startTime;
630
709
  const objectCount = Object.keys(newManifest.objects).length;
631
710
  if (objectCount > 0) {
@@ -809,7 +888,8 @@ export function createMCPServer(options = {}) {
809
888
  */
810
889
  function generateClientModeTypes(manifest) {
811
890
  const typeDefinitions = [];
812
- for (const objectMeta of Object.values(manifest.objects)) {
891
+ const sortedClientModeObjects = Object.entries(manifest.objects).sort(([leftKey, left], [rightKey, right]) => compareText(left.qualifiedName || leftKey, right.qualifiedName || rightKey) || compareText(leftKey, rightKey)).map(([, obj]) => obj);
892
+ for (const objectMeta of sortedClientModeObjects) {
813
893
  const interfaceName = objectMeta.className;
814
894
  const fields = objectMeta.fields || {};
815
895
  const propertyLines = [];
@@ -918,7 +998,7 @@ async function generateTypeDeclarationFile(manifest, projectRoot, typeDeclaratio
918
998
  const declarationsDir = join(projectRoot, typeDeclarationsPath);
919
999
  const declarationsFile = join(declarationsDir, "virtual-modules.d.ts");
920
1000
  if (!existsSync(declarationsDir)) mkdirSync(declarationsDir, { recursive: true });
921
- const objectInterfaces = Object.entries(manifest.objects).map(([_name, obj]) => {
1001
+ const objectInterfaces = Object.entries(manifest.objects).sort(([leftKey, left], [rightKey, right]) => compareText(left.qualifiedName || leftKey, right.qualifiedName || rightKey) || compareText(leftKey, rightKey)).map(([_name, obj]) => {
922
1002
  return ` export interface ${`${obj.className}Data`} {
923
1003
  id?: string;
924
1004
  ${Object.entries(obj.fields).map(([fieldName, field]) => {
@@ -1296,6 +1376,6 @@ async function loadDefaultUI() {
1296
1376
  return getDefaultUIModule();
1297
1377
  }
1298
1378
  //#endregion
1299
- export { buildWebMcpToolDefinitions, findCliApiCoherenceViolations, generateInlineRegisterModule, generateSvelteKitRoutes, generateTypeDeclarationFile, isRegisterShimModuleId, loadVerifiedSmrtGenerationSnapshot, methodNameToKebab, resolveApiActionRouteConfig, resolveApiActionSet, serializeSmrtGenerationSnapshot, sha256SmrtGenerationSnapshot, smrtPlugin, toKnowledgeAgentSurface, validateCliIncludeAgainstApi };
1379
+ export { buildWebMcpToolDefinitions, collectAgentSurfaceToolNameCollisions, findCliApiCoherenceViolations, generateInlineRegisterModule, generateSvelteKitRoutes, generateTypeDeclarationFile, isRegisterShimModuleId, loadVerifiedSmrtGenerationSnapshot, methodNameToKebab, resolveApiActionRouteConfig, resolveApiActionSet, serializeSmrtGenerationSnapshot, sha256SmrtGenerationSnapshot, smrtPlugin, toKnowledgeAgentSurface, validateCliIncludeAgainstApi };
1300
1380
 
1301
1381
  //# sourceMappingURL=index.js.map