@descryy/mcp 0.4.0 → 0.6.0

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 (121) hide show
  1. package/dist/bin/descry-mcp.js +16 -2
  2. package/dist/bin/descry-mcp.js.map +1 -1
  3. package/dist/browser/driver.d.ts +105 -6
  4. package/dist/browser/driver.d.ts.map +1 -1
  5. package/dist/browser/driver.js +17 -3
  6. package/dist/browser/driver.js.map +1 -1
  7. package/dist/browser/evidence.d.ts +11 -0
  8. package/dist/browser/evidence.d.ts.map +1 -1
  9. package/dist/browser/evidence.js +64 -8
  10. package/dist/browser/evidence.js.map +1 -1
  11. package/dist/browser/fake-driver.d.ts +8 -0
  12. package/dist/browser/fake-driver.d.ts.map +1 -1
  13. package/dist/browser/fake-driver.js +26 -3
  14. package/dist/browser/fake-driver.js.map +1 -1
  15. package/dist/browser/playwright-driver.d.ts +68 -14
  16. package/dist/browser/playwright-driver.d.ts.map +1 -1
  17. package/dist/browser/playwright-driver.js +318 -38
  18. package/dist/browser/playwright-driver.js.map +1 -1
  19. package/dist/browser/provider.d.ts +10 -4
  20. package/dist/browser/provider.d.ts.map +1 -1
  21. package/dist/browser/provider.js +10 -4
  22. package/dist/browser/provider.js.map +1 -1
  23. package/dist/browser/scenario-runner.d.ts +9 -0
  24. package/dist/browser/scenario-runner.d.ts.map +1 -1
  25. package/dist/browser/scenario-runner.js +32 -2
  26. package/dist/browser/scenario-runner.js.map +1 -1
  27. package/dist/browser/tool-support.js +1 -1
  28. package/dist/browser/tool-support.js.map +1 -1
  29. package/dist/cancellation.d.ts +55 -0
  30. package/dist/cancellation.d.ts.map +1 -0
  31. package/dist/cancellation.js +76 -0
  32. package/dist/cancellation.js.map +1 -0
  33. package/dist/capped.d.ts +41 -0
  34. package/dist/capped.d.ts.map +1 -0
  35. package/dist/capped.js +35 -0
  36. package/dist/capped.js.map +1 -0
  37. package/dist/registry.d.ts +20 -1
  38. package/dist/registry.d.ts.map +1 -1
  39. package/dist/registry.js +71 -4
  40. package/dist/registry.js.map +1 -1
  41. package/dist/render.d.ts +92 -0
  42. package/dist/render.d.ts.map +1 -1
  43. package/dist/render.js +250 -5
  44. package/dist/render.js.map +1 -1
  45. package/dist/runtime-registry.d.ts +19 -1
  46. package/dist/runtime-registry.d.ts.map +1 -1
  47. package/dist/runtime-registry.js +88 -4
  48. package/dist/runtime-registry.js.map +1 -1
  49. package/dist/server.d.ts +19 -0
  50. package/dist/server.d.ts.map +1 -1
  51. package/dist/server.js +135 -11
  52. package/dist/server.js.map +1 -1
  53. package/dist/session.d.ts +22 -0
  54. package/dist/session.d.ts.map +1 -1
  55. package/dist/session.js +27 -1
  56. package/dist/session.js.map +1 -1
  57. package/dist/tools/analyze.d.ts +23 -3
  58. package/dist/tools/analyze.d.ts.map +1 -1
  59. package/dist/tools/analyze.js +35 -3
  60. package/dist/tools/analyze.js.map +1 -1
  61. package/dist/tools/browser-click.d.ts.map +1 -1
  62. package/dist/tools/browser-click.js +14 -0
  63. package/dist/tools/browser-click.js.map +1 -1
  64. package/dist/tools/browser-fill.d.ts.map +1 -1
  65. package/dist/tools/browser-fill.js +14 -0
  66. package/dist/tools/browser-fill.js.map +1 -1
  67. package/dist/tools/browser-navigate.d.ts.map +1 -1
  68. package/dist/tools/browser-navigate.js +14 -0
  69. package/dist/tools/browser-navigate.js.map +1 -1
  70. package/dist/tools/browser-run-scenario.d.ts.map +1 -1
  71. package/dist/tools/browser-run-scenario.js +12 -3
  72. package/dist/tools/browser-run-scenario.js.map +1 -1
  73. package/dist/tools/browser-save-scenario.d.ts.map +1 -1
  74. package/dist/tools/browser-save-scenario.js +109 -3
  75. package/dist/tools/browser-save-scenario.js.map +1 -1
  76. package/dist/tools/browser-start-session.d.ts.map +1 -1
  77. package/dist/tools/browser-start-session.js +43 -0
  78. package/dist/tools/browser-start-session.js.map +1 -1
  79. package/dist/tools/browser-type.d.ts.map +1 -1
  80. package/dist/tools/browser-type.js +14 -0
  81. package/dist/tools/browser-type.js.map +1 -1
  82. package/dist/tools/contracts.d.ts +41 -10
  83. package/dist/tools/contracts.d.ts.map +1 -1
  84. package/dist/tools/contracts.js +117 -17
  85. package/dist/tools/contracts.js.map +1 -1
  86. package/dist/tools/cross-pr.d.ts +39 -10
  87. package/dist/tools/cross-pr.d.ts.map +1 -1
  88. package/dist/tools/cross-pr.js +113 -29
  89. package/dist/tools/cross-pr.js.map +1 -1
  90. package/dist/tools/git-diff.d.ts.map +1 -1
  91. package/dist/tools/git-diff.js +30 -2
  92. package/dist/tools/git-diff.js.map +1 -1
  93. package/dist/tools/impact.d.ts.map +1 -1
  94. package/dist/tools/impact.js +50 -2
  95. package/dist/tools/impact.js.map +1 -1
  96. package/dist/tools/observe-runtime.d.ts.map +1 -1
  97. package/dist/tools/observe-runtime.js +84 -4
  98. package/dist/tools/observe-runtime.js.map +1 -1
  99. package/dist/tools/observe-tests.d.ts +12 -0
  100. package/dist/tools/observe-tests.d.ts.map +1 -1
  101. package/dist/tools/observe-tests.js +92 -8
  102. package/dist/tools/observe-tests.js.map +1 -1
  103. package/dist/tools/pre-push.d.ts +40 -7
  104. package/dist/tools/pre-push.d.ts.map +1 -1
  105. package/dist/tools/pre-push.js +65 -23
  106. package/dist/tools/pre-push.js.map +1 -1
  107. package/dist/tools/scope.d.ts.map +1 -1
  108. package/dist/tools/scope.js +20 -4
  109. package/dist/tools/scope.js.map +1 -1
  110. package/dist/tools/validate.d.ts +40 -1
  111. package/dist/tools/validate.d.ts.map +1 -1
  112. package/dist/tools/validate.js +150 -27
  113. package/dist/tools/validate.js.map +1 -1
  114. package/dist/tools/verification-status.d.ts.map +1 -1
  115. package/dist/tools/verification-status.js +3 -3
  116. package/dist/tools/verification-status.js.map +1 -1
  117. package/dist/transport.d.ts +12 -1
  118. package/dist/transport.d.ts.map +1 -1
  119. package/dist/transport.js +30 -16
  120. package/dist/transport.js.map +1 -1
  121. package/package.json +22 -13
