@specverse/engines 6.42.3 → 6.53.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/dist/ai/analyse-runner.d.ts.map +1 -1
  2. package/dist/ai/analyse-runner.js +53 -1
  3. package/dist/ai/analyse-runner.js.map +1 -1
  4. package/dist/ai/prompt-runner.d.ts +39 -1
  5. package/dist/ai/prompt-runner.d.ts.map +1 -1
  6. package/dist/ai/prompt-runner.js +44 -3
  7. package/dist/ai/prompt-runner.js.map +1 -1
  8. package/dist/ai/providers/claude-cli.d.ts.map +1 -1
  9. package/dist/ai/providers/claude-cli.js +8 -1
  10. package/dist/ai/providers/claude-cli.js.map +1 -1
  11. package/dist/ai/skill-loader.d.ts +50 -0
  12. package/dist/ai/skill-loader.d.ts.map +1 -0
  13. package/dist/ai/skill-loader.js +96 -0
  14. package/dist/ai/skill-loader.js.map +1 -0
  15. package/dist/analyse-prepass/adapters/index.d.ts +2 -0
  16. package/dist/analyse-prepass/adapters/index.d.ts.map +1 -1
  17. package/dist/analyse-prepass/adapters/index.js +2 -0
  18. package/dist/analyse-prepass/adapters/index.js.map +1 -1
  19. package/dist/analyse-prepass/adapters/module-functions.d.ts +95 -0
  20. package/dist/analyse-prepass/adapters/module-functions.d.ts.map +1 -0
  21. package/dist/analyse-prepass/adapters/module-functions.js +358 -0
  22. package/dist/analyse-prepass/adapters/module-functions.js.map +1 -0
  23. package/dist/analyse-prepass/adapters/naming-convention-fks.d.ts +90 -0
  24. package/dist/analyse-prepass/adapters/naming-convention-fks.d.ts.map +1 -0
  25. package/dist/analyse-prepass/adapters/naming-convention-fks.js +181 -0
  26. package/dist/analyse-prepass/adapters/naming-convention-fks.js.map +1 -0
  27. package/dist/analyse-prepass/index.d.ts +8 -0
  28. package/dist/analyse-prepass/index.d.ts.map +1 -1
  29. package/dist/analyse-prepass/index.js +130 -0
  30. package/dist/analyse-prepass/index.js.map +1 -1
  31. package/dist/libs/instance-factories/cli/templates/commander/cli-entry-generator.js +11 -12
  32. package/dist/libs/instance-factories/cli/templates/commander/command-generator.js +2 -2
  33. package/dist/libs/instance-factories/services/templates/prisma/behavior-generator.js +24 -2
  34. package/dist/libs/instance-factories/services/templates/prisma/controller-generator.js +28 -20
  35. package/dist/normalise/index.d.ts +14 -0
  36. package/dist/normalise/index.d.ts.map +1 -0
  37. package/dist/normalise/index.js +14 -0
  38. package/dist/normalise/index.js.map +1 -0
  39. package/dist/normalise/load-overrides.d.ts +43 -0
  40. package/dist/normalise/load-overrides.d.ts.map +1 -0
  41. package/dist/normalise/load-overrides.js +121 -0
  42. package/dist/normalise/load-overrides.js.map +1 -0
  43. package/dist/normalise/normalise-rules.d.ts +181 -0
  44. package/dist/normalise/normalise-rules.d.ts.map +1 -0
  45. package/dist/normalise/normalise-rules.js +79 -0
  46. package/dist/normalise/normalise-rules.js.map +1 -0
  47. package/dist/normalise/rules/cluster-module-functions.d.ts +31 -0
  48. package/dist/normalise/rules/cluster-module-functions.d.ts.map +1 -0
  49. package/dist/normalise/rules/cluster-module-functions.js +238 -0
  50. package/dist/normalise/rules/cluster-module-functions.js.map +1 -0
  51. package/dist/normalise/rules/crud-into-curved.d.ts +117 -0
  52. package/dist/normalise/rules/crud-into-curved.d.ts.map +1 -0
  53. package/dist/normalise/rules/crud-into-curved.js +303 -0
  54. package/dist/normalise/rules/crud-into-curved.js.map +1 -0
  55. package/dist/normalise/rules/drop-trivial-passthrough.d.ts +92 -0
  56. package/dist/normalise/rules/drop-trivial-passthrough.d.ts.map +1 -0
  57. package/dist/normalise/rules/drop-trivial-passthrough.js +217 -0
  58. package/dist/normalise/rules/drop-trivial-passthrough.js.map +1 -0
  59. package/dist/normalise/runner.d.ts +58 -0
  60. package/dist/normalise/runner.d.ts.map +1 -0
  61. package/dist/normalise/runner.js +114 -0
  62. package/dist/normalise/runner.js.map +1 -0
  63. package/dist/parser/import-resolver/resolver.js +1 -1
  64. package/dist/parser/import-resolver/resolver.js.map +1 -1
  65. package/dist/realize/engines/typescript-engine.js +1 -1
  66. package/dist/realize/engines/typescript-engine.js.map +1 -1
  67. package/dist/realize/index.d.ts.map +1 -1
  68. package/dist/realize/index.js +142 -90
  69. package/dist/realize/index.js.map +1 -1
  70. package/dist/realize/library/library.js +1 -1
  71. package/dist/realize/library/library.js.map +1 -1
  72. package/dist/realize/library/resolver.d.ts.map +1 -1
  73. package/dist/realize/library/resolver.js +14 -1
  74. package/dist/realize/library/resolver.js.map +1 -1
  75. package/dist/realize/owner-emit-shared.d.ts +114 -0
  76. package/dist/realize/owner-emit-shared.d.ts.map +1 -0
  77. package/dist/realize/owner-emit-shared.js +227 -0
  78. package/dist/realize/owner-emit-shared.js.map +1 -0
  79. package/dist/realize/per-owner-emit.d.ts +1 -58
  80. package/dist/realize/per-owner-emit.d.ts.map +1 -1
  81. package/dist/realize/per-owner-emit.js +45 -209
  82. package/dist/realize/per-owner-emit.js.map +1 -1
  83. package/dist/realize/per-owner-runner.d.ts +1 -2
  84. package/dist/realize/per-owner-runner.d.ts.map +1 -1
  85. package/dist/realize/per-owner-runner.js +1 -1
  86. package/dist/realize/per-owner-runner.js.map +1 -1
  87. package/dist/realize/post-emit-verify/feedback-runner.d.ts +84 -0
  88. package/dist/realize/post-emit-verify/feedback-runner.d.ts.map +1 -0
  89. package/dist/realize/post-emit-verify/feedback-runner.js +177 -0
  90. package/dist/realize/post-emit-verify/feedback-runner.js.map +1 -0
  91. package/dist/realize/post-emit-verify/index.d.ts +17 -0
  92. package/dist/realize/post-emit-verify/index.d.ts.map +1 -0
  93. package/dist/realize/post-emit-verify/index.js +16 -0
  94. package/dist/realize/post-emit-verify/index.js.map +1 -0
  95. package/dist/realize/post-emit-verify/reemit.d.ts +61 -0
  96. package/dist/realize/post-emit-verify/reemit.d.ts.map +1 -0
  97. package/dist/realize/post-emit-verify/reemit.js +122 -0
  98. package/dist/realize/post-emit-verify/reemit.js.map +1 -0
  99. package/dist/realize/post-emit-verify/types.d.ts +138 -0
  100. package/dist/realize/post-emit-verify/types.d.ts.map +1 -0
  101. package/dist/realize/post-emit-verify/types.js +28 -0
  102. package/dist/realize/post-emit-verify/types.js.map +1 -0
  103. package/dist/realize/post-emit-verify/verifier-manifest.d.ts +29 -0
  104. package/dist/realize/post-emit-verify/verifier-manifest.d.ts.map +1 -0
  105. package/dist/realize/post-emit-verify/verifier-manifest.js +55 -0
  106. package/dist/realize/post-emit-verify/verifier-manifest.js.map +1 -0
  107. package/dist/realize/post-emit-verify/verifiers/tsc.d.ts +24 -0
  108. package/dist/realize/post-emit-verify/verifiers/tsc.d.ts.map +1 -0
  109. package/dist/realize/post-emit-verify/verifiers/tsc.js +148 -0
  110. package/dist/realize/post-emit-verify/verifiers/tsc.js.map +1 -0
  111. package/dist/realize/realize-rules.d.ts +113 -0
  112. package/dist/realize/realize-rules.d.ts.map +1 -0
  113. package/dist/realize/realize-rules.js +271 -0
  114. package/dist/realize/realize-rules.js.map +1 -0
  115. package/libs/instance-factories/cli/templates/commander/cli-entry-generator.ts +11 -12
  116. package/libs/instance-factories/cli/templates/commander/command-generator.ts +2 -2
  117. package/libs/instance-factories/services/templates/prisma/behavior-generator.ts +62 -2
  118. package/libs/instance-factories/services/templates/prisma/controller-generator.ts +42 -20
  119. package/package.json +9 -1
@@ -67,20 +67,19 @@ import { fileURLToPath } from 'url';
67
67
  import { dirname, join } from 'path';
68
68
  ${imports}
69
69
 
70
- // Read version: env var (set by bin entry point) or walk up to find package.json
70
+ // Read version: walk up to find the @specverse/self package.json,
71
+ // fall back to the build-time interpolation when not found.
71
72
  const __filename = fileURLToPath(import.meta.url);
72
73
  const __dirname = dirname(__filename);
73
- let _version = process.env.SPECVERSE_VERSION || '${version}';
74
- if (_version === '${version}') {
75
- try {
76
- for (const rel of ['../../package.json', '../../../package.json', '../../../../package.json', '../../../../../package.json']) {
77
- try {
78
- const pkg = JSON.parse(readFileSync(join(__dirname, rel), 'utf8'));
79
- if (pkg.name === '@specverse/self' && pkg.version) { _version = pkg.version; break; }
80
- } catch { /* try next */ }
81
- }
82
- } catch { /* use fallback */ }
83
- }
74
+ let _version = '${version}';
75
+ try {
76
+ for (const rel of ['../../package.json', '../../../package.json', '../../../../package.json', '../../../../../package.json']) {
77
+ try {
78
+ const pkg = JSON.parse(readFileSync(join(__dirname, rel), 'utf8'));
79
+ if (pkg.name === '@specverse/self' && pkg.version) { _version = pkg.version; break; }
80
+ } catch { /* try next */ }
81
+ }
82
+ } catch { /* use fallback */ }
84
83
 
