chore(web): format-gate the ungated first-party TS/JS (server/, vite.config.ts, scripts/) (#1788)
* chore(web): format-gate the ungated first-party TS/JS (#1778) Prettier only covered core/ and each client's src/, leaving the web Node backend (clients/web/server/**), web top-level configs (vite.config.ts, tsup.runner.config.ts, eslint.config.js, ...), and the root build/verify tooling (scripts/**/*.mjs) ungated — so their formatting was never checked by validate/CI. eslint already reached these via `eslint .`, so this is a prettier-only gap. - clients/web format/format:check now cover src, server, and top-level *.{ts,js}, not just src. - New root format:scripts / format:check:scripts for scripts/**/*.mjs, folded into the root format and into validate:core. - Normalized the newly-covered files with prettier --write (pure formatting; no runtime change). Closes #1778 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5 * chore: future-proof the scripts format glob (#1778 review) Widen format:scripts / format:check:scripts from "scripts/**/*.mjs" to "scripts/**/*.{mjs,js,cjs,ts}" so a future non-.mjs file under scripts/ is auto-gated, matching the future-proof glob style clients/web now uses. A brace glob is a single pattern, so prettier does not error on the unmatched branches. Addresses observation #2 from the PR #1788 review. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5 * docs: sync AGENTS.md scripts glob after the widening (#1788 review r2) d86d8f7 widened the scripts glob to {mjs,js,cjs,ts} and updated the validate:core bullet, but the format bullet at AGENTS.md:217 still said scripts/**/*.mjs. Bring it in line so the two mentions agree. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5 --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a82a70f4f5
commit
166ed38e7f
2 changed files with 406 additions and 324 deletions
|
|
@ -45,7 +45,12 @@ import { join, resolve } from "node:path";
|
|||
import { setTimeout as delay } from "node:timers/promises";
|
||||
|
||||
const repoRoot = resolve(import.meta.dirname, "..");
|
||||
const testServer = join(repoRoot, "test-servers", "build", "test-server-stdio.js");
|
||||
const testServer = join(
|
||||
repoRoot,
|
||||
"test-servers",
|
||||
"build",
|
||||
"test-server-stdio.js",
|
||||
);
|
||||
|
||||
// Mirrors INSPECTOR_API_TOKEN_GLOBAL in core/mcp/remote/constants.ts; kept as a
|
||||
// literal because this plain .mjs script can't import the TS source.
|
||||
|
|
@ -72,7 +77,9 @@ function fail(message) {
|
|||
if (workDir) {
|
||||
rmSync(workDir, { recursive: true, force: true });
|
||||
// `tarball` is initialized before `workDir` is ever set, so this is safe.
|
||||
console.error(`pack:verify — tarball retained for inspection at ${tarball}`);
|
||||
console.error(
|
||||
`pack:verify — tarball retained for inspection at ${tarball}`,
|
||||
);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
|
|
@ -97,7 +104,9 @@ function ensureTestServer() {
|
|||
step("building test-servers (missing build output)...");
|
||||
const status = runInherit("npx", ["tsc", "-p", "test-servers", "--noCheck"]);
|
||||
if (status !== 0 || !existsSync(testServer)) {
|
||||
fail("could not build the stdio test server (test-servers/build/test-server-stdio.js)");
|
||||
fail(
|
||||
"could not build the stdio test server (test-servers/build/test-server-stdio.js)",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -175,10 +184,16 @@ const work = mkdtempSync(join(tmpdir(), "pack-verify-"));
|
|||
workDir = work; // from now on, fail() cleans this up
|
||||
try {
|
||||
ensureTestServer();
|
||||
step(`installing the tarball into a clean consumer at ${work} (pulls runtime deps)...`);
|
||||
step(
|
||||
`installing the tarball into a clean consumer at ${work} (pulls runtime deps)...`,
|
||||
);
|
||||
writeFileSync(
|
||||
join(work, "package.json"),
|
||||
JSON.stringify({ name: "pack-verify-consumer", private: true, version: "0.0.0" }),
|
||||
JSON.stringify({
|
||||
name: "pack-verify-consumer",
|
||||
private: true,
|
||||
version: "0.0.0",
|
||||
}),
|
||||
);
|
||||
const install = runInherit(
|
||||
"npm",
|
||||
|
|
@ -189,8 +204,18 @@ try {
|
|||
fail("`npm install <tarball>` into the throwaway consumer failed");
|
||||
}
|
||||
|
||||
const installedPkg = join(work, "node_modules", "@modelcontextprotocol", "inspector");
|
||||
const bin = join(work, "node_modules", ".bin", process.platform === "win32" ? "mcp-inspector.cmd" : "mcp-inspector");
|
||||
const installedPkg = join(
|
||||
work,
|
||||
"node_modules",
|
||||
"@modelcontextprotocol",
|
||||
"inspector",
|
||||
);
|
||||
const bin = join(
|
||||
work,
|
||||
"node_modules",
|
||||
".bin",
|
||||
process.platform === "win32" ? "mcp-inspector.cmd" : "mcp-inspector",
|
||||
);
|
||||
if (!existsSync(bin)) {
|
||||
fail(`installed \`mcp-inspector\` bin not found at ${bin}`);
|
||||
}
|
||||
|
|
@ -213,7 +238,11 @@ try {
|
|||
env: { ...process.env, ...extraEnv },
|
||||
shell: process.platform === "win32",
|
||||
});
|
||||
return { status: r.status, output: `${r.stdout ?? ""}${r.stderr ?? ""}`, stdout: r.stdout ?? "" };
|
||||
return {
|
||||
status: r.status,
|
||||
output: `${r.stdout ?? ""}${r.stderr ?? ""}`,
|
||||
stdout: r.stdout ?? "",
|
||||
};
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -223,17 +252,33 @@ try {
|
|||
// build from its installed location.
|
||||
step("verifying help dispatch (--help, --cli --help, --tui --help)...");
|
||||
const helpChecks = [
|
||||
{ args: ["--help"], marker: "Mode flags (--web, --cli, --tui)", label: "launcher --help" },
|
||||
{ args: ["--cli", "--help"], marker: "Usage: inspector-cli", label: "--cli dispatch" },
|
||||
{ args: ["--tui", "--help"], marker: "Usage: mcp-inspector-tui", label: "--tui dispatch" },
|
||||
{
|
||||
args: ["--help"],
|
||||
marker: "Mode flags (--web, --cli, --tui)",
|
||||
label: "launcher --help",
|
||||
},
|
||||
{
|
||||
args: ["--cli", "--help"],
|
||||
marker: "Usage: inspector-cli",
|
||||
label: "--cli dispatch",
|
||||
},
|
||||
{
|
||||
args: ["--tui", "--help"],
|
||||
marker: "Usage: mcp-inspector-tui",
|
||||
label: "--tui dispatch",
|
||||
},
|
||||
];
|
||||
for (const { args, marker, label } of helpChecks) {
|
||||
const r = runBin(args);
|
||||
if (r.status !== 0) {
|
||||
fail(`\`${args.join(" ")}\` exited ${r.status}\n${r.output.slice(0, 800)}`);
|
||||
fail(
|
||||
`\`${args.join(" ")}\` exited ${r.status}\n${r.output.slice(0, 800)}`,
|
||||
);
|
||||
}
|
||||
if (!r.output.includes(marker)) {
|
||||
fail(`\`${args.join(" ")}\` (${label}) did not print "${marker}"\n${r.output.slice(0, 800)}`);
|
||||
fail(
|
||||
`\`${args.join(" ")}\` (${label}) did not print "${marker}"\n${r.output.slice(0, 800)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -250,7 +295,15 @@ try {
|
|||
},
|
||||
}),
|
||||
);
|
||||
const list = runBin(["--cli", "--catalog", catalogPath, "--server", "test", "--method", "tools/list"]);
|
||||
const list = runBin([
|
||||
"--cli",
|
||||
"--catalog",
|
||||
catalogPath,
|
||||
"--server",
|
||||
"test",
|
||||
"--method",
|
||||
"tools/list",
|
||||
]);
|
||||
if (list.status !== 0) {
|
||||
fail(`\`--cli … tools/list\` exited ${list.status}\n${list.output}`);
|
||||
}
|
||||
|
|
@ -258,7 +311,9 @@ try {
|
|||
try {
|
||||
parsed = JSON.parse(list.stdout);
|
||||
} catch {
|
||||
fail(`\`--cli … tools/list\` did not return JSON on stdout:\n${list.stdout}`);
|
||||
fail(
|
||||
`\`--cli … tools/list\` did not return JSON on stdout:\n${list.stdout}`,
|
||||
);
|
||||
}
|
||||
if (!(parsed.tools ?? []).some((t) => t.name === "echo")) {
|
||||
fail(`\`--cli … tools/list\` missing expected "echo" tool`);
|
||||
|
|
@ -291,7 +346,9 @@ try {
|
|||
* shipped `dist`. Kills the server before returning.
|
||||
*/
|
||||
async function verifyWeb(bin, cwd) {
|
||||
step("verifying prod `--web` serves the shipped dist from the installed package...");
|
||||
step(
|
||||
"verifying prod `--web` serves the shipped dist from the installed package...",
|
||||
);
|
||||
const host = "127.0.0.1";
|
||||
const port = process.env.PACK_VERIFY_WEB_PORT ?? "6399";
|
||||
const token = "pack-verify-token";
|
||||
|
|
@ -326,7 +383,9 @@ async function verifyWeb(bin, cwd) {
|
|||
let res = null;
|
||||
for (let attempt = 0; attempt < 120 && !res; attempt++) {
|
||||
if (exited) {
|
||||
fail(`\`--web\` exited (code ${exitCode}) before serving — see output above`);
|
||||
fail(
|
||||
`\`--web\` exited (code ${exitCode}) before serving — see output above`,
|
||||
);
|
||||
}
|
||||
try {
|
||||
res = await fetch(`http://${host}:${port}/`);
|
||||
|
|
@ -342,7 +401,9 @@ async function verifyWeb(bin, cwd) {
|
|||
}
|
||||
const body = await res.text();
|
||||
if (!body.includes(TOKEN_GLOBAL)) {
|
||||
fail(`\`--web\` served HTML is missing the ${TOKEN_GLOBAL} global (token not injected)`);
|
||||
fail(
|
||||
`\`--web\` served HTML is missing the ${TOKEN_GLOBAL} global (token not injected)`,
|
||||
);
|
||||
}
|
||||
if (!body.includes(token)) {
|
||||
fail("`--web` served HTML is missing the injected auth-token value");
|
||||
|
|
|
|||
|
|
@ -33,7 +33,10 @@ import { tmpdir } from "node:os";
|
|||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const repoRoot = path.resolve(
|
||||
path.dirname(fileURLToPath(import.meta.url)),
|
||||
"..",
|
||||
);
|
||||
const webDir = path.join(repoRoot, "clients/web");
|
||||
// Hardcoded browser entry. If it's ever renamed, the guarded read below fails
|
||||
// with an actionable message rather than a raw ENOENT stack.
|
||||
|
|
|
|||
Loading…
Reference in a new issue