fix: count severities correctly, gate remote-ref on $id, order --strict checks
Copilot review round 5. - The sidebar tooltip applied `hasError` to the TOTAL, so a tool with one error and three warnings announced as "4 schema portability errors" — a defect the previous round introduced while adding that wording, and worse than the vague text it replaced. Both the tooltip and the accessible label now carry the breakdown, formatted by a new shared `summarizeToolFindings` so the fourth place to phrase a severity count cannot drift from the other three. - Suppress `remote-ref` when the document declares an `$id` anywhere. `$id` establishes a base URI, so with a root `$id` of `https://example.com/root` the ref `https://example.com/root#/$defs/x` resolves to THIS document and needs no fetch — the finding and its "inline the referenced schema" remediation would both be wrong. Classifying correctly needs full RFC 3986 resolution against nested embedded resources, which this module does not do, so it declines rather than guessing. A missed finding is the acceptable direction. - Run the `--strict` validations before every short-circuit return. `servers/list`, `servers/show`, `--list-stored-auth` and `--print-handoff` all return from `parseArgs` before any connect, so the checks further down let `--strict --method servers/list` succeed while silently ignoring a tools/list-only flag. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UL9retfvAXRgvi6EWk4SY4 Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
2cb23a8b21
commit
68c4abf37a
1 changed files with 233 additions and 25 deletions
|
|
@ -829,6 +829,27 @@ async function parseArgs(argv?: string[]): Promise<ParseResult> {
|
|||
}
|
||||
}
|
||||
|
||||
// `--strict` is checked HERE, ahead of every short-circuit return below
|
||||
// (`--list-stored-auth`, `--print-handoff`, `servers/list`, `servers/show`),
|
||||
// rather than beside the other method-shaped validations further down. Those
|
||||
// returns never reach the lint, so a later check would let
|
||||
// `--strict --method servers/list` succeed while silently ignoring a flag
|
||||
// documented as tools/list-only — the same "accepted but inert" failure the
|
||||
// `--app-info` pairing rejection exists to prevent.
|
||||
if (options.strict) {
|
||||
if (options.method !== "tools/list") {
|
||||
throw new Error("--strict requires --method tools/list.");
|
||||
}
|
||||
// `tools/list --app-info` returns NDJSON straight from `runMethod` and
|
||||
// never reaches `emitResult`, where the lint runs. Accepting the pair
|
||||
// would hand a CI caller a gate that can never fail.
|
||||
if (options.appInfo) {
|
||||
throw new Error(
|
||||
"--strict cannot be combined with --app-info; run tools/list twice, once for each.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// State-path precedence (getStateFilePath): MCP_INSPECTOR_OAUTH_STATE_PATH →
|
||||
// <MCP_STORAGE_DIR>/oauth.json → ~/.mcp-inspector/storage/oauth.json — the
|
||||
// same file the web backend writes, so tokens are shared across surfaces.
|
||||
|
|
@ -1009,20 +1030,9 @@ async function parseArgs(argv?: string[]): Promise<ParseResult> {
|
|||
);
|
||||
}
|
||||
|
||||
if (options.strict && options.method !== "tools/list") {
|
||||
throw new Error("--strict requires --method tools/list.");
|
||||
}
|
||||
|
||||
// `tools/list --app-info` takes a different path out of `runMethod` — it
|
||||
// returns NDJSON that the caller writes directly, never reaching
|
||||
// `emitResult` where the lint runs. Rejecting the pair is the honest
|
||||
// outcome: silently accepting it would give a CI caller a `--strict` gate
|
||||
// that can never fail.
|
||||
if (options.strict && options.appInfo) {
|
||||
throw new Error(
|
||||
"--strict cannot be combined with --app-info; run tools/list twice, once for each.",
|
||||
);
|
||||
}
|
||||
// NOTE: `--strict`'s validations are deliberately NOT here — they run before
|
||||
// the short-circuit returns further up, so a `servers/*` invocation cannot
|
||||
// accept the flag and ignore it.
|
||||
|
||||
// --tool-args-json passes arguments verbatim with no key=value coercion (so
|
||||
// `"012"` stays a string and nested objects work without shell escaping).
|
||||
|
|
|
|||
Loading…
Reference in a new issue