85
84
  const program = new Command();
86
85
 
@@ -208,7 +208,7 @@ import type { ParserEngine } from '@specverse/types';`,
208
208
  } catch (qe: any) {
209
209
  // Don't let quint-gen module-loading issues block normal
210
210
  // validate (e.g. running against a much older engines version).
211
- if (process.env.SPECVERSE_DEBUG) {
211
+ if (process.env.SPECVERSE_VERBOSE === '2') {
212
212
  console.warn('quint-gen check skipped:', qe?.message ?? String(qe));
213
213
  }
214
214
  }
@@ -377,7 +377,7 @@ import type { ParserEngine, InferenceEngine, RealizeEngine } from '@specverse/ty
377
377
  process.exit(1);
378
378
  }
379
379
  } catch (qe: any) {
380
- if (process.env.SPECVERSE_DEBUG) {
380
+ if (process.env.SPECVERSE_VERBOSE === '2') {
381
381
  console.warn('quint-gen check skipped:', qe?.message ?? String(qe));
382
382
  }
383
383
  }
@@ -128,6 +128,14 @@ export function generateBehaviorWithHelpers(
128
128
 
129
129
  let body = parts.join('\n\n');
130
130
 
131
+ // Rename precondition-fetched `const X = await prisma.X.findUniqueOrThrow(...)`
132
+ // bindings to `_X` when the body has no other reference to `X`. The
133
+ // existence-check pattern emits a const for "{Model} exists" preconditions;
134
+ // if no subsequent precondition / step / postcondition references it, tsc
135
+ // raises TS6133 unused-decl. Renaming to _-prefix suppresses tsc's check
136
+ // while preserving the throw-on-missing semantics.
137
+ body = renameUnusedFindUniqueBindings(body);
138
+
131
139
  // Wrap in transaction if flagged
132
140
  if (behavior.transactional) {
133
141
  body = generateTransactionWrapper(body, context);
@@ -136,6 +144,50 @@ export function generateBehaviorWithHelpers(
136
144
  return { body, helperMethods, unmatchedSteps };
137
145
  }
138
146
 
147
+ /**
148
+ * Post-process a method body string: find each `const X = await prisma.X.findUniqueOrThrow(...)`
149
+ * binding, count downstream references to `X`, and DROP the `const X =`
150
+ * binding entirely when the var is otherwise unused (keeping just the
151
+ * `await prisma.X.findUniqueOrThrow(...)` expression statement). The
152
+ * throw-on-missing semantic is preserved; tsc's noUnusedLocals stops
153
+ * complaining because there's no local to be unused.
154
+ *
155
+ * Why drop instead of rename to `_X`: TypeScript's `_`-prefix
156
+ * exemption only applies to `noUnusedParameters` (function arg names),
157
+ * NOT to `noUnusedLocals` (var decls). A `_invoice` const still trips
158
+ * TS6133 — dropping the binding is the actual fix.
159
+ *
160
+ * The `prisma.X` namespace reference inside the call is a model
161
+ * lookup — DO NOT touch it.
162
+ */
163
+ function renameUnusedFindUniqueBindings(body: string): string {
164
+ const declRe = /\bconst\s+([a-zA-Z_][\w$]*)\s*=\s*await\s+prisma\.[\w.$]+\.findUniqueOrThrow\b/g;
165
+ const declared: string[] = [];
166
+ let m: RegExpExecArray | null;
167
+ while ((m = declRe.exec(body)) !== null) declared.push(m[1]!);
168
+ if (declared.length === 0) return body;
169
+
170
+ let out = body;
171
+ for (const name of declared) {
172
+ // Count occurrences of the bare identifier as a USAGE reference.
173
+ // The declaration line contributes 2: the `const NAME` binding
174
+ // and the `prisma.NAME` model reference. So 2 total = unused; 3+
175
+ // means at least one downstream reference.
176
+ const refRe = new RegExp(`\\b${name}\\b`, 'g');
177
+ const count = (out.match(refRe) ?? []).length;
178
+ if (count <= 2) {
179
+ // Drop the `const NAME =` prefix from the declaration line,
180
+ // leaving the `await prisma.NAME.findUniqueOrThrow(...);` as a
181
+ // pure side-effect statement.
182
+ out = out.replace(
183
+ new RegExp(`\\bconst\\s+${name}\\s*=\\s*(await\\s+prisma\\.)`),
184
+ `$1`,
185
+ );
186
+ }
187
+ }
188
+ return out;
189
+ }
190
+
139
191
  /**
140
192
  * Generate precondition checks from natural-language strings.
141
193
  * Tracks declared variables to avoid duplicates and reuses fetched entities.
@@ -304,14 +356,22 @@ function inferLogicFromOperationName(context: BehaviorContext): string {
304
356
 
305
357
  if (op.startsWith('handle')) {
306
358
  const event = op.replace('handle', '');
359
+ // Use the first declared parameter name (typically `event`) instead
360
+ // of the hard-coded `params`. The method signature uses the spec-
361
+ // derived param name, so referencing `params` produces TS2304
362
+ // "Cannot find name" errors at compile time.
363
+ const eventParam = context.parameterNames?.[0] ?? '_event';
307
364
  return ` // Event handler: ${op}
