Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
"test:smoke:browser:install": "playwright install chromium",
"test:smoke:browser": "node --experimental-strip-types scripts/smoke-ui-browser.ts",
"pretest:ci": "npm run check-node-version",
"test:ci": "git diff --check && npm run actionlint && npm run lint:composite-actions && npm run db:migrations:check && npm run db:schema-drift:check && npm run selfhost:env-reference:check && npm run miner:env-reference:check && npm run selfhost:validate-observability && npm run cf-typegen:check && npm run build --workspace @loopover/engine && npm run build --workspace @loopover/discovery-index && npm run build:mcp && npm run build:miner && npm run typecheck && npm run test:coverage && npm run test:engine-parity && npm run test:live-gate-parity && npm run test:driver-parity && npm run test --workspace @loopover/engine && npm run test:workers && npm run test:mcp-pack && npm run test:miner-pack && npm run test:engine-pack && npm run test:ui-kit-pack && npm run test:miner-deployment-docs-audit && npm run rees:test && npm run ui:openapi:check && npm run ui:openapi:settings-parity && npm run ui:version-audit && npm run docs:drift-check && npm run coverage-boltons:check && npm run branding-drift:check && npm run manifest:drift-check && npm run engine-parity:drift-check && npm run engines-nvmrc:check && npm run release-manifest:sync:check && npm run command-reference:check && npm run ui:lint && npm run ui:typecheck && npm run ui:test && npm run ui:build",
"test:ci": "git diff --check && npm run actionlint && npm run lint:composite-actions && npm run db:migrations:check && npm run db:schema-drift:check && npm run selfhost:env-reference:check && npm run miner:env-reference:check && npm run selfhost:validate-observability && npm run cf-typegen:check && npm run build --workspace @loopover/engine && npm run build --workspace @loopover/discovery-index && npm run build:mcp && npm run build:miner && npm run build --workspace @loopover/ui-kit && npm run typecheck && npm run test:coverage && npm run test:engine-parity && npm run test:live-gate-parity && npm run test:driver-parity && npm run test --workspace @loopover/engine && npm run test:workers && npm run test:mcp-pack && npm run test:miner-pack && npm run test:engine-pack && npm run test:ui-kit-pack && npm run test:miner-deployment-docs-audit && npm run rees:test && npm run ui:openapi:check && npm run ui:openapi:settings-parity && npm run ui:version-audit && npm run docs:drift-check && npm run coverage-boltons:check && npm run branding-drift:check && npm run manifest:drift-check && npm run engine-parity:drift-check && npm run engines-nvmrc:check && npm run release-manifest:sync:check && npm run command-reference:check && npm run ui:lint && npm run ui:typecheck && npm run ui:test && npm run ui:build",
"test:release": "npm run test:ci && npm run changelog:check",
"test:release:mcp": "npm run test:ci",
"test:watch": "vitest",
Expand Down Expand Up @@ -174,12 +174,13 @@
"@lovable.dev/vite-plugin-hmr-gate": "1.1.2",
"esbuild": "^0.28.1",
"ws": "^8.21.0",
"tar": "^7.5.19",
"tar": "^7.5.21",
"js-yaml": "^4.3.0",
"adm-zip": "^0.6.0",
"fast-uri": "^3.1.4",
"@hono/node-server": "^2.0.8",
"sharp": "^0.35.0",
"postcss": "^8.5.18",
"lovable-tagger@1.2.0": {
"esbuild": "^0.28.1"
},
Expand Down
16 changes: 14 additions & 2 deletions packages/loopover-mcp/bin/loopover-mcp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1673,14 +1673,26 @@ function stdioToolDescription(name: any) {
return tool.description;
}

/* v8 ignore next 8 -- the CLI dispatch runs only in the launched process (runAsCliEntrypoint); an in-process
/* v8 ignore next 5 -- draining stdout/stderr before exit only matters for the real launched process writing to
an OS pipe (large output can exceed the pipe's buffer, and a POSIX pipe write is asynchronous); the
in-process test harness below never spawns a subprocess, so this never runs there. */
function flushStdio(): Promise<void> {
const drained = (stream: NodeJS.WriteStream) =>
stream.writableLength > 0 ? new Promise<void>((resolve) => stream.once("drain", resolve)) : Promise.resolve();
return Promise.all([drained(process.stdout), drained(process.stderr)]).then(() => undefined);
}

/* v8 ignore next 11 -- the CLI dispatch runs only in the launched process (runAsCliEntrypoint); an in-process
unit importer keeps it false and drives runCli/maintainCli directly instead (mcp-cli-plan-issues.test.ts). */
if (runAsCliEntrypoint && cliArgs[0] !== "--stdio") {
try {
const exitCode = await runCli(cliArgs);
await flushStdio();
process.exit(typeof exitCode === "number" ? exitCode : 0);
} catch (error) {
process.exit(reportCliFailure(argsWantJson(cliArgs), describeCliError(error), 1));
const code = reportCliFailure(argsWantJson(cliArgs), describeCliError(error), 1);
await flushStdio();
process.exit(code);
}
}

Expand Down
29 changes: 19 additions & 10 deletions test/unit/miner-package-skeleton.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,25 @@ describe("loopover-miner package skeleton (#2287)", () => {
expect(miner.scripts["build:verify"]).toBe("node scripts/check-syntax.mjs");
});

it("build:verify's syntax check actually covers the CLI bin entry points, not just lib/", () => {
// The pre-split build script explicitly node --check'd bin/loopover-miner.js and
// bin/loopover-miner-mcp.js by name; the glob-driven replacement must still reach them. Requires a
// prior build (dist/bin, dist/lib populated) -- same precondition as every other test in this file
// that reads real compiled output, and as the package's own real `npm run build`.
const result = spawnSync("node", ["scripts/check-syntax.mjs"], { cwd: minerRoot, encoding: "utf8" });
expect(result.status).toBe(0);
expect(result.stdout).toContain("node --check passed for all");
expect(result.stdout).toMatch(/passed for all \d+ files in dist\/bin\/ and dist\/lib\//);
});
it(
"build:verify's syntax check actually covers the CLI bin entry points, not just lib/",
() => {
// The pre-split build script explicitly node --check'd bin/loopover-miner.js and
// bin/loopover-miner-mcp.js by name; the glob-driven replacement must still reach them. Requires a
// prior build (dist/bin, dist/lib populated) -- same precondition as every other test in this file
// that reads real compiled output, and as the package's own real `npm run build`.
// Genuinely real subprocess work (node --check over every dist/bin+dist/lib file), no redundancy to
// cut -- 5.5s in isolation but can exceed the default 15s testTimeout under the full suite's parallel
// load. 60000ms matches the same evidence-based ceiling already used for this repo's other
// real-subprocess timeout flakes (agent-sdk-driver.test.ts, miner-attempt-worktree.test.ts,
// miner-repo-clone.test.ts, #6869/#6871).
const result = spawnSync("node", ["scripts/check-syntax.mjs"], { cwd: minerRoot, encoding: "utf8" });
expect(result.status).toBe(0);
expect(result.stdout).toContain("node --check passed for all");
expect(result.stdout).toMatch(/passed for all \d+ files in dist\/bin\/ and dist\/lib\//);
},
60000,
);

it("starts the CLI bin with a node shebang", () => {
const bin = readFileSync(join(minerRoot, "dist/bin/loopover-miner.js"), "utf8");
Expand Down
Loading