chore: close quality-gate coverage gaps (#1689) (#1766)
Some checks failed
Run install, format, lint, build, and test on every push / build (push) Has been cancelled
Run install, format, lint, build, and test on every push / publish (push) Has been cancelled
Run install, format, lint, build, and test on every push / publish-github-container-registry (push) Has been cancelled
Some checks failed
Run install, format, lint, build, and test on every push / build (push) Has been cancelled
Run install, format, lint, build, and test on every push / publish (push) Has been cancelled
Run install, format, lint, build, and test on every push / publish-github-container-registry (push) Has been cancelled
Closes #1689. Typecheck cli/tui src, add a core/ format+lint gate, and gate core/json + core/client coverage. See PR #1766 for the full review history.
This commit is contained in:
parent
d76c4d5379
commit
373f346e5f
7 changed files with 2210 additions and 467 deletions
|
|
@ -32,9 +32,7 @@ export function isOAuthCapableServerType(type: ServerType): boolean {
|
|||
* MCP server URL used as the OAuth storage key (includes path, for discovery).
|
||||
* Undefined for stdio transports.
|
||||
*/
|
||||
export function getOAuthServerUrl(
|
||||
config: MCPServerConfig,
|
||||
): string | undefined {
|
||||
export function getOAuthServerUrl(config: MCPServerConfig): string | undefined {
|
||||
if (config.type === "sse" || config.type === "streamable-http") {
|
||||
return config.url;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1827,9 +1827,12 @@ export class InspectorClient extends InspectorClientEventTarget {
|
|||
// a future modern-family revision would negotiate a different string, and
|
||||
// the two must not disagree. The raw channel only runs on a connected modern
|
||||
// session, so this is always set; the constant is a defensive fallback.
|
||||
/* v8 ignore next -- fallback only if getProtocolVersion() is unset, which
|
||||
can't happen on the connected modern session this runs on. */
|
||||
const protocolVersion = this.getProtocolVersion() ?? MODERN_PROTOCOL_VERSION;
|
||||
/* v8 ignore start -- fallback only if getProtocolVersion() is unset, which
|
||||
can't happen on the connected modern session this runs on. Bracketed so
|
||||
the ignore is reflow-proof however prettier splits the statement. */
|
||||
const protocolVersion =
|
||||
this.getProtocolVersion() ?? MODERN_PROTOCOL_VERSION;
|
||||
/* v8 ignore stop */
|
||||
return {
|
||||
...params,
|
||||
_meta: {
|
||||
|
|
@ -1861,9 +1864,7 @@ export class InspectorClient extends InspectorClientEventTarget {
|
|||
...message,
|
||||
result: {
|
||||
resultType: "complete",
|
||||
content: [
|
||||
{ type: "text", text: `Modern task ${task.taskId} created` },
|
||||
],
|
||||
content: [{ type: "text", text: `Modern task ${task.taskId} created` }],
|
||||
_meta: { [MODERN_TASK_HANDLE_META]: task },
|
||||
},
|
||||
};
|
||||
|
|
@ -1906,7 +1907,9 @@ export class InspectorClient extends InspectorClientEventTarget {
|
|||
const raw = await new Promise<unknown>((resolve, reject) => {
|
||||
const timer = setTimeout(() => {
|
||||
this.pendingRawWireRequests.delete(id);
|
||||
reject(new Error(`Raw request "${method}" timed out after ${timeoutMs} ms`));
|
||||
reject(
|
||||
new Error(`Raw request "${method}" timed out after ${timeoutMs} ms`),
|
||||
);
|
||||
}, timeoutMs);
|
||||
this.pendingRawWireRequests.set(id, { resolve, reject, timer });
|
||||
transport.send(message).catch((err: unknown) => {
|
||||
|
|
@ -4443,7 +4446,10 @@ export class InspectorClient extends InspectorClientEventTarget {
|
|||
this.modernReconnectTimer = undefined;
|
||||
// Disconnect/unsubscribe may have raced the timer — bail if the reconnect
|
||||
// is no longer wanted.
|
||||
if (isTerminalStatus(this.status) || this.subscribedResources.size === 0) {
|
||||
if (
|
||||
isTerminalStatus(this.status) ||
|
||||
this.subscribedResources.size === 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
this.refreshModernSubscription(true).catch(() =>
|
||||
|
|
|
|||
|
|
@ -32,4 +32,4 @@ export function createAuthChallengeInterceptFetch(
|
|||
`MCP auth challenge (${response.status})`,
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
import type { SecretStore } from "../../auth/node/secret-store.js";
|
||||
import {
|
||||
expectedSecretFields,
|
||||
mergeSecretsIntoStored,
|
||||
} from "../serverList.js";
|
||||
import { expectedSecretFields, mergeSecretsIntoStored } from "../serverList.js";
|
||||
import type { MCPConfig } from "../types.js";
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -72,7 +72,10 @@ export class ManagedRequestorTasksState extends TypedEventTarget<ManagedRequesto
|
|||
// A status update is ignored when the task was dismissed (clearCompleted)
|
||||
// or when the user cancelled it and the update isn't itself "cancelled" —
|
||||
// the deliberate cancel wins over a late completed/working update.
|
||||
const shouldIgnoreUpdate = (taskId: string, status: Task["status"]): boolean =>
|
||||
const shouldIgnoreUpdate = (
|
||||
taskId: string,
|
||||
status: Task["status"],
|
||||
): boolean =>
|
||||
this.dismissedTaskIds.has(taskId) ||
|
||||
(this.cancelledTaskIds.has(taskId) && status !== "cancelled");
|
||||
const onTaskStatusChange = (
|
||||
|
|
@ -200,7 +203,9 @@ export class ManagedRequestorTasksState extends TypedEventTarget<ManagedRequesto
|
|||
* whole refresh. No known tasks ⇒ a no-op refresh (the correct "no server
|
||||
* list" semantics).
|
||||
*/
|
||||
private async refreshModern(client: InspectorClientProtocol): Promise<Task[]> {
|
||||
private async refreshModern(
|
||||
client: InspectorClientProtocol,
|
||||
): Promise<Task[]> {
|
||||
const ids = this.tasks
|
||||
.map((t) => t.taskId)
|
||||
.filter((id) => !this.dismissedTaskIds.has(id));
|
||||
|
|
|
|||
|
|
@ -25,7 +25,10 @@ import type {
|
|||
InspectorResourceSubscription,
|
||||
ResourceSubscriptionStreamState,
|
||||
} from "../types.js";
|
||||
import { isTerminalStatus, INACTIVE_SUBSCRIPTION_STREAM_STATE } from "../types.js";
|
||||
import {
|
||||
isTerminalStatus,
|
||||
INACTIVE_SUBSCRIPTION_STREAM_STATE,
|
||||
} from "../types.js";
|
||||
import type { Resource } from "@modelcontextprotocol/client";
|
||||
import {
|
||||
TypedEventTarget,
|
||||
|
|
|
|||
|
|
@ -583,8 +583,7 @@ export const MODERN_LOG_LEVELS: ModernLogLevel[] = [
|
|||
/** Runtime guard for the {@link ModernLogLevel} literal (hand-edited files). */
|
||||
export function isModernLogLevel(value: unknown): value is ModernLogLevel {
|
||||
return (
|
||||
typeof value === "string" &&
|
||||
(MODERN_LOG_LEVELS as string[]).includes(value)
|
||||
typeof value === "string" && (MODERN_LOG_LEVELS as string[]).includes(value)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue