midnight-mcp 0.1.21 → 0.1.23
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/tools/analyze.js
CHANGED
|
@@ -377,7 +377,11 @@ const explainCircuitOutputSchema = {
|
|
|
377
377
|
export const analyzeTools = [
|
|
378
378
|
{
|
|
379
379
|
name: "midnight-analyze-contract",
|
|
380
|
-
description: "
|
|
380
|
+
description: "⚠️ STATIC ANALYSIS ONLY - Analyze contract structure and patterns. " +
|
|
381
|
+
"🚫 THIS DOES NOT COMPILE THE CONTRACT. Cannot catch: sealed field rules, disclose() requirements, semantic errors. " +
|
|
382
|
+
"👉 ALWAYS call 'midnight-validate-contract' FIRST to verify the code actually compiles. " +
|
|
383
|
+
"Use this for: understanding structure, security pattern analysis, recommendations. " +
|
|
384
|
+
"NEVER claim a contract 'works' or 'compiles' based on this tool alone.",
|
|
381
385
|
inputSchema: {
|
|
382
386
|
type: "object",
|
|
383
387
|
properties: {
|
|
@@ -358,7 +358,13 @@ export const repositoryTools = [
|
|
|
358
358
|
// ============================================================================
|
|
359
359
|
{
|
|
360
360
|
name: "midnight-validate-contract",
|
|
361
|
-
description: "
|
|
361
|
+
description: "� REQUIRED - ALWAYS CALL THIS FIRST: Compile a Compact contract using the REAL compiler. " +
|
|
362
|
+
"⚠️ CRITICAL: You MUST call this tool BEFORE telling the user a contract works or is correct. " +
|
|
363
|
+
"Static analysis tools like 'extract-contract-structure' or 'analyze-contract' CANNOT verify compilation - they miss semantic errors like: " +
|
|
364
|
+
"(1) sealed fields require constructor, (2) constructor params need disclose(), (3) export circuits cannot modify sealed fields. " +
|
|
365
|
+
"This tool runs the ACTUAL Compact compiler and returns real errors with line numbers. " +
|
|
366
|
+
"If compiler not installed, it provides installation instructions. " +
|
|
367
|
+
"WORKFLOW: Generate code → Call this tool → Fix errors → Repeat until success → THEN present to user.",
|
|
362
368
|
inputSchema: {
|
|
363
369
|
type: "object",
|
|
364
370
|
properties: {
|
|
@@ -454,7 +460,12 @@ export const repositoryTools = [
|
|
|
454
460
|
},
|
|
455
461
|
{
|
|
456
462
|
name: "midnight-extract-contract-structure",
|
|
457
|
-
description: "
|
|
463
|
+
description: "⚠️ STATIC ANALYSIS ONLY - NOT A COMPILER: Extracts contract structure (circuits, witnesses, ledger) and detects common patterns. " +
|
|
464
|
+
"🚫 THIS TOOL CANNOT VERIFY COMPILATION. It will NOT catch: sealed field rules, disclose() requirements, type mismatches, or semantic errors. " +
|
|
465
|
+
"✅ USE FOR: Understanding structure, quick pattern checks, fallback when compiler unavailable. " +
|
|
466
|
+
"❌ NEVER USE TO: Verify a contract works, claim code 'compiles correctly', or validate before presenting to user. " +
|
|
467
|
+
"👉 ALWAYS call 'midnight-validate-contract' FIRST to actually compile the code. " +
|
|
468
|
+
"Detects: module-level const, stdlib collisions, sealed+export conflicts, missing disclose(), Counter.value access, division operator.",
|
|
458
469
|
inputSchema: {
|
|
459
470
|
type: "object",
|
|
460
471
|
properties: {
|
|
@@ -1379,6 +1379,44 @@ export async function extractContractStructure(input) {
|
|
|
1379
1379
|
}
|
|
1380
1380
|
}
|
|
1381
1381
|
}
|
|
1382
|
+
// 10. Detect constructor parameters assigned to ledger without disclose()
|
|
1383
|
+
// Constructor parameters are treated as witness values and need disclose() when written to ledger
|
|
1384
|
+
const constructorMatch = code.match(/constructor\s*\(([^)]*)\)\s*\{([\s\S]*?)(?=\n\s*(?:export|circuit|witness|ledger|constructor|\}|$))/);
|
|
1385
|
+
if (constructorMatch) {
|
|
1386
|
+
const paramsStr = constructorMatch[1];
|
|
1387
|
+
const constructorBody = constructorMatch[2];
|
|
1388
|
+
// Extract constructor parameter names
|
|
1389
|
+
const paramPattern = /(\w+)\s*:\s*[^,)]+/g;
|
|
1390
|
+
const constructorParams = [];
|
|
1391
|
+
let paramMatch;
|
|
1392
|
+
while ((paramMatch = paramPattern.exec(paramsStr)) !== null) {
|
|
1393
|
+
constructorParams.push(paramMatch[1]);
|
|
1394
|
+
}
|
|
1395
|
+
// Check each parameter for direct assignment to ledger without disclose
|
|
1396
|
+
for (const param of constructorParams) {
|
|
1397
|
+
// Look for direct assignment: ledgerField = param (without disclose)
|
|
1398
|
+
const assignmentPattern = new RegExp(`(\\w+)\\s*=\\s*(?!disclose\\s*\\()${param}\\b`, "g");
|
|
1399
|
+
let assignMatch;
|
|
1400
|
+
while ((assignMatch = assignmentPattern.exec(constructorBody)) !== null) {
|
|
1401
|
+
const fieldName = assignMatch[1];
|
|
1402
|
+
// Check if the field is a ledger item
|
|
1403
|
+
const isLedgerField = ledgerItems.some((l) => l.name === fieldName);
|
|
1404
|
+
if (isLedgerField) {
|
|
1405
|
+
// Find the line number
|
|
1406
|
+
const beforeAssign = code.substring(0, constructorMatch.index +
|
|
1407
|
+
constructorMatch[0].indexOf(assignMatch[0]));
|
|
1408
|
+
const lineNum = (beforeAssign.match(/\n/g) || []).length + 1;
|
|
1409
|
+
potentialIssues.push({
|
|
1410
|
+
type: "undisclosed_constructor_param",
|
|
1411
|
+
line: lineNum,
|
|
1412
|
+
message: `Constructor parameter '${param}' assigned to ledger field '${fieldName}' without disclose()`,
|
|
1413
|
+
suggestion: `Wrap in disclose(): '${fieldName} = disclose(${param});'`,
|
|
1414
|
+
severity: "error",
|
|
1415
|
+
});
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1382
1420
|
const summary = [];
|
|
1383
1421
|
if (circuits.length > 0) {
|
|
1384
1422
|
summary.push(`${circuits.length} circuit(s)`);
|