@@ -17,9 +17,10 @@
17
17
  import process from "node:process";
18
18
  import { createRequire } from "node:module";
19
19
  import { resolve } from "node:path";
20
- import { createMcpServer } from "../server.js";
20
+ import { createMcpServer, isOutOfBand } from "../server.js";
21
21
  import { Session } from "../session.js";
22
22
  import { serveStdio } from "../transport.js";
23
+ import { createPlaywrightBrowserDriver } from "../browser/playwright-driver.js";
23
24
  /**
24
25
  * The version this build actually is, read from the installed package rather
25
26
  * than written here.
@@ -57,9 +58,22 @@ async function main() {
57
58
  }
58
59
  const repoPath = resolve(args[0] ?? process.cwd());
59
60
  const session = await Session.open({ repoPath });
61
+ // The nine browser_* tools ask `session.browserBackend()` for a driver
62
+ // factory and get `BROWSER_BACKEND_NOT_INSTALLED` unless one is installed
63
+ // here — `Session` itself never defaults `#browserDriverFactory` away from
64
+ // null. Without this line the tools refuse unconditionally in every real
65
+ // MCP host regardless of what is installed: declaring the dependency in
66
+ // package.json makes `@descryy/runtime-browser` resolvable, not reachable.
67
+ // `createPlaywrightBrowserDriver` itself still turns a missing package, a
68
+ // failed import or a missing Chromium binary into a named refusal rather
69
+ // than a crash — this wiring does not change that.
70
+ session.useBrowserDriverFactory((options) => createPlaywrightBrowserDriver(options));
60
71
  const server = createMcpServer({ session, name: "descry", version: VERSION });
61
72
  try {
62
- await serveStdio({ stdin: process.stdin, stdout: process.stdout, stderr: process.stderr }, (line, transport) => server.dispatch(line, transport));
73
+ await serveStdio({ stdin: process.stdin, stdout: process.stdout, stderr: process.stderr }, (line, transport) => server.dispatch(line, transport),
74
+ // Without this, `notifications/cancelled` waits in the ordered queue
75
+ // behind the very call it cancels and can never do anything.
76
+ { isOutOfBand });
63
77
  return 0;
64
78
  }
65
79
  finally {
@@ -1 +1 @@
1
- {"version":3,"file":"descry-mcp.js","sourceRoot":"","sources":["../../src/bin/descry-mcp.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C;;;;;;;;;;GAUG;AACH,MAAM,OAAO,GAAW,CAAC,GAAW,EAAE;IACpC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,oBAAoB,CAA0B,CAAC;QAC1F,OAAO,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,0EAA0E;QAC1E,+DAA+D;QAC/D,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC,CAAC,EAAE,CAAC;AAEL,MAAM,KAAK,GAAG;;;;;;CAMb,CAAC;AAEF,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC5B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAE9E,IAAI,CAAC;QACH,MAAM,UAAU,CACd,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,EACxE,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CACtD,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;YAAS,CAAC;QACT,0EAA0E;QAC1E,kEAAkE;QAClE,EAAE;QACF,uEAAuE;QACvE,wEAAwE;QACxE,qEAAqE;QACrE,4DAA4D;QAC5D,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,IAAI,CACT,CAAC,IAAI,EAAE,EAAE;IACP,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;AAC1B,CAAC,EACD,CAAC,KAAc,EAAE,EAAE;IACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,eAAe,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CACzF,CAAC;IACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CACF,CAAC"}
1
+ {"version":3,"file":"descry-mcp.js","sourceRoot":"","sources":["../../src/bin/descry-mcp.ts"],"names":[],"mappings":"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"}
@@ -47,8 +47,21 @@ export interface SnapshotElement {
47
47
  * read by a human, **not** so a caller can act on it: every verb takes a
48
48
  * `ref`, never a selector, because a ref ties the action to a snapshot the
49
49
  * agent actually saw and a selector does not.
50
+ *
51
+ * Also what a scenario stores to find the element again in a *later*
52
+ * session (`scenario-resolve.ts`), which is the property that actually
53
+ * needs it to be durable — a value scoped to this one snapshot would defeat
54
+ * that the moment the generation counter moved on.
55
+ *
56
+ * **Null when no candidate resolves to exactly one element on the page.**
57
+ * A driver must never fabricate a selector that might not match, or might
58
+ * match the wrong thing — that is precision over recall (rule 2) applied
59
+ * here: an honest null beats a value that looks like a selector and isn't
60
+ * one. `browser_save_scenario` refuses to save a step naming such an
61
+ * element, by name, rather than writing a scenario doomed to fail at
62
+ * replay.
50
63
  */
