midnight-mcp 0.1.15 → 0.1.17

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.
@@ -11,6 +11,9 @@ export interface CodeDocument {
11
11
  codeType: string;
12
12
  codeName: string;
13
13
  isPublic: boolean;
14
+ repoVersion?: string;
15
+ pragmaVersion?: string;
16
+ indexedAt?: string;
14
17
  };
15
18
  }
16
19
  export interface SearchResult {
@@ -16,6 +16,9 @@ export interface ChunkMetadata {
16
16
  startLine: number;
17
17
  endLine: number;
18
18
  isPublic: boolean;
19
+ repoVersion?: string;
20
+ pragmaVersion?: string;
21
+ indexedAt?: string;
19
22
  }
20
23
  /**
21
24
  * Index a single repository
@@ -3,12 +3,26 @@ import { parseFile } from "./parser.js";
3
3
  import { embeddingGenerator } from "./embeddings.js";
4
4
  import { vectorStore } from "../db/vectorStore.js";
5
5
  import { logger, DEFAULT_REPOSITORIES, } from "../utils/index.js";
6
+ /**
7
+ * Extract pragma language_version from Compact file content
8
+ * Returns the version string or undefined if not found
9
+ */
10
+ function extractPragmaVersion(content) {
11
+ // Match patterns like: pragma language_version >= 0.14.0;
12
+ const pragmaMatch = content.match(/pragma\s+language_version\s*[><=]*\s*([\d.]+)/);
13
+ return pragmaMatch?.[1];
14
+ }
6
15
  /**
7
16
  * Create chunks from a parsed file
8
17
  * Uses intelligent chunking based on code structure
9
18
  */
10
- function createChunks(file, repository) {
19
+ function createChunks(file, repository, repoVersion) {
11
20
  const chunks = [];
21
+ const indexedAt = new Date().toISOString();
22
+ // Extract pragma version for Compact files
23
+ const pragmaVersion = file.language === "compact"
24
+ ? extractPragmaVersion(file.content)
25
+ : undefined;
12
26
  // Add code units as individual chunks
13
27
  for (const unit of file.codeUnits) {
14
28
  chunks.push({
@@ -23,6 +37,9 @@ function createChunks(file, repository) {
23
37
  startLine: unit.startLine,
24
38
  endLine: unit.endLine,
25
39
  isPublic: unit.isPublic,
40
+ repoVersion,
41
+ pragmaVersion,
42
+ indexedAt,
26
43
  },
27
44
  });
28
45
  }
@@ -47,6 +64,9 @@ function createChunks(file, repository) {
47
64
  startLine,
48
65
  endLine: currentLine - 1,
49
66
  isPublic: true,
67
+ repoVersion,
68
+ pragmaVersion,
69
+ indexedAt,
50
70
  },
51
71
  });
52
72
  // Start new chunk with overlap
@@ -69,6 +89,9 @@ function createChunks(file, repository) {
69
89
  startLine,
70
90
  endLine: currentLine - 1,
71
91
  isPublic: true,
92
+ repoVersion,
93
+ pragmaVersion,
94
+ indexedAt,
72
95
  },
73
96
  });
74
97
  }
@@ -81,6 +104,8 @@ function createChunks(file, repository) {
81
104
  export async function indexRepository(repoConfig) {
82
105
  const repoName = `${repoConfig.owner}/${repoConfig.repo}`;
83
106
  logger.info(`Starting index for ${repoName}...`);
107
+ // Get repo version (branch name or tag)
108
+ const repoVersion = repoConfig.branch || "main";
84
109
  try {
85
110
  // Fetch all files from the repository
86
111
  const files = await githubClient.fetchRepositoryFiles(repoConfig);
@@ -90,8 +115,8 @@ export async function indexRepository(repoConfig) {
90
115
  for (const file of files) {
91
116
  // Parse the file
92
117
  const parsed = parseFile(file.path, file.content);
93
- // Create chunks
94
- const chunks = createChunks(parsed, repoName);
118
+ // Create chunks with version info
119
+ const chunks = createChunks(parsed, repoName, repoVersion);
95
120
  for (const chunk of chunks) {
96
121
  documents.push({
97
122
  id: `${repoName}:${file.path}:${chunk.metadata.startLine}`,
@@ -105,6 +130,9 @@ export async function indexRepository(repoConfig) {
105
130
  codeType: chunk.metadata.codeUnitType || "unknown",
106
131
  codeName: chunk.metadata.codeUnitName || "",
107
132
  isPublic: chunk.metadata.isPublic,
133
+ repoVersion: chunk.metadata.repoVersion,
134
+ pragmaVersion: chunk.metadata.pragmaVersion,
135
+ indexedAt: chunk.metadata.indexedAt,
108
136
  },
109
137
  });
110
138
  chunkCount++;
@@ -181,7 +209,8 @@ export async function incrementalUpdate(repoConfig, since) {
181
209
  const file = await githubClient.getFileContent(repoConfig.owner, repoConfig.repo, filePath, repoConfig.branch);
182
210
  if (file) {
183
211
  const parsed = parseFile(file.path, file.content);
184
- const chunks = createChunks(parsed, repoName);
212
+ const repoVersion = repoConfig.branch || "main";
213
+ const chunks = createChunks(parsed, repoName, repoVersion);
185
214
  for (const chunk of chunks) {
186
215
  documents.push({
187
216
  id: `${repoName}:${filePath}:${chunk.metadata.startLine}`,
@@ -195,6 +224,9 @@ export async function incrementalUpdate(repoConfig, since) {
195
224
  codeType: chunk.metadata.codeUnitType || "unknown",
196
225
  codeName: chunk.metadata.codeUnitName || "",
197
226
  isPublic: chunk.metadata.isPublic,
227
+ repoVersion: chunk.metadata.repoVersion,
228
+ pragmaVersion: chunk.metadata.pragmaVersion,
229
+ indexedAt: chunk.metadata.indexedAt,
198
230
  },
199
231
  });
200
232
  chunkCount++;
@@ -157,6 +157,17 @@ export declare function compareSyntax(input: CompareSyntaxInput): Promise<{
157
157
  * This is the source of truth for writing valid, compilable contracts
158
158
  */
159
159
  export declare function getLatestSyntax(input: GetLatestSyntaxInput): Promise<{
160
+ syntaxReference: string;
161
+ sections: string[];
162
+ pitfalls: string[];
163
+ note: string;
164
+ versionWarning?: string | undefined;
165
+ repository: string;
166
+ version: string;
167
+ warning?: undefined;
168
+ syntaxFiles?: undefined;
169
+ examplePaths?: undefined;
170
+ } | {
160
171
  repository: string;
161
172
  version: string;
162
173
  warning: string;
@@ -6,6 +6,7 @@ import { githubClient } from "../../pipeline/index.js";
6
6
  import { releaseTracker } from "../../pipeline/releases.js";
7
7
  import { logger, DEFAULT_REPOSITORIES, SelfCorrectionHints, } from "../../utils/index.js";
8
8
  import { REPO_ALIASES, EXAMPLES } from "./constants.js";
9
+ import { EMBEDDED_DOCS } from "../../resources/content/docs-content.js";
9
10
  /**
10
11
  * Resolve repository name alias to owner/repo
11
12
  */
@@ -301,6 +302,62 @@ export async function getLatestSyntax(input) {
301
302
  // Ensure repo defaults to compact if undefined/empty
302
303
  const repoName = input?.repo || "compact";
303
304
  logger.debug("Getting latest syntax reference", { repo: repoName });
305
+ // For Compact language, always return our curated reference first
306
+ // This is more reliable than fetching from GitHub and includes pitfalls/patterns
307
+ if (repoName === "compact" || repoName === "midnight-compact") {
308
+ const compactReference = EMBEDDED_DOCS["midnight://docs/compact-reference"];
309
+ // Check if there's a newer release we might not have documented
310
+ const EMBEDDED_DOCS_VERSION = "0.16"; // Version our docs are based on
311
+ let versionWarning;
312
+ try {
313
+ const versionInfo = await releaseTracker.getVersionInfo("midnightntwrk", "compact");
314
+ const latestTag = versionInfo.latestStableRelease?.tag || versionInfo.latestRelease?.tag;
315
+ if (latestTag) {
316
+ // Extract version number from tag (e.g., "v0.18.0" -> "0.18")
317
+ const latestVersion = latestTag
318
+ .replace(/^v/, "")
319
+ .split(".")
320
+ .slice(0, 2)
321
+ .join(".");
322
+ const embeddedMajorMinor = EMBEDDED_DOCS_VERSION.split(".")
323
+ .slice(0, 2)
324
+ .join(".");
325
+ if (latestVersion !== embeddedMajorMinor &&
326
+ parseFloat(latestVersion) > parseFloat(embeddedMajorMinor)) {
327
+ versionWarning = `⚠️ Compact ${latestTag} is available. This reference is based on ${EMBEDDED_DOCS_VERSION}. Some syntax may have changed - check release notes for breaking changes.`;
328
+ }
329
+ }
330
+ }
331
+ catch {
332
+ // Ignore version check errors, still return cached docs
333
+ }
334
+ if (compactReference) {
335
+ return {
336
+ repository: "midnightntwrk/compact",
337
+ version: "0.16+ (current)",
338
+ ...(versionWarning && { versionWarning }),
339
+ syntaxReference: compactReference,
340
+ sections: [
341
+ "Basic Structure",
342
+ "Data Types",
343
+ "Circuits",
344
+ "Witnesses",
345
+ "State Management",
346
+ "Common Patterns",
347
+ "Disclosure in Conditionals (IMPORTANT)",
348
+ "Common Pitfalls & Solutions",
349
+ ],
350
+ pitfalls: [
351
+ "Cell<T> wrapper deprecated in 0.15+ - use direct type",
352
+ 'Cannot assign string literals to Opaque<"string"> - use enum or parameters',
353
+ "Must disclose() comparisons used in if/else conditions",
354
+ "Counter uses .increment()/.value(), Field uses direct assignment",
355
+ "Boolean returns from witnesses need disclose()",
356
+ ],
357
+ note: "This is the curated syntax reference for Compact 0.16+. Includes common pitfalls and correct patterns.",
358
+ };
359
+ }
360
+ }
304
361
  const resolved = resolveRepo(repoName);
305
362
  if (!resolved) {
306
363
  throw new Error(`Unknown repository: ${repoName}. Available: ${Object.keys(REPO_ALIASES).join(", ")}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "midnight-mcp",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "Model Context Protocol Server for Midnight Blockchain Development",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",