mcprigor 1.4.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/README.md +21 -4
  2. package/dist/audit.d.ts +44 -0
  3. package/dist/audit.d.ts.map +1 -0
  4. package/dist/audit.js +157 -0
  5. package/dist/audit.js.map +1 -0
  6. package/dist/cli.js +243 -10
  7. package/dist/cli.js.map +1 -1
  8. package/dist/composition.d.ts +42 -0
  9. package/dist/composition.d.ts.map +1 -0
  10. package/dist/composition.js +130 -0
  11. package/dist/composition.js.map +1 -0
  12. package/dist/coverage.d.ts +33 -0
  13. package/dist/coverage.d.ts.map +1 -0
  14. package/dist/coverage.js +83 -0
  15. package/dist/coverage.js.map +1 -0
  16. package/dist/export.d.ts +4 -0
  17. package/dist/export.d.ts.map +1 -1
  18. package/dist/export.js +56 -0
  19. package/dist/export.js.map +1 -1
  20. package/dist/index.d.ts +5 -0
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +5 -0
  23. package/dist/index.js.map +1 -1
  24. package/dist/language.js +1 -1
  25. package/dist/language.js.map +1 -1
  26. package/dist/loader.d.ts.map +1 -1
  27. package/dist/loader.js +4 -1
  28. package/dist/loader.js.map +1 -1
  29. package/dist/monitor.d.ts +22 -0
  30. package/dist/monitor.d.ts.map +1 -0
  31. package/dist/monitor.js +71 -0
  32. package/dist/monitor.js.map +1 -0
  33. package/dist/oauth.d.ts +73 -0
  34. package/dist/oauth.d.ts.map +1 -0
  35. package/dist/oauth.js +144 -0
  36. package/dist/oauth.js.map +1 -0
  37. package/dist/perf.d.ts +37 -0
  38. package/dist/perf.d.ts.map +1 -0
  39. package/dist/perf.js +90 -0
  40. package/dist/perf.js.map +1 -0
  41. package/dist/publish.d.ts +19 -0
  42. package/dist/publish.d.ts.map +1 -0
  43. package/dist/publish.js +58 -0
  44. package/dist/publish.js.map +1 -0
  45. package/dist/qa-language.d.ts.map +1 -1
  46. package/dist/qa-language.js +75 -3
  47. package/dist/qa-language.js.map +1 -1
  48. package/dist/reporters.d.ts +3 -1
  49. package/dist/reporters.d.ts.map +1 -1
  50. package/dist/reporters.js +21 -3
  51. package/dist/reporters.js.map +1 -1
  52. package/dist/runner.d.ts +7 -0
  53. package/dist/runner.d.ts.map +1 -1
  54. package/dist/runner.js +53 -15
  55. package/dist/runner.js.map +1 -1
  56. package/dist/schema.d.ts +66 -0
  57. package/dist/schema.d.ts.map +1 -1
  58. package/dist/schema.js +21 -1
  59. package/dist/schema.js.map +1 -1
  60. package/dist/session.d.ts +2 -1
  61. package/dist/session.d.ts.map +1 -1
  62. package/dist/session.js +7 -3
  63. package/dist/session.js.map +1 -1
  64. package/dist/timeline.d.ts +18 -0
  65. package/dist/timeline.d.ts.map +1 -0
  66. package/dist/timeline.js +59 -0
  67. package/dist/timeline.js.map +1 -0
  68. package/dist/types.d.ts +29 -0
  69. package/dist/types.d.ts.map +1 -1
  70. package/dist/version.d.ts +1 -1
  71. package/dist/version.js +1 -1
  72. package/dist/workspace.d.ts.map +1 -1
  73. package/dist/workspace.js +35 -3
  74. package/dist/workspace.js.map +1 -1
  75. package/docs/AUTHENTICATION.md +213 -0
  76. package/docs/CLI-REFERENCE.md +123 -2
  77. package/docs/COVERAGE.md +37 -0
  78. package/docs/ENGINEER-SETUP.md +1 -1
  79. package/docs/EVIDENCE.md +11 -0
  80. package/docs/GETTING-STARTED.md +1 -1
  81. package/docs/GITHUB-ACTION.md +82 -0
  82. package/docs/LANGUAGE-SPEC.md +64 -7
  83. package/docs/MCP-SERVER.md +1 -1
  84. package/docs/MONITORING.md +62 -0
  85. package/docs/MULTI-SERVER-COMPOSITIONS.md +103 -0
  86. package/docs/{PLAIN-LANGUAGE-COOKBOOK.md → NATURAL-LANGUAGE-COOKBOOK.md} +63 -4
  87. package/docs/PERFORMANCE-GOVERNANCE.md +85 -0
  88. package/docs/PUBLISHING.md +53 -0
  89. package/docs/QA-GUIDE.md +2 -2
  90. package/docs/QA-WORKSPACE.md +5 -1
  91. package/docs/README.md +10 -2
  92. package/docs/SECURITY-AUDIT.md +77 -0
  93. package/editors/mcpr-language.json +2 -2
  94. package/editors/vscode/package.json +1 -1
  95. package/editors/vscode/syntaxes/mcpr.tmLanguage.json +2 -2
  96. package/package.json +1 -2
  97. package/workspace-assets/app.js +35 -4
  98. package/workspace-assets/index.html +4 -1
  99. package/workspace-assets/style.css +2 -0
@@ -1 +1 @@
1
- {"version":3,"file":"language.js","sourceRoot":"","sources":["../src/language.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"language.js","sourceRoot":"","sources":["../src/language.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAMxC,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAmB5D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAUpE"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAMxC,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAmB5D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAYpE"}
package/dist/loader.js CHANGED
@@ -34,11 +34,14 @@ export function validateSuite(value) {
34
34
  const detail = (validate.errors ?? []).map(formatError).join("; ");
35
35
  throw new Error(`MCP-CONFIG-003 Invalid suite: ${detail}`);
36
36
  }
37
+ const suite = value;
37
38
  const names = new Set();
38
- for (const test of value.tests) {
39
+ for (const test of suite.tests) {
39
40
  if (names.has(test.name))
40
41
  throw new Error(`MCP-CONFIG-004 Duplicate test name: ${test.name}`);
41
42
  names.add(test.name);
43
+ if (test.server && !suite.servers?.[test.server])
44
+ throw new Error(`MCP-CONFIG-007 Test “${test.name}” selects unknown server “${test.server}”`);
42
45
  }
43
46
  }
44
47
  function formatError(error) {
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { RunResult } from "./types.js";
2
+ export interface MonitorOptions {
3
+ cwd?: string;
4
+ everyMs: number;
5
+ notify?: string;
6
+ notifyOn?: "failure" | "recovery" | "change" | "always";
7
+ maxRuns?: number;
8
+ signal?: AbortSignal;
9
+ onRun?: (event: MonitorEvent) => void;
10
+ }
11
+ export interface MonitorEvent {
12
+ run: number;
13
+ suite: string;
14
+ result: RunResult;
15
+ previousStatus?: RunResult["status"];
16
+ notification?: "failure" | "recovery" | "change" | "always";
17
+ }
18
+ export declare function parseDuration(value: string): number;
19
+ /** Run immediately, then on a fixed interval until aborted or maxRuns. */
20
+ export declare function monitorSuite(file: string, options: MonitorOptions): Promise<MonitorEvent[]>;
21
+ export declare function monitorLine(event: MonitorEvent): string;
22
+ //# sourceMappingURL=monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor.d.ts","sourceRoot":"","sources":["../src/monitor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAS,MAAM,YAAY,CAAC;AAEnD,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;CACvC;AACD,MAAM,WAAW,YAAY;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,CAAC;IAAC,cAAc,CAAC,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;IAAC,YAAY,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,QAAQ,GAAG,QAAQ,CAAA;CAAE;AAElL,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOnD;AAED,0EAA0E;AAC1E,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAgBjG;AAoBD,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAGvD"}
@@ -0,0 +1,71 @@
1
+ import { join, relative, resolve } from "node:path";
2
+ import { loadTestFile } from "./qa-loader.js";
3
+ import { runSuite } from "./runner.js";
4
+ import { appendHistory } from "./workspace.js";
5
+ export function parseDuration(value) {
6
+ const match = value.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h)$/i);
7
+ if (!match)
8
+ throw new Error("MCP-MONITOR-001 --every must be a duration such as 30s, 15m, or 1h");
9
+ const amount = Number(match[1]);
10
+ const factor = { ms: 1, s: 1000, m: 60_000, h: 3_600_000 }[match[2].toLowerCase()];
11
+ const result = amount * factor;
12
+ if (!Number.isFinite(result) || result < 1000)
13
+ throw new Error("MCP-MONITOR-001 --every must be at least 1s");
14
+ return result;
15
+ }
16
+ /** Run immediately, then on a fixed interval until aborted or maxRuns. */
17
+ export async function monitorSuite(file, options) {
18
+ const cwd = options.cwd ?? process.cwd();
19
+ const absolute = resolve(cwd, file);
20
+ const suitePath = relative(cwd, absolute);
21
+ const events = [];
22
+ let previous;
23
+ for (let run = 1; !options.signal?.aborted && (!options.maxRuns || run <= options.maxRuns); run++) {
24
+ const suite = await loadTestFile(absolute);
25
+ requireRemoteTarget(suite);
26
+ const result = await runSuite(suite, { cwd });
27
+ await appendHistory(join(cwd, ".mcprigor", "workspace-history.jsonl"), { at: new Date().toISOString(), mode: "test", suite: suitePath, status: result.status, durationMs: result.durationMs, tests: result.tests.map((test) => ({ name: test.name, status: test.status, durationMs: test.durationMs, ...(test.error ? { error: test.error } : {}) })) });
28
+ const kind = notificationKind(result.status, previous, options.notifyOn ?? "change");
29
+ const event = { run, suite: suitePath, result, previousStatus: previous, ...(kind ? { notification: kind } : {}) };
30
+ events.push(event);
31
+ options.onRun?.(event);
32
+ if (kind && options.notify)
33
+ await notifyWebhook(options.notify, event, kind);
34
+ previous = result.status;
35
+ if (options.maxRuns && run >= options.maxRuns)
36
+ break;
37
+ await wait(options.everyMs, options.signal);
38
+ }
39
+ return events;
40
+ }
41
+ function requireRemoteTarget(suite) {
42
+ if (suite.target.transport !== "streamable-http")
43
+ throw new Error("MCP-MONITOR-002 monitor requires an HTTP suite target; scheduled monitoring will not repeatedly spawn local commands");
44
+ }
45
+ function notificationKind(status, previous, policy) {
46
+ if (policy === "always")
47
+ return "always";
48
+ if (policy === "failure")
49
+ return status === "failed" ? "failure" : undefined;
50
+ if (policy === "recovery")
51
+ return previous === "failed" && status === "passed" ? "recovery" : undefined;
52
+ if (previous === undefined)
53
+ return status === "failed" ? "failure" : undefined;
54
+ if (status !== previous)
55
+ return status === "passed" ? "recovery" : "failure";
56
+ return undefined;
57
+ }
58
+ async function notifyWebhook(url, event, kind) {
59
+ const payload = { source: "mcprigor", event: `monitor.${kind}`, suite: event.suite, run: event.run, status: event.result.status, startedAt: event.result.startedAt, durationMs: event.result.durationMs, summary: event.result.summary, failures: event.result.tests.filter((test) => test.status === "failed").map((test) => ({ name: test.name, error: test.error })) };
60
+ const response = await fetch(url, { method: "POST", headers: { "content-type": "application/json", "user-agent": "mcprigor-monitor" }, body: JSON.stringify(payload), signal: AbortSignal.timeout(15_000) });
61
+ if (!response.ok)
62
+ throw new Error(`MCP-MONITOR-003 Webhook returned HTTP ${response.status}`);
63
+ }
64
+ function wait(ms, signal) { return new Promise((resolveWait) => { if (signal?.aborted)
65
+ return resolveWait(); const timer = setTimeout(resolveWait, ms); timer.unref?.(); signal?.addEventListener("abort", () => { clearTimeout(timer); resolveWait(); }, { once: true }); }); }
66
+ export function monitorLine(event) {
67
+ const summary = event.result.summary;
68
+ const mark = event.result.status === "passed" ? "✓" : "✗";
69
+ return `${new Date().toISOString()} ${mark} run ${event.run}: ${event.result.status} — ${summary.passed} passed, ${summary.failed} failed, ${summary.skipped} skipped (${event.result.durationMs}ms)${event.notification ? ` — notified ${event.notification}` : ""}`;
70
+ }
71
+ //# sourceMappingURL=monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor.js","sourceRoot":"","sources":["../src/monitor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import type { OAuthConfig } from "./types.js";
2
+ /**
3
+ * Interactive browser-redirect OAuth for MCP Rigor.
4
+ *
5
+ * The login runs once per target at suite start: the SDK transport drives OIDC
6
+ * discovery + PKCE, MCP Rigor opens the system browser, a loopback HTTP server
7
+ * captures the authorization code, and the resulting session (with the SDK's
8
+ * automatic refresh) is carried into every test in the same process. Nothing is
9
+ * written to disk — tokens live only in this in-memory provider for the run.
10
+ */
11
+ type OAuthTokens = {
12
+ access_token: string;
13
+ token_type?: string;
14
+ expires_in?: number;
15
+ refresh_token?: string;
16
+ scope?: string;
17
+ id_token?: string;
18
+ };
19
+ type ClientInformation = {
20
+ client_id: string;
21
+ client_secret?: string;
22
+ [k: string]: unknown;
23
+ };
24
+ /** In-memory OAuthClientProvider. Holds tokens, PKCE verifier, and (optionally DCR-registered) client info for one target, for one process. */
25
+ export declare class InMemoryOAuthProvider {
26
+ private readonly config;
27
+ private _tokens?;
28
+ private _verifier?;
29
+ private _client?;
30
+ private _authUrl?;
31
+ readonly redirectUrl: string;
32
+ private readonly _redirectPort;
33
+ constructor(config: OAuthConfig, redirectPort: number);
34
+ get clientMetadata(): {
35
+ scope?: string | undefined;
36
+ client_name: string;
37
+ redirect_uris: string[];
38
+ grant_types: string[];
39
+ response_types: string[];
40
+ token_endpoint_auth_method: string;
41
+ };
42
+ state(): string;
43
+ clientInformation(): ClientInformation | undefined;
44
+ saveClientInformation(info: ClientInformation): void;
45
+ tokens(): OAuthTokens | undefined;
46
+ saveTokens(tokens: OAuthTokens): void;
47
+ redirectToAuthorization(url: URL): void;
48
+ saveCodeVerifier(verifier: string): void;
49
+ codeVerifier(): string;
50
+ /** The authorization URL captured during the failed first connect, if any. */
51
+ pendingAuthorizationUrl(): URL | undefined;
52
+ /** Access token currently held (for redaction). */
53
+ currentAccessToken(): string | undefined;
54
+ get scope(): string | undefined;
55
+ get redirectPort(): number;
56
+ }
57
+ export interface LoginOptions {
58
+ /** Override the browser opener (tests inject a fake user agent). */
59
+ openBrowser?: (url: string) => void;
60
+ /** Where human-readable prompts are written. Defaults to stderr. */
61
+ notify?: (message: string) => void;
62
+ /** Milliseconds to wait for the user to complete the browser flow. */
63
+ timeoutMs?: number;
64
+ }
65
+ /**
66
+ * Run the interactive browser-redirect OAuth flow for one target and return a
67
+ * provider primed with the resulting in-memory session. The provider is then
68
+ * reused by every test session, so refresh happens automatically and the login
69
+ * prompt appears only once.
70
+ */
71
+ export declare function interactiveLogin(serverUrl: string, provider: InMemoryOAuthProvider, options?: LoginOptions): Promise<InMemoryOAuthProvider>;
72
+ export {};
73
+ //# sourceMappingURL=oauth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;GAQG;AAEH,KAAK,WAAW,GAAG;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AACjJ,KAAK,iBAAiB,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAE7F,+IAA+I;AAC/I,qBAAa,qBAAqB;IAQpB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPnC,OAAO,CAAC,OAAO,CAAC,CAAc;IAC9B,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,OAAO,CAAC,CAAoB;IACpC,OAAO,CAAC,QAAQ,CAAC,CAAM;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;gBAEV,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM;IAMtE,IAAI,cAAc;;;;;;;MASjB;IACD,KAAK,IAAI,MAAM;IACf,iBAAiB,IAAI,iBAAiB,GAAG,SAAS;IAClD,qBAAqB,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI;IACpD,MAAM,IAAI,WAAW,GAAG,SAAS;IACjC,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IACrC,uBAAuB,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IACvC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IACxC,YAAY,IAAI,MAAM;IAEtB,8EAA8E;IAC9E,uBAAuB,IAAI,GAAG,GAAG,SAAS;IAC1C,mDAAmD;IACnD,kBAAkB,IAAI,MAAM,GAAG,SAAS;IACxC,IAAI,KAAK,IAAI,MAAM,GAAG,SAAS,CAA8B;IAC7D,IAAI,YAAY,IAAI,MAAM,CAA+B;CAC1D;AAUD,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,oEAAoE;IACpE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA0BD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,qBAAqB,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA6BrJ"}
package/dist/oauth.js ADDED
@@ -0,0 +1,144 @@
1
+ import { createServer } from "node:http";
2
+ import { spawn } from "node:child_process";
3
+ import { randomBytes } from "node:crypto";
4
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
5
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
6
+ import { UnauthorizedError } from "@modelcontextprotocol/sdk/client/auth.js";
7
+ import { RigorError } from "./errors.js";
8
+ /** In-memory OAuthClientProvider. Holds tokens, PKCE verifier, and (optionally DCR-registered) client info for one target, for one process. */
9
+ export class InMemoryOAuthProvider {
10
+ config;
11
+ _tokens;
12
+ _verifier;
13
+ _client;
14
+ _authUrl;
15
+ redirectUrl;
16
+ _redirectPort;
17
+ constructor(config, redirectPort) {
18
+ this.config = config;
19
+ this._redirectPort = redirectPort;
20
+ this.redirectUrl = `http://127.0.0.1:${redirectPort}/callback`;
21
+ if (config.clientId)
22
+ this._client = { client_id: config.clientId, ...(config.clientSecret ? { client_secret: config.clientSecret } : {}) };
23
+ }
24
+ get clientMetadata() {
25
+ return {
26
+ client_name: "MCP Rigor",
27
+ redirect_uris: [this.redirectUrl],
28
+ grant_types: ["authorization_code", "refresh_token"],
29
+ response_types: ["code"],
30
+ token_endpoint_auth_method: this.config.clientSecret ? "client_secret_post" : "none",
31
+ ...(this.config.scope ? { scope: this.config.scope } : {}),
32
+ };
33
+ }
34
+ state() { return randomBytes(16).toString("hex"); }
35
+ clientInformation() { return this._client; }
36
+ saveClientInformation(info) { this._client = info; }
37
+ tokens() { return this._tokens; }
38
+ saveTokens(tokens) { this._tokens = tokens; }
39
+ redirectToAuthorization(url) { this._authUrl = url; }
40
+ saveCodeVerifier(verifier) { this._verifier = verifier; }
41
+ codeVerifier() { if (!this._verifier)
42
+ throw new RigorError("initialization", "MCP-OAUTH-003", "No PKCE code verifier was prepared before authorization."); return this._verifier; }
43
+ /** The authorization URL captured during the failed first connect, if any. */
44
+ pendingAuthorizationUrl() { return this._authUrl; }
45
+ /** Access token currently held (for redaction). */
46
+ currentAccessToken() { return this._tokens?.access_token; }
47
+ get scope() { return this.config.scope; }
48
+ get redirectPort() { return this._redirectPort; }
49
+ }
50
+ /** Spawn the platform browser opener; never throws (headless users paste the URL that is always printed). */
51
+ function openBrowser(url) {
52
+ const platform = process.platform;
53
+ const command = platform === "darwin" ? "open" : platform === "win32" ? "cmd" : "xdg-open";
54
+ const args = platform === "win32" ? ["/c", "start", "", url] : [url];
55
+ try {
56
+ const child = spawn(command, args, { stdio: "ignore", detached: true });
57
+ child.on("error", () => { });
58
+ child.unref();
59
+ }
60
+ catch { /* headless: URL is printed */ }
61
+ }
62
+ /** Start the loopback listener and resolve with the authorization callback query. */
63
+ function awaitCallback(port, timeoutMs) {
64
+ let settle;
65
+ let fail;
66
+ const done = new Promise((resolve, reject) => { settle = resolve; fail = reject; });
67
+ const server = createServer((req, res) => {
68
+ const url = new URL(req.url ?? "/", `http://127.0.0.1:${port}`);
69
+ if (url.pathname !== "/callback") {
70
+ res.writeHead(404).end("Not found");
71
+ return;
72
+ }
73
+ const error = url.searchParams.get("error") ?? undefined;
74
+ const page = error
75
+ ? `<h1>Authentication failed</h1><p>${escapeHtml(url.searchParams.get("error_description") ?? error)}</p><p>You can close this tab and return to the terminal.</p>`
76
+ : `<h1>Authentication complete</h1><p>MCP Rigor captured your session. You can close this tab and return to the terminal.</p>`;
77
+ res.writeHead(200, { "content-type": "text/html; charset=utf-8" }).end(`<!doctype html><meta charset="utf-8"><title>MCP Rigor</title><style>body{font:16px system-ui;margin:15% auto;max-width:32rem;text-align:center;color:#0b1a12}h1{color:#0a7d33}</style>${page}`);
78
+ settle({ code: url.searchParams.get("code") ?? undefined, state: url.searchParams.get("state") ?? undefined, error, errorDescription: url.searchParams.get("error_description") ?? undefined });
79
+ });
80
+ server.on("error", (err) => fail(err instanceof Error ? err : new Error(String(err))));
81
+ server.listen(port, "127.0.0.1");
82
+ const timer = setTimeout(() => fail(new RigorError("timeout", "MCP-OAUTH-002", `Timed out after ${Math.round(timeoutMs / 1000)}s waiting for the browser authorization to complete.`)), timeoutMs);
83
+ return { done: done.finally(() => { clearTimeout(timer); server.close(); }), close: () => { clearTimeout(timer); server.close(); } };
84
+ }
85
+ function escapeHtml(value) { return value.replace(/[&<>"']/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" }[c])); }
86
+ /**
87
+ * Run the interactive browser-redirect OAuth flow for one target and return a
88
+ * provider primed with the resulting in-memory session. The provider is then
89
+ * reused by every test session, so refresh happens automatically and the login
90
+ * prompt appears only once.
91
+ */
92
+ export async function interactiveLogin(serverUrl, provider, options = {}) {
93
+ const notify = options.notify ?? ((message) => process.stderr.write(message + "\n"));
94
+ const timeoutMs = options.timeoutMs ?? 300_000;
95
+ const listener = awaitCallback(provider.redirectPort, timeoutMs);
96
+ // First connect: the SDK sends `initialize`, receives 401, performs discovery + PKCE,
97
+ // then throws Unauthorized after calling redirectToAuthorization().
98
+ const probe = new StreamableHTTPClientTransport(new URL(serverUrl), { authProvider: provider });
99
+ const probeClient = new Client({ name: "mcprigor-login", version: "0" }, { capabilities: {} });
100
+ try {
101
+ await probeClient.connect(probe);
102
+ // Already authorized (a token was somehow present) — nothing interactive to do.
103
+ listener.close();
104
+ await probeClient.close().catch(() => { });
105
+ return provider;
106
+ }
107
+ catch (error) {
108
+ if (!(error instanceof UnauthorizedError)) {
109
+ listener.close();
110
+ await probeClient.close().catch(() => { });
111
+ throw wrap(error);
112
+ }
113
+ }
114
+ const authUrl = provider.pendingAuthorizationUrl();
115
+ if (!authUrl) {
116
+ listener.close();
117
+ throw new RigorError("initialization", "MCP-OAUTH-001", "The server did not provide an OAuth authorization URL. Confirm it advertises OAuth protected-resource metadata.");
118
+ }
119
+ notify(`\nMCP Rigor needs you to sign in to ${new URL(serverUrl).host}.`);
120
+ notify(`Opening your browser. If it does not open, visit this URL:\n ${authUrl.toString()}\n`);
121
+ (options.openBrowser ?? openBrowser)(authUrl.toString());
122
+ const callback = await listener.done;
123
+ if (callback.error)
124
+ throw new RigorError("initialization", "MCP-OAUTH-004", `Authorization was denied: ${callback.errorDescription ?? callback.error}`);
125
+ if (!callback.code)
126
+ throw new RigorError("initialization", "MCP-OAUTH-001", "The authorization redirect did not include a code.");
127
+ try {
128
+ await probe.finishAuth(callback.code);
129
+ }
130
+ catch (error) {
131
+ await probeClient.close().catch(() => { });
132
+ throw wrap(error);
133
+ }
134
+ await probeClient.close().catch(() => { });
135
+ if (!provider.currentAccessToken())
136
+ throw new RigorError("initialization", "MCP-OAUTH-001", "Token exchange completed without returning an access token.");
137
+ notify("Sign-in complete. Running tests with the authorized session.\n");
138
+ return provider;
139
+ }
140
+ function wrap(error) {
141
+ const message = error instanceof Error ? error.message : String(error);
142
+ return new RigorError("initialization", "MCP-OAUTH-005", `Interactive OAuth failed: ${message}`, undefined, error);
143
+ }
144
+ //# sourceMappingURL=oauth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../src/oauth.ts"],"names":[],"mappings":"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"}
package/dist/perf.d.ts ADDED
@@ -0,0 +1,37 @@
1
+ import type { PerfBudget, RunResult, Suite } from "./types.js";
2
+ import type { HistoryEntry } from "./workspace.js";
3
+ export interface BudgetOutcome {
4
+ budget: PerfBudget;
5
+ test: string;
6
+ samples: number;
7
+ measuredMs: number;
8
+ withinBudget: boolean;
9
+ /** Not enough recorded runs yet to make the call. */
10
+ insufficient: boolean;
11
+ }
12
+ export interface RegressionOutcome {
13
+ test: string;
14
+ baselineP50: number;
15
+ currentMs: number;
16
+ ratio: number;
17
+ regressed: boolean;
18
+ }
19
+ /** Nearest-rank percentile on a sorted copy; deterministic, no interpolation surprises. */
20
+ export declare function percentile(values: number[], pct: number): number;
21
+ /** Evaluate every suite budget against history + the current run. */
22
+ export declare function checkBudgets(suite: Suite, entries: HistoryEntry[], suitePath: string | undefined, current: RunResult): BudgetOutcome[];
23
+ /**
24
+ * Latency regression gate: compare each passed test in the current run against
25
+ * the median of its recent history. Regressed when slower than
26
+ * max(baseline * ratio, baseline + minDeltaMs) — the floor keeps micro-tests
27
+ * (3ms -> 6ms) from tripping the gate.
28
+ */
29
+ export declare function checkRegressions(entries: HistoryEntry[], suitePath: string | undefined, current: RunResult, options?: {
30
+ ratio?: number;
31
+ minSamples?: number;
32
+ minDeltaMs?: number;
33
+ window?: number;
34
+ }): RegressionOutcome[];
35
+ export declare function budgetReport(outcomes: BudgetOutcome[]): string;
36
+ export declare function regressionReport(outcomes: RegressionOutcome[]): string;
37
+ //# sourceMappingURL=perf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perf.d.ts","sourceRoot":"","sources":["../src/perf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,qDAAqD;IACrD,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,2FAA2F;AAC3F,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAKhE;AAmBD,qEAAqE;AACrE,wBAAgB,YAAY,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,SAAS,GAAG,aAAa,EAAE,CAYtI;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,iBAAiB,EAAE,CAezN;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,MAAM,CAU9D;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAMtE"}
package/dist/perf.js ADDED
@@ -0,0 +1,90 @@
1
+ /** Nearest-rank percentile on a sorted copy; deterministic, no interpolation surprises. */
2
+ export function percentile(values, pct) {
3
+ if (!values.length)
4
+ return 0;
5
+ const sorted = [...values].sort((a, b) => a - b);
6
+ const rank = Math.ceil((Math.min(100, Math.max(0, pct)) / 100) * sorted.length);
7
+ return sorted[Math.max(0, rank - 1)];
8
+ }
9
+ /** Collect recent durations per test for one suite from history plus the current run. */
10
+ function durationsFor(entries, suitePath, testName, window, current) {
11
+ const scoped = suitePath ? entries.filter((entry) => entry.suite === suitePath) : entries;
12
+ const values = [];
13
+ for (const entry of scoped)
14
+ for (const test of entry.tests ?? []) {
15
+ if (test.status !== "passed")
16
+ continue;
17
+ if (testName !== "*" && test.name !== testName)
18
+ continue;
19
+ if (typeof test.durationMs === "number")
20
+ values.push(test.durationMs);
21
+ }
22
+ if (current)
23
+ for (const test of current.tests) {
24
+ if (test.status !== "passed")
25
+ continue;
26
+ if (testName !== "*" && test.name !== testName)
27
+ continue;
28
+ values.push(test.durationMs);
29
+ }
30
+ return values.slice(-window);
31
+ }
32
+ /** Evaluate every suite budget against history + the current run. */
33
+ export function checkBudgets(suite, entries, suitePath, current) {
34
+ const outcomes = [];
35
+ for (const budget of suite.budgets ?? []) {
36
+ const window = budget.window ?? 20;
37
+ const names = budget.test === "*" ? [...new Set(current.tests.map((test) => test.name))] : [budget.test];
38
+ for (const test of names) {
39
+ const samples = durationsFor(entries, suitePath, test, window, current);
40
+ const measuredMs = percentile(samples, budget.percentile);
41
+ outcomes.push({ budget, test, samples: samples.length, measuredMs, withinBudget: measuredMs <= budget.maxMs, insufficient: samples.length < Math.min(3, window) });
42
+ }
43
+ }
44
+ return outcomes;
45
+ }
46
+ /**
47
+ * Latency regression gate: compare each passed test in the current run against
48
+ * the median of its recent history. Regressed when slower than
49
+ * max(baseline * ratio, baseline + minDeltaMs) — the floor keeps micro-tests
50
+ * (3ms -> 6ms) from tripping the gate.
51
+ */
52
+ export function checkRegressions(entries, suitePath, current, options) {
53
+ const ratio = options?.ratio ?? 1.5;
54
+ const minSamples = options?.minSamples ?? 5;
55
+ const minDeltaMs = options?.minDeltaMs ?? 50;
56
+ const window = options?.window ?? 50;
57
+ const outcomes = [];
58
+ for (const test of current.tests) {
59
+ if (test.status !== "passed")
60
+ continue;
61
+ const history = durationsFor(entries, suitePath, test.name, window);
62
+ if (history.length < minSamples)
63
+ continue;
64
+ const baselineP50 = percentile(history, 50);
65
+ const threshold = Math.max(baselineP50 * ratio, baselineP50 + minDeltaMs);
66
+ outcomes.push({ test: test.name, baselineP50, currentMs: test.durationMs, ratio: baselineP50 ? test.durationMs / baselineP50 : 0, regressed: test.durationMs > threshold });
67
+ }
68
+ return outcomes;
69
+ }
70
+ export function budgetReport(outcomes) {
71
+ const lines = ["", "Latency budgets:"];
72
+ for (const outcome of outcomes) {
73
+ const mark = outcome.insufficient ? "○" : outcome.withinBudget ? "✓" : "✗";
74
+ const detail = outcome.insufficient
75
+ ? `only ${outcome.samples} recorded sample${outcome.samples === 1 ? "" : "s"} — need more runs before this budget can be judged`
76
+ : `p${outcome.budget.percentile} ${outcome.measuredMs} ms over ${outcome.samples} samples (budget ${outcome.budget.maxMs} ms)`;
77
+ lines.push(`${mark} ${outcome.test}: ${detail}`);
78
+ }
79
+ return lines.join("\n");
80
+ }
81
+ export function regressionReport(outcomes) {
82
+ const regressed = outcomes.filter((outcome) => outcome.regressed);
83
+ if (!regressed.length)
84
+ return `\nLatency regression gate: ✓ no regressions (${outcomes.length} test${outcomes.length === 1 ? "" : "s"} compared against baseline)`;
85
+ const lines = ["", "Latency regression gate:"];
86
+ for (const outcome of regressed)
87
+ lines.push(`✗ ${outcome.test}: ${outcome.currentMs} ms vs baseline median ${outcome.baselineP50} ms (${outcome.ratio.toFixed(1)}x)`);
88
+ return lines.join("\n");
89
+ }
90
+ //# sourceMappingURL=perf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perf.js","sourceRoot":"","sources":["../src/perf.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export interface PublishFiles {
2
+ [path: string]: string;
3
+ }
4
+ export interface NetlifyOptions {
5
+ site: string;
6
+ token: string;
7
+ apiBase?: string;
8
+ timeoutMs?: number;
9
+ }
10
+ export interface PublishResult {
11
+ url: string;
12
+ deployId: string;
13
+ files: string[];
14
+ }
15
+ /** Deploy a small set of text files to Netlify using the dependency-free file-digest API. */
16
+ export declare function publishToNetlify(files: PublishFiles, options: NetlifyOptions): Promise<PublishResult>;
17
+ /** Write the bundle to a local directory when no hosting credentials are available. */
18
+ export declare function writeLocalBundle(files: PublishFiles, directory: string): Promise<string[]>;
19
+ //# sourceMappingURL=publish.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE;AACxD,MAAM,WAAW,cAAc;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE;AACrG,MAAM,WAAW,aAAa;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE;AAEjF,6FAA6F;AAC7F,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAqB3G;AAED,uFAAuF;AACvF,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAUhG"}