308
- console.log('[${context.serviceName}] Processing ${event}', params);
365
+ console.log('[${context.serviceName}] Processing ${event}', ${eventParam});
309
366
  return { handled: true, event: '${event}' };`;
310
367
  }
311
368
 
312
369
  if (op.startsWith('validate')) {
370
+ // Same fix as handle*: use the actual first parameter name. For
371
+ // validateX patterns the first param is conventionally `id`.
372
+ const idParam = context.parameterNames?.[0] ?? 'id';
313
373
  return ` // Validation: ${op}
314
- const records = await prisma.${modelVar}.findMany({ where: { id: params.id } });
374
+ const records = await prisma.${modelVar}.findMany({ where: { id: ${idParam} } });
315
375
  return { valid: records.length > 0, checked: records.length };`;
316
376
  }
317
377
 
@@ -46,34 +46,56 @@ export default function generatePrismaController(context: TemplateContext): stri
46
46
  // Generate custom actions and collect AI behavior stubs
47
47
  const customActions = generateCustomActions(controller, modelName, modelVar);
48
48
 
49
+ // Build the class body first, then introspect to decide which
50
+ // top-of-file declarations are actually needed. Controllers with no
51
+ // CURVED ops and no prisma-using custom actions (e.g. a controller
52
+ // that only delegates to .ai.ts behaviour) end up with empty
53
+ // bodies — emitting `prisma` / `parseId` / `PrismaClient` import
54
+ // unconditionally produced TS6133 unused-decl errors at every
55
+ // realize run. Gating on actual body content drops those.
56
+ const classBody = [
57
+ generateValidateMethod(model, modelName),
58
+ curedOps.create ? generateCreateMethod(model, modelName, modelVar, prismaDelegate, controller, allModels) : '',
59
+ curedOps.retrieve ? generateRetrieveMethod(model, modelName, modelVar, prismaDelegate) : '',
60
+ curedOps.update ? generateUpdateMethod(model, modelName, modelVar, prismaDelegate, controller, allModels) : '',
61
+ curedOps.evolve ? generateEvolveMethod(model, modelName, modelVar, prismaDelegate, controller) : '',
62
+ curedOps.delete ? generateDeleteMethod(model, modelName, modelVar, prismaDelegate, controller) : '',
63
+ customActions.code,
64
+ ].filter(Boolean).join('\n ');
65
+
66
+ const usesPrisma = /\bprisma\b/.test(classBody);
67
+ const usesParseId = /\bparseId\(/.test(classBody);
68
+ const usesEventBus = hasEventPublishing(curedOps, controller);
69
+ const usesAiBehaviors = customActions.needsAiBehaviors;
70
+
71
+ // Build top-of-file declarations conditionally.
72
+ const imports = [
73
+ usesPrisma ? `import { PrismaClient } from '@prisma/client';` : '',
74
+ usesEventBus ? `import { eventBus } from '../events/eventBus.js';` : '',
75
+ usesAiBehaviors ? `import * as aiBehaviors from '../behaviors/${modelName}Controller.ai.js';` : '',
76
+ ].filter(Boolean).join('\n');
77
+
78
+ const declarations = [
79
+ usesPrisma ? `const prisma = new PrismaClient();` : '',
80
+ usesParseId
81
+ ? `/** Parse ID from string to the correct type for this model */
82
+ function parseId(id: string): ${needsIntParse ? 'number' : 'string'} {
83
+ ${needsIntParse ? 'return parseInt(id, 10);' : 'return id;'}
84
+ }`
85
+ : '',
86
+ ].filter(Boolean).join('\n\n');
87
+
49
88
  return `/**
50
89
  * ${controllerName}
51
90
  * Model-specific business logic for ${modelName}
52
91
  * ${controller.description || ''}
53
92
  */
