devsmind-mcp 2.3.0 → 3.0.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 (130) hide show
  1. package/README.md +326 -234
  2. package/dist/cli/activity.d.ts +9 -0
  3. package/dist/cli/activity.js +69 -0
  4. package/dist/cli/activity.js.map +1 -0
  5. package/dist/cli/describe.d.ts +31 -0
  6. package/dist/cli/describe.js +201 -0
  7. package/dist/cli/describe.js.map +1 -0
  8. package/dist/cli/diff.d.ts +14 -0
  9. package/dist/cli/diff.js +161 -0
  10. package/dist/cli/diff.js.map +1 -0
  11. package/dist/cli/embed.d.ts +6 -0
  12. package/dist/cli/embed.js +109 -0
  13. package/dist/cli/embed.js.map +1 -0
  14. package/dist/cli/extract-agent.d.ts +66 -0
  15. package/dist/cli/extract-agent.js +192 -0
  16. package/dist/cli/extract-agent.js.map +1 -0
  17. package/dist/cli/feedback.d.ts +11 -0
  18. package/dist/cli/feedback.js +90 -0
  19. package/dist/cli/feedback.js.map +1 -0
  20. package/dist/cli/index.js +128 -5
  21. package/dist/cli/index.js.map +1 -1
  22. package/dist/cli/init.d.ts +30 -0
  23. package/dist/cli/init.js +98 -18
  24. package/dist/cli/init.js.map +1 -1
  25. package/dist/cli/integrations/memory-topics.d.ts +44 -0
  26. package/dist/cli/integrations/memory-topics.js +295 -0
  27. package/dist/cli/integrations/memory-topics.js.map +1 -0
  28. package/dist/cli/integrations/memory.d.ts +11 -5
  29. package/dist/cli/integrations/memory.js +132 -36
  30. package/dist/cli/integrations/memory.js.map +1 -1
  31. package/dist/cli/integrations/prompt.d.ts +8 -0
  32. package/dist/cli/integrations/prompt.js +24 -3
  33. package/dist/cli/integrations/prompt.js.map +1 -1
  34. package/dist/cli/integrations/registry.d.ts +19 -5
  35. package/dist/cli/integrations/registry.js +23 -13
  36. package/dist/cli/integrations/registry.js.map +1 -1
  37. package/dist/cli/llm-client.d.ts +116 -0
  38. package/dist/cli/llm-client.js +322 -0
  39. package/dist/cli/llm-client.js.map +1 -0
  40. package/dist/cli/prune.js +4 -3
  41. package/dist/cli/prune.js.map +1 -1
  42. package/dist/cli/rule.d.ts +22 -2
  43. package/dist/cli/rule.js +116 -56
  44. package/dist/cli/rule.js.map +1 -1
  45. package/dist/cli/runner.d.ts +21 -0
  46. package/dist/cli/runner.js +94 -276
  47. package/dist/cli/runner.js.map +1 -1
  48. package/dist/cli/sync-progress.d.ts +9 -0
  49. package/dist/cli/sync-progress.js +41 -0
  50. package/dist/cli/sync-progress.js.map +1 -0
  51. package/dist/cli/sync.js +5 -2
  52. package/dist/cli/sync.js.map +1 -1
  53. package/dist/cli/view.js +3 -2
  54. package/dist/cli/view.js.map +1 -1
  55. package/dist/cli/workflow.js +26 -20
  56. package/dist/cli/workflow.js.map +1 -1
  57. package/dist/db/activity.d.ts +200 -0
  58. package/dist/db/activity.js +347 -0
  59. package/dist/db/activity.js.map +1 -0
  60. package/dist/db/analyze.js +25 -9
  61. package/dist/db/analyze.js.map +1 -1
  62. package/dist/db/database.d.ts +607 -79
  63. package/dist/db/database.js +1936 -488
  64. package/dist/db/database.js.map +1 -1
  65. package/dist/db/edges.d.ts +24 -0
  66. package/dist/db/edges.js +84 -0
  67. package/dist/db/edges.js.map +1 -1
  68. package/dist/db/embedder.d.ts +39 -0
  69. package/dist/db/embedder.js +0 -0
  70. package/dist/db/embedder.js.map +1 -0
  71. package/dist/db/feedback.d.ts +128 -0
  72. package/dist/db/feedback.js +182 -0
  73. package/dist/db/feedback.js.map +1 -0
  74. package/dist/db/file-diff.d.ts +32 -0
  75. package/dist/db/file-diff.js +110 -0
  76. package/dist/db/file-diff.js.map +1 -0
  77. package/dist/db/grep.d.ts +78 -0
  78. package/dist/db/grep.js +475 -0
  79. package/dist/db/grep.js.map +1 -0
  80. package/dist/db/message-revert.d.ts +63 -0
  81. package/dist/db/message-revert.js +258 -0
  82. package/dist/db/message-revert.js.map +1 -0
  83. package/dist/db/revert.d.ts +31 -0
  84. package/dist/db/revert.js +108 -0
  85. package/dist/db/revert.js.map +1 -0
  86. package/dist/db/schema.d.ts +49 -4
  87. package/dist/db/schema.js +125 -73
  88. package/dist/db/schema.js.map +1 -1
  89. package/dist/db/search-index.d.ts +65 -0
  90. package/dist/db/search-index.js +74 -0
  91. package/dist/db/search-index.js.map +1 -0
  92. package/dist/db/staging.d.ts +90 -5
  93. package/dist/db/staging.js +148 -22
  94. package/dist/db/staging.js.map +1 -1
  95. package/dist/mcp/server.d.ts +29 -7
  96. package/dist/mcp/server.js +2755 -745
  97. package/dist/mcp/server.js.map +1 -1
  98. package/dist/mcp/vendor/3d-force-graph.min.js +5 -0
  99. package/dist/mcp/vendor/force-graph.min.js +5 -0
  100. package/dist/mcp/vendor/model/model_int8.onnx +0 -0
  101. package/dist/mcp/vendor/model/vocab.txt +30522 -0
  102. package/dist/mcp/vendor/three.min.js +7 -0
  103. package/dist/mcp/view.css +419 -0
  104. package/dist/mcp/view.html +161 -0
  105. package/dist/mcp/view.js +245 -0
  106. package/dist/mcp/view_chat.js +382 -0
  107. package/dist/mcp/view_graph.js +576 -0
  108. package/dist/mcp/visualizer.d.ts +25 -2
  109. package/dist/mcp/visualizer.js +31 -4
  110. package/dist/mcp/visualizer.js.map +1 -1
  111. package/dist/utils/ast.d.ts +187 -0
  112. package/dist/utils/ast.js +640 -20
  113. package/dist/utils/ast.js.map +1 -1
  114. package/dist/utils/diff.d.ts +44 -0
  115. package/dist/utils/diff.js +78 -0
  116. package/dist/utils/diff.js.map +1 -0
  117. package/dist/utils/edit.d.ts +47 -0
  118. package/dist/utils/edit.js +196 -0
  119. package/dist/utils/edit.js.map +1 -0
  120. package/dist/utils/scanner.js +12 -4
  121. package/dist/utils/scanner.js.map +1 -1
  122. package/dist/utils/tokenize.d.ts +45 -0
  123. package/dist/utils/tokenize.js +129 -0
  124. package/dist/utils/tokenize.js.map +1 -0
  125. package/dist/utils/version.d.ts +14 -0
  126. package/dist/utils/version.js +61 -0
  127. package/dist/utils/version.js.map +1 -0
  128. package/package.json +18 -5
  129. package/dist/mcp/visualizer_2d.html +0 -635
  130. package/dist/mcp/visualizer_3d.html +0 -613
@@ -1 +1 @@
1
- {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/utils/scanner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/utils/scanner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Shared tokenization for search-nodes' fuzzy ranking AND the description-quality gate at
3
+ * commit time. Both need the SAME splitting logic — if the gate accepted a description using
4
+ * one definition of "new word" while search matched using another, a description could pass
5
+ * validation and still be invisible to search. One pipeline, two callers.
6
+ */
7
+ /**
8
+ * Splits camelCase / PascalCase / snake_case / kebab-case / dotted identifiers and paths into
9
+ * lowercase word fragments — "verifyCredentials" -> ["verify","credentials"],
10
+ * "pages/product-detail" -> ["pages","product","detail"]. This is what lets a query token match
11
+ * a WORD inside a compound identifier rather than only a raw substring.
12
+ */
13
+ export declare function splitIdentifier(text: string): string[];
14
+ /**
15
+ * Light suffix stemming so "logins"/"logged"/"validated" collapse onto the same token as
16
+ * "login"/"validate". Deliberately crude — a handful of suffix rules, no dictionary, no real
17
+ * morphology — good enough to close the common inflection gap between a query and a
18
+ * description without pulling in a stemming dependency.
19
+ */
20
+ export declare function stem(token: string): string;
21
+ /**
22
+ * Full pipeline for natural-language text — queries, descriptions, reasoning: lowercase, split
23
+ * on non-alphanumeric, drop stopwords and anything under 3 chars, stem. Order matters: filtering
24
+ * short/stop tokens BEFORE stemming means stemming never has to special-case them.
25
+ */
26
+ export declare function tokenizeText(text: string): string[];
27
+ /**
28
+ * Tokenization for identifiers/paths specifically: split on case/separator boundaries first,
29
+ * THEN run the identical stopword+stem pipeline used for natural-language text, so a query
30
+ * token and an identifier fragment that mean the same thing collapse to the same string.
31
+ */
32
+ export declare function tokenizeIdentifier(text: string): string[];
33
+ export interface DescriptionValidation {
34
+ ok: boolean;
35
+ error?: string;
36
+ }
37
+ /**
38
+ * Rejects the two laziest failure modes of an AI-written description: too short to carry real
39
+ * information, or merely restating the identifier's own words back. "verifyCredentials" ->
40
+ * "verifies credentials" tokenizes to a subset of the identifier's own tokens — it satisfies
41
+ * any naive length check while adding nothing a search query wouldn't already find via the
42
+ * identifier itself. Rejecting it is what keeps the commit-time gate from being satisfied by
43
+ * pure compliance instead of actual searchable value.
44
+ */
45
+ export declare function validateDescription(description: string, identifierSource: string): DescriptionValidation;
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ /**
3
+ * Shared tokenization for search-nodes' fuzzy ranking AND the description-quality gate at
4
+ * commit time. Both need the SAME splitting logic — if the gate accepted a description using
5
+ * one definition of "new word" while search matched using another, a description could pass
6
+ * validation and still be invisible to search. One pipeline, two callers.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.splitIdentifier = splitIdentifier;
10
+ exports.stem = stem;
11
+ exports.tokenizeText = tokenizeText;
12
+ exports.tokenizeIdentifier = tokenizeIdentifier;
13
+ exports.validateDescription = validateDescription;
14
+ /**
15
+ * English function words + generic dev-question filler that carry no search signal on their
16
+ * own. A natural-language query like "where do we handle user login" is mostly this — without
17
+ * filtering it, short tokens like "we"/"do"/"is" substring-match dozens of unrelated
18
+ * identifiers and bury the one real match under noise.
19
+ */
20
+ const STOPWORDS = new Set([
21
+ // function words
22
+ 'a', 'an', 'the', 'is', 'are', 'was', 'were', 'be', 'been', 'being', 'do', 'does', 'did', 'doing',
23
+ 'has', 'have', 'had', 'having', 'to', 'of', 'in', 'on', 'at', 'by', 'for', 'with', 'from', 'into',
24
+ 'about', 'as', 'it', 'its', 'this', 'that', 'these', 'those', 'and', 'or', 'but', 'if', 'then',
25
+ 'so', 'not', 'no', 'yes', 'than', 'too', 'very', 'can', 'could', 'will', 'would', 'should', 'may',
26
+ 'might', 'must', 'shall', 'we', 'you', 'he', 'she', 'they', 'me', 'my', 'our', 'your', 'their',
27
+ 'what', 'which', 'who', 'whom', 'when', 'where', 'why', 'how', 'all', 'each', 'every', 'both',
28
+ 'few', 'more', 'most', 'other', 'some', 'such', 'only', 'own', 'same', 'just', 'also',
29
+ // generic dev-question / filler words that name no specific thing
30
+ 'find', 'get', 'gets', 'set', 'sets', 'use', 'uses', 'used', 'using', 'handle', 'handles',
31
+ 'handled', 'handling', 'implement', 'implements', 'implementation', 'code', 'function',
32
+ 'method', 'logic', 'thing', 'things', 'something', 'anything', 'page', 'file'
33
+ ]);
34
+ /**
35
+ * Splits camelCase / PascalCase / snake_case / kebab-case / dotted identifiers and paths into
36
+ * lowercase word fragments — "verifyCredentials" -> ["verify","credentials"],
37
+ * "pages/product-detail" -> ["pages","product","detail"]. This is what lets a query token match
38
+ * a WORD inside a compound identifier rather than only a raw substring.
39
+ */
40
+ function splitIdentifier(text) {
41
+ if (!text)
42
+ return [];
43
+ return text
44
+ // camelCase boundary: lower/digit -> Upper ("verifyCredentials" -> "verify Credentials")
45
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
46
+ // acronym boundary: a run of Upper followed by Upper+lower ("XMLParser" -> "XML Parser")
47
+ .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')
48
+ .split(/[^a-zA-Z0-9]+/)
49
+ .map(s => s.toLowerCase())
50
+ .filter(Boolean);
51
+ }
52
+ /**
53
+ * Light suffix stemming so "logins"/"logged"/"validated" collapse onto the same token as
54
+ * "login"/"validate". Deliberately crude — a handful of suffix rules, no dictionary, no real
55
+ * morphology — good enough to close the common inflection gap between a query and a
56
+ * description without pulling in a stemming dependency.
57
+ */
58
+ function stem(token) {
59
+ if (token.length <= 4)
60
+ return token; // too short to safely strip anything
61
+ if (token.endsWith('ies') && token.length > 5)
62
+ return token.slice(0, -3) + 'y';
63
+ if (token.endsWith('ing') && token.length > 6)
64
+ return token.slice(0, -3);
65
+ if (token.endsWith('tion') && token.length > 6)
66
+ return token.slice(0, -4);
67
+ if (token.endsWith('ed') && token.length > 5)
68
+ return token.slice(0, -2);
69
+ if (token.endsWith('es') && token.length > 5)
70
+ return token.slice(0, -2);
71
+ if (token.endsWith('s') && !token.endsWith('ss') && token.length > 4)
72
+ return token.slice(0, -1);
73
+ return token;
74
+ }
75
+ /**
76
+ * Full pipeline for natural-language text — queries, descriptions, reasoning: lowercase, split
77
+ * on non-alphanumeric, drop stopwords and anything under 3 chars, stem. Order matters: filtering
78
+ * short/stop tokens BEFORE stemming means stemming never has to special-case them.
79
+ */
80
+ function tokenizeText(text) {
81
+ if (!text)
82
+ return [];
83
+ const out = [];
84
+ for (const raw of text.toLowerCase().split(/[^a-z0-9]+/i)) {
85
+ if (raw.length < 3)
86
+ continue;
87
+ if (STOPWORDS.has(raw))
88
+ continue;
89
+ out.push(stem(raw));
90
+ }
91
+ return out;
92
+ }
93
+ /**
94
+ * Tokenization for identifiers/paths specifically: split on case/separator boundaries first,
95
+ * THEN run the identical stopword+stem pipeline used for natural-language text, so a query
96
+ * token and an identifier fragment that mean the same thing collapse to the same string.
97
+ */
98
+ function tokenizeIdentifier(text) {
99
+ return tokenizeText(splitIdentifier(text).join(' '));
100
+ }
101
+ const MIN_DESCRIPTION_LENGTH = 40;
102
+ /**
103
+ * Rejects the two laziest failure modes of an AI-written description: too short to carry real
104
+ * information, or merely restating the identifier's own words back. "verifyCredentials" ->
105
+ * "verifies credentials" tokenizes to a subset of the identifier's own tokens — it satisfies
106
+ * any naive length check while adding nothing a search query wouldn't already find via the
107
+ * identifier itself. Rejecting it is what keeps the commit-time gate from being satisfied by
108
+ * pure compliance instead of actual searchable value.
109
+ */
110
+ function validateDescription(description, identifierSource) {
111
+ const trimmed = (description || '').trim();
112
+ if (trimmed.length < MIN_DESCRIPTION_LENGTH) {
113
+ return {
114
+ ok: false,
115
+ error: `Description too short (${trimmed.length} chars, need at least ${MIN_DESCRIPTION_LENGTH}). Write 1-3 sentences of real purpose, not a label.`
116
+ };
117
+ }
118
+ const identifierTokens = new Set(tokenizeIdentifier(identifierSource));
119
+ const descriptionTokens = new Set(tokenizeText(trimmed));
120
+ const newTokens = Array.from(descriptionTokens).filter(t => !identifierTokens.has(t));
121
+ if (identifierTokens.size > 0 && newTokens.length === 0) {
122
+ return {
123
+ ok: false,
124
+ error: `Description only restates the identifier's own words ("${identifierSource}") — it adds no vocabulary a search query wouldn't already find via the name itself. Describe what it actually DOES and the domain concepts involved, using terms someone might search by.`
125
+ };
126
+ }
127
+ return { ok: true };
128
+ }
129
+ //# sourceMappingURL=tokenize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenize.js","sourceRoot":"","sources":["../../src/utils/tokenize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The published package version, read from package.json at runtime.
3
+ *
4
+ * Deliberately not a hardcoded constant: the previous one was, and it drifted the whole way from
5
+ * the first commit to 2.5.0 — `devsmind -v` answered `1.0.0` for every release in between, which
6
+ * is worse than no version at all, since a user reporting a bug reads it and believes it. There is
7
+ * exactly one number now (package.json's) and everything that reports a version derives it.
8
+ *
9
+ * `src/<dir>/` and `dist/<dir>/` both sit two levels under the package root, so one relative path
10
+ * resolves correctly under ts-node, jest and the published build alike. A read failure falls back
11
+ * to `'unknown'` rather than throwing — a missing package.json means a broken install, and failing
12
+ * to start the server over a cosmetic string would be the wrong trade.
13
+ */
14
+ export declare const DEVSMIND_VERSION: string;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DEVSMIND_VERSION = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ /**
40
+ * The published package version, read from package.json at runtime.
41
+ *
42
+ * Deliberately not a hardcoded constant: the previous one was, and it drifted the whole way from
43
+ * the first commit to 2.5.0 — `devsmind -v` answered `1.0.0` for every release in between, which
44
+ * is worse than no version at all, since a user reporting a bug reads it and believes it. There is
45
+ * exactly one number now (package.json's) and everything that reports a version derives it.
46
+ *
47
+ * `src/<dir>/` and `dist/<dir>/` both sit two levels under the package root, so one relative path
48
+ * resolves correctly under ts-node, jest and the published build alike. A read failure falls back
49
+ * to `'unknown'` rather than throwing — a missing package.json means a broken install, and failing
50
+ * to start the server over a cosmetic string would be the wrong trade.
51
+ */
52
+ exports.DEVSMIND_VERSION = (() => {
53
+ try {
54
+ const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '..', 'package.json'), 'utf-8'));
55
+ return typeof pkg.version === 'string' ? pkg.version : 'unknown';
56
+ }
57
+ catch {
58
+ return 'unknown';
59
+ }
60
+ })();
61
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/utils/version.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAE7B;;;;;;;;;;;;GAYG;AACU,QAAA,gBAAgB,GAAW,CAAC,GAAG,EAAE;IAC5C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;QACnG,OAAO,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC,CAAC,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devsmind-mcp",
3
- "version": "2.3.0",
3
+ "version": "3.0.0",
4
4
  "description": "DevsMind — Team AI Brain",
5
5
  "main": "dist/cli/index.js",
6
6
  "bin": {
@@ -13,11 +13,14 @@
13
13
  "LICENSE"
14
14
  ],
15
15
  "scripts": {
16
- "build": "node node_modules/typescript/bin/tsc && node scripts/copy-assets.js",
16
+ "build": "node scripts/clean.js && node node_modules/typescript/bin/tsc && node scripts/copy-assets.js",
17
17
  "start": "tsx src/cli/index.ts start",
18
18
  "dev": "tsx src/cli/index.ts",
19
- "test": "echo \"Error: no test specified\" && exit 0",
20
- "prepublishOnly": "node node_modules/typescript/bin/tsc && node scripts/copy-assets.js"
19
+ "test": "jest",
20
+ "test:cov": "jest --coverage",
21
+ "test:watch": "jest --watch",
22
+ "prepack": "node scripts/clean.js && node node_modules/typescript/bin/tsc && node scripts/copy-assets.js",
23
+ "prepublishOnly": "node node_modules/typescript/bin/tsc --noEmit -p . && node node_modules/jest/bin/jest.js --coverage --ci"
21
24
  },
22
25
  "keywords": [
23
26
  "mcp",
@@ -45,19 +48,29 @@
45
48
  "@types/express": "^5.0.6",
46
49
  "better-sqlite3": "^12.11.1",
47
50
  "commander": "^12.1.0",
51
+ "diff": "^9.0.0",
48
52
  "dotenv": "^16.4.5",
49
53
  "express": "^5.2.1",
50
54
  "prompts": "^2.4.2",
51
55
  "typescript": "^5.5.2"
52
56
  },
57
+ "optionalDependencies": {
58
+ "onnxruntime-node": "1.19.2"
59
+ },
53
60
  "devDependencies": {
54
61
  "@types/better-sqlite3": "^7.6.11",
62
+ "@types/jest": "^29.5.12",
55
63
  "@types/node": "^20.14.9",
56
64
  "@types/prompts": "^2.4.9",
65
+ "@types/supertest": "^6.0.2",
66
+ "jest": "^29.7.0",
67
+ "supertest": "^7.0.0",
68
+ "ts-jest": "^29.2.5",
57
69
  "tsx": "^4.16.0"
58
70
  },
59
71
  "allowScripts": {
60
72
  "better-sqlite3@12.11.1": true,
61
- "esbuild@0.28.1": true
73
+ "esbuild@0.28.1": true,
74
+ "onnxruntime-node@1.19.2": true
62
75
  }
63
76
  }