@happyvertical/smrt-dev-mcp 0.47.2 → 0.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/AGENTS.md +7 -9
  2. package/README.md +88 -66
  3. package/dist/dev-plane.d.ts +48 -0
  4. package/dist/dev-plane.d.ts.map +1 -0
  5. package/dist/dev-plane.js +211 -0
  6. package/dist/dev-plane.js.map +1 -0
  7. package/dist/http-TeoaK9Xr.js +168 -0
  8. package/dist/http-TeoaK9Xr.js.map +1 -0
  9. package/dist/http.d.ts +1 -0
  10. package/dist/http.d.ts.map +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +31 -850
  13. package/dist/index.js.map +1 -1
  14. package/dist/knowledge/index.d.ts +27 -1
  15. package/dist/knowledge/index.d.ts.map +1 -1
  16. package/dist/{knowledge-CY6sQzpj.js → knowledge-BOsSAdPo.js} +81 -713
  17. package/dist/knowledge-BOsSAdPo.js.map +1 -0
  18. package/dist/knowledge.js +2 -2
  19. package/dist/observation-VJgHaPps.js +802 -0
  20. package/dist/observation-VJgHaPps.js.map +1 -0
  21. package/dist/runtime.d.ts +21 -0
  22. package/dist/runtime.d.ts.map +1 -0
  23. package/dist/runtime.js +18 -0
  24. package/dist/runtime.js.map +1 -0
  25. package/dist/tool-catalog-Zl-bcimC.js +643 -0
  26. package/dist/tool-catalog-Zl-bcimC.js.map +1 -0
  27. package/dist/tool-catalog.d.ts.map +1 -1
  28. package/dist/tools/introspect-project.d.ts +8 -0
  29. package/dist/tools/introspect-project.d.ts.map +1 -1
  30. package/dist/tools/runtime/boot.d.ts +10 -0
  31. package/dist/tools/runtime/boot.d.ts.map +1 -1
  32. package/dist/tools/runtime/connection.d.ts +19 -0
  33. package/dist/tools/runtime/connection.d.ts.map +1 -1
  34. package/dist/tools/runtime/observation.d.ts +12 -0
  35. package/dist/tools/runtime/observation.d.ts.map +1 -1
  36. package/dist/tools/runtime/tools.d.ts.map +1 -1
  37. package/package.json +13 -5
  38. package/skills/smrt-code-review/SKILL.md +1 -1
  39. package/dist/knowledge-CY6sQzpj.js.map +0 -1
@@ -1,3 +1,4 @@
1
+ import { n as TOOLS } from "./tool-catalog-Zl-bcimC.js";
1
2
  import { existsSync, lstatSync, opendirSync, readFileSync, readdirSync, realpathSync } from "node:fs";
2
3
  import { basename, dirname, isAbsolute, join, matchesGlob, relative, resolve, sep } from "node:path";
3
4
  import { createHash } from "node:crypto";
@@ -5,708 +6,6 @@ import { execFileSync } from "node:child_process";
5
6
  import { AGENT_SURFACE_HASH_PREFIX, MODULE_DOC_HASH_PREFIX, discoverScopedPackageDirectories, readAgentModuleDocs, readPackageAgentDoc, resolveAgentModuleDocPaths } from "@happyvertical/smrt-core/knowledge";
6
7
  import { toSnakeCase } from "@happyvertical/smrt-core/utils";
7
8
  import { ManifestAdapter, OxcScanner, isAgentSurfaceSourcePath, isPrunedAgentSurfacePath, lintNumericPrecision, mergeAgentSurfaces, parseSource, scanSvelteAgentSurface, sourceMayContainNumericPrecisionIssue, sourceMayDeclareAgentSurface } from "@happyvertical/smrt-scanner";