51
- readonly selector: string;
64
+ readonly selector: string | null;
52
65
  }
53
66
  export interface PageSnapshot {
54
67
  readonly url: string;
@@ -86,24 +99,80 @@ export interface ObservedAction {
86
99
  readonly url: string;
87
100
  readonly at: string;
88
101
  }
102
+ /**
103
+ * What `rewriteScriptUrls` did with one script URL in a stack.
104
+ *
105
+ * Per URL rather than a summary, because partial mapping is the steady state:
106
+ * an application's own bundle maps, its CDN dependency does not, and a
107
+ * browser extension's frame never will. Collapsing that into a count would
108
+ * report a shortfall where there is a boundary, and would leave a caller
109
+ * unable to tell a misconfigured `documentRoot` from a third-party script it
110
+ * should ignore.
111
+ */
112
+ export interface ScriptUrlOutcome {
113
+ /** The URL as it appeared in the stack, `:line:column` suffix included. */
114
+ readonly url: string;
115
+ /** The on-disk file it was rewritten to, or null when it was left as a URL. */
116
+ readonly mapped: string | null;
117
+ /** Why it was left alone. Null exactly when `mapped` is set. */
118
+ readonly reason: string | null;
119
+ }
89
120
  export interface ObservedConsoleError {
90
121
  readonly text: string;
91
122
  /**
92
- * Raw stack text as the page produced it, or null. **Not yet rewritten to
93
- * real files and lines** — that is `rewriteScriptUrls`' job and it needs a
94
- * source-root resolver the driver does not have. The port carries the raw
95
- * text so the mapping happens once, above, where the repo root is known.
123
+ * The stack, rendered from parsed frames, or null.
124
+ *
125
+ * Already rewritten to real files and lines where that was possible:
126
+ * `rewriteScriptUrls` runs inside the runtime collector, on the stack text
127
+ * *before* the parser sees it, using the `resolveSourceRoot` the driver put
128
+ * on the collector context. What survives as an `http://` URL here is a
129
+ * frame that genuinely did not map, and `scriptUrlMapping` says why.
96
130
  */
97
131
  readonly stackText: string | null;
132
+ /**
133
+ * Per-URL mapping outcomes from the collector, empty when it attempted no
134
+ * mapping. **Empty is not "nothing mapped"** — it is "no rewrite ran",
135
+ * which happens with no stack parser configured, and the two must not be
136
+ * reported alike.
137
+ */
138
+ readonly scriptUrlMapping: readonly ScriptUrlOutcome[];
98
139
  readonly at: string;
99
140
  }
141
+ /**
142
+ * How a request's lifecycle actually ended, when the collector can tell.
143
+ *
144
+ * `status: null` used to carry two different facts at once: "this will never
145
+ * answer" and "it has not answered *yet*". `"pending"` splits the second one
146
+ * back out — a request still in flight when the observation window closed is
147
+ * neither a success nor a failure, and folding it into either taught a false
148
+ * positive on a perfectly healthy, still-loading page.
149
+ *
150
+ * - `"answered"` — a real status came back, carried in `status`.
151
+ * - `"unanswered"` — a real failure: Playwright's own `requestfailed` fired,
152
+ * or the page closed with this request outstanding.
153
+ * - `"pending"` — still in flight when the drain happened. Not a verdict
154
+ * either way; reported under its own key rather than as a failure.
155
+ */
156
+ export type RequestOutcome = "answered" | "unanswered" | "pending";
100
157
  export interface ObservedRequest {
101
158
  readonly method: string;
102
159
  readonly url: string;
103
160
  /** Null when the request produced no response at all, which is a different fact from a 500. */
104
161
  readonly status: number | null;
162
+ /**
163
+ * How this request's lifecycle ended, when the collector reports it.
164
+ *
165
+ * Optional on purpose: the field is `descry-runtime`'s browser collector to
166
+ * populate (a separate lane's work), and this port must not assume that
167
+ * build is running. Absent means no outcome information at all — see
168
+ * `isFailedRequest`, which degrades to its pre-existing status-only rule
169
+ * rather than mis-reading an older build's silence as a new fact.
170
+ */
171
+ readonly outcome?: RequestOutcome;
105
172
  /** The `fetch()` call site as raw text, when the initiator capture claimed one. Null is honest absence. */
106
173
  readonly stackText: string | null;
174
+ /** Per-URL mapping outcomes for that call site. See `ScriptUrlOutcome`. */
175
+ readonly scriptUrlMapping: readonly ScriptUrlOutcome[];
107
176
  /**
108
177
  * The same call site, parsed into frames with real file paths.
109
178
  *
@@ -116,7 +185,17 @@ export interface ObservedRequest {
116
185
  readonly stackTrace: StackTrace | null;
117
186
  readonly at: string;
118
187
  }
119
- /** A request that did not succeed. Mechanical, not a judgement: no response, or a 4xx/5xx status. */
188
+ /**
189
+ * A request that did not succeed. Mechanical, not a judgement.
190
+ *
191
+ * With no `outcome` reported (an older `descry-runtime` build), this keeps
192
+ * the original rule exactly: no response at all, or a 4xx/5xx status. With an
193
+ * `outcome`, `"pending"` is deliberately excluded — a request still in flight
194
+ * when the window closed is not evidence of anything — and `"unanswered"` is
195
+ * always a failure regardless of `status`, since Playwright's own
196
+ * `requestfailed` (or a page closing mid-request) is a stronger signal than
197
+ * an absent status by itself.
198
+ */
120
199
  export declare function isFailedRequest(request: ObservedRequest): boolean;
121
200
  /** Everything witnessed since the last drain. Raw — see this file's header. */
122
201
  export interface BrowserObservation {
@@ -131,6 +210,26 @@ export interface BrowserObservation {
131
210
  * The reply narrows to failures for readability; the correlation does not.
132
211
  */
133
212
  readonly requests: readonly ObservedRequest[];
213
+ /**
214
+ * Actions whose network activity had not finished when the driver stopped
215
+ * waiting.
216
+ *
217
+ * This exists because the alternative is the failure this surface is built
218
+ * to prevent. An action returns after a bounded wait; if a request it
219
+ * caused is still in flight at that bound, its evidence lands after the
220
+ * drain and is simply not in the reply — and a reply missing evidence looks
221
+ * exactly like a reply from a page that produced none. One is "nothing
222
+ * happened", the other is "I stopped looking", and rule 7 does not permit
223
+ * them to render the same. Anything in here means the observation for that
224
+ * action is incomplete and says so.
225
+ */
226
+ readonly unsettled: readonly UnsettledAction[];
227
+ }
228
+ export interface UnsettledAction {
229
+ readonly action: ObservedAction["action"];
230
+ readonly ref: string | null;
231
+ /** How long the driver waited before giving up, in ms. */
232
+ readonly waitedMs: number;
134
233
  }
135
234
  export declare const EMPTY_OBSERVATION: BrowserObservation;
136
235
  export interface BrowserLaunchOptions {
@@ -1 +1 @@
1
- {"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../src/browser/driver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../src/browser/driver.ts"],"names":[],"mappings":"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"}
@@ -36,11 +36,25 @@
36
36
  * Rule 1 holds here as everywhere — nothing in this file names a language, a
37
37
  * framework, or a file extension.
38
38
  */
39
- /** A request that did not succeed. Mechanical, not a judgement: no response, or a 4xx/5xx status. */
39
+ /**
40
+ * A request that did not succeed. Mechanical, not a judgement.
41
+ *
42
+ * With no `outcome` reported (an older `descry-runtime` build), this keeps
43
+ * the original rule exactly: no response at all, or a 4xx/5xx status. With an
44
+ * `outcome`, `"pending"` is deliberately excluded — a request still in flight
45
+ * when the window closed is not evidence of anything — and `"unanswered"` is
46
+ * always a failure regardless of `status`, since Playwright's own
47
+ * `requestfailed` (or a page closing mid-request) is a stronger signal than
48
+ * an absent status by itself.
49
+ */
40
50
  export function isFailedRequest(request) {
41
- return request.status === null || request.status >= 400;
51
+ if (request.outcome === undefined)
52
+ return request.status === null || request.status >= 400;
53
+ if (request.outcome === "pending")
54
+ return false;
55
+ return request.outcome === "unanswered" || (request.status !== null && request.status >= 400);
42
56
  }
43
- export const EMPTY_OBSERVATION = { actions: [], consoleErrors: [], requests: [] };
57
+ export const EMPTY_OBSERVATION = { actions: [], consoleErrors: [], requests: [], unsettled: [] };
44
58
  /** The browser died. Distinct from a closed session: a crash invalidates the id rather than ending it cleanly. */
45
59
  export class BrowserSessionCrashedError extends Error {
46
60
  sessionId;
@@ -1 +1 @@
1
- {"version":3,"file":"driver.js","sourceRoot":"","sources":["../../src/browser/driver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAyFH,qGAAqG;AACrG,MAAM,UAAU,eAAe,CAAC,OAAwB;IACtD,OAAO,OAAO,CAAC,MAAM,KAAK,IAAI,IAAI,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC;AAC1D,CAAC;AAiBD,MAAM,CAAC,MAAM,iBAAiB,GAAuB,EAAE,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;AA0BtG,kHAAkH;AAClH,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IAC1C,SAAS,CAAS;IAE3B,YAAY,SAAiB;QAC3B,KAAK,CACH,mBAAmB,SAAS,yEAAyE;YACnG,gGAAgG;YAChG,+EAA+E,CAClF,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;QACzC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;CACF;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/C,YAAY,GAAW;QACrB,KAAK,CACH,IAAI,GAAG,+FAA+F;YACpG,kFAAkF,CACrF,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF"}
1
+ {"version":3,"file":"driver.js","sourceRoot":"","sources":["../../src/browser/driver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAgKH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAAC,OAAwB;IACtD,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC,MAAM,KAAK,IAAI,IAAI,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC;IAC3F,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAChD,OAAO,OAAO,CAAC,OAAO,KAAK,YAAY,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,IAAI,IAAI,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC;AAChG,CAAC;AAsCD,MAAM,CAAC,MAAM,iBAAiB,GAAuB,EAAE,OAAO,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;AA0BrH,kHAAkH;AAClH,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IAC1C,SAAS,CAAS;IAE3B,YAAY,SAAiB;QAC3B,KAAK,CACH,mBAAmB,SAAS,yEAAyE;YACnG,gGAAgG;YAChG,+EAA+E,CAClF,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;QACzC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;CACF;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/C,YAAY,GAAW;QACrB,KAAK,CACH,IAAI,GAAG,+FAA+F;YACpG,kFAAkF,CACrF,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF"}
@@ -29,9 +29,20 @@ export interface BrowserEvidenceReport {
29
29
  * frontend action reached a backend route.
30
30
  */
31
31
  readonly failedRequests: readonly ObservedRequest[];
32
+ /**
33
+ * Requests still in flight when the observation window closed.
34
+ *
35
+ * Not a failure and not a success — `isFailedRequest` deliberately excludes
36
+ * these. Reported under its own key rather than silently absent, because a
37
+ * healthy request that simply had not answered yet must not read the same
38
+ * as a page that issued nothing.
39
+ */
40
+ readonly pendingRequests: readonly ObservedRequest[];
32
41
  /** How many requests the page issued in total, so the list above is read as a subset and not as all of it. */
33
42
  readonly totalRequests: number;
34
43
  readonly actions: BrowserObservation["actions"];
44
+ /** Actions the driver stopped waiting on. Empty on every ordinary reply. */
45
+ readonly unsettled: BrowserObservation["unsettled"];
35
46
  }
36
47
  export declare function evidenceReport(observation: BrowserObservation): BrowserEvidenceReport;
37
48
  export declare function isEmpty(report: BrowserEvidenceReport): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"evidence.d.ts","sourceRoot":"","sources":["../../src/browser/evidence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAmB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAE7F,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,aAAa,EAAE,kBAAkB,CAAC,eAAe,CAAC,CAAC;IAC5D;;;;;;;;;OASG;IACH,QAAQ,CAAC,cAAc,EAAE,SAAS,eAAe,EAAE,CAAC;IACpD,8GAA8G;IAC9G,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;CACjD;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,kBAAkB,GAAG,qBAAqB,CAOrF;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAE9D;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,EAAE,CAsBrE"}
1
+ {"version":3,"file":"evidence.d.ts","sourceRoot":"","sources":["../../src/browser/evidence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAmB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAE7F,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,aAAa,EAAE,kBAAkB,CAAC,eAAe,CAAC,CAAC;IAC5D;;;;;;;;;OASG;IACH,QAAQ,CAAC,cAAc,EAAE,SAAS,eAAe,EAAE,CAAC;IACpD;;;;;;;OAOG;IACH,QAAQ,CAAC,eAAe,EAAE,SAAS,eAAe,EAAE,CAAC;IACrD,8GAA8G;IAC9G,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAChD,4EAA4E;IAC5E,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC;CACrD;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,kBAAkB,GAAG,qBAAqB,CASrF;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAE9D;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,EAAE,CAmCrE"}
@@ -20,12 +20,14 @@ export function evidenceReport(observation) {
20
20
  return {
21
21
  consoleErrors: observation.consoleErrors,
22
22
  failedRequests: observation.requests.filter(isFailedRequest),
23
+ pendingRequests: observation.requests.filter((request) => request.outcome === "pending"),
23
24
  totalRequests: observation.requests.length,
24
25
  actions: observation.actions,
26
+ unsettled: observation.unsettled,
25
27
  };
26
28
  }
27
29
  export function isEmpty(report) {
28
- return report.consoleErrors.length === 0 && report.failedRequests.length === 0;
30
+ return report.consoleErrors.length === 0 && report.failedRequests.length === 0 && report.pendingRequests.length === 0;
29
31
  }
30
32
  /**
31
33
  * The notes any reply carrying evidence must include.
@@ -36,20 +38,74 @@ export function isEmpty(report) {
36
38
  * how a real disclosure stops being read.
37
39
  */
38
40
  export function evidenceNotes(report) {
41
+ // Checked before the emptiness gate, deliberately. An action whose network
42
+ // never settled produces a report that can be *empty in every other
43
+ // respect*, and staying silent about it is the one thing this note exists
44
+ // to prevent: the reply would then be indistinguishable from a clean one.
45
+ const unsettledNotes = report.unsettled.map((item) => `The "${item.action}" action${item.ref === null ? "" : ` on ${item.ref}`} was still causing network ` +
46
+ `activity when Descry stopped waiting, after ${item.waitedMs}ms. Evidence for anything that finished ` +
47
+ "after that point is not in this reply — this is an incomplete observation of that action, not a " +
48
+ "clean one.");
49
+ // Checked before the emptiness gate too, and for the same reason as
50
+ // `unsettledNotes`: a request that is merely still in flight is not a
51
+ // failure and must not be silently folded into a report that then reads as
52
+ // clean when it is really "the window closed before this one finished."
53
+ const pendingNotes = report.pendingRequests.map((request) => `${request.method} ${request.url} was still in flight when the observation window closed. That is not ` +
54
+ "evidence it will fail — the request simply had not answered yet.");
39
55
  if (isEmpty(report))
40
- return [];
56
+ return [...unsettledNotes, ...pendingNotes];
41
57
  const notes = [
58
+ ...unsettledNotes,
59
+ ...pendingNotes,
42
60
  `${report.consoleErrors.length} console error(s) and ${report.failedRequests.length} failed request(s) ` +
43
61
  "were observed in the browser during this call. They are reported raw and have not been triaged — " +
44
62
  "Descry is not claiming any of them is a bug, only that the page produced them. Deciding which " +
45
63
  "matter is the calling agent's job.",
46
64
  ];
47
- const unmapped = [...report.consoleErrors, ...report.failedRequests].filter((item) => item.stackText !== null && !item.stackText.startsWith("/") && item.stackText.includes("http")).length;
48
- if (unmapped > 0) {
49
- notes.push(`${unmapped} stack trace(s) still name script URLs rather than repository files. Mapping them back ` +
50
- "to real files and lines needs the browser backend's source-root resolver, which this build does " +
51
- "not have wired yet, so the raw text is passed through rather than a guess being printed.");
65
+ return [...notes, ...scriptUrlNotes(report)];
66
+ }
67
+ /**
68
+ * What the source-root mapping actually managed, per URL.
69
+ *
70
+ * This replaced a heuristic that sniffed rendered stack text for the
71
+ * substring `http` and reported a count. Two things were wrong with it. It
72
+ * guessed at an answer the collector had already computed exactly — and its
73
+ * guess was broken besides, since it also required the text to not start with
74
+ * `/`, which a rendering that begins `> at fn (…)` never does. And it
75
+ * described the mapping as un-wired, which stopped being true once
76
+ * `browser_start_session` began building a `resolveSourceRoot` for every
77
+ * session: the rewrite runs inside the runtime collector, on the stack text
78
+ * before the parser reads it.
79
+ *
80
+ * What remains worth disclosing is narrower and real: **which** URLs did not
81
+ * map, and why. Partial coverage is the normal case — an application's own
82
+ * bundle maps and its CDN dependency does not — so the note leads with the
83
+ * coverage and then names each miss with the collector's own reason. A caller
84
+ * can then tell a misconfigured document root from a third-party script that
85
+ * was never going to map.
86
+ */
87
+ function scriptUrlNotes(report) {
88
+ const outcomes = [...report.consoleErrors, ...report.failedRequests].flatMap((item) => item.scriptUrlMapping);
89
+ // No outcomes means no rewrite was attempted — no stack parser, or no stack
90
+ // at all. That is not a mapping shortfall and must not be reported as one.
91
+ if (outcomes.length === 0)
92
+ return [];
93
+ const unmapped = outcomes.filter((outcome) => outcome.mapped === null);
94
+ if (unmapped.length === 0)
95
+ return [];
96
+ // De-duplicated: one script referenced from ten frames is one unmapped
97
+ // script, and listing it ten times would overstate the shortfall.
98
+ const byUrl = new Map();
99
+ for (const outcome of unmapped) {
100
+ if (!byUrl.has(outcome.url))
101
+ byUrl.set(outcome.url, outcome.reason ?? "no reason given");
52
102
  }
53
- return notes;
103
+ const distinct = new Set(outcomes.map((outcome) => outcome.url));
104
+ return [
105
+ `${distinct.size - byUrl.size} of ${distinct.size} script URL(s) in these stacks were mapped back to ` +
106
+ "repository files. The rest are reported as the URLs the browser gave, not as a guessed file — a stack " +
107
+ "frame pointing at the wrong line is worse than one that admits it is a URL:\n" +
108
+ [...byUrl].map(([url, reason]) => ` ${url} — ${reason}`).join("\n"),
109
+ ];
54
110
  }
55
111
  //# sourceMappingURL=evidence.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"evidence.js","sourceRoot":"","sources":["../../src/browser/evidence.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,eAAe,EAAiD,MAAM,aAAa,CAAC;AAoB7F,MAAM,UAAU,cAAc,CAAC,WAA+B;IAC5D,OAAO;QACL,aAAa,EAAE,WAAW,CAAC,aAAa;QACxC,cAAc,EAAE,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,eAAe,CAAC;QAC5D,aAAa,EAAE,WAAW,CAAC,QAAQ,CAAC,MAAM;QAC1C,OAAO,EAAE,WAAW,CAAC,OAAO;KAC7B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,MAA6B;IACnD,OAAO,MAAM,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,CAAC;AACjF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,aAAa,CAAC,MAA6B;IACzD,IAAI,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC;IAE/B,MAAM,KAAK,GAAG;QACZ,GAAG,MAAM,CAAC,aAAa,CAAC,MAAM,yBAAyB,MAAM,CAAC,cAAc,CAAC,MAAM,qBAAqB;YACtG,mGAAmG;YACnG,gGAAgG;YAChG,oCAAoC;KACvC,CAAC;IAEF,MAAM,QAAQ,GAAG,CAAC,GAAG,MAAM,CAAC,aAAa,EAAE,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC,MAAM,CACzE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CACxG,CAAC,MAAM,CAAC;IACT,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QACjB,KAAK,CAAC,IAAI,CACR,GAAG,QAAQ,yFAAyF;YAClG,kGAAkG;YAClG,0FAA0F,CAC7F,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"evidence.js","sourceRoot":"","sources":["../../src/browser/evidence.ts"],"names":[],"mappings":"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"}
@@ -41,6 +41,8 @@ export interface FakeBrowserDriver extends BrowserDriver {
41
41
  readonly status: number | null;
42
42
  readonly stackText: string | null;
43
43
  readonly stackTrace?: ObservedRequest["stackTrace"];
44
+ /** Omit to leave this request's outcome unreported, the way an older `descry-runtime` build would. */
45
+ readonly outcome?: ObservedRequest["outcome"];
44
46
  }): void;
45
47
  /** Sugar for `emitRequest` with a failing status. */
46
48
  emitFailedRequest(sessionId: string, request: {
@@ -49,6 +51,12 @@ export interface FakeBrowserDriver extends BrowserDriver {
49
51
  readonly status: number | null;
50
52
  readonly stackText: string | null;
51
53
  }): void;
54
+ /** Sugar for `emitRequest` still in flight when the window closed — `outcome: "pending"`, `status: null`. */
55
+ emitPendingRequest(sessionId: string, request: {
56
+ readonly method: string;
57
+ readonly url: string;
58
+ readonly stackText: string | null;
59
+ }): void;
52
60
  /** Kill the browser behind a session, the way a real crash does — usable goes false, the id stays invalid. */
53
61
  crash(sessionId: string): void;
54
62
  /** Every session this driver has opened and not closed. What the registry's orphan-cleanup tests assert against. */
@@ -1 +1 @@
1
- {"version":3,"file":"fake-driver.d.ts","sourceRoot":"","sources":["../../src/browser/fake-driver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,EAGL,KAAK,aAAa,EAOlB,KAAK,eAAe,EAGrB,MAAM,aAAa,CAAC;AAErB,mFAAmF;AACnF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC3G;AAED,MAAM,WAAW,iBAAkB,SAAQ,aAAa;IACtD,0JAA0J;IAC1J,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC3C,kFAAkF;IAClF,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAC/G,iGAAiG;IACjG,WAAW,CACT,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;QACP,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;KACrD,GACA,IAAI,CAAC;IACR,qDAAqD;IACrD,iBAAiB,CACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAC5H,IAAI,CAAC;IACR,8GAA8G;IAC9G,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,oHAAoH;IACpH,cAAc,IAAI,SAAS,MAAM,EAAE,CAAC;CACrC;AAeD,wBAAgB,uBAAuB,IAAI,iBAAiB,CAsJ3D"}
1
+ {"version":3,"file":"fake-driver.d.ts","sourceRoot":"","sources":["../../src/browser/fake-driver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,EAGL,KAAK,aAAa,EAOlB,KAAK,eAAe,EAGrB,MAAM,aAAa,CAAC;AAErB,mFAAmF;AACnF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC3G;AAED,MAAM,WAAW,iBAAkB,SAAQ,aAAa;IACtD,0JAA0J;IAC1J,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC3C,kFAAkF;IAClF,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAC/G,iGAAiG;IACjG,WAAW,CACT,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;QACP,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;QACpD,sGAAsG;QACtG,QAAQ,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;KAC/C,GACA,IAAI,CAAC;IACR,qDAAqD;IACrD,iBAAiB,CACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAC5H,IAAI,CAAC;IACR,6GAA6G;IAC7G,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAC3I,8GAA8G;IAC9G,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,oHAAoH;IACpH,cAAc,IAAI,SAAS,MAAM,EAAE,CAAC;CACrC;AAeD,wBAAgB,uBAAuB,IAAI,iBAAiB,CA6K3D"}
@@ -35,6 +35,8 @@ export function createFakeBrowserDriver() {
35
35
  actions: state.buffer.actions,
36
36
  consoleErrors: state.buffer.consoleErrors,
37
37
  requests: state.buffer.requests,
38
+ // The fake page has no network, so nothing can be left in flight.
39
+ unsettled: [],
38
40
  };
39
41
  state.buffer.actions = [];
40
42
  state.buffer.consoleErrors = [];
@@ -142,13 +144,34 @@ export function createFakeBrowserDriver() {
142
144
  chromiumMissing = { remedy };
143
145
  },
144
146
  emitConsoleError(sessionId, error) {
145
- stateOf(sessionId).buffer.consoleErrors.push({ ...error, at: new Date().toISOString() });
147
+ stateOf(sessionId).buffer.consoleErrors.push({ scriptUrlMapping: [], ...error, at: new Date().toISOString() });
146
148
  },
147
149
  emitRequest(sessionId, request) {
148
- stateOf(sessionId).buffer.requests.push({ stackTrace: null, ...request, at: new Date().toISOString() });
150
+ // `outcome` is destructured out and re-added only when present:
151
+ // `exactOptionalPropertyTypes` treats a spread of an optional field as
152
+ // `T | undefined`, which `ObservedRequest`'s own `outcome?:` does not
153
+ // accept — the key must be omitted, never present as `undefined`.
154
+ const { outcome, ...rest } = request;
155
+ stateOf(sessionId).buffer.requests.push({
156
+ stackTrace: null,
157
+ scriptUrlMapping: [],
158
+ ...rest,
159
+ ...(outcome === undefined ? {} : { outcome }),
160
+ at: new Date().toISOString(),
161
+ });
149
162
  },
150
163
  emitFailedRequest(sessionId, request) {
151
- stateOf(sessionId).buffer.requests.push({ ...request, stackTrace: null, at: new Date().toISOString() });
164
+ stateOf(sessionId).buffer.requests.push({ scriptUrlMapping: [], ...request, stackTrace: null, at: new Date().toISOString() });
165
+ },
166
+ emitPendingRequest(sessionId, request) {
167
+ stateOf(sessionId).buffer.requests.push({
168
+ scriptUrlMapping: [],
169
+ stackTrace: null,
170
+ ...request,
171
+ status: null,
172
+ outcome: "pending",
173
+ at: new Date().toISOString(),
174
+ });
152
175
  },
153
176
  crash(sessionId) {
154
177
  stateOf(sessionId).crashed = true;
@@ -1 +1 @@
1
- {"version":3,"file":"fake-driver.js","sourceRoot":"","sources":["../../src/browser/fake-driver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fake-driver.js","sourceRoot":"","sources":["../../src/browser/fake-driver.ts"],"names":[],"mappings":"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"}
@@ -1,19 +1,22 @@
1
1
  /**
2
2
  * The real `BrowserDriver`, over `@descryy/runtime-browser`.
3
3
  *
4
- * ## Why the import is dynamic
4
+ * ## Why the import is still dynamic
5
5
  *
6
- * `@descryy/runtime-browser` is not on the npm registry yet
7
- * (`mcp-browser-tools.md` §3.1 — the publish returns 429 on new-scoped-package
8
- * creation). Declaring it in `package.json` today would break `npm install`
9
- * for everyone, including the lanes that never touch a browser. So it is
10
- * imported by specifier at call time and its absence is a **named refusal
11
- * with a remedy**, exactly as a missing Chromium is.
12
- *
13
- * That is a temporary shape and it is written down as one: the final swap
14
- * (§8's tool-count item) declares the dependency and makes this a static
15
- * import. What must *not* happen in the meantime is the tools quietly
16
- * appearing to work — see `provider.ts`.
6
+ * `@descryy/runtime-browser` is now a declared dependency of `@descryy/mcp`
7
+ * (`mcp-browser-tools.md` §3.1's publish landed) — so the reason this module
8
+ * used to give for a call-time specifier import, "not on the registry yet,"
9
+ * no longer holds. It stays dynamic anyway, for a reason that outgrew that
10
+ * one: `loadRuntimeModule` (`PlaywrightDriverOptions`, below) is a real
11
+ * injection seam that `browser-action-settle.test.ts` uses today to drive
12
+ * this file's settle logic against a fake module shaped like this one,
13
+ * deterministically, with no real browser involved. A static
14
+ * `import … from "@descryy/runtime-browser"` at the top of this file would
15
+ * remove that seam along with the indirection, and nothing here needs
16
+ * removing it — the package being on the registry made the *dependency*
17
+ * declarable, not the import path mandatory. Absence (package missing,
18
+ * import throws, or Chromium missing) is still a **named refusal with a
19
+ * remedy**, exactly as before — see `provider.ts`.
17
20
  *
18
21
  * ## What this adds over the runtime package, and what it deliberately does not
19
22
  *
@@ -38,9 +41,9 @@
38
41
  * the same reason. Without one, requests are still observed and no caller
39
42
  * edge is written; the reply says so.
40
43
  */
41
- import type { ServiceRootLookup } from "@descryy/runtime-contracts";
44
+ import type { StackTrace, ServiceRootLookup } from "@descryy/runtime-contracts";
42
45
  import type { StackTraceParser } from "@descryy/runtime-backend-observation";
43
- import type { BrowserDriver } from "./driver.ts";
46
+ import type { BrowserDriver, BrowserObservation, ObservedAction, UnsettledAction } from "./driver.ts";
44
47
  export interface PlaywrightDriverOptions {
45
48
  /**
46
49
  * Turns a raw browser stack into resolved frames. Supplied by the caller;
@@ -55,11 +58,62 @@ export interface PlaywrightDriverOptions {
55
58
  readonly resolveSourceRoot?: SourceRootResolver;
56
59
  /** Which service the evidence is attributed to. */
57
60
  readonly service?: string;
61
+ /**
62
+ * How the runtime browser module is loaded. Defaults to importing
63
+ * `@descryy/runtime-browser` by specifier.
64
+ *
65
+ * It exists because the settle logic below is timing-dependent and this
66
+ * build has no browser backend to run it against — the conformance test
67
+ * that would exercise it skips on every machine without
68
+ * `@descryy/runtime-browser` and Chromium. A driver-level fake page is the
69
+ * only way that logic is executable at all here — and a sleep that dropped
70
+ * evidence shipped in this file with no executable test over it at all,
71
+ * which is the argument for the seam rather than against it.
72
+ *
73
+ * Keep it. Ruled on when it was introduced: exporting `openSession` instead
74
+ * would widen the public surface to an internal lifecycle, where this
75
+ * narrows to one injection point with a stated purpose.
76
+ */
77
+ readonly loadRuntimeModule?: () => Promise<unknown>;
58
78
  }
59
79
  type SourceRootResolver = (origin: string) => ServiceRootLookup;
60
80
  export declare class BrowserBackendMissingError extends Error {
61
81
  constructor(cause: unknown);
62
82
  }
83
+ /**
84
+ * An `Evidence`-shaped record, as the collectors emit it.
85
+ *
86
+ * Typed structurally rather than imported wholesale because only four fields
87
+ * are read: everything else the collectors attach travels to nobody here.
88
+ */
89
+ /**
90
+ * Exported for `browser-request-outcome-mapping.test.ts`, which drives
91
+ * `collect()` directly with synthetic evidence records — the real
92
+ * evidence-to-`ObservedRequest` mapping, not the fake driver's fixtures. That
93
+ * test is the regression test for B3: the fake driver lets a fixture declare
94
+ * `outcome` directly, which let this mapping function ship never populating
95
+ * the field at all while every test still passed.
96
+ */
97
+ export interface EmittedEvidence {
98
+ readonly eventType: string;
99
+ readonly payload: Record<string, unknown>;
100
+ readonly stackTrace: StackTrace | null;
101
+ readonly requestId: string | null;
102
+ readonly timestamp: string;
103
+ }
63
104
  export declare function createPlaywrightBrowserDriver(options?: PlaywrightDriverOptions): Promise<BrowserDriver>;
105
+ /**
106
+ * Turn what the collectors emitted into the port's vocabulary.
107
+ *
108
+ * The request/response join is on `requestId`, because a `NETWORK_REQUEST`
109
+ * carries the method, the URL and the call-site stack while only the matching
110
+ * `NETWORK_RESPONSE` knows the status. A request with no response is kept with
111
+ * `status: null` — "never answered" is a different fact from a 500, and the
112
+ * port says so.
113
+ *
114
+ * Exported for `browser-request-outcome-mapping.test.ts` — see
115
+ * `EmittedEvidence`'s doc comment for why.
116
+ */
117
+ export declare function collect(emitted: readonly EmittedEvidence[], actions: readonly ObservedAction[], unsettled: readonly UnsettledAction[]): BrowserObservation;
64
118
  export {};
65
119
  //# sourceMappingURL=playwright-driver.d.ts.map