54
-
55
- import { PrismaClient } from '@prisma/client';
56
- ${hasEventPublishing(curedOps, controller) ? `import { eventBus } from '../events/eventBus.js';` : ''}
57
- ${customActions.needsAiBehaviors ? `import * as aiBehaviors from '../behaviors/${modelName}Controller.ai.js';` : ''}
58
-
59
- const prisma = new PrismaClient();
60
-
61
- /** Parse ID from string to the correct type for this model */
62
- function parseId(id: string): ${needsIntParse ? 'number' : 'string'} {
63
- ${needsIntParse ? 'return parseInt(id, 10);' : 'return id;'}
64
- }
65
-
66
- /**
93
+ ${imports ? '\n' + imports + '\n' : ''}
94
+ ${declarations ? declarations + '\n\n' : ''}/**
67
95
  * ${controllerName} class
68
96
  */
69
97
  export class ${controllerName} {
70
- ${generateValidateMethod(model, modelName)}
71
- ${curedOps.create ? generateCreateMethod(model, modelName, modelVar, prismaDelegate, controller, allModels) : ''}
72
- ${curedOps.retrieve ? generateRetrieveMethod(model, modelName, modelVar, prismaDelegate) : ''}
73
- ${curedOps.update ? generateUpdateMethod(model, modelName, modelVar, prismaDelegate, controller, allModels) : ''}
74
- ${curedOps.evolve ? generateEvolveMethod(model, modelName, modelVar, prismaDelegate, controller) : ''}
75
- ${curedOps.delete ? generateDeleteMethod(model, modelName, modelVar, prismaDelegate, controller) : ''}
76
- ${customActions.code}
98
+ ${classBody}
77
99
  }
78
100
 
79
101
  // Export singleton instance
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@specverse/engines",
3
- "version": "6.42.3",
3
+ "version": "6.53.1",
4
4
  "description": "SpecVerse toolchain — parser, inference, realize, generators, AI, registry, bundles",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -35,6 +35,14 @@
35
35
  "types": "./dist/realize/index.d.ts",
36
36
  "import": "./dist/realize/index.js"
37
37
  },
38
+ "./realize/post-emit-verify": {
39
+ "types": "./dist/realize/post-emit-verify/index.d.ts",
40
+ "import": "./dist/realize/post-emit-verify/index.js"
41
+ },
42
+ "./normalise": {
43
+ "types": "./dist/normalise/index.d.ts",
44
+ "import": "./dist/normalise/index.js"
45
+ },
38
46
  "./generators": {
39
47
  "types": "./dist/generators/index.d.ts",
40
48
  "import": "./dist/generators/index.js"