8
- //#region src/tool-catalog.ts
9
- var REVIEW_SKILL_NAME = "smrt-code-review";
10
- var JSON_SCHEMA_2020_12 = "https://json-schema.org/draft/2020-12/schema";
11
- function compareToolNames(left, right) {
12
- return left < right ? -1 : left > right ? 1 : 0;
13
- }
14
- /**
15
- * Stable success/error envelope for development tools. `data` preserves each
16
- * tool's existing payload exactly; coverage/diagnostics are promoted only when
17
- * the underlying result actually reports them.
18
- */
19
- var DEV_MCP_OUTPUT_SCHEMA = {
20
- $schema: JSON_SCHEMA_2020_12,
21
- type: "object",
22
- additionalProperties: false,
23
- required: [
24
- "ok",
25
- "coverage",
26
- "diagnostics",
27
- "data"
28
- ],
29
- properties: {
30
- ok: { type: "boolean" },
31
- coverage: {
32
- type: ["object", "null"],
33
- additionalProperties: true
34
- },
35
- diagnostics: {
36
- type: "array",
37
- items: {
38
- type: "object",
39
- additionalProperties: true
40
- }
41
- },
42
- data: {}
43
- }
44
- };
45
- var KNOWLEDGE_DETAIL_DESCRIPTION = "summary: authored package docs are listed by path to stay inside tool-result budgets. full: embed package docs and matching modules with structural object facts. complete: embed all modules and return full package records.";
46
- var DATABASE_URL_PROPERTY = {
47
- type: "string",
48
- description: "Optional dev database URL override (read-only diagnostics); prefer SMRT_DEV_DB_URL or cli.database config"
49
- };
50
- var DATABASE_TYPE_PROPERTY = {
51
- type: "string",
52
- enum: [
53
- "sqlite",
54
- "postgres",
55
- "duckdb"
56
- ],
57
- description: "Optional engine hint for dbUrl or the environment connection (sqlite, postgres, duckdb); inferred from the URL scheme when omitted"
58
- };
59
- var PROJECT_PATH_PROPERTY = {
60
- type: "string",
61
- description: "Project root to boot manifests from (default: the server working directory; ignored by the HTTP host, which boots once)"
62
- };
63
- var LIMIT_PROPERTY = {
64
- type: "number",
65
- description: "Row budget for result lists (default 50, capped at 500)"
66
- };
67
- var TOOLS = [
68
- {
69
- name: "generate-smrt-class",
70
- description: "Generate a complete SMRT class with @smrt() decorator",
71
- inputSchema: {
72
- type: "object",
73
- properties: {
74
- className: {
75
- type: "string",
76
- description: "Name of the class (PascalCase)"
77
- },
78
- properties: {
79
- type: "array",
80
- description: "Array of property definitions",
81
- items: {
82
- type: "object",
83
- properties: {
84
- name: { type: "string" },
85
- type: {
86
- type: "string",
87
- enum: [
88
- "text",
89
- "integer",
90
- "decimal",
91
- "boolean",
92
- "datetime",
93
- "json"
94
- ]
95
- },
96
- required: { type: "boolean" },
97
- nullable: { type: "boolean" },
98
- description: { type: "string" },
99
- defaultValue: { oneOf: [
100
- { type: "string" },
101
- { type: "number" },
102
- { type: "boolean" },
103
- { type: "object" },
104
- { type: "null" }
105
- ] }
106
- },
107
- required: ["name", "type"]
108
- }
109
- },
110
- baseClass: {
111
- type: "string",
112
- enum: ["SmrtObject", "SmrtCollection"],
113
- default: "SmrtObject"
114
- },
115
- template: {
116
- type: "string",
117
- enum: [
118
- "basic",
119
- "global-catalog",
120
- "optional-catalog",
121
- "tenant-project-object",
122
- "tenant-event-log-object",
123
- "cross-package-reference"
124
- ],
125
- default: "basic"
126
- },
127
- tableName: { type: "string" },
128
- conflictColumns: {
129
- type: "array",
130
- items: { type: "string" }
131
- },
132
- tenantScoped: { oneOf: [{ type: "boolean" }, {
133
- type: "object",
134
- properties: {
135
- mode: {
136
- type: "string",
137
- enum: ["required", "optional"]
138
- },
139
- field: { type: "string" },
140
- autoFilter: { type: "boolean" },
141
- autoPopulate: { type: "boolean" },
142
- allowSuperAdminBypass: { type: "boolean" }
143
- }
144
- }] },
145
- includeTenantIdField: { type: "boolean" },
146
- relationships: {
147
- type: "array",
148
- items: {
149
- type: "object",
150
- properties: {
151
- name: { type: "string" },
152
- type: {
153
- type: "string",
154
- enum: [
155
- "foreignKey",
156
- "crossPackageRef",
157
- "oneToMany",
158
- "manyToMany"
159
- ]
160
- },
161
- related: { type: "string" },
162
- required: { type: "boolean" },
163
- nullable: { type: "boolean" },
164
- description: { type: "string" },
165
- validate: { type: "boolean" },
166
- foreignKey: { type: "string" },
167
- through: { type: "string" },
168
- sourceKey: { type: "string" },
169
- targetKey: { type: "string" }
170
- },
171
- required: [
172
- "name",
173
- "type",
174
- "related"
175
- ]
176
- }
177
- },
178
- includeCompanionSnippets: {
179
- type: "boolean",
180
- default: false
181
- },
182
- includeApiConfig: {
183
- type: "boolean",
184
- default: true
185
- },
186
- includeMcpConfig: {
187
- type: "boolean",
188
- default: true
189
- },
190
- includeCliConfig: {
191
- type: "boolean",
192
- default: true
193
- }
194
- },
195
- required: ["className", "properties"]
196
- }
197
- },
198
- {
199
- name: "introspect-project",
200
- description: "Scan a directory for SMRT objects. Returns a compact summary by default; pass detail: \"full\" for field, schema, and method details.",
201
- inputSchema: {
202
- type: "object",
203
- properties: {
204
- directory: {
205
- type: "string",
206
- description: "Project directory (default: cwd)"
207
- },
208
- manifestPath: {
209
- type: "string",
210
- description: "Optional manifest path. Defaults to .smrt/manifest.json, dist/manifest.json, then source scanning."
211
- },
212
- detail: {
213
- type: "string",
214
- enum: ["summary", "full"],
215
- default: "summary",
216
- description: "summary: one compact record per object. full: complete field/schema/method detail (large)."
217
- },
218
- maxChars: {
219
- type: "number",
220
- description: "Character budget for the `objects` payload. Objects past the budget are omitted and reported under `truncated`. Project metadata and diagnostics are always returned in full, so the serialized response is somewhat larger than this budget."
221
- },
222
- includeFields: {
223
- type: "boolean",
224
- description: "Include field details (detail: \"full\" only)"
225
- },
226
- includeRelationships: {
227
- type: "boolean",
228
- description: "Analyze relationships (detail: \"full\" only)"
229
- },
230
- includeMethods: {
231
- type: "boolean",
232
- description: "Include public method details (detail: \"full\" only)"
233
- }
234
- }
235
- }
236
- },
237
- {
238
- name: "review-smrt-project",
239
- description: "Advisory ecosystem alignment review for downstream SMRT projects",
240
- inputSchema: {
241
- type: "object",
242
- properties: {
243
- directory: {
244
- type: "string",
245
- description: "Project directory (default: cwd)"
246
- },
247
- rootDir: {
248
- type: "string",
249
- description: "Compatibility alias for directory"
250
- },
251
- includeSourceEvidence: {
252
- type: "boolean",
253
- description: "Include file and line evidence in findings",
254
- default: true
255
- },
256
- maxFindings: {
257
- type: "number",
258
- description: "Optional maximum number of findings to return"
259
- }
260
- }
261
- }
262
- },
263
- {
264
- name: "reflect-knowledge",
265
- description: "Report deterministic SMRT + HappyVertical SDK knowledge coverage and freshness",
266
- inputSchema: {
267
- type: "object",
268
- properties: { rootDir: {
269
- type: "string",
270
- description: "Project root directory (default: cwd)"
271
- } }
272
- }
273
- },
274
- {
275
- name: "reflect-domain-knowledge",
276
- description: "Report domain-scoped SMRT knowledge artifacts, SDK packages, and freshness",
277
- inputSchema: {
278
- type: "object",
279
- properties: {
280
- rootDir: { type: "string" },
281
- scope: {
282
- type: "string",
283
- enum: [
284
- "project",
285
- "local",
286
- "package",
287
- "sdk",
288
- "installed"
289
- ],
290
- default: "project"
291
- },
292
- package: { type: "string" }
293
- }
294
- }
295
- },
296
- {
297
- name: "check-knowledge-freshness",
298
- description: "Run deterministic freshness checks for SMRT agent knowledge",
299
- inputSchema: {
300
- type: "object",
301
- properties: {
302
- rootDir: { type: "string" },
303
- changed: {
304
- type: "boolean",
305
- description: "Limit stale-pattern checks to changed files"
306
- },
307
- strict: {
308
- type: "boolean",
309
- description: "Treat stale-pattern findings as errors"
310
- }
311
- }
312
- }
313
- },
314
- {
315
- name: "check-domain-knowledge",
316
- description: "Run deterministic freshness checks for domain knowledge artifacts",
317
- inputSchema: {
318
- type: "object",
319
- properties: {
320
- rootDir: { type: "string" },
321
- changed: { type: "boolean" },
322
- strict: { type: "boolean" },
323
- scope: {
324
- type: "string",
325
- enum: [
326
- "project",
327
- "local",
328
- "package",
329
- "sdk",
330
- "installed"
331
- ],
332
- default: "project"
333
- },
334
- package: { type: "string" }
335
- }
336
- }
337
- },
338
- {
339
- name: "build-review-context",
340
- description: "Build model-ready SMRT review context from changed files and optional focus text",
341
- inputSchema: {
342
- type: "object",
343
- properties: {
344
- rootDir: { type: "string" },
345
- changedFiles: {
346
- type: "array",
347
- items: { type: "string" }
348
- },
349
- focus: { type: "string" },
350
- documentation: { type: "string" },
351
- detail: {
352
- type: "string",
353
- enum: [
354
- "summary",
355
- "full",
356
- "complete"
357
- ],
358
- default: "summary",
359
- description: KNOWLEDGE_DETAIL_DESCRIPTION
360
- }
361
- }
362
- }
363
- },
364
- {
365
- name: "build-domain-review-context",
366
- description: "Build domain-scoped model-ready SMRT review context and prompt bundle",
367
- inputSchema: {
368
- type: "object",
369
- properties: {
370
- rootDir: { type: "string" },
371
- changedFiles: {
372
- type: "array",
373
- items: { type: "string" }
374
- },
375
- focus: { type: "string" },
376
- documentation: { type: "string" },
377
- scope: {
378
- type: "string",
379
- enum: [
380
- "project",
381
- "local",
382
- "package",
383
- "sdk",
384
- "installed"
385
- ],
386
- default: "project"
387
- },
388
- package: { type: "string" },
389
- detail: {
390
- type: "string",
391
- enum: [
392
- "summary",
393
- "full",
394
- "complete"
395
- ],
396
- default: "summary",
397
- description: KNOWLEDGE_DETAIL_DESCRIPTION
398
- }
399
- }
400
- }
401
- },
402
- {
403
- name: "smrt-review",
404
- description: "Return deterministic review findings and/or a reusable model prompt bundle. For a formal downstream review, first call get-agent-skill with { \"name\": \"smrt-code-review\" } or load the smrt-code-review MCP prompt/resource.",
405
- inputSchema: {
406
- type: "object",
407
- properties: {
408
- rootDir: { type: "string" },
409
- changedFiles: {
410
- type: "array",
411
- items: { type: "string" }
412
- },
413
- focus: { type: "string" },
414
- documentation: { type: "string" },
415
- mode: {
416
- type: "string",
417
- enum: [
418
- "findings",
419
- "prompt-bundle",
420
- "both"
421
- ],
422
- default: "both"
423
- },
424
- detail: {
425
- type: "string",
426
- enum: [
427
- "summary",
428
- "full",
429
- "complete"
430
- ],
431
- default: "summary",
432
- description: KNOWLEDGE_DETAIL_DESCRIPTION
433
- }
434
- }
435
- }
436
- },
437
- {
438
- name: "build-architecture-context",
439
- description: "Build model-ready SMRT architecture context from an idea or documentation",
440
- inputSchema: {
441
- type: "object",
442
- properties: {
443
- rootDir: { type: "string" },
444
- idea: { type: "string" },
445
- documentation: { type: "string" },
446
- focus: { type: "string" },
447
- detail: {
448
- type: "string",
449
- enum: [
450
- "summary",
451
- "full",
452
- "complete"
453
- ],
454
- default: "summary",
455
- description: KNOWLEDGE_DETAIL_DESCRIPTION
456
- }
457
- }
458
- }
459
- },
460
- {
461
- name: "build-package-specialist-context",
462
- description: "Build deterministic package specialist context for the SMRT workbench",
463
- inputSchema: {
464
- type: "object",
465
- properties: {
466
- rootDir: { type: "string" },
467
- package: {
468
- type: "string",
469
- description: "Package name or short package query, e.g. @happyvertical/smrt-content or content"
470
- },
471
- focus: { type: "string" }
472
- },
473
- required: ["package"]
474
- }
475
- },
476
- {
477
- name: "build-domain-architecture-context",
478
- description: "Build domain-scoped model-ready SMRT architecture context and prompt bundle",
479
- inputSchema: {
480
- type: "object",
481
- properties: {
482
- rootDir: { type: "string" },
483
- idea: { type: "string" },
484
- documentation: { type: "string" },
485
- focus: { type: "string" },
486
- scope: {
487
- type: "string",
488
- enum: [
489
- "project",
490
- "local",
491
- "package",
492
- "sdk",
493
- "installed"
494
- ],
495
- default: "project"
496
- },
497
- package: { type: "string" },
498
- detail: {
499
- type: "string",
500
- enum: [
501
- "summary",
502
- "full",
503
- "complete"
504
- ],
505
- default: "summary",
506
- description: KNOWLEDGE_DETAIL_DESCRIPTION
507
- }
508
- }
509
- }
510
- },
511
- {
512
- name: "smrt-architecture",
513
- description: "Suggest SMRT and HappyVertical SDK packages and return an architecture prompt bundle",
514
- inputSchema: {
515
- type: "object",
516
- properties: {
517
- rootDir: { type: "string" },
518
- idea: { type: "string" },
519
- documentation: { type: "string" },
520
- focus: { type: "string" },
521
- detail: {
522
- type: "string",
523
- enum: [
524
- "summary",
525
- "full",
526
- "complete"
527
- ],
528
- default: "summary",
529
- description: KNOWLEDGE_DETAIL_DESCRIPTION
530
- }
531
- }
532
- }
533
- },
534
- {
535
- name: "list-agent-skills",
536
- description: "List bundled harness-agnostic agent skills shipped with smrt-dev-mcp",
537
- inputSchema: {
538
- type: "object",
539
- properties: {}
540
- }
541
- },
542
- {
543
- name: "get-agent-skill",
544
- description: "Return a bundled harness-agnostic agent skill as Markdown plus optional references",
545
- inputSchema: {
546
- type: "object",
547
- properties: {
548
- name: {
549
- type: "string",
550
- enum: [REVIEW_SKILL_NAME],
551
- description: "Bundled agent skill name"
552
- },
553
- includeReferences: {
554
- type: "boolean",
555
- default: true,
556
- description: "Include referenced files with the skill bundle"
557
- }
558
- },
559
- required: ["name"]
560
- }
561
- },
562
- {
563
- name: "migration-status",
564
- description: "Live migration status from the _smrt_schema_migrations system table (runtime provenance; read-only)",
565
- inputSchema: {
566
- type: "object",
567
- properties: {
568
- dbUrl: DATABASE_URL_PROPERTY,
569
- dbType: DATABASE_TYPE_PROPERTY,
570
- limit: LIMIT_PROPERTY
571
- }
572
- }
573
- },
574
- {
575
- name: "job-health",
576
- description: "Live job queue health from the _smrt_jobs/_smrt_workers system tables (runtime provenance; read-only)",
577
- inputSchema: {
578
- type: "object",
579
- properties: {
580
- dbUrl: DATABASE_URL_PROPERTY,
581
- dbType: DATABASE_TYPE_PROPERTY,
582
- limit: LIMIT_PROPERTY
583
- }
584
- }
585
- },
586
- {
587
- name: "schedule-health",
588
- description: "Live agent schedule health from the _smrt_agent_schedules system table (runtime provenance; read-only; sensitive agentConfig never read)",
589
- inputSchema: {
590
- type: "object",
591
- properties: {
592
- dbUrl: DATABASE_URL_PROPERTY,
593
- dbType: DATABASE_TYPE_PROPERTY,
594
- limit: LIMIT_PROPERTY
595
- }
596
- }
597
- },
598
- {
599
- name: "dispatch-health",
600
- description: "Live dispatch health from the _smrt_dispatch/_smrt_dispatch_subscriptions system tables (runtime provenance; read-only; payloads never read)",
601
- inputSchema: {
602
- type: "object",
603
- properties: {
604
- dbUrl: DATABASE_URL_PROPERTY,
605
- dbType: DATABASE_TYPE_PROPERTY,
606
- limit: LIMIT_PROPERTY
607
- }
608
- }
609
- },
610
- {
611
- name: "recent-changes",
612
- description: "Tail of the _smrt_changes change feed (runtime provenance; read-only; filter by table/tenant)",
613
- inputSchema: {
614
- type: "object",
615
- properties: {
616
- dbUrl: DATABASE_URL_PROPERTY,
617
- dbType: DATABASE_TYPE_PROPERTY,
618
- since: {
619
- type: "number",
620
- description: "Cursor to read after (default 0)"
621
- },
622
- tables: {
623
- type: "array",
624
- items: { type: "string" },
625
- description: "Restrict to these physical table names"
626
- },
627
- tenantId: {
628
- type: "string",
629
- description: "Tenant narrowing filter"
630
- },
631
- limit: LIMIT_PROPERTY
632
- }
633
- }
634
- },
635
- {
636
- name: "registry-drift",
637
- description: "Registry drift report; _smrt_registry is retired and reported as such, never queried (read-only)",
638
- inputSchema: {
639
- type: "object",
640
- properties: {
641
- dbUrl: DATABASE_URL_PROPERTY,
642
- dbType: DATABASE_TYPE_PROPERTY
643
- }
644
- }
645
- },
646
- {
647
- name: "runtime-registry",
648
- description: "Sanitized snapshot of the booted ObjectRegistry from the project and installed manifests (booted provenance; read-only; no project code executed)",
649
- inputSchema: {
650
- type: "object",
651
- properties: {
652
- projectPath: PROJECT_PATH_PROPERTY,
653
- objects: {
654
- type: "array",
655
- items: { type: "string" },
656
- description: "Restrict field/method detail to these simple or qualified object names"
657
- },
658
- detail: {
659
- type: "boolean",
660
- description: "Include field and method detail for every object (default: only when objects is given)"
661
- }
662
- }
663
- }
664
- },
665
- {
666
- name: "runtime-object",
667
- description: "One booted object: sanitized fields, methods, tenancy, inheritance, and the DDL the registry would generate (booted provenance; read-only)",
668
- inputSchema: {
669
- type: "object",
670
- properties: {
671
- projectPath: PROJECT_PATH_PROPERTY,
672
- name: {
673
- type: "string",
674
- description: "Simple or qualified object name"
675
- },
676
- engine: {
677
- type: "string",
678
- enum: [
679
- "sqlite",
680
- "postgres",
681
- "duckdb"
682
- ],
683
- description: "Engine for the DDL preview (default: registry default)"
684
- }
685
- },
686
- required: ["name"]
687
- }
688
- },
689
- {
690
- name: "runtime-schema-diff",
691
- description: "Booted registry schemas versus the live dev database using the db:diff comparer; introspection only, drops/relaxations never proposed (runtime provenance; read-only)",
692
- inputSchema: {
693
- type: "object",
694
- properties: {
695
- projectPath: PROJECT_PATH_PROPERTY,
696
- dbUrl: DATABASE_URL_PROPERTY,
697
- dbType: DATABASE_TYPE_PROPERTY
698
- }
699
- }
700
- }
701
- ].map((tool) => ({
702
- ...tool,
703
- inputSchema: {
704
- ...tool.inputSchema,
705
- $schema: JSON_SCHEMA_2020_12
706
- },
707
- outputSchema: DEV_MCP_OUTPUT_SCHEMA
708
- })).sort((left, right) => compareToolNames(left.name, right.name));
709
- //#endregion
710
9
  //#region src/knowledge/mcp-docs.ts
711
10
  var PACKAGE_NAME = "@happyvertical/smrt-dev-mcp";
712
11
  /**
@@ -1500,10 +799,12 @@ async function buildReviewContext(options = {}) {
1500
799
  scope: options.scope,
1501
800
  packageName: options.packageName ?? options.package
1502
801
  });
802
+ const reviewFindings = buildReviewFindings(index, changedFiles, selectedPackages);
1503
803
  return {
1504
804
  selectedPackages,
1505
805
  selectedSdkPackages,
1506
- deterministicFindings: findStalePatternIssues(index.rootDir, changedFiles.length > 0 ? changedFiles : void 0).concat(buildReviewFindings(index, changedFiles, selectedPackages)),
806
+ deterministicFindings: findStalePatternIssues(index.rootDir, changedFiles.length > 0 ? changedFiles : void 0).concat(reviewFindings.findings),
807
+ reviewHints: reviewFindings.hints,
1507
808
  promptBundle: buildPromptBundle({
1508
809
  title: "SMRT code review",
1509
810
  task: "Review the changed SMRT code. Prioritize correctness, relationships-v2 invariants, tenancy, SDK usage, prompt/data safety, and stale documentation.",
@@ -1529,7 +830,10 @@ async function smrtReview(options = {}) {
1529
830
  mode,
1530
831
  selectedPackages: context.selectedPackages,
1531
832
  selectedSdkPackages: context.selectedSdkPackages,
1532
- ...mode !== "prompt-bundle" ? { deterministicFindings: context.deterministicFindings } : {},
833
+ ...mode !== "prompt-bundle" ? {
834
+ deterministicFindings: context.deterministicFindings,
835
+ reviewHints: context.reviewHints
836
+ } : {},
1533
837
  ...mode !== "findings" ? { promptBundle: context.promptBundle } : {},
1534
838
  coverage: context.coverage,
1535
839
  diagnostics: context.diagnostics
@@ -1598,6 +902,24 @@ async function buildPackageSpecialistContext(options = {}) {
1598
902
  })
1599
903
  };
1600
904
  }
905
+ /**
906
+ * The single context entry point (#2780). `task: 'review'` routes changed
907
+ * files and focus text to package experts and returns findings, hints, and a
908
+ * prompt bundle; `task: 'architecture'` ranks packages by the idea text and
909
+ * returns the bundle plus recommendations. Replaces build-review-context,
910
+ * build-domain-review-context, build-architecture-context, and
911
+ * build-domain-architecture-context, which dispatched to the same code.
912
+ */
913
+ async function buildContext(options) {
914
+ if (options.task === "architecture") return {
915
+ task: "architecture",
916
+ ...await smrtArchitecture(options)
917
+ };
918
+ return {
919
+ task: "review",
920
+ ...await smrtReview(options)
921
+ };
922
+ }
1601
923
  async function smrtArchitecture(options = {}) {
1602
924
  const context = await buildArchitectureContext(options);
1603
925
  const ideaText = [
@@ -2726,6 +2048,7 @@ function shouldScanStalePatternFile(rootDir, filePath) {
2726
2048
  }
2727
2049
  function buildReviewFindings(index, changedFiles, selectedPackages) {
2728
2050
  const issues = [];
2051
+ const hints = [];
2729
2052
  for (const pkg of selectedPackages) {
2730
2053
  const changedPackageFiles = changedFiles.filter((file) => packageOwnsFile(pkg, file, index.packages));
2731
2054
  if (!pkg.agentDoc && pkg.kind === "smrt") issues.push({
@@ -2735,15 +2058,15 @@ function buildReviewFindings(index, changedFiles, selectedPackages) {
2735
2058
  file: pkg.relativeDirectory,
2736
2059
  packageName: pkg.name
2737
2060
  });
2738
- if (changedPackageFiles.some((file) => file.endsWith(".ts")) && pkg.relationshipFeatures.length > 0) issues.push({
2739
- severity: "warning",
2061
+ if (changedPackageFiles.some((file) => file.endsWith(".ts")) && pkg.relationshipFeatures.length > 0) hints.push({
2062
+ severity: "info",
2740
2063
  code: "relationship-sensitive-review",
2741
2064
  message: `Package uses relationships-v2 features: ${pkg.relationshipFeatures.join(", ")}`,
2742
2065
  file: changedPackageFiles.find((file) => file.endsWith(".ts")),
2743
2066
  packageName: pkg.name
2744
2067
  });
2745
- if (changedPackageFiles.some((file) => file.endsWith(".ts")) && pkg.mcpTools.length > 0) issues.push({
2746
- severity: "warning",
2068
+ if (changedPackageFiles.some((file) => file.endsWith(".ts")) && pkg.mcpTools.length > 0) hints.push({
2069
+ severity: "info",
2747
2070
  code: "mcp-surface-review",
2748
2071
  message: `Package exposes ${pkg.mcpTools.length} generated MCP tool(s); check public tool compatibility`,
2749
2072
  file: changedPackageFiles.find((file) => file.endsWith(".ts")),
@@ -2784,7 +2107,10 @@ function buildReviewFindings(index, changedFiles, selectedPackages) {
2784
2107
  file
2785
2108
  });
2786
2109
  }
2787
- return issues;
2110
+ return {
2111
+ findings: issues,
2112
+ hints
2113
+ };
2788
2114
  }
2789
2115
  /**
2790
2116
  * Joins a package-relative path onto a package's workspace-relative directory.
@@ -2896,9 +2222,14 @@ function selectPackages(index, options) {
2896
2222
  }
2897
2223
  for (const pkg of selectPackagesForFiles(index, options.changedFiles ?? [])) if (scopeAllowsPackage(pkg, options.scope)) selected.add(pkg);
2898
2224
  const text = (options.text ?? "").toLowerCase();
2225
+ const scores = /* @__PURE__ */ new Map();
2899
2226
  if (text) for (const pkg of domainPackages(index)) {
2900
2227
  if (!scopeAllowsPackage(pkg, options.scope)) continue;
2901
- if (includesToken(text, pkg.name.replace("@happyvertical/smrt-", "")) || text.includes(pkg.name.toLowerCase()) || pkg.objects.some((object) => includesToken(text, object.className.toLowerCase()))) selected.add(pkg);
2228
+ const score = scorePackageForText(pkg, text);
2229
+ if (score > 0) {
2230
+ selected.add(pkg);
2231
+ scores.set(pkg, score);
2232
+ }
2902
2233
  }
2903
2234
  if (selected.size === 0 && options.scope === "local") for (const pkg of domainPackages(index).filter((item) => scopeAllowsPackage(item, "local"))) selected.add(pkg);
2904
2235
  if (selected.size === 0 && options.scope !== "sdk") {
@@ -2917,7 +2248,44 @@ function selectPackages(index, options) {
2917
2248
  for (const pkg of contributing) selected.add(pkg);
2918
2249
  }
2919
2250
  }
2920
- return [...selected].sort((a, b) => a.name.localeCompare(b.name));
2251
+ return [...selected].sort((a, b) => (scores.get(b) ?? 0) - (scores.get(a) ?? 0) || a.name.localeCompare(b.name));
2252
+ }
2253
+ /** Word tokens (3+ chars) with naive singular/plural variants. */
2254
+ function textTokens(text) {
2255
+ const tokens = /* @__PURE__ */ new Set();
2256
+ for (const raw of text.toLowerCase().match(/[a-z][a-z0-9_-]{2,}/g) ?? []) {
2257
+ tokens.add(raw);
2258
+ if (raw.endsWith("ies")) tokens.add(`${raw.slice(0, -3)}y`);
2259
+ else if (raw.endsWith("sses") || raw.endsWith("xes") || raw.endsWith("ches") || raw.endsWith("shes")) tokens.add(raw.slice(0, -2));
2260
+ else if (raw.endsWith("s") && !raw.endsWith("ss")) tokens.add(raw.slice(0, -1));
2261
+ else tokens.add(`${raw}s`);
2262
+ }
2263
+ return tokens;
2264
+ }
2265
+ /**
2266
+ * Score how strongly free text names a package: its short name, its full
2267
+ * name, its object class names, and its tables/collections/fields. A
2268
+ * request for "newsletter subscription with double opt-in" must rank
2269
+ * `smrt-subscriptions` above the framework default list.
2270
+ */
2271
+ function scorePackageForText(pkg, text) {
2272
+ const tokens = textTokens(text);
2273
+ let score = 0;
2274
+ const shortName = pkg.name.replace("@happyvertical/smrt-", "").replace("@happyvertical/", "").toLowerCase();
2275
+ if (text.includes(pkg.name.toLowerCase())) score += 5;
2276
+ if (tokens.has(shortName)) score += 4;
2277
+ for (const object of pkg.objects) {
2278
+ const className = object.className.toLowerCase();
2279
+ if (tokens.has(className) || includesToken(text, className)) score += 3;
2280
+ for (const candidate of [object.collection, object.tableName]) if (candidate && tokens.has(candidate.toLowerCase())) score += 1;
2281
+ let fieldHits = 0;
2282
+ for (const field of object.fields) if (tokens.has(field.name.toLowerCase()) && fieldHits < 3) {
2283
+ fieldHits += 1;
2284
+ score += 1;
2285
+ }
2286
+ }
2287
+ for (const tag of pkg.domainKnowledge?.tags ?? []) if (tokens.has(String(tag).toLowerCase())) score += 1;
2288
+ return score;
2921
2289
  }
2922
2290
  function selectSdkPackages(index, selectedPackages, texts, options = {}) {
2923
2291
  const selected = /* @__PURE__ */ new Set();
@@ -3297,6 +2665,6 @@ function compactKnowledgePackage(pkg) {
3297
2665
  };
3298
2666
  }
3299
2667
  //#endregion
3300
- export { checkKnowledgeFreshness as a, diffKnowledgeIndex as c, renderKnowledgeIndexMarkdown as d, smrtArchitecture as f, TOOLS as h, buildReviewContext as i, packageDocPaths as l, REVIEW_SKILL_NAME as m, buildKnowledgeIndex as n, checkKnowledgeFreshnessFromIndex as o, smrtReview as p, buildPackageSpecialistContext as r, compactContextResult as s, buildArchitectureContext as t, renderFreshnessResult as u };
2668
+ export { buildReviewContext as a, compactContextResult as c, renderFreshnessResult as d, renderKnowledgeIndexMarkdown as f, buildPackageSpecialistContext as i, diffKnowledgeIndex as l, smrtReview as m, buildContext as n, checkKnowledgeFreshness as o, smrtArchitecture as p, buildKnowledgeIndex as r, checkKnowledgeFreshnessFromIndex as s, buildArchitectureContext as t, packageDocPaths as u };
3301
2669
 
3302
- //# sourceMappingURL=knowledge-CY6sQzpj.js.map
2670
+ //# sourceMappingURL=knowledge-BOsSAdPo.js.map