@happyvertical/smrt-dev-mcp 0.40.65 → 0.40.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md CHANGED
@@ -18,6 +18,7 @@ deterministic SMRT ecosystem knowledge, and portable agent workflows.
18
18
  | `build-domain-review-context` | Domain-scoped review context builder with `scope`/`package` filters |
19
19
  | `smrt-review` | Returns deterministic review findings and a reusable review prompt bundle |
20
20
  | `build-architecture-context` | Builds architecture planning context from an idea or docs |
21
+ | `build-package-specialist-context` | Builds deterministic package-specific Workbench context and source references |
21
22
  | `build-domain-architecture-context` | Domain-scoped architecture context builder with `scope`/`package` filters |
22
23
  | `smrt-architecture` | Recommends SMRT/SDK packages, object-model sketch, risks, and questions |
23
24
  | `list-agent-skills` | Lists bundled harness-agnostic agent skills |
@@ -146,6 +147,16 @@ launcher or a small wrapper script with an absolute Node path.
146
147
  - **Domain artifacts first**: discovery must prefer `.smrt/smrt-knowledge.json`,
147
148
  then `dist/smrt-knowledge.json`, then source artifacts before raw manifest
148
149
  fallback
150
+ - **Structural projection stays additive and sanitized**: schema-version-1
151
+ domain artifacts and raw-manifest fallback both carry tenant mode/field,
152
+ `cti`/`sti`, conflict columns, method signatures, and selected field schema
153
+ facts. Preserve `methods: string[]`; remove top-level and `_meta` sensitive
154
+ fields before deriving both fields and relationships, and remove their field
155
+ and snake-case column names from projected conflict columns.
156
+ If a custom tenant field is sensitive, retain scope/mode but omit its name.
157
+ A schema-v1 artifact without `sensitiveFieldsExcluded: true` is legacy: use
158
+ the owning raw manifest to allowlist its current non-sensitive fields and
159
+ structural identifiers, or omit uncorroborated field facts fail-closed.
149
160
  - **Skill loading**: bundled skills must be included in `package.json` `files`
150
161
  because runtime reads them from the installed package directory
151
162
  - **Portable plugin boundary**: `mcp.json` launches only `./dist/index.js` from
@@ -185,7 +196,8 @@ launcher or a small wrapper script with an absolute Node path.
185
196
  - **Budgets are enforced at the transport boundary**: `KnowledgePackage` carries
186
197
  the full `agentDoc` and domain manifest, so the MCP handlers project a compact
187
198
  package record unless `detail: 'full'`. Library callers (the CLI) still receive
188
- the full objects.
199
+ the full objects. Structural object facts render into prompt Markdown only in
200
+ full detail; summary mode remains names/counts/paths.
189
201
  - **Private packages skip packaging checks**: the `files` allowlist governs npm
190
202
  publication, so `private: true` packages are exempt; authored docs are still
191
203
  required. A workspace root is exempt from both — but **only when member
package/README.md CHANGED
@@ -154,10 +154,13 @@ Knowledge and introspection tools return a **summary** by default and accept
154
154
  budget.
155
155
  - `smrt-architecture`, `smrt-review`, and the `build-*-context` tools list
156
156
  authored `AGENTS.md` and module docs **by path** rather than embedding them,
157
- and return compact package records.
157
+ and return compact package records. With `detail: "full"`, their prompt
158
+ bundles also render high-signal object facts: tenant mode/field, `cti`/`sti`
159
+ strategy, conflict columns, method signatures, and field
160
+ defaults/constraints/readonly/transient flags.
158
161
 
159
- The `smrt dev:knowledge-*` CLI commands request `detail: "full"`, so their output
160
- is unchanged.
162
+ The `smrt dev:knowledge-*` CLI commands request `detail: "full"`, so they remain
163
+ full-detail and unbudgeted.
161
164
 
162
165
  ## Knowledge Boundary
163
166
 
@@ -171,7 +174,16 @@ Downstream s-m-r-t packages/apps can publish their own scoped
171
174
  `.smrt/smrt-knowledge.json`, then `dist/smrt-knowledge.json`, then source
172
175
  manifest artifacts before falling back to raw manifest/doc scanning. The runtime
173
176
  `manifest.json` stays focused on object registration; `smrt-knowledge.json` is
174
- the agent/developer contract.
177
+ the agent/developer contract. Its schema-version-1 structural keys are additive,
178
+ and older artifacts without them remain readable. Sensitive fields are excluded
179
+ from both the curated artifact and raw-manifest fallback projection, including
180
+ legacy sensitivity flags under `_meta`.
181
+ Sensitive field names and their snake-case column names are also removed from
182
+ projected conflict columns. A sensitive custom tenant-field name is omitted
183
+ while its tenant scope and mode remain available.
184
+ New artifacts record `sensitiveFieldsExcluded: true`. For a legacy schema-v1
185
+ artifact without that marker, the reader cross-checks the owning raw manifest
186
+ and omits any field or structural identifier it cannot corroborate as safe.
175
187
 
176
188
  ## Cache Metadata
177
189
 
@@ -386,6 +398,18 @@ then return a model-ready architecture prompt bundle.
386
398
  | `focus` | `string` | No | Architecture concern to prioritize |
387
399
  | `detail` | `'summary' \| 'full'` | No | Default `summary`; `full` embeds authored docs and full package records |
388
400
 
401
+ ### `build-package-specialist-context`
402
+
403
+ Build deterministic package-specific context for the Workbench, including the
404
+ package's authored docs, manifests, routes, tests, prompts, and SDK dependency
405
+ context.
406
+
407
+ | Parameter | Type | Required | Description |
408
+ |-----------|------|----------|-------------|
409
+ | `rootDir` | `string` | No | Project root directory (default: cwd) |
410
+ | `package` | `string` | Yes | Package name or short package query |
411
+ | `focus` | `string` | No | Package concern to prioritize |
412
+
389
413
  ### `build-domain-architecture-context`
390
414
 
391
415
  Domain-scoped alias for `build-architecture-context`.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAGL,MAAM,EACP,MAAM,8BAA8B,CAAC;AAqBtC,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG1C,eAAO,MAAM,cAAc,QAAuB,CAAC;AAuBnD,wBAAgB,YAAY,IAAI,MAAM,CAkfrC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAGL,MAAM,EACP,MAAM,8BAA8B,CAAC;AAsBtC,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG1C,eAAO,MAAM,cAAc,QAAuB,CAAC;AA6BnD,wBAAgB,YAAY,IAAI,MAAM,CAgnBrC"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as checkKnowledgeFreshnessFromIndex, d as smrtReview, f as REVIEW_SKILL_NAME, i as checkKnowledgeFreshness, n as buildKnowledgeIndex, p as TOOLS, r as buildReviewContext, s as packageDocPaths, t as buildArchitectureContext, u as smrtArchitecture } from "./knowledge-A7-gIjW4.js";
2
+ import { a as checkKnowledgeFreshness, c as packageDocPaths, d as smrtArchitecture, f as smrtReview, i as buildReviewContext, m as TOOLS, n as buildKnowledgeIndex, o as checkKnowledgeFreshnessFromIndex, p as REVIEW_SKILL_NAME, r as buildPackageSpecialistContext, t as buildArchitectureContext } from "./knowledge-L22wrifG.js";
3
3
  import { existsSync, readFileSync, realpathSync } from "node:fs";
4
4
  import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
5
5
  import { fileURLToPath, pathToFileURL } from "node:url";
@@ -1074,6 +1074,9 @@ var LIVE_KNOWLEDGE_CACHE_HINT = {
1074
1074
  ttlMs: 0,
1075
1075
  cacheScope: "private"
1076
1076
  };
1077
+ var WORKBENCH_PROJECT_URI = "smrt://workbench/project";
1078
+ var WORKBENCH_PACKAGE_PREFIX = "smrt://workbench/package/";
1079
+ var WORKBENCH_SPECIALIST_SUFFIX = "/specialist";
1077
1080
  function createServer() {
1078
1081
  if (DEBUG) console.error(`[${SERVER_NAME}] Starting server v${SERVER_VERSION}`);
1079
1082
  const server = new Server({
@@ -1230,13 +1233,33 @@ function createServer() {
1230
1233
  description: "Composed SMRT, downstream domain, and HappyVertical SDK knowledge index.",
1231
1234
  mimeType: "application/json"
1232
1235
  },
1236
+ {
1237
+ uri: WORKBENCH_PROJECT_URI,
1238
+ name: "smrt-workbench-project",
1239
+ title: "SMRT Workbench Project",
1240
+ description: "Workbench-facing package and knowledge resource index for the current project.",
1241
+ mimeType: "application/json"
1242
+ },
1233
1243
  ...index.packages.map((pkg) => ({
1234
1244
  uri: `${KNOWLEDGE_PACKAGE_PREFIX}${encodeURIComponent(pkg.name)}`,
1235
1245
  name: `smrt-domain-knowledge-${pkg.name}`,
1236
1246
  title: `SMRT Domain Knowledge: ${pkg.name}`,
1237
1247
  description: "Package-scoped SMRT domain knowledge, generated surfaces, and authored context.",
1238
1248
  mimeType: "application/json"
1239
- }))
1249
+ })),
1250
+ ...index.packages.filter((pkg) => pkg.kind !== "sdk").flatMap((pkg) => [{
1251
+ uri: `${WORKBENCH_PACKAGE_PREFIX}${encodeURIComponent(pkg.name)}`,
1252
+ name: `smrt-workbench-${pkg.name}`,
1253
+ title: `SMRT Workbench Package: ${pkg.name}`,
1254
+ description: "Workbench package resource with docs, manifest, knowledge, scripts, and surface metadata.",
1255
+ mimeType: "application/json"
1256
+ }, {
1257
+ uri: `${WORKBENCH_PACKAGE_PREFIX}${encodeURIComponent(pkg.name)}${WORKBENCH_SPECIALIST_SUFFIX}`,
1258
+ name: `smrt-workbench-specialist-${pkg.name}`,
1259
+ title: `SMRT Package Specialist: ${pkg.name}`,
1260
+ description: "Deterministic package specialist prompt bundle and source list.",
1261
+ mimeType: "application/json"
1262
+ }])
1240
1263
  ] };
1241
1264
  });
1242
1265
  server.setRequestHandler("resources/read", async (request) => {
@@ -1254,6 +1277,42 @@ function createServer() {
1254
1277
  text: JSON.stringify(sanitizeKnowledgeIndex(index), null, 2)
1255
1278
  }] };
1256
1279
  }
1280
+ if (uri === WORKBENCH_PROJECT_URI) {
1281
+ const index = await buildKnowledgeIndex();
1282
+ return { contents: [{
1283
+ uri,
1284
+ mimeType: "application/json",
1285
+ text: JSON.stringify({
1286
+ project: sanitizeKnowledgeIndex(index),
1287
+ workbenchResources: index.packages.filter((pkg) => pkg.kind !== "sdk").map((pkg) => ({
1288
+ packageName: pkg.name,
1289
+ packageUri: `${WORKBENCH_PACKAGE_PREFIX}${encodeURIComponent(pkg.name)}`,
1290
+ specialistUri: `${WORKBENCH_PACKAGE_PREFIX}${encodeURIComponent(pkg.name)}${WORKBENCH_SPECIALIST_SUFFIX}`
1291
+ }))
1292
+ }, null, 2)
1293
+ }] };
1294
+ }
1295
+ if (uri.startsWith(WORKBENCH_PACKAGE_PREFIX) && uri.endsWith(WORKBENCH_SPECIALIST_SUFFIX)) {
1296
+ const specialist = await buildPackageSpecialistContext({ package: decodeURIComponent(uri.slice(25, -11)) });
1297
+ return { contents: [{
1298
+ uri,
1299
+ mimeType: "application/json",
1300
+ text: JSON.stringify(sanitizePackageSpecialist(specialist), null, 2)
1301
+ }] };
1302
+ }
1303
+ if (uri.startsWith(WORKBENCH_PACKAGE_PREFIX)) {
1304
+ const packageName = decodeURIComponent(uri.slice(25));
1305
+ const pkg = (await buildKnowledgeIndex()).packages.find((item) => item.name === packageName);
1306
+ if (!pkg) throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Unknown workbench package: ${packageName}`);
1307
+ return { contents: [{
1308
+ uri,
1309
+ mimeType: "application/json",
1310
+ text: JSON.stringify({
1311
+ package: sanitizeKnowledgePackage(pkg),
1312
+ specialistUri: `${WORKBENCH_PACKAGE_PREFIX}${encodeURIComponent(pkg.name)}${WORKBENCH_SPECIALIST_SUFFIX}`
1313
+ }, null, 2)
1314
+ }] };
1315
+ }
1257
1316
  if (uri.startsWith(KNOWLEDGE_PACKAGE_PREFIX)) {
1258
1317
  const packageName = decodeURIComponent(uri.slice(25));
1259
1318
  const pkg = (await buildKnowledgeIndex()).packages.find((item) => item.name === packageName);
@@ -1329,6 +1388,9 @@ function createServer() {
1329
1388
  case "smrt-review":
1330
1389
  result = JSON.stringify(compactContextResult(await smrtReview(args), detailArg(args)), null, 2);
1331
1390
  break;
1391
+ case "build-package-specialist-context":
1392
+ result = JSON.stringify(sanitizePackageSpecialist(await buildPackageSpecialistContext(args)), null, 2);
1393
+ break;
1332
1394
  case "build-architecture-context":
1333
1395
  case "build-domain-architecture-context":
1334
1396
  result = JSON.stringify(compactContextResult(await buildArchitectureContext(args), detailArg(args)), null, 2);
@@ -1528,6 +1590,21 @@ function sanitizeKnowledgePackage(pkg) {
1528
1590
  }))
1529
1591
  };
1530
1592
  }
1593
+ function sanitizePackageSpecialist(specialist) {
1594
+ return {
1595
+ selectedPackage: sanitizeKnowledgePackage(specialist.selectedPackage),
1596
+ selectedSdkPackages: specialist.selectedSdkPackages.map((pkg) => sanitizeKnowledgePackage(pkg)),
1597
+ promptBundle: {
1598
+ ...specialist.promptBundle,
1599
+ contextMarkdown: specialist.promptBundle.contextMarkdown.replace(/^Baseline root: .+$/m, "Baseline root: ."),
1600
+ sourceFiles: sanitizePaths(specialist.promptBundle.sourceFiles)
1601
+ },
1602
+ sourceFiles: sanitizePaths(specialist.sourceFiles)
1603
+ };
1604
+ }
1605
+ function sanitizePaths(paths) {
1606
+ return paths.map(sanitizePath).filter((path) => typeof path === "string");
1607
+ }
1531
1608
  function sanitizePath(path) {
1532
1609
  if (!path) return path;
1533
1610
  if (path.startsWith("/") || /^[A-Za-z]:[\\/]/.test(path)) return "<absolute-path>";