midnight-mcp 0.2.8 → 0.2.9

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/dist/bin.js CHANGED
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  startHttpServer,
4
4
  startServer
5
- } from "./chunk-QPQOD3S6.js";
5
+ } from "./chunk-5PGBYGCG.js";
6
6
  import {
7
7
  setOutputFormat
8
- } from "./chunk-VQTI7YUU.js";
8
+ } from "./chunk-WZVWUFLH.js";
9
9
 
10
10
  // src/bin.ts
11
11
  import { config } from "dotenv";
@@ -13,7 +13,7 @@ import { resolve } from "path";
13
13
  import yargs from "yargs";
14
14
  import { hideBin } from "yargs/helpers";
15
15
  config({ path: resolve(process.cwd(), ".env") });
16
- var CURRENT_VERSION = "0.2.8";
16
+ var CURRENT_VERSION = "0.2.9";
17
17
  process.on("uncaughtException", (error) => {
18
18
  console.error("Uncaught exception:", error);
19
19
  process.exit(1);
@@ -25,7 +25,7 @@ import {
25
25
  validateNumber,
26
26
  validateQuery,
27
27
  vectorStore
28
- } from "./chunk-VQTI7YUU.js";
28
+ } from "./chunk-WZVWUFLH.js";
29
29
 
30
30
  // src/tools/search/schemas.ts
31
31
  import { z } from "zod";
@@ -102,7 +102,49 @@ async function tryHostedSearch(searchType, hostedSearchFn, cacheKey, warnings) {
102
102
  ...response,
103
103
  ...warnings.length > 0 && { warnings }
104
104
  };
105
- searchCache.set(cacheKey, finalResponse);
105
+ searchCache.set(cacheKey, {
106
+ results: finalResponse.results.map((item) => {
107
+ const result = item;
108
+ let startLine;
109
+ let endLine;
110
+ if (result.source.lines) {
111
+ const lineParts = result.source.lines.split("-");
112
+ if (lineParts.length === 2) {
113
+ const parsedStart = parseInt(lineParts[0], 10);
114
+ const parsedEnd = parseInt(lineParts[1], 10);
115
+ if (!Number.isNaN(parsedStart)) {
116
+ startLine = parsedStart;
117
+ }
118
+ if (!Number.isNaN(parsedEnd)) {
119
+ endLine = parsedEnd;
120
+ }
121
+ } else if (lineParts.length === 1) {
122
+ const parsed = parseInt(lineParts[0], 10);
123
+ if (!Number.isNaN(parsed)) {
124
+ startLine = endLine = parsed;
125
+ }
126
+ }
127
+ }
128
+ return {
129
+ code: result.code,
130
+ content: result.content,
131
+ relevanceScore: result.relevanceScore,
132
+ source: {
133
+ repository: result.source.repository,
134
+ filePath: result.source.filePath,
135
+ startLine,
136
+ endLine,
137
+ lines: result.source.lines,
138
+ section: result.source.section
139
+ },
140
+ codeType: result.codeType,
141
+ name: result.name,
142
+ isExported: result.isExported
143
+ };
144
+ }),
145
+ totalResults: finalResponse.totalResults ?? finalResponse.results.length,
146
+ warnings: warnings.length > 0 ? warnings : void 0
147
+ });
106
148
  return {
107
149
  result: finalResponse,
108
150
  cached: true
@@ -122,7 +164,11 @@ function finalizeResponse(response, cacheKey, warnings) {
122
164
  ...response,
123
165
  ...warnings.length > 0 && { warnings }
124
166
  };
125
- searchCache.set(cacheKey, finalResponse);
167
+ searchCache.set(cacheKey, {
168
+ results: finalResponse.results,
169
+ totalResults: finalResponse.totalResults ?? finalResponse.results.length,
170
+ warnings: warnings.length > 0 ? warnings : void 0
171
+ });
126
172
  return finalResponse;
127
173
  }
128
174
  async function searchCompact(input) {
@@ -5852,6 +5898,9 @@ CORRECT: pure circuit helper(...): Type { }`
5852
5898
  import { readFile } from "fs/promises";
5853
5899
  import { basename, isAbsolute, resolve } from "path";
5854
5900
  import { platform } from "process";
5901
+ function escapeRegex(str) {
5902
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
5903
+ }
5855
5904
  function validateFilePath(filePath) {
5856
5905
  if (!isAbsolute(filePath)) {
5857
5906
  return {
@@ -6311,16 +6360,20 @@ async function extractContractStructure(input) {
6311
6360
  if (sealedFields.length > 0) {
6312
6361
  for (const circuit of circuits) {
6313
6362
  if (circuit.isExport) {
6363
+ const escapedCircuitName = escapeRegex(circuit.name);
6314
6364
  const circuitBodyMatch = code.match(
6315
6365
  new RegExp(
6316
- `(?:export\\s+)?circuit\\s+${circuit.name}\\s*\\([^)]*\\)\\s*:[^{]*\\{([\\s\\S]*?)\\n\\}`,
6366
+ `(?:export\\s+)?circuit\\s+${escapedCircuitName}\\s*\\([^)]*\\)\\s*:[^{]*\\{([\\s\\S]*?)\\n\\}`,
6317
6367
  "m"
6318
6368
  )
6319
6369
  );
6320
6370
  if (circuitBodyMatch) {
6321
6371
  const body = circuitBodyMatch[1];
6322
6372
  for (const field of sealedFields) {
6323
- if (new RegExp(`\\b${field.name}\\s*=`).test(body) || new RegExp(`\\b${field.name}\\s*\\.\\s*\\w+\\s*\\(`).test(body)) {
6373
+ const escapedFieldName = escapeRegex(field.name);
6374
+ if (new RegExp(`\\b${escapedFieldName}\\s*=`).test(body) || new RegExp(`\\b${escapedFieldName}\\s*\\.\\s*\\w+\\s*\\(`).test(
6375
+ body
6376
+ )) {
6324
6377
  potentialIssues.push({
6325
6378
  type: "sealed_export_conflict",
6326
6379
  line: circuit.line,
@@ -6469,8 +6522,9 @@ async function extractContractStructure(input) {
6469
6522
  constructorParams.push(paramMatch[1]);
6470
6523
  }
6471
6524
  for (const param of constructorParams) {
6525
+ const escapedParam = escapeRegex(param);
6472
6526
  const assignmentPattern = new RegExp(
6473
- `(\\w+)\\s*=\\s*(?!disclose\\s*\\()${param}\\b`,
6527
+ `(\\w+)\\s*=\\s*(?!disclose\\s*\\()${escapedParam}\\b`,
6474
6528
  "g"
6475
6529
  );
6476
6530
  let assignMatch;
@@ -9576,4 +9630,4 @@ export {
9576
9630
  startServer,
9577
9631
  startHttpServer
9578
9632
  };
9579
- //# sourceMappingURL=chunk-QPQOD3S6.js.map
9633
+ //# sourceMappingURL=chunk-5PGBYGCG.js.map
@@ -851,7 +851,11 @@ var GitHubClient = class {
851
851
  }
852
852
  }
853
853
  /**
854
- * Filter files by patterns
854
+ * Filter files by patterns (glob matching)
855
+ *
856
+ * SECURITY NOTE: Patterns come from trusted REPOSITORIES config, not user input.
857
+ * The glob-to-regex conversion only handles **, *, and . characters.
858
+ * This is safe because malicious patterns could only come from internal config.
855
859
  */
856
860
  filterFilesByPatterns(files, patterns, exclude) {
857
861
  const matchPattern = (file, pattern) => {
@@ -1016,6 +1020,20 @@ var GitHubClient = class {
1016
1020
  var githubClient = new GitHubClient();
1017
1021
 
1018
1022
  // src/pipeline/parser.ts
1023
+ var LANGUAGES = {
1024
+ COMPACT: "compact",
1025
+ TYPESCRIPT: "typescript",
1026
+ MARKDOWN: "markdown"
1027
+ };
1028
+ var EXTENSION_LANGUAGE_MAP = {
1029
+ compact: LANGUAGES.COMPACT,
1030
+ ts: LANGUAGES.TYPESCRIPT,
1031
+ tsx: LANGUAGES.TYPESCRIPT,
1032
+ js: LANGUAGES.TYPESCRIPT,
1033
+ jsx: LANGUAGES.TYPESCRIPT,
1034
+ md: LANGUAGES.MARKDOWN,
1035
+ mdx: LANGUAGES.MARKDOWN
1036
+ };
1019
1037
  function parseCompactFile(path, content) {
1020
1038
  const lines = content.split("\n");
1021
1039
  const codeUnits = [];
@@ -1161,7 +1179,7 @@ function parseCompactFile(path, content) {
1161
1179
  }
1162
1180
  return {
1163
1181
  path,
1164
- language: "compact",
1182
+ language: LANGUAGES.COMPACT,
1165
1183
  content,
1166
1184
  codeUnits,
1167
1185
  imports,
@@ -1594,7 +1612,7 @@ async function checkGitHubAPI() {
1594
1612
  }
1595
1613
  async function checkVectorStore() {
1596
1614
  try {
1597
- const { vectorStore: vectorStore2 } = await import("./db-7F5YOZB7.js");
1615
+ const { vectorStore: vectorStore2 } = await import("./db-2VUY2I5E.js");
1598
1616
  if (vectorStore2) {
1599
1617
  return {
1600
1618
  status: "pass",
@@ -2069,7 +2087,7 @@ function serialize(data) {
2069
2087
  }
2070
2088
 
2071
2089
  // src/utils/version.ts
2072
- var CURRENT_VERSION = "0.2.8";
2090
+ var CURRENT_VERSION = "0.2.9";
2073
2091
 
2074
2092
  // src/db/vectorStore.ts
2075
2093
  var VectorStore = class {
@@ -2278,4 +2296,4 @@ export {
2278
2296
  serialize,
2279
2297
  CURRENT_VERSION
2280
2298
  };
2281
- //# sourceMappingURL=chunk-VQTI7YUU.js.map
2299
+ //# sourceMappingURL=chunk-WZVWUFLH.js.map
@@ -0,0 +1,7 @@
1
+ import {
2
+ vectorStore
3
+ } from "./chunk-WZVWUFLH.js";
4
+ export {
5
+ vectorStore
6
+ };
7
+ //# sourceMappingURL=db-2VUY2I5E.js.map
package/dist/index.d.ts CHANGED
@@ -85,6 +85,13 @@ interface PropertySchema {
85
85
  properties?: Record<string, PropertySchema>;
86
86
  enum?: string[];
87
87
  }
88
+ /**
89
+ * Extended tool definition with handler
90
+ *
91
+ * Note: Handler uses `unknown` for input to allow flexibility in tool implementations.
92
+ * Each tool module defines its own specific input/output types via Zod schemas.
93
+ * The MCP server validates inputs against the inputSchema before calling handlers.
94
+ */
88
95
  interface ExtendedToolDefinition {
89
96
  name: string;
90
97
  description: string;
@@ -95,7 +102,15 @@ interface ExtendedToolDefinition {
95
102
  };
96
103
  outputSchema?: OutputSchema;
97
104
  annotations?: ToolAnnotations;
98
- handler: (input: any) => Promise<any>;
105
+ /**
106
+ * Handler function that processes tool inputs
107
+ * Input is validated against inputSchema before this is called
108
+ * Output should match outputSchema if defined
109
+ *
110
+ * Using `unknown` allows specific handler types to be assigned.
111
+ * Type safety is enforced by Zod schema validation at runtime.
112
+ */
113
+ handler: (input: any) => Promise<unknown>;
99
114
  }
100
115
 
101
116
  /**
package/dist/index.js CHANGED
@@ -9,10 +9,10 @@ import {
9
9
  promptDefinitions,
10
10
  startHttpServer,
11
11
  startServer
12
- } from "./chunk-QPQOD3S6.js";
12
+ } from "./chunk-5PGBYGCG.js";
13
13
  import {
14
14
  logger
15
- } from "./chunk-VQTI7YUU.js";
15
+ } from "./chunk-WZVWUFLH.js";
16
16
  export {
17
17
  allResources,
18
18
  allTools,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "midnight-mcp",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "description": "Model Context Protocol Server for Midnight Blockchain Development",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,7 +0,0 @@
1
- import {
2
- vectorStore
3
- } from "./chunk-VQTI7YUU.js";
4
- export {
5
- vectorStore
6
- };
7
- //# sourceMappingURL=db-7F5YOZB7.js.map