@happyvertical/smrt-cli 0.45.1 → 0.45.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.
package/AGENTS.md CHANGED
@@ -271,7 +271,7 @@ sessions/magic-link tokens/CLI-auth requests from `smrt-users`).
271
271
  - `src/commands/` — individual command implementations
272
272
  - `src/loaders/` — class-loader, local-loader, npm-loader, git-loader, template-loader
273
273
  - `src/discovery/manifest-discovery.ts` — manifest auto-discovery
274
- - `src/commands/docs-claude.ts` — downstream AGENTS.md generation plus Claude compatibility alias
274
+ - `src/commands/docs-claude.ts` — downstream AGENTS.md generation plus Claude compatibility alias; uses core knowledge discovery without object scanning
275
275
 
276
276
  ## Gotchas
277
277
 
package/README.md CHANGED
@@ -140,6 +140,18 @@ layout that means declaring them, not relying on the CLI's own dependencies.
140
140
  | `smrt knowledge:review-context --scope project\|local\|package\|sdk\|installed --package <name> --format markdown\|json` | Build a model-ready domain review prompt bundle |
141
141
  | `smrt knowledge:architecture-context --scope project\|local\|package\|sdk\|installed --package <name> --format markdown\|json` | Build a model-ready domain architecture prompt bundle |
142
142
 
143
+ `docs:agents` includes package AGENTS guidance and lists linked module files by
144
+ source path; it does not read or embed their bodies. Use
145
+ `smrt docs:agents --complete` for a complete authored reference. The deprecated `docs:claude`
146
+ alias supports the same flag and retains its historical output path.
147
+ Regenerate snapshots after moving the project or updating dependencies so the
148
+ local source paths remain current.
149
+
150
+ Review and architecture prompt bundles include package guidance and modules
151
+ matched by file or focus hints. Add `--complete` to either context command to
152
+ include every module for the selected packages. These commands still build the
153
+ knowledge index; documentation snapshots use lightweight package discovery.
154
+
143
155
  ### Configuration
144
156
 
145
157
  | Command | Description |
@@ -1,7 +1,7 @@
1
1
  import { t as resolveManifestEntryPackageName } from "./index.js";
2
2
  import { createRequire } from "node:module";
3
3
  import * as fs from "node:fs";
4
- import { existsSync, lstatSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
4
+ import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
5
5
  import * as path from "node:path";
6
6
  import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
7
7
  import { fileURLToPath, pathToFileURL } from "node:url";
@@ -12,7 +12,7 @@ import { createLogger } from "@happyvertical/logger";
12
12
  import glob from "fast-glob";
13
13
  import { createHash } from "node:crypto";
14
14
  import { toSnakeCase } from "@happyvertical/smrt-core/utils";
15
- import { readAgentModuleDocs } from "@happyvertical/smrt-core/knowledge";
15
+ import { discoverScopedPackageDirectories, readAgentModuleDocs, readPackageAgentDoc, resolveAgentModuleDocPaths } from "@happyvertical/smrt-core/knowledge";
16
16
  import { MCPGenerator } from "@happyvertical/smrt-core/generators";
17
17
  import { generateDeclarationsFromCLI } from "@happyvertical/smrt-core/prebuild";
18
18
  import { execFileSync, execSync, spawn, spawnSync } from "node:child_process";
@@ -21,7 +21,7 @@ import { homedir, tmpdir } from "node:os";
21
21
  import { extract } from "tar";
22
22
  import { importWorkspaceModule } from "@happyvertical/smrt-core/utils/import-workspace-module";
23
23
  import { buildIntegerWidthTableStatements, collectIntegerWidthTargets, parsePostgresTimeoutMs, preflightIntegerWidthWidening, widenIntegerColumnsToBigInt } from "@happyvertical/smrt-core/migrations";
24
- import { buildArchitectureContext, buildKnowledgeIndex, buildReviewContext, checkKnowledgeFreshness, diffKnowledgeIndex, renderFreshnessResult, renderKnowledgeIndexMarkdown } from "@happyvertical/smrt-dev-mcp/knowledge";
24
+ import { buildArchitectureContext, buildKnowledgeIndex, buildReviewContext, checkKnowledgeFreshness, compactContextResult, diffKnowledgeIndex, renderFreshnessResult, renderKnowledgeIndexMarkdown } from "@happyvertical/smrt-dev-mcp/knowledge";
25
25
  //#region src/commands/db-command-utils.ts
26
26
  var SENSITIVE_QUERY_PARAMS = /* @__PURE__ */ new Set([
27
27
  "access_token",
@@ -3183,6 +3183,11 @@ function createDocsCommand(config) {
3183
3183
  description: `Output file path (default: ${config.defaultOutput})`,
3184
3184
  short: "o"
3185
3185
  },
3186
+ complete: {
3187
+ type: "boolean",
3188
+ description: "Include every linked module document in the snapshot",
3189
+ default: false
3190
+ },
3186
3191
  "dry-run": {
3187
3192
  type: "boolean",
3188
3193
  description: "Print to stdout without writing file",
@@ -3197,14 +3202,15 @@ function createDocsCommand(config) {
3197
3202
  const dryRun = options["dry-run"];
3198
3203
  const monorepoRoot = detectMonorepoRoot();
3199
3204
  const rootDocs = monorepoRoot ? loadRootDocs(monorepoRoot) : [];
3200
- const packages = await discoverInstalledPackages();
3201
- const sdkPackages = await discoverSdkPackages();
3205
+ const installedDirectories = discoverScopedPackageDirectories([join(process.cwd(), "node_modules", "@happyvertical")]);
3206
+ const packages = await discoverInstalledPackages(installedDirectories, options.complete);
3207
+ const sdkPackages = discoverSdkPackages(installedDirectories, options.complete);
3202
3208
  if (packages.length === 0 && sdkPackages.length === 0) {
3203
3209
  console.log("\n⚠️ No @happyvertical packages found in node_modules");
3204
3210
  console.log(" Make sure packages are installed before running this command.\n");
3205
3211
  process.exit(1);
3206
3212
  }
3207
- const content = generateMarkdown(packages, rootDocs.length > 0 ? rootDocs : void 0, sdkPackages.length > 0 ? sdkPackages : void 0, config.generatedBy);
3213
+ const content = generateMarkdown(packages, rootDocs.length > 0 ? rootDocs : void 0, sdkPackages.length > 0 ? sdkPackages : void 0, config.generatedBy, { complete: options.complete });
3208
3214
  if (dryRun) {
3209
3215
  console.log(content);
3210
3216
  return;
@@ -3220,7 +3226,7 @@ function createDocsCommand(config) {
3220
3226
  const allPackages = [...packages, ...sdkPackages];
3221
3227
  const withAgentDocs = allPackages.filter((p) => p.agentMd).length;
3222
3228
  if (withAgentDocs > 0) console.log(` ${withAgentDocs} with AGENTS.md`);
3223
- const moduleDocCount = allPackages.reduce((total, p) => total + (p.moduleDocs?.length ?? 0), 0);
3229
+ const moduleDocCount = allPackages.reduce((total, p) => total + (p.moduleDocPaths?.length ?? p.moduleDocs?.length ?? 0), 0);
3224
3230
  if (moduleDocCount > 0) console.log(` ${moduleDocCount} linked module docs`);
3225
3231
  if (rootDocs.length > 0) console.log(` ${rootDocs.length} framework documents included`);
3226
3232
  console.log("");
@@ -3249,22 +3255,13 @@ var docsClaudeCommand = createDocsCommand({
3249
3255
  * Discover installed @happyvertical/smrt-* packages.
3250
3256
  * Checks both node_modules and workspace packages directory.
3251
3257
  */
3252
- async function discoverInstalledPackages() {
3258
+ async function discoverInstalledPackages(installedDirectories, complete = false) {
3253
3259
  const packages = [];
3254
3260
  const { readdirSync } = await import("node:fs");
3255
- const nodeModulesPath = join(process.cwd(), "node_modules", "@happyvertical");
3256
- if (existsSync(nodeModulesPath)) {
3257
- const entries = readdirSync(nodeModulesPath, { withFileTypes: true });
3258
- for (const entry of entries) {
3259
- if (!entry.name.startsWith("smrt-")) continue;
3260
- const entryPath = join(nodeModulesPath, entry.name);
3261
- let packagePath = entryPath;
3262
- try {
3263
- if (lstatSync(entryPath).isSymbolicLink()) packagePath = realpathSync(entryPath);
3264
- } catch {}
3265
- const pkg = loadPackageInfo(packagePath, entry.name);
3266
- if (pkg) packages.push(pkg);
3267
- }
3261
+ for (const entry of installedDirectories) {
3262
+ if (!entry.name.startsWith("smrt-")) continue;
3263
+ const pkg = loadPackageInfo(entry.realDirectory, entry.name, complete);
3264
+ if (pkg) packages.push(pkg);
3268
3265
  }
3269
3266
  if (packages.length === 0) {
3270
3267
  const workspacePath = join(process.cwd(), "packages");
@@ -3278,7 +3275,7 @@ async function discoverInstalledPackages() {
3278
3275
  if (!existsSync(packageJsonPath)) continue;
3279
3276
  try {
3280
3277
  if (!JSON.parse(readFileSync(packageJsonPath, "utf-8")).name?.startsWith("@happyvertical/smrt-")) continue;
3281
- const pkg = loadPackageInfo(packagePath, entry.name);
3278
+ const pkg = loadPackageInfo(packagePath, entry.name, complete);
3282
3279
  if (pkg) packages.push(pkg);
3283
3280
  } catch {}
3284
3281
  }
@@ -3289,32 +3286,22 @@ async function discoverInstalledPackages() {
3289
3286
  /**
3290
3287
  * Discover installed @happyvertical/* SDK packages (non-smrt).
3291
3288
  */
3292
- async function discoverSdkPackages() {
3289
+ function discoverSdkPackages(installedDirectories, complete = false) {
3293
3290
  const packages = [];
3294
- const { readdirSync } = await import("node:fs");
3295
- const nodeModulesPath = join(process.cwd(), "node_modules", "@happyvertical");
3296
- if (!existsSync(nodeModulesPath)) return packages;
3297
- const entries = readdirSync(nodeModulesPath, { withFileTypes: true });
3298
- for (const entry of entries) {
3299
- if (entry.name.startsWith("smrt-")) continue;
3300
- if (entry.name === "smrt") continue;
3301
- const entryPath = join(nodeModulesPath, entry.name);
3302
- let packagePath = entryPath;
3303
- try {
3304
- if (lstatSync(entryPath).isSymbolicLink()) packagePath = realpathSync(entryPath);
3305
- } catch {}
3306
- const pkg = loadPackageInfo(packagePath, entry.name);
3291
+ for (const entry of installedDirectories) {
3292
+ if (entry.name.startsWith("smrt-") || entry.name === "smrt") continue;
3293
+ const pkg = loadPackageInfo(entry.realDirectory, entry.name, complete);
3307
3294
  if (pkg) packages.push(pkg);
3308
3295
  }
3309
3296
  return packages.sort((a, b) => a.name.localeCompare(b.name));
3310
3297
  }
3311
- function loadPackageInfo(packagePath, dirName) {
3298
+ function loadPackageInfo(packagePath, dirName, complete) {
3312
3299
  const packageJsonPath = join(packagePath, "package.json");
3313
3300
  if (!existsSync(packageJsonPath)) return null;
3314
3301
  try {
3315
3302
  const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
3316
3303
  const readmePath = join(packagePath, "README.md");
3317
- const agentDoc = loadAgentDoc(join(packagePath, "AGENTS.md"), join(packagePath, "CLAUDE.md"));
3304
+ const agentDoc = readPackageAgentDoc(packagePath);
3318
3305
  return {
3319
3306
  name: packageJson.name,
3320
3307
  version: packageJson.version,
@@ -3322,32 +3309,15 @@ function loadPackageInfo(packagePath, dirName) {
3322
3309
  agentMd: agentDoc.content,
3323
3310
  claudeMd: agentDoc.content,
3324
3311
  docSource: agentDoc.source,
3325
- moduleDocs: agentDoc.source === "AGENTS.md" ? readAgentModuleDocs(packagePath, agentDoc.content ?? void 0) : []
3312
+ directory: packagePath,
3313
+ moduleDocPaths: agentDoc.source === "AGENTS.md" ? resolveAgentModuleDocPaths(packagePath, agentDoc.content ?? void 0) : [],
3314
+ moduleDocs: complete && agentDoc.source === "AGENTS.md" ? readAgentModuleDocs(packagePath, agentDoc.content ?? void 0) : []
3326
3315
  };
3327
3316
  } catch {
3328
3317
  console.warn(` ⚠️ Could not read package.json for ${dirName}`);
3329
3318
  return null;
3330
3319
  }
3331
3320
  }
3332
- function loadAgentDoc(agentsPath, claudePath) {
3333
- if (existsSync(agentsPath)) return {
3334
- content: readFileSync(agentsPath, "utf-8"),
3335
- source: "AGENTS.md"
3336
- };
3337
- if (!existsSync(claudePath)) return {
3338
- content: null,
3339
- source: null
3340
- };
3341
- const claude = readFileSync(claudePath, "utf-8");
3342
- if (claude.trim() === "@AGENTS.md") return {
3343
- content: null,
3344
- source: null
3345
- };
3346
- return {
3347
- content: claude,
3348
- source: "CLAUDE.md"
3349
- };
3350
- }
3351
3321
  function detectMonorepoRoot() {
3352
3322
  try {
3353
3323
  let currentDir = realpathSync(process.cwd());
@@ -3401,28 +3371,27 @@ function renderAgentMd(content) {
3401
3371
  if (h1Match) content = content.slice(h1Match[0].length);
3402
3372
  return content.trim();
3403
3373
  }
3404
- /**
3405
- * The package's AGENTS.md followed by every module doc it links (#2108).
3406
- * The links stay in the rendered text so a reader can still map a section back
3407
- * to its source path; the bodies follow so nothing is lost downstream.
3408
- */
3409
- function renderPackageDoc(pkg, lines) {
3374
+ /** Keep package orientation inline; load module bodies only on explicit request. */
3375
+ function renderPackageDoc(pkg, lines, complete) {
3410
3376
  const content = pkg.agentMd ?? pkg.claudeMd;
3411
3377
  if (!content) {
3412
- lines.push("*No AGENTS.md found for this package.*");
3413
- lines.push("");
3378
+ lines.push("*No AGENTS.md found for this package.*", "");
3414
3379
  return;
3415
3380
  }
3416
- lines.push(renderAgentMd(content));
3417
- lines.push("");
3418
- for (const doc of pkg.moduleDocs ?? []) {
3419
- lines.push(`#### ${doc.path}`);
3420
- lines.push("");
3421
- lines.push(renderAgentMd(doc.content));
3381
+ lines.push(renderAgentMd(content), "");
3382
+ const paths = pkg.moduleDocPaths ?? pkg.moduleDocs?.map((doc) => doc.path) ?? [];
3383
+ if (!complete && paths.length > 0) {
3384
+ lines.push("#### Module documentation", "");
3385
+ lines.push("Read the relevant source file on demand, or regenerate with `--complete`.", "");
3386
+ for (const path of paths) {
3387
+ const source = (pkg.directory ? join(pkg.directory, path) : path).replace(/\\/g, "/");
3388
+ lines.push(`- [${path}](<${source}>)`);
3389
+ }
3422
3390
  lines.push("");
3423
3391
  }
3392
+ if (complete) for (const doc of pkg.moduleDocs ?? []) lines.push(`#### ${doc.path}`, "", renderAgentMd(doc.content), "");
3424
3393
  }
3425
- function generateMarkdown(packages, rootDocs, sdkPackages, generatedBy = "smrt docs:agents") {
3394
+ function generateMarkdown(packages, rootDocs, sdkPackages, generatedBy = "smrt docs:agents", options = {}) {
3426
3395
  const lines = [];
3427
3396
  lines.push("# SMRT Framework Context");
3428
3397
  lines.push("");
@@ -3465,7 +3434,7 @@ function generateMarkdown(packages, rootDocs, sdkPackages, generatedBy = "smrt d
3465
3434
  lines.push("");
3466
3435
  lines.push(`## ${pkg.name}`);
3467
3436
  lines.push("");
3468
- renderPackageDoc(pkg, lines);
3437
+ renderPackageDoc(pkg, lines, options.complete === true);
3469
3438
  }
3470
3439
  if (sdkPackages && sdkPackages.length > 0) {
3471
3440
  lines.push("---");
@@ -3477,7 +3446,7 @@ function generateMarkdown(packages, rootDocs, sdkPackages, generatedBy = "smrt d
3477
3446
  lines.push("");
3478
3447
  lines.push(`### ${pkg.name}`);
3479
3448
  lines.push("");
3480
- renderPackageDoc(pkg, lines);
3449
+ renderPackageDoc(pkg, lines, options.complete === true);
3481
3450
  }
3482
3451
  }
3483
3452
  lines.push("---");
@@ -3494,7 +3463,7 @@ function generateMarkdown(packages, rootDocs, sdkPackages, generatedBy = "smrt d
3494
3463
  lines.push("- Example code if applicable");
3495
3464
  lines.push("");
3496
3465
  lines.push("---");
3497
- lines.push(`*Generated by \`${generatedBy}\` — regenerate after dependency updates*`);
3466
+ lines.push(`*Generated by \`${generatedBy}${options.complete ? " --complete" : ""}\` — regenerate after dependency updates*`);
3498
3467
  lines.push("");
3499
3468
  return lines.join("\n");
3500
3469
  }
@@ -6836,10 +6805,10 @@ var devKnowledgeCommands = {
6836
6805
  focus: args.join(" ") || options.focus,
6837
6806
  scope: options.scope,
6838
6807
  package: options.package,
6839
- detail: "full"
6808
+ detail: options.complete ? "complete" : "full"
6840
6809
  });
6841
6810
  if ((options.json ? "json" : options.format) === "json") {
6842
- console.log(JSON.stringify(result, null, 2));
6811
+ console.log(JSON.stringify(compactContextResult(result, options.complete ? "complete" : "full"), null, 2));
6843
6812
  return;
6844
6813
  }
6845
6814
  console.log(renderContextMarkdown(result));
@@ -6857,10 +6826,10 @@ var devKnowledgeCommands = {
6857
6826
  focus: options.focus,
6858
6827
  scope: options.scope,
6859
6828
  package: options.package,
6860
- detail: "full"
6829
+ detail: options.complete ? "complete" : "full"
6861
6830
  });
6862
6831
  if ((options.json ? "json" : options.format) === "json") {
6863
- console.log(JSON.stringify(result, null, 2));
6832
+ console.log(JSON.stringify(compactContextResult(result, options.complete ? "complete" : "full"), null, 2));
6864
6833
  return;
6865
6834
  }
6866
6835
  console.log(renderContextMarkdown(result));
@@ -6869,6 +6838,11 @@ var devKnowledgeCommands = {
6869
6838
  };
6870
6839
  function contextOptions(defaultFormat) {
6871
6840
  return {
6841
+ complete: {
6842
+ type: "boolean",
6843
+ description: "Include all module documentation for selected packages",
6844
+ default: false
6845
+ },
6872
6846
  format: {
6873
6847
  type: "string",
6874
6848
  description: "Output format: markdown or json",
package/dist/index.js CHANGED
@@ -49,63 +49,63 @@ var _playgroundCommands = null;
49
49
  var _workbenchCommands = null;
50
50
  async function getGnodeCommands() {
51
51
  if (!_gnodeCommands) {
52
- const { gnodeCommands } = await import("./commands-DBnnqrFy.js");
52
+ const { gnodeCommands } = await import("./commands-COd77prj.js");
53
53
  _gnodeCommands = gnodeCommands;
54
54
  }
55
55
  return _gnodeCommands;
56
56
  }
57
57
  async function getGitCommands() {
58
58
  if (!_gitCommands) {
59
- const { gitCommands } = await import("./commands-DBnnqrFy.js");
59
+ const { gitCommands } = await import("./commands-COd77prj.js");
60
60
  _gitCommands = gitCommands;
61
61
  }
62
62
  return _gitCommands;
63
63
  }
64
64
  async function getGenerateCommands() {
65
65
  if (!_generateCommands) {
66
- const { generateCommands } = await import("./commands-DBnnqrFy.js");
66
+ const { generateCommands } = await import("./commands-COd77prj.js");
67
67
  _generateCommands = generateCommands;
68
68
  }
69
69
  return _generateCommands;
70
70
  }
71
71
  async function getInitCommands() {
72
72
  if (!_initCommands) {
73
- const { initCommands } = await import("./commands-DBnnqrFy.js");
73
+ const { initCommands } = await import("./commands-COd77prj.js");
74
74
  _initCommands = initCommands;
75
75
  }
76
76
  return _initCommands;
77
77
  }
78
78
  async function getUtilityCommands() {
79
79
  if (!_utilityCommands) {
80
- const { utilityCommands } = await import("./commands-DBnnqrFy.js");
80
+ const { utilityCommands } = await import("./commands-COd77prj.js");
81
81
  _utilityCommands = utilityCommands;
82
82
  }
83
83
  return _utilityCommands;
84
84
  }
85
85
  async function getDispatchCommands() {
86
86
  if (!_dispatchCommands) {
87
- const { dispatchCommands } = await import("./commands-DBnnqrFy.js");
87
+ const { dispatchCommands } = await import("./commands-COd77prj.js");
88
88
  _dispatchCommands = dispatchCommands;
89
89
  }
90
90
  return _dispatchCommands;
91
91
  }
92
92
  async function getDocsCommands() {
93
93
  if (!_docsCommands) {
94
- const { docsCommands } = await import("./commands-DBnnqrFy.js");
94
+ const { docsCommands } = await import("./commands-COd77prj.js");
95
95
  _docsCommands = docsCommands;
96
96
  }
97
97
  return _docsCommands;
98
98
  }
99
99
  async function getPlaygroundCommands() {
100
100
  if (!_playgroundCommands) {
101
- const { playgroundCommands } = await import("./commands-DBnnqrFy.js");
101
+ const { playgroundCommands } = await import("./commands-COd77prj.js");
102
102
  _playgroundCommands = playgroundCommands;
103
103
  }
104
104
  return _playgroundCommands;
105
105
  }
106
106
  async function getWorkbenchCommands() {
107
107
  if (!_workbenchCommands) {
108
- const { workbenchCommands } = await import("./commands-DBnnqrFy.js");
108
+ const { workbenchCommands } = await import("./commands-COd77prj.js");
109
109
  _workbenchCommands = workbenchCommands;
110
110
  }
111
111
  return _workbenchCommands;
@@ -959,7 +959,7 @@ var CLIGenerator = class {
959
959
  const methods = await ObjectRegistry.getAllMethods(objKey);
960
960
  const methodNames = Array.from(methods.keys());
961
961
  if (typeof cliConfig === "object" && cliConfig.include) cliMethods = methodNames.filter((m) => cliConfig.include?.includes(m) && methods.get(m)?.isPublic);
962
- else if (cliConfig === true) cliMethods = methodNames.filter((m) => methods.get(m)?.isPublic);
962
+ else cliMethods = methodNames.filter((m) => methods.get(m)?.isPublic);
963
963
  }
964
964
  if (options.verbose) {
965
965
  console.log(` • ${objName}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-cli",
3
- "version": "0.45.1",
3
+ "version": "0.45.2",
4
4
  "description": "Developer CLI for SMRT framework - introspection, testing, and project management",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -32,12 +32,12 @@
32
32
  "acorn": "^8.17.0",
33
33
  "fast-glob": "3.3.3",
34
34
  "tar": "^7.5.19",
35
- "@happyvertical/smrt-agents": "0.45.1",
36
- "@happyvertical/smrt-config": "0.45.1",
37
- "@happyvertical/smrt-dev-mcp": "0.45.1",
38
- "@happyvertical/smrt-playground": "0.45.1",
39
- "@happyvertical/smrt-types": "0.45.1",
40
- "@happyvertical/smrt-core": "0.45.1"
35
+ "@happyvertical/smrt-agents": "0.45.2",
36
+ "@happyvertical/smrt-config": "0.45.2",
37
+ "@happyvertical/smrt-core": "0.45.2",
38
+ "@happyvertical/smrt-playground": "0.45.2",
39
+ "@happyvertical/smrt-dev-mcp": "0.45.2",
40
+ "@happyvertical/smrt-types": "0.45.2"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "24.13.2",