From 37f1028fe93232962bba52852799f6780cb41be3 Mon Sep 17 00:00:00 2001 From: Mikael Hugo Date: Sat, 2 May 2026 05:46:32 +0200 Subject: [PATCH] test: fix mcp-server imports, regex patterns, and add sqlite fallback in parallel-merge --- src/resources/extensions/sf/parallel-merge.ts | 27 ++++++++++++++++++- src/tests/mcp-server.test.ts | 4 +-- src/tests/node-modules-symlink.test.ts | 4 +-- .../onboarding-claude-cli-provider.test.ts | 6 +++-- .../package-mcp-server-elicitation.test.ts | 1 + 5 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/resources/extensions/sf/parallel-merge.ts b/src/resources/extensions/sf/parallel-merge.ts index b499413e0..81562aa5b 100644 --- a/src/resources/extensions/sf/parallel-merge.ts +++ b/src/resources/extensions/sf/parallel-merge.ts @@ -8,6 +8,20 @@ import { spawnSync } from "node:child_process"; import { existsSync, readdirSync } from "node:fs"; import { join } from "node:path"; + +interface SqliteModule { + DatabaseSync: new (path: string) => { + prepare(sql: string): { get(...args: unknown[]): { status: string } | undefined }; + close(): void; + }; +} + +let sqliteModule: SqliteModule | undefined; +try { + sqliteModule = require("node:sqlite") as SqliteModule; +} catch { + // node:sqlite unavailable — fall back to sqlite3 CLI +} import { mergeMilestoneToMain } from "./auto-worktree.js"; import { getErrorMessage } from "./error-utils.js"; import { loadFile } from "./files.js"; @@ -48,6 +62,17 @@ export function isMilestoneCompleteInWorktreeDb( if (!existsSync(dbPath)) return false; try { + if (sqliteModule) { + const db = new sqliteModule.DatabaseSync(dbPath); + try { + const stmt = db.prepare("SELECT status FROM milestones WHERE id = ? LIMIT 1"); + const row = stmt.get(mid) as { status: string } | undefined; + return row?.status === "complete"; + } finally { + db.close(); + } + } + const result = spawnSync( "sqlite3", [dbPath, `SELECT status FROM milestones WHERE id='${mid}' LIMIT 1`], @@ -57,7 +82,7 @@ export function isMilestoneCompleteInWorktreeDb( } catch (e) { logWarning( "parallel", - `spawnSync milestone completion check failed for ${mid}: ${(e as Error).message}`, + `milestone completion check failed for ${mid}: ${(e as Error).message}`, ); return false; } diff --git a/src/tests/mcp-server.test.ts b/src/tests/mcp-server.test.ts index d4f8fd464..7f4bcabeb 100644 --- a/src/tests/mcp-server.test.ts +++ b/src/tests/mcp-server.test.ts @@ -2,7 +2,7 @@ import assert from "node:assert/strict"; import { test } from 'vitest'; test("mcp-server module imports without errors", async () => { - const mod = await import("../mcp-server.js"); + const mod = await import("../mcp-server.ts"); assert.ok(mod, "module should be importable"); assert.strictEqual( typeof mod.startMcpServer, @@ -12,7 +12,7 @@ test("mcp-server module imports without errors", async () => { }); test("startMcpServer accepts the correct argument shape", async () => { - const { startMcpServer } = await import("../mcp-server.js"); + const { startMcpServer } = await import("../mcp-server.ts"); assert.strictEqual(typeof startMcpServer, "function"); assert.strictEqual( diff --git a/src/tests/node-modules-symlink.test.ts b/src/tests/node-modules-symlink.test.ts index a64a704c6..c4c8fba9d 100644 --- a/src/tests/node-modules-symlink.test.ts +++ b/src/tests/node-modules-symlink.test.ts @@ -397,12 +397,12 @@ test("reconcileMergedNodeModules uses junction symlinks for Windows compatibilit assert.match( source, - /symlinkSync\(join\(hoisted,\s*entry\.name\),\s*join\(agentNodeModules,\s*entry\.name\),\s*['"]junction['"]\)/, + /symlinkSync\(\s*join\(hoisted,\s*entry\.name\),\s*join\(agentNodeModules,\s*entry\.name\),\s*['"]junction['"],?\s*\)/s, "hoisted merged symlink must use 'junction'", ); assert.match( source, - /symlinkSync\(join\(internal,\s*entry\.name\),\s*link,\s*['"]junction['"]\)/, + /symlinkSync\(\s*join\(internal,\s*entry\.name\),\s*link,\s*['"]junction['"],?\s*\)/s, "internal merged symlink must use 'junction'", ); }); diff --git a/src/tests/onboarding-claude-cli-provider.test.ts b/src/tests/onboarding-claude-cli-provider.test.ts index 5031fe3a0..729d6ad24 100644 --- a/src/tests/onboarding-claude-cli-provider.test.ts +++ b/src/tests/onboarding-claude-cli-provider.test.ts @@ -18,9 +18,11 @@ test("onboarding claude-cli path persists defaultProvider to settings.json", () ); // The claude-cli branch must write defaultProvider = 'claude-code' to settings.json + const blockStart = source.search(/method\s*===\s*["']claude-cli["']/); + const blockEnd = source.indexOf("// ── Step 2", blockStart); const cliBlock = source.slice( - source.indexOf("method === 'claude-cli'"), - source.indexOf("// ── Step 2"), + blockStart, + blockEnd, ); assert.ok(cliBlock.length > 0, "claude-cli block not found in onboarding.ts"); assert.match( diff --git a/src/tests/package-mcp-server-elicitation.test.ts b/src/tests/package-mcp-server-elicitation.test.ts index 4fb2aa861..7c21be70a 100644 --- a/src/tests/package-mcp-server-elicitation.test.ts +++ b/src/tests/package-mcp-server-elicitation.test.ts @@ -179,6 +179,7 @@ test("ask_user_questions returns the cancellation message when elicitation is de const { client, close } = await createConnectedClient({ onElicit: async () => ({ action: "decline", + content: {}, }), });