@descryy/mcp 0.11.3 → 0.11.5
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.
- package/package.json +20 -20
- package/dist/action-handshake.d.ts +0 -38
- package/dist/action-handshake.d.ts.map +0 -1
- package/dist/action-handshake.js +0 -127
- package/dist/action-handshake.js.map +0 -1
- package/dist/bin/descry-mcp.d.ts +0 -7
- package/dist/bin/descry-mcp.d.ts.map +0 -1
- package/dist/bin/descry-mcp.js +0 -72
- package/dist/bin/descry-mcp.js.map +0 -1
- package/dist/browser/auth.d.ts +0 -84
- package/dist/browser/auth.d.ts.map +0 -1
- package/dist/browser/auth.js +0 -233
- package/dist/browser/auth.js.map +0 -1
- package/dist/browser/capability-probe.d.ts +0 -109
- package/dist/browser/capability-probe.d.ts.map +0 -1
- package/dist/browser/capability-probe.js +0 -201
- package/dist/browser/capability-probe.js.map +0 -1
- package/dist/browser/driver.d.ts +0 -570
- package/dist/browser/driver.d.ts.map +0 -1
- package/dist/browser/driver.js +0 -116
- package/dist/browser/driver.js.map +0 -1
- package/dist/browser/evidence.d.ts +0 -28
- package/dist/browser/evidence.d.ts.map +0 -1
- package/dist/browser/evidence.js +0 -82
- package/dist/browser/evidence.js.map +0 -1
- package/dist/browser/fake-driver.d.ts +0 -116
- package/dist/browser/fake-driver.d.ts.map +0 -1
- package/dist/browser/fake-driver.js +0 -416
- package/dist/browser/fake-driver.js.map +0 -1
- package/dist/browser/fault-attribution.d.ts +0 -178
- package/dist/browser/fault-attribution.d.ts.map +0 -1
- package/dist/browser/fault-attribution.js +0 -266
- package/dist/browser/fault-attribution.js.map +0 -1
- package/dist/browser/graph-write.d.ts +0 -45
- package/dist/browser/graph-write.d.ts.map +0 -1
- package/dist/browser/graph-write.js +0 -103
- package/dist/browser/graph-write.js.map +0 -1
- package/dist/browser/identity-graph-write.d.ts +0 -55
- package/dist/browser/identity-graph-write.d.ts.map +0 -1
- package/dist/browser/identity-graph-write.js +0 -45
- package/dist/browser/identity-graph-write.js.map +0 -1
- package/dist/browser/page-probe.d.ts +0 -81
- package/dist/browser/page-probe.d.ts.map +0 -1
- package/dist/browser/page-probe.js +0 -202
- package/dist/browser/page-probe.js.map +0 -1
- package/dist/browser/playwright-driver.d.ts +0 -114
- package/dist/browser/playwright-driver.d.ts.map +0 -1
- package/dist/browser/playwright-driver.js +0 -1479
- package/dist/browser/playwright-driver.js.map +0 -1
- package/dist/browser/provider.d.ts +0 -26
- package/dist/browser/provider.d.ts.map +0 -1
- package/dist/browser/provider.js +0 -14
- package/dist/browser/provider.js.map +0 -1
- package/dist/browser/reach-recording-session.d.ts +0 -44
- package/dist/browser/reach-recording-session.d.ts.map +0 -1
- package/dist/browser/reach-recording-session.js +0 -143
- package/dist/browser/reach-recording-session.js.map +0 -1
- package/dist/browser/reachability.d.ts +0 -168
- package/dist/browser/reachability.d.ts.map +0 -1
- package/dist/browser/reachability.js +0 -294
- package/dist/browser/reachability.js.map +0 -1
- package/dist/browser/registry.d.ts +0 -126
- package/dist/browser/registry.d.ts.map +0 -1
- package/dist/browser/registry.js +0 -177
- package/dist/browser/registry.js.map +0 -1
- package/dist/browser/scenario-provenance.d.ts +0 -23
- package/dist/browser/scenario-provenance.d.ts.map +0 -1
- package/dist/browser/scenario-provenance.js +0 -73
- package/dist/browser/scenario-provenance.js.map +0 -1
- package/dist/browser/scenario-resolve.d.ts +0 -28
- package/dist/browser/scenario-resolve.d.ts.map +0 -1
- package/dist/browser/scenario-resolve.js +0 -96
- package/dist/browser/scenario-resolve.js.map +0 -1
- package/dist/browser/scenario-runner.d.ts +0 -72
- package/dist/browser/scenario-runner.d.ts.map +0 -1
- package/dist/browser/scenario-runner.js +0 -353
- package/dist/browser/scenario-runner.js.map +0 -1
- package/dist/browser/stack-parser.d.ts +0 -19
- package/dist/browser/stack-parser.d.ts.map +0 -1
- package/dist/browser/stack-parser.js +0 -85
- package/dist/browser/stack-parser.js.map +0 -1
- package/dist/browser/tool-support.d.ts +0 -71
- package/dist/browser/tool-support.d.ts.map +0 -1
- package/dist/browser/tool-support.js +0 -216
- package/dist/browser/tool-support.js.map +0 -1
- package/dist/browser/url-scheme.d.ts +0 -14
- package/dist/browser/url-scheme.d.ts.map +0 -1
- package/dist/browser/url-scheme.js +0 -38
- package/dist/browser/url-scheme.js.map +0 -1
- package/dist/browser/wait-target.d.ts +0 -37
- package/dist/browser/wait-target.d.ts.map +0 -1
- package/dist/browser/wait-target.js +0 -54
- package/dist/browser/wait-target.js.map +0 -1
- package/dist/cancellation.d.ts +0 -20
- package/dist/cancellation.d.ts.map +0 -1
- package/dist/cancellation.js +0 -41
- package/dist/cancellation.js.map +0 -1
- package/dist/capped.d.ts +0 -17
- package/dist/capped.d.ts.map +0 -1
- package/dist/capped.js +0 -15
- package/dist/capped.js.map +0 -1
- package/dist/credential-store.d.ts +0 -22
- package/dist/credential-store.d.ts.map +0 -1
- package/dist/credential-store.js +0 -33
- package/dist/credential-store.js.map +0 -1
- package/dist/disclosure-ledger.d.ts +0 -14
- package/dist/disclosure-ledger.d.ts.map +0 -1
- package/dist/disclosure-ledger.js +0 -18
- package/dist/disclosure-ledger.js.map +0 -1
- package/dist/evidence/observed-route-evidence.d.ts +0 -25
- package/dist/evidence/observed-route-evidence.d.ts.map +0 -1
- package/dist/evidence/observed-route-evidence.js +0 -76
- package/dist/evidence/observed-route-evidence.js.map +0 -1
- package/dist/heap.d.ts +0 -61
- package/dist/heap.d.ts.map +0 -1
- package/dist/heap.js +0 -82
- package/dist/heap.js.map +0 -1
- package/dist/heartbeat.d.ts +0 -46
- package/dist/heartbeat.d.ts.map +0 -1
- package/dist/heartbeat.js +0 -66
- package/dist/heartbeat.js.map +0 -1
- package/dist/index.d.ts +0 -32
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -19
- package/dist/index.js.map +0 -1
- package/dist/module-trust.d.ts +0 -37
- package/dist/module-trust.d.ts.map +0 -1
- package/dist/module-trust.js +0 -77
- package/dist/module-trust.js.map +0 -1
- package/dist/path-confinement.d.ts +0 -31
- package/dist/path-confinement.d.ts.map +0 -1
- package/dist/path-confinement.js +0 -44
- package/dist/path-confinement.js.map +0 -1
- package/dist/planner/predict-then-propose.d.ts +0 -134
- package/dist/planner/predict-then-propose.d.ts.map +0 -1
- package/dist/planner/predict-then-propose.js +0 -138
- package/dist/planner/predict-then-propose.js.map +0 -1
- package/dist/planner/propose-journey.d.ts +0 -75
- package/dist/planner/propose-journey.d.ts.map +0 -1
- package/dist/planner/propose-journey.js +0 -96
- package/dist/planner/propose-journey.js.map +0 -1
- package/dist/protocol.d.ts +0 -57
- package/dist/protocol.d.ts.map +0 -1
- package/dist/protocol.js +0 -90
- package/dist/protocol.js.map +0 -1
- package/dist/registry.d.ts +0 -103
- package/dist/registry.d.ts.map +0 -1
- package/dist/registry.js +0 -319
- package/dist/registry.js.map +0 -1
- package/dist/render.d.ts +0 -580
- package/dist/render.d.ts.map +0 -1
- package/dist/render.js +0 -867
- package/dist/render.js.map +0 -1
- package/dist/runtime-registry.d.ts +0 -22
- package/dist/runtime-registry.d.ts.map +0 -1
- package/dist/runtime-registry.js +0 -142
- package/dist/runtime-registry.js.map +0 -1
- package/dist/sandbox-defaults.d.ts +0 -41
- package/dist/sandbox-defaults.d.ts.map +0 -1
- package/dist/sandbox-defaults.js +0 -14
- package/dist/sandbox-defaults.js.map +0 -1
- package/dist/scenarios/browser-run-plan-projection.d.ts +0 -161
- package/dist/scenarios/browser-run-plan-projection.d.ts.map +0 -1
- package/dist/scenarios/browser-run-plan-projection.js +0 -264
- package/dist/scenarios/browser-run-plan-projection.js.map +0 -1
- package/dist/scenarios/credential-ref.d.ts +0 -102
- package/dist/scenarios/credential-ref.d.ts.map +0 -1
- package/dist/scenarios/credential-ref.js +0 -148
- package/dist/scenarios/credential-ref.js.map +0 -1
- package/dist/scenarios/index.d.ts +0 -7
- package/dist/scenarios/index.d.ts.map +0 -1
- package/dist/scenarios/index.js +0 -7
- package/dist/scenarios/index.js.map +0 -1
- package/dist/scenarios/parse.d.ts +0 -18
- package/dist/scenarios/parse.d.ts.map +0 -1
- package/dist/scenarios/parse.js +0 -212
- package/dist/scenarios/parse.js.map +0 -1
- package/dist/scenarios/scenario.d.ts +0 -93
- package/dist/scenarios/scenario.d.ts.map +0 -1
- package/dist/scenarios/scenario.js +0 -27
- package/dist/scenarios/scenario.js.map +0 -1
- package/dist/scenarios/secret-ref.d.ts +0 -86
- package/dist/scenarios/secret-ref.d.ts.map +0 -1
- package/dist/scenarios/secret-ref.js +0 -125
- package/dist/scenarios/secret-ref.js.map +0 -1
- package/dist/scenarios/storage.d.ts +0 -21
- package/dist/scenarios/storage.d.ts.map +0 -1
- package/dist/scenarios/storage.js +0 -103
- package/dist/scenarios/storage.js.map +0 -1
- package/dist/server.d.ts +0 -61
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js +0 -541
- package/dist/server.js.map +0 -1
- package/dist/session.d.ts +0 -243
- package/dist/session.d.ts.map +0 -1
- package/dist/session.js +0 -602
- package/dist/session.js.map +0 -1
- package/dist/tools/alias-kit.d.ts +0 -29
- package/dist/tools/alias-kit.d.ts.map +0 -1
- package/dist/tools/alias-kit.js +0 -21
- package/dist/tools/alias-kit.js.map +0 -1
- package/dist/tools/aliases.d.ts +0 -42
- package/dist/tools/aliases.d.ts.map +0 -1
- package/dist/tools/aliases.js +0 -52
- package/dist/tools/aliases.js.map +0 -1
- package/dist/tools/analyze-workspace.d.ts +0 -52
- package/dist/tools/analyze-workspace.d.ts.map +0 -1
- package/dist/tools/analyze-workspace.js +0 -207
- package/dist/tools/analyze-workspace.js.map +0 -1
- package/dist/tools/analyze.d.ts +0 -163
- package/dist/tools/analyze.d.ts.map +0 -1
- package/dist/tools/analyze.js +0 -724
- package/dist/tools/analyze.js.map +0 -1
- package/dist/tools/browser-click.d.ts +0 -18
- package/dist/tools/browser-click.d.ts.map +0 -1
- package/dist/tools/browser-click.js +0 -110
- package/dist/tools/browser-click.js.map +0 -1
- package/dist/tools/browser-close-session.d.ts +0 -39
- package/dist/tools/browser-close-session.d.ts.map +0 -1
- package/dist/tools/browser-close-session.js +0 -120
- package/dist/tools/browser-close-session.js.map +0 -1
- package/dist/tools/browser-fill.d.ts +0 -18
- package/dist/tools/browser-fill.d.ts.map +0 -1
- package/dist/tools/browser-fill.js +0 -117
- package/dist/tools/browser-fill.js.map +0 -1
- package/dist/tools/browser-navigate.d.ts +0 -15
- package/dist/tools/browser-navigate.d.ts.map +0 -1
- package/dist/tools/browser-navigate.js +0 -104
- package/dist/tools/browser-navigate.js.map +0 -1
- package/dist/tools/browser-read.d.ts +0 -33
- package/dist/tools/browser-read.d.ts.map +0 -1
- package/dist/tools/browser-read.js +0 -113
- package/dist/tools/browser-read.js.map +0 -1
- package/dist/tools/browser-run-scenario.d.ts +0 -28
- package/dist/tools/browser-run-scenario.d.ts.map +0 -1
- package/dist/tools/browser-run-scenario.js +0 -206
- package/dist/tools/browser-run-scenario.js.map +0 -1
- package/dist/tools/browser-save-scenario.d.ts +0 -19
- package/dist/tools/browser-save-scenario.d.ts.map +0 -1
- package/dist/tools/browser-save-scenario.js +0 -447
- package/dist/tools/browser-save-scenario.js.map +0 -1
- package/dist/tools/browser-select.d.ts +0 -20
- package/dist/tools/browser-select.d.ts.map +0 -1
- package/dist/tools/browser-select.js +0 -120
- package/dist/tools/browser-select.js.map +0 -1
- package/dist/tools/browser-snapshot.d.ts +0 -46
- package/dist/tools/browser-snapshot.d.ts.map +0 -1
- package/dist/tools/browser-snapshot.js +0 -127
- package/dist/tools/browser-snapshot.js.map +0 -1
- package/dist/tools/browser-start-session.d.ts +0 -24
- package/dist/tools/browser-start-session.d.ts.map +0 -1
- package/dist/tools/browser-start-session.js +0 -622
- package/dist/tools/browser-start-session.js.map +0 -1
- package/dist/tools/browser-submit.d.ts +0 -18
- package/dist/tools/browser-submit.d.ts.map +0 -1
- package/dist/tools/browser-submit.js +0 -106
- package/dist/tools/browser-submit.js.map +0 -1
- package/dist/tools/browser-type.d.ts +0 -18
- package/dist/tools/browser-type.d.ts.map +0 -1
- package/dist/tools/browser-type.js +0 -115
- package/dist/tools/browser-type.js.map +0 -1
- package/dist/tools/browser-wait-for.d.ts +0 -45
- package/dist/tools/browser-wait-for.d.ts.map +0 -1
- package/dist/tools/browser-wait-for.js +0 -150
- package/dist/tools/browser-wait-for.js.map +0 -1
- package/dist/tools/browser.d.ts +0 -69
- package/dist/tools/browser.d.ts.map +0 -1
- package/dist/tools/browser.js +0 -386
- package/dist/tools/browser.js.map +0 -1
- package/dist/tools/chain.d.ts +0 -41
- package/dist/tools/chain.d.ts.map +0 -1
- package/dist/tools/chain.js +0 -105
- package/dist/tools/chain.js.map +0 -1
- package/dist/tools/change-scope.d.ts +0 -25
- package/dist/tools/change-scope.d.ts.map +0 -1
- package/dist/tools/change-scope.js +0 -110
- package/dist/tools/change-scope.js.map +0 -1
- package/dist/tools/code-context.d.ts +0 -83
- package/dist/tools/code-context.d.ts.map +0 -1
- package/dist/tools/code-context.js +0 -416
- package/dist/tools/code-context.js.map +0 -1
- package/dist/tools/contracts.d.ts +0 -74
- package/dist/tools/contracts.d.ts.map +0 -1
- package/dist/tools/contracts.js +0 -196
- package/dist/tools/contracts.js.map +0 -1
- package/dist/tools/cross-pr.d.ts +0 -178
- package/dist/tools/cross-pr.d.ts.map +0 -1
- package/dist/tools/cross-pr.js +0 -321
- package/dist/tools/cross-pr.js.map +0 -1
- package/dist/tools/disclosure.d.ts +0 -75
- package/dist/tools/disclosure.d.ts.map +0 -1
- package/dist/tools/disclosure.js +0 -288
- package/dist/tools/disclosure.js.map +0 -1
- package/dist/tools/draw-conclusion.d.ts +0 -55
- package/dist/tools/draw-conclusion.d.ts.map +0 -1
- package/dist/tools/draw-conclusion.js +0 -259
- package/dist/tools/draw-conclusion.js.map +0 -1
- package/dist/tools/git-context.d.ts +0 -39
- package/dist/tools/git-context.d.ts.map +0 -1
- package/dist/tools/git-context.js +0 -364
- package/dist/tools/git-context.js.map +0 -1
- package/dist/tools/git-diff.d.ts +0 -45
- package/dist/tools/git-diff.d.ts.map +0 -1
- package/dist/tools/git-diff.js +0 -338
- package/dist/tools/git-diff.js.map +0 -1
- package/dist/tools/git-history.d.ts +0 -16
- package/dist/tools/git-history.d.ts.map +0 -1
- package/dist/tools/git-history.js +0 -86
- package/dist/tools/git-history.js.map +0 -1
- package/dist/tools/history.d.ts +0 -34
- package/dist/tools/history.d.ts.map +0 -1
- package/dist/tools/history.js +0 -121
- package/dist/tools/history.js.map +0 -1
- package/dist/tools/impact.d.ts +0 -46
- package/dist/tools/impact.d.ts.map +0 -1
- package/dist/tools/impact.js +0 -225
- package/dist/tools/impact.js.map +0 -1
- package/dist/tools/index.d.ts +0 -59
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/index.js +0 -70
- package/dist/tools/index.js.map +0 -1
- package/dist/tools/kit.d.ts +0 -165
- package/dist/tools/kit.d.ts.map +0 -1
- package/dist/tools/kit.js +0 -153
- package/dist/tools/kit.js.map +0 -1
- package/dist/tools/link-workspace.d.ts +0 -24
- package/dist/tools/link-workspace.d.ts.map +0 -1
- package/dist/tools/link-workspace.js +0 -131
- package/dist/tools/link-workspace.js.map +0 -1
- package/dist/tools/lookup.d.ts +0 -19
- package/dist/tools/lookup.d.ts.map +0 -1
- package/dist/tools/lookup.js +0 -63
- package/dist/tools/lookup.js.map +0 -1
- package/dist/tools/mark-incident.d.ts +0 -28
- package/dist/tools/mark-incident.d.ts.map +0 -1
- package/dist/tools/mark-incident.js +0 -188
- package/dist/tools/mark-incident.js.map +0 -1
- package/dist/tools/merged-browser.d.ts +0 -11
- package/dist/tools/merged-browser.d.ts.map +0 -1
- package/dist/tools/merged-browser.js +0 -20
- package/dist/tools/merged-browser.js.map +0 -1
- package/dist/tools/merged-context.d.ts +0 -11
- package/dist/tools/merged-context.d.ts.map +0 -1
- package/dist/tools/merged-context.js +0 -21
- package/dist/tools/merged-context.js.map +0 -1
- package/dist/tools/merged-observe.d.ts +0 -13
- package/dist/tools/merged-observe.d.ts.map +0 -1
- package/dist/tools/merged-observe.js +0 -21
- package/dist/tools/merged-observe.js.map +0 -1
- package/dist/tools/merged-workspace.d.ts +0 -14
- package/dist/tools/merged-workspace.d.ts.map +0 -1
- package/dist/tools/merged-workspace.js +0 -21
- package/dist/tools/merged-workspace.js.map +0 -1
- package/dist/tools/observe-runtime.d.ts +0 -250
- package/dist/tools/observe-runtime.d.ts.map +0 -1
- package/dist/tools/observe-runtime.js +0 -1753
- package/dist/tools/observe-runtime.js.map +0 -1
- package/dist/tools/observe-tests.d.ts +0 -57
- package/dist/tools/observe-tests.d.ts.map +0 -1
- package/dist/tools/observe-tests.js +0 -368
- package/dist/tools/observe-tests.js.map +0 -1
- package/dist/tools/observe.d.ts +0 -28
- package/dist/tools/observe.d.ts.map +0 -1
- package/dist/tools/observe.js +0 -330
- package/dist/tools/observe.js.map +0 -1
- package/dist/tools/pr-analysis.d.ts +0 -189
- package/dist/tools/pr-analysis.d.ts.map +0 -1
- package/dist/tools/pr-analysis.js +0 -299
- package/dist/tools/pr-analysis.js.map +0 -1
- package/dist/tools/pre-push.d.ts +0 -168
- package/dist/tools/pre-push.d.ts.map +0 -1
- package/dist/tools/pre-push.js +0 -416
- package/dist/tools/pre-push.js.map +0 -1
- package/dist/tools/predict-reach.d.ts +0 -57
- package/dist/tools/predict-reach.d.ts.map +0 -1
- package/dist/tools/predict-reach.js +0 -159
- package/dist/tools/predict-reach.js.map +0 -1
- package/dist/tools/propagation.d.ts +0 -37
- package/dist/tools/propagation.d.ts.map +0 -1
- package/dist/tools/propagation.js +0 -162
- package/dist/tools/propagation.js.map +0 -1
- package/dist/tools/propose-journey.d.ts +0 -16
- package/dist/tools/propose-journey.d.ts.map +0 -1
- package/dist/tools/propose-journey.js +0 -121
- package/dist/tools/propose-journey.js.map +0 -1
- package/dist/tools/prove-reach.d.ts +0 -74
- package/dist/tools/prove-reach.d.ts.map +0 -1
- package/dist/tools/prove-reach.js +0 -286
- package/dist/tools/prove-reach.js.map +0 -1
- package/dist/tools/questions.d.ts +0 -30
- package/dist/tools/questions.d.ts.map +0 -1
- package/dist/tools/questions.js +0 -232
- package/dist/tools/questions.js.map +0 -1
- package/dist/tools/refusal-fetch.d.ts +0 -35
- package/dist/tools/refusal-fetch.d.ts.map +0 -1
- package/dist/tools/refusal-fetch.js +0 -103
- package/dist/tools/refusal-fetch.js.map +0 -1
- package/dist/tools/runtime-incident.d.ts +0 -33
- package/dist/tools/runtime-incident.d.ts.map +0 -1
- package/dist/tools/runtime-incident.js +0 -67
- package/dist/tools/runtime-incident.js.map +0 -1
- package/dist/tools/runtime-journey-drive.d.ts +0 -102
- package/dist/tools/runtime-journey-drive.d.ts.map +0 -1
- package/dist/tools/runtime-journey-drive.js +0 -247
- package/dist/tools/runtime-journey-drive.js.map +0 -1
- package/dist/tools/scope.d.ts +0 -45
- package/dist/tools/scope.d.ts.map +0 -1
- package/dist/tools/scope.js +0 -186
- package/dist/tools/scope.js.map +0 -1
- package/dist/tools/similar-incidents.d.ts +0 -43
- package/dist/tools/similar-incidents.d.ts.map +0 -1
- package/dist/tools/similar-incidents.js +0 -179
- package/dist/tools/similar-incidents.js.map +0 -1
- package/dist/tools/validate.d.ts +0 -133
- package/dist/tools/validate.d.ts.map +0 -1
- package/dist/tools/validate.js +0 -442
- package/dist/tools/validate.js.map +0 -1
- package/dist/tools/verb.d.ts +0 -46
- package/dist/tools/verb.d.ts.map +0 -1
- package/dist/tools/verb.js +0 -78
- package/dist/tools/verb.js.map +0 -1
- package/dist/tools/verification-status.d.ts +0 -38
- package/dist/tools/verification-status.d.ts.map +0 -1
- package/dist/tools/verification-status.js +0 -203
- package/dist/tools/verification-status.js.map +0 -1
- package/dist/tools/verify-claim.d.ts +0 -29
- package/dist/tools/verify-claim.d.ts.map +0 -1
- package/dist/tools/verify-claim.js +0 -220
- package/dist/tools/verify-claim.js.map +0 -1
- package/dist/tools/workspace.d.ts +0 -28
- package/dist/tools/workspace.d.ts.map +0 -1
- package/dist/tools/workspace.js +0 -101
- package/dist/tools/workspace.js.map +0 -1
- package/dist/transport.d.ts +0 -32
- package/dist/transport.d.ts.map +0 -1
- package/dist/transport.js +0 -85
- package/dist/transport.js.map +0 -1
- package/dist/workspace-index.d.ts +0 -164
- package/dist/workspace-index.d.ts.map +0 -1
- package/dist/workspace-index.js +0 -381
- package/dist/workspace-index.js.map +0 -1
package/dist/browser/auth.js
DELETED
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Reading an authenticated session in from a file — B1 of
|
|
3
|
-
* `documents/plans/browser-reliability.md`.
|
|
4
|
-
*
|
|
5
|
-
* ## What was already here, and what was missing
|
|
6
|
-
*
|
|
7
|
-
* `browser_start_session` already accepted an inline `storageState` (11.4-b)
|
|
8
|
-
* and `driver.ts` already carries it. Two things were missing and both are
|
|
9
|
-
* about *reuse*: a caller had no way to point at a file, and a session had no
|
|
10
|
-
* way to write one. Without those, "seed an authenticated session" means the
|
|
11
|
-
* caller has to produce the cookie values by hand every time, which in
|
|
12
|
-
* practice means nobody does it.
|
|
13
|
-
*
|
|
14
|
-
* So this module is the file half: load a browser's own saved state blob and
|
|
15
|
-
* narrow it to the same-origin shape the port carries, refusing anything that
|
|
16
|
-
* reaches outside the consented origin.
|
|
17
|
-
*
|
|
18
|
-
* ## Why the narrowing refuses rather than filters
|
|
19
|
-
*
|
|
20
|
-
* A saved state is whatever the browser had. A developer who logs in to their
|
|
21
|
-
* application and saves the state has a file with one origin in it; a
|
|
22
|
-
* developer who reuses a personal profile has a file with everything they are
|
|
23
|
-
* logged into. Loading the second one wholesale would put unrelated
|
|
24
|
-
* production sessions inside a browser the developer approved for one local
|
|
25
|
-
* application. Quietly keeping only the matching cookies is worse than
|
|
26
|
-
* refusing: a caller who believes they seeded a session and did not gets a run
|
|
27
|
-
* that silently tested the logged-out surface and reported it as a clean one.
|
|
28
|
-
*
|
|
29
|
-
* ## Secrets
|
|
30
|
-
*
|
|
31
|
-
* Nothing here formats a value, including in a refusal — every message names a
|
|
32
|
-
* cookie, a host or a path. `storageStateSecrets` returns the literal values
|
|
33
|
-
* for `@descryy/core`'s `redactSecretsInText`, which replaces literal
|
|
34
|
-
* substrings and never interprets one as a pattern, for the reason that
|
|
35
|
-
* redactor's own header gives.
|
|
36
|
-
*
|
|
37
|
-
* Rule 1: a cookie, a header and an origin are facts about HTTP. No language,
|
|
38
|
-
* framework or file extension is named here.
|
|
39
|
-
*/
|
|
40
|
-
import { readFileSync } from "node:fs";
|
|
41
|
-
import { isAbsolute, join, relative, resolve } from "node:path";
|
|
42
|
-
import { ToolInputError } from "../tools/kit.js";
|
|
43
|
-
const SAME_SITE = ["Strict", "Lax", "None"];
|
|
44
|
-
function hostOf(origin) {
|
|
45
|
-
try {
|
|
46
|
-
return new URL(origin).hostname;
|
|
47
|
-
}
|
|
48
|
-
catch {
|
|
49
|
-
return origin;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Does `domain` name the consented host and nothing else?
|
|
54
|
-
*
|
|
55
|
-
* A leading dot is how a saved jar spells "this domain and its subdomains", so
|
|
56
|
-
* `.localhost` for `localhost` is the same host written two ways. What is not
|
|
57
|
-
* accepted is a domain that covers *more* than the consented host — a cookie
|
|
58
|
-
* for a parent domain travels to every sibling application under it, and that
|
|
59
|
-
* is the widening this check exists to stop happening by accident.
|
|
60
|
-
*/
|
|
61
|
-
function namesConsentedHost(domain, host) {
|
|
62
|
-
const bare = (domain.startsWith(".") ? domain.slice(1) : domain).toLowerCase();
|
|
63
|
-
return bare === host.toLowerCase();
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Load a browser's saved storage state and narrow it to one origin.
|
|
67
|
-
*
|
|
68
|
-
* `path` is absolute or relative to the repository root. Throws
|
|
69
|
-
* `ToolInputError` — every failure here is something the caller can fix by
|
|
70
|
-
* changing an argument, and none of them is a bug in this server.
|
|
71
|
-
*/
|
|
72
|
-
export function loadStorageStateFile(path, context) {
|
|
73
|
-
const resolved = isAbsolute(path) ? path : join(context.repoPath, path);
|
|
74
|
-
let text;
|
|
75
|
-
try {
|
|
76
|
-
text = readFileSync(resolved, "utf8");
|
|
77
|
-
}
|
|
78
|
-
catch (error) {
|
|
79
|
-
throw new ToolInputError(`Could not read the storage state at ${resolved}: ${error instanceof Error ? error.message : String(error)}. ` +
|
|
80
|
-
"A relative path is resolved against the repository root. The usual way to produce this file is to " +
|
|
81
|
-
"start a session with headless false and saveStorageStateTo, log in by hand, and close it.");
|
|
82
|
-
}
|
|
83
|
-
return parseStorageStateJson(text, resolved, context);
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* The parse-and-narrow half of {@link loadStorageStateFile}, taken directly rather than read
|
|
87
|
-
* from a file — `browser-start-session.ts`'s `storageStateCredential` calls this against text
|
|
88
|
-
* retrieved from `Session.credentialStore` (RG-1(4), lane "signin"). `sourceLabel` replaces the
|
|
89
|
-
* file path in every message this can throw, so a credential-sourced refusal reads
|
|
90
|
-
* `credential "NAME"` rather than a nonexistent file path.
|
|
91
|
-
*/
|
|
92
|
-
export function parseStorageStateJson(text, sourceLabel, context) {
|
|
93
|
-
let parsed;
|
|
94
|
-
try {
|
|
95
|
-
parsed = JSON.parse(text);
|
|
96
|
-
}
|
|
97
|
-
catch {
|
|
98
|
-
// The parser's own message quotes the text around the failure, and in this
|
|
99
|
-
// one file that text is credential material.
|
|
100
|
-
throw new ToolInputError(`The storage state at ${sourceLabel} is not valid JSON. Its contents are deliberately not quoted here.`);
|
|
101
|
-
}
|
|
102
|
-
return narrowToOrigin(parsed, sourceLabel, context);
|
|
103
|
-
}
|
|
104
|
-
function narrowToOrigin(raw, path, context) {
|
|
105
|
-
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
106
|
-
throw new ToolInputError(`The storage state at ${path} is not an object.`);
|
|
107
|
-
}
|
|
108
|
-
const fields = raw;
|
|
109
|
-
const rawCookies = fields["cookies"];
|
|
110
|
-
const rawOrigins = fields["origins"];
|
|
111
|
-
// Both keys required rather than defaulted to empty. A blob missing one is
|
|
112
|
-
// far more likely to be the wrong file than a deliberately empty jar, and
|
|
113
|
-
// loading it produces a session that looks seeded and is not.
|
|
114
|
-
if (!Array.isArray(rawCookies) || !Array.isArray(rawOrigins)) {
|
|
115
|
-
throw new ToolInputError(`${path} does not look like a saved browser storage state — it needs a "cookies" array and an "origins" ` +
|
|
116
|
-
"array. Nothing was loaded.");
|
|
117
|
-
}
|
|
118
|
-
const host = hostOf(context.consentedOrigin);
|
|
119
|
-
const strayHosts = new Set();
|
|
120
|
-
const cookies = [];
|
|
121
|
-
for (const [index, entry] of rawCookies.entries()) {
|
|
122
|
-
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
|
|
123
|
-
throw new ToolInputError(`${path}: cookies[${index}] is not an object. Nothing was loaded.`);
|
|
124
|
-
}
|
|
125
|
-
const cookie = entry;
|
|
126
|
-
const name = cookie["name"];
|
|
127
|
-
const value = cookie["value"];
|
|
128
|
-
const domain = cookie["domain"];
|
|
129
|
-
if (typeof name !== "string" || typeof value !== "string") {
|
|
130
|
-
throw new ToolInputError(`${path}: cookies[${index}] needs a string "name" and "value". Nothing was loaded.`);
|
|
131
|
-
}
|
|
132
|
-
if (typeof domain !== "string" || !namesConsentedHost(domain, host)) {
|
|
133
|
-
strayHosts.add(typeof domain === "string" ? domain : "(no domain)");
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
136
|
-
const sameSite = cookie["sameSite"];
|
|
137
|
-
cookies.push({
|
|
138
|
-
name,
|
|
139
|
-
value,
|
|
140
|
-
// The domain is deliberately dropped rather than carried: the port's
|
|
141
|
-
// shape has no field for one, which is what makes a second origin
|
|
142
|
-
// unnameable rather than merely unaccepted.
|
|
143
|
-
...(typeof cookie["path"] === "string" ? { path: cookie["path"] } : {}),
|
|
144
|
-
...(typeof cookie["httpOnly"] === "boolean" ? { httpOnly: cookie["httpOnly"] } : {}),
|
|
145
|
-
...(typeof cookie["secure"] === "boolean" ? { secure: cookie["secure"] } : {}),
|
|
146
|
-
...(typeof sameSite === "string" && SAME_SITE.includes(sameSite)
|
|
147
|
-
? { sameSite: sameSite }
|
|
148
|
-
: {}),
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
const strayOrigins = new Set();
|
|
152
|
-
const localStorage = {};
|
|
153
|
-
for (const [index, entry] of rawOrigins.entries()) {
|
|
154
|
-
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
|
|
155
|
-
throw new ToolInputError(`${path}: origins[${index}] is not an object. Nothing was loaded.`);
|
|
156
|
-
}
|
|
157
|
-
const origin = entry["origin"];
|
|
158
|
-
if (typeof origin !== "string") {
|
|
159
|
-
throw new ToolInputError(`${path}: origins[${index}] needs a string "origin". Nothing was loaded.`);
|
|
160
|
-
}
|
|
161
|
-
if (origin !== context.consentedOrigin) {
|
|
162
|
-
strayOrigins.add(origin);
|
|
163
|
-
continue;
|
|
164
|
-
}
|
|
165
|
-
const items = entry["localStorage"];
|
|
166
|
-
if (items !== undefined && !Array.isArray(items)) {
|
|
167
|
-
throw new ToolInputError(`${path}: origins[${index}].localStorage is not an array. Nothing was loaded.`);
|
|
168
|
-
}
|
|
169
|
-
for (const item of items ?? []) {
|
|
170
|
-
if (typeof item !== "object" || item === null)
|
|
171
|
-
continue;
|
|
172
|
-
const { name, value } = item;
|
|
173
|
-
if (typeof name === "string" && typeof value === "string")
|
|
174
|
-
localStorage[name] = value;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
if (strayHosts.size > 0 || strayOrigins.size > 0) {
|
|
178
|
-
const parts = [];
|
|
179
|
-
if (strayHosts.size > 0)
|
|
180
|
-
parts.push(`cookies for ${[...strayHosts].join(", ")}`);
|
|
181
|
-
if (strayOrigins.size > 0)
|
|
182
|
-
parts.push(`stored data for ${[...strayOrigins].join(", ")}`);
|
|
183
|
-
throw new ToolInputError(`${path} carries ${parts.join(" and ")}, which ${context.consentedOrigin} does not cover. This session's ` +
|
|
184
|
-
"consent is bound to one origin, and seeding credentials for other hosts would put sessions the " +
|
|
185
|
-
"developer never approved inside this browser. Nothing was loaded, and no value from the file is " +
|
|
186
|
-
"printed here. Save a state for this application alone — a session started with saveStorageStateTo " +
|
|
187
|
-
"writes exactly that.");
|
|
188
|
-
}
|
|
189
|
-
return {
|
|
190
|
-
...(cookies.length === 0 ? {} : { cookies }),
|
|
191
|
-
...(Object.keys(localStorage).length === 0 ? {} : { localStorage }),
|
|
192
|
-
};
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Where a saved state may be written.
|
|
196
|
-
*
|
|
197
|
-
* Inside the repository is refused. A storage state is a live credential in a
|
|
198
|
-
* file, and the likeliest thing to happen to a file written into a working
|
|
199
|
-
* tree is that it gets committed. Refusing costs the caller one argument; the
|
|
200
|
-
* alternative costs them a session in their history.
|
|
201
|
-
*/
|
|
202
|
-
export function resolveSavePath(raw, repoPath) {
|
|
203
|
-
const path = isAbsolute(raw) ? raw : resolve(join(repoPath, raw));
|
|
204
|
-
const within = relative(resolve(repoPath), path);
|
|
205
|
-
if (within !== "" && !within.startsWith("..") && !isAbsolute(within)) {
|
|
206
|
-
throw new ToolInputError(`"saveStorageStateTo" resolves to ${path}, which is inside the repository at ${repoPath}. A saved storage ` +
|
|
207
|
-
"state is a live credential in a file, and a credential written into a working tree is one `git add .` " +
|
|
208
|
-
"away from being committed. Give an absolute path outside the repository.");
|
|
209
|
-
}
|
|
210
|
-
return path;
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Every literal value a state carries. Names are deliberately absent — a
|
|
214
|
-
* cookie called `session` is not a secret, and redacting the word would make
|
|
215
|
-
* every reply that mentions a session unreadable.
|
|
216
|
-
*
|
|
217
|
-
* Values under four characters are dropped: one that short matches everywhere
|
|
218
|
-
* and would redact a reply into noise, which is a worse outcome than leaving
|
|
219
|
-
* a four-character credential in it.
|
|
220
|
-
*/
|
|
221
|
-
export function storageStateSecrets(state) {
|
|
222
|
-
if (state === null)
|
|
223
|
-
return [];
|
|
224
|
-
const values = [...(state.cookies ?? []).map((cookie) => cookie.value), ...Object.values(state.localStorage ?? {})];
|
|
225
|
-
return [...new Set(values.filter((value) => value.length >= 4))];
|
|
226
|
-
}
|
|
227
|
-
/** The same, for header values. Separate because headers are not part of a storage state. */
|
|
228
|
-
export function headerSecrets(headers) {
|
|
229
|
-
if (headers === null)
|
|
230
|
-
return [];
|
|
231
|
-
return [...new Set(Object.values(headers).filter((value) => value.length >= 4))];
|
|
232
|
-
}
|
|
233
|
-
//# sourceMappingURL=auth.js.map
|
package/dist/browser/auth.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/browser/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fingerprint the application before driving it, and say up front how much of
|
|
3
|
-
* it is likely reachable. §4.2.
|
|
4
|
-
*
|
|
5
|
-
* ## Why a probe is worth more than it looks
|
|
6
|
-
*
|
|
7
|
-
* The obvious value is expectation-setting: a run that opens by saying "this
|
|
8
|
-
* page has a payment widget in a frame I cannot enter and a canvas I cannot
|
|
9
|
-
* read" is a better run than one that discovers it at the end. The larger value
|
|
10
|
-
* is the second-order one §4.2 names — **the distribution of these fingerprints
|
|
11
|
-
* across real applications is the roadmap.** The corpus in
|
|
12
|
-
* `fixtures/hostile-apps/` was drawn from imagination, which is exactly the
|
|
13
|
-
* method §4 says does not scale. A risk kind counted across real sessions is
|
|
14
|
-
* drawn from the field, and it ranks the work without anybody guessing.
|
|
15
|
-
*
|
|
16
|
-
* That is why `ReachRiskKind` is a small closed vocabulary and not free text.
|
|
17
|
-
* A count is only a roadmap if the same shape lands in the same bucket every
|
|
18
|
-
* time.
|
|
19
|
-
*
|
|
20
|
-
* ## The estimate is pessimistic in exactly one direction
|
|
21
|
-
*
|
|
22
|
-
* `full` requires **zero** named risks. Anything else is at best `partial`. An
|
|
23
|
-
* estimate that reads high and then disappoints is the failure this exists to
|
|
24
|
-
* remove, so the asymmetry is deliberate: a `partial` that turns out to be full
|
|
25
|
-
* coverage costs a sentence of hedging, and a `full` that turns out to be 30%
|
|
26
|
-
* costs the report's credibility.
|
|
27
|
-
*
|
|
28
|
-
* Nothing here names a language or a framework (rule 1) — every field is a
|
|
29
|
-
* property of a rendered document.
|
|
30
|
-
*/
|
|
31
|
-
/** How much of the application this page is likely to expose. Four values, ordered worst-last. */
|
|
32
|
-
export declare const REACH_BANDS: readonly ["full", "partial", "low", "blocked"];
|
|
33
|
-
export type ReachBand = (typeof REACH_BANDS)[number];
|
|
34
|
-
/**
|
|
35
|
-
* The closed vocabulary of reasons reach is at risk. Extend it only with a
|
|
36
|
-
* shape seen in the field — a kind nobody counts is a kind that cannot rank
|
|
37
|
-
* anything, and a kind that overlaps another makes both counts meaningless.
|
|
38
|
-
*/
|
|
39
|
-
export declare const REACH_RISK_KINDS: readonly ["shadowRoot", "childFrame", "crossOriginFrame", "virtualizedRegion", "belowTheFold", "canvasRendered", "overlay", "inertSubtree", "authWall", "challenge", "clientSideRouting"];
|
|
40
|
-
export type ReachRiskKind = (typeof REACH_RISK_KINDS)[number];
|
|
41
|
-
export interface ReachRisk {
|
|
42
|
-
readonly kind: ReachRiskKind;
|
|
43
|
-
/** What was found, with the number that was found. */
|
|
44
|
-
readonly detail: string;
|
|
45
|
-
/** What it costs — stated as a consequence for this run, not as a category. */
|
|
46
|
-
readonly effect: string;
|
|
47
|
-
}
|
|
48
|
-
export interface ReachEstimate {
|
|
49
|
-
readonly band: ReachBand;
|
|
50
|
-
readonly risks: readonly ReachRisk[];
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* What one probe of a page found. Counts, never verdicts: a fingerprint is
|
|
54
|
-
* evidence, and `estimateReach` is the only thing that turns it into a claim.
|
|
55
|
-
*/
|
|
56
|
-
export interface PageFingerprint {
|
|
57
|
-
readonly url: string;
|
|
58
|
-
/** Interactive elements the snapshot query matched, shadow roots included. */
|
|
59
|
-
readonly interactiveElements: number;
|
|
60
|
-
/** Open shadow roots found. Closed ones cannot be counted at all, which is disclosed rather than reported as zero. */
|
|
61
|
-
readonly openShadowRoots: number;
|
|
62
|
-
/** Of `interactiveElements`, how many live inside a shadow root. These are drivable and unsaveable. */
|
|
63
|
-
readonly shadowInteractiveElements: number;
|
|
64
|
-
readonly childFrames: number;
|
|
65
|
-
readonly crossOriginChildFrames: number;
|
|
66
|
-
/** Regions whose scrollable content exceeds their box — a paged, virtualized or otherwise windowed list. */
|
|
67
|
-
readonly scrollableRegions: number;
|
|
68
|
-
/** Largest canvas area as a share of the viewport, 0–1. */
|
|
69
|
-
readonly canvasViewportShare: number;
|
|
70
|
-
/** Largest canvas area in CSS pixels. Needed alongside the share because a
|
|
71
|
-
* small viewport and a large one disagree about the same canvas. */
|
|
72
|
-
readonly largestCanvasArea: number;
|
|
73
|
-
/** Fixed-position elements covering a large part of the viewport — a consent
|
|
74
|
-
* banner, a cookie wall, an interstitial. Counted because the app underneath
|
|
75
|
-
* one is fully enumerable and completely unclickable, which is the single
|
|
76
|
-
* most misleading state this probe can be in. */
|
|
77
|
-
readonly fixedOverlays: number;
|
|
78
|
-
/** Elements marked `inert`. Their descendants are in the DOM, are enumerated,
|
|
79
|
-
* and are removed from hit-testing and focus entirely. */
|
|
80
|
-
readonly inertSubtrees: number;
|
|
81
|
-
/** Modal dialogs currently open. A modal makes the rest of the document
|
|
82
|
-
* unreachable whether or not anyone marked it inert. */
|
|
83
|
-
readonly openModalDialogs: number;
|
|
84
|
-
readonly passwordFields: number;
|
|
85
|
-
/**
|
|
86
|
-
* Fields declaring `autocomplete="one-time-code"` — a second factor.
|
|
87
|
-
*
|
|
88
|
-
* Counted apart from `passwordFields` because a second-factor screen usually
|
|
89
|
-
* has no password on it, so a session that landed on one would otherwise look
|
|
90
|
-
* like an ordinary page with a text box. It is deliberately **not** a
|
|
91
|
-
* `challenge`: the code is a fact Descry does not have rather than a test it
|
|
92
|
-
* is refusing to sit, and the remedy — seed a session that is already past it
|
|
93
|
-
* — is the same one an auth wall has, so it is reported as the same risk with
|
|
94
|
-
* its own sentence. Matched on the standard attribute alone: a looser match
|
|
95
|
-
* would put a wall in front of an application that has none.
|
|
96
|
-
*/
|
|
97
|
-
readonly oneTimeCodeFields: number;
|
|
98
|
-
/** Markers a human-verification challenge leaves behind, in plain words. Empty is a real "none found", not "did not look". */
|
|
99
|
-
readonly challengeMarkers: readonly string[];
|
|
100
|
-
/** The page changed history without a document navigation. **Null means not
|
|
101
|
-
* probed** — a single static look cannot tell a routed application from a
|
|
102
|
-
* server-rendered one, and `false` there would be a claim nothing supports. */
|
|
103
|
-
readonly clientSideRouting: boolean | null;
|
|
104
|
-
/** Document height over viewport height. 1 means everything is on screen. */
|
|
105
|
-
readonly documentHeightRatio: number;
|
|
106
|
-
}
|
|
107
|
-
export declare function estimateReach(fingerprint: PageFingerprint): ReachEstimate;
|
|
108
|
-
export declare function reachEstimateNotes(estimate: ReachEstimate, notProbedRouting?: boolean): readonly string[];
|
|
109
|
-
//# sourceMappingURL=capability-probe.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"capability-probe.d.ts","sourceRoot":"","sources":["../../src/browser/capability-probe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,kGAAkG;AAClG,eAAO,MAAM,WAAW,gDAAiD,CAAC;AAC1E,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAErD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,2LAYnB,CAAC;AACX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,sDAAsD;IACtD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+EAA+E;IAC/E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAC;CACtC;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC,sHAAsH;IACtH,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,uGAAuG;IACvG,QAAQ,CAAC,yBAAyB,EAAE,MAAM,CAAC;IAC3C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACxC,4GAA4G;IAC5G,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,2DAA2D;IAC3D,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;IACrC;yEACqE;IACrE,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC;;;sDAGkD;IAClD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;+DAC2D;IAC3D,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;6DACyD;IACzD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,8HAA8H;IAC9H,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C;;oFAEgF;IAChF,QAAQ,CAAC,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3C,6EAA6E;IAC7E,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;CACtC;AAgBD,wBAAgB,aAAa,CAAC,WAAW,EAAE,eAAe,GAAG,aAAa,CAiIzE;AAmBD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,aAAa,EAAE,gBAAgB,UAAQ,GAAG,SAAS,MAAM,EAAE,CAkBvG"}
|
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fingerprint the application before driving it, and say up front how much of
|
|
3
|
-
* it is likely reachable. §4.2.
|
|
4
|
-
*
|
|
5
|
-
* ## Why a probe is worth more than it looks
|
|
6
|
-
*
|
|
7
|
-
* The obvious value is expectation-setting: a run that opens by saying "this
|
|
8
|
-
* page has a payment widget in a frame I cannot enter and a canvas I cannot
|
|
9
|
-
* read" is a better run than one that discovers it at the end. The larger value
|
|
10
|
-
* is the second-order one §4.2 names — **the distribution of these fingerprints
|
|
11
|
-
* across real applications is the roadmap.** The corpus in
|
|
12
|
-
* `fixtures/hostile-apps/` was drawn from imagination, which is exactly the
|
|
13
|
-
* method §4 says does not scale. A risk kind counted across real sessions is
|
|
14
|
-
* drawn from the field, and it ranks the work without anybody guessing.
|
|
15
|
-
*
|
|
16
|
-
* That is why `ReachRiskKind` is a small closed vocabulary and not free text.
|
|
17
|
-
* A count is only a roadmap if the same shape lands in the same bucket every
|
|
18
|
-
* time.
|
|
19
|
-
*
|
|
20
|
-
* ## The estimate is pessimistic in exactly one direction
|
|
21
|
-
*
|
|
22
|
-
* `full` requires **zero** named risks. Anything else is at best `partial`. An
|
|
23
|
-
* estimate that reads high and then disappoints is the failure this exists to
|
|
24
|
-
* remove, so the asymmetry is deliberate: a `partial` that turns out to be full
|
|
25
|
-
* coverage costs a sentence of hedging, and a `full` that turns out to be 30%
|
|
26
|
-
* costs the report's credibility.
|
|
27
|
-
*
|
|
28
|
-
* Nothing here names a language or a framework (rule 1) — every field is a
|
|
29
|
-
* property of a rendered document.
|
|
30
|
-
*/
|
|
31
|
-
/** How much of the application this page is likely to expose. Four values, ordered worst-last. */
|
|
32
|
-
export const REACH_BANDS = ["full", "partial", "low", "blocked"];
|
|
33
|
-
/**
|
|
34
|
-
* The closed vocabulary of reasons reach is at risk. Extend it only with a
|
|
35
|
-
* shape seen in the field — a kind nobody counts is a kind that cannot rank
|
|
36
|
-
* anything, and a kind that overlaps another makes both counts meaningless.
|
|
37
|
-
*/
|
|
38
|
-
export const REACH_RISK_KINDS = [
|
|
39
|
-
"shadowRoot",
|
|
40
|
-
"childFrame",
|
|
41
|
-
"crossOriginFrame",
|
|
42
|
-
"virtualizedRegion",
|
|
43
|
-
"belowTheFold",
|
|
44
|
-
"canvasRendered",
|
|
45
|
-
"overlay",
|
|
46
|
-
"inertSubtree",
|
|
47
|
-
"authWall",
|
|
48
|
-
"challenge",
|
|
49
|
-
"clientSideRouting",
|
|
50
|
-
];
|
|
51
|
-
/** Above this share of the viewport, a canvas is the application rather than a chart in it. */
|
|
52
|
-
const CANVAS_DOMINATES = 0.5;
|
|
53
|
-
/**
|
|
54
|
-
* A canvas can be the whole application and still be a quarter of a large
|
|
55
|
-
* viewport — `fixtures/hostile-apps/` app 08 measured 0.25 on a 1280×720
|
|
56
|
-
* window and the share rule alone called it `full` reach, which is the wrong
|
|
57
|
-
* answer about an app with no DOM controls at all. So a large canvas on a page
|
|
58
|
-
* with almost nothing to click also counts. Both numbers are starting values.
|
|
59
|
-
*/
|
|
60
|
-
const CANVAS_LARGE_AREA = 50_000;
|
|
61
|
-
const FEW_CONTROLS = 2;
|
|
62
|
-
/** Below this, a taller-than-viewport document is ordinary rather than a long unvisited page. */
|
|
63
|
-
const TALL_DOCUMENT = 2;
|
|
64
|
-
export function estimateReach(fingerprint) {
|
|
65
|
-
const risks = [];
|
|
66
|
-
if (fingerprint.challengeMarkers.length > 0) {
|
|
67
|
-
risks.push({
|
|
68
|
-
kind: "challenge",
|
|
69
|
-
detail: `A human-verification challenge is present: ${fingerprint.challengeMarkers.join("; ")}.`,
|
|
70
|
-
effect: "Descry does not attempt to pass a challenge, by design. Everything behind this screen is not analysable, " +
|
|
71
|
-
"and reporting it as clean would be the more serious error.",
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
if (fingerprint.passwordFields > 0 || fingerprint.oneTimeCodeFields > 0) {
|
|
75
|
-
const parts = [];
|
|
76
|
-
if (fingerprint.passwordFields > 0) {
|
|
77
|
-
parts.push(`${fingerprint.passwordFields} password field${fingerprint.passwordFields === 1 ? "" : "s"}`);
|
|
78
|
-
}
|
|
79
|
-
if (fingerprint.oneTimeCodeFields > 0) {
|
|
80
|
-
parts.push(`${fingerprint.oneTimeCodeFields} one-time code field${fingerprint.oneTimeCodeFields === 1 ? "" : "s"} (a second factor)`);
|
|
81
|
-
}
|
|
82
|
-
risks.push({
|
|
83
|
-
kind: "authWall",
|
|
84
|
-
detail: `The entry screen has ${parts.join(" and ")}.`,
|
|
85
|
-
effect: "This looks like a sign-in step rather than the application. Without a seeded session, only this screen " +
|
|
86
|
-
"and whatever it links to without signing in can be reached. A second factor in particular is a value " +
|
|
87
|
-
"Descry does not hold and does not try to obtain — a session seeded from past it is the way through.",
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
if (fingerprint.fixedOverlays > 0) {
|
|
91
|
-
risks.push({
|
|
92
|
-
kind: "overlay",
|
|
93
|
-
detail: `${fingerprint.fixedOverlays} fixed element${fingerprint.fixedOverlays === 1 ? "" : "s"} cover${fingerprint.fixedOverlays === 1 ? "s" : ""} a large part of the viewport.`,
|
|
94
|
-
effect: "A consent banner or interstitial over the application leaves every control beneath it enumerable, " +
|
|
95
|
-
"counted and untouchable. Until it is dismissed, an element list of this page describes an app that " +
|
|
96
|
-
"cannot be operated.",
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
if (fingerprint.openModalDialogs > 0 || fingerprint.inertSubtrees > 0) {
|
|
100
|
-
risks.push({
|
|
101
|
-
kind: "inertSubtree",
|
|
102
|
-
detail: `${fingerprint.openModalDialogs} open modal dialog${fingerprint.openModalDialogs === 1 ? "" : "s"} and ` +
|
|
103
|
-
`${fingerprint.inertSubtrees} inert subtree${fingerprint.inertSubtrees === 1 ? "" : "s"} on the page.`,
|
|
104
|
-
effect: "Everything outside the modal is still in the document and still enumerated, but is out of the hit-testing " +
|
|
105
|
-
"and focus trees. A click on it does not time out slowly — it cannot land at all.",
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
if (fingerprint.canvasViewportShare >= CANVAS_DOMINATES ||
|
|
109
|
-
(fingerprint.largestCanvasArea >= CANVAS_LARGE_AREA && fingerprint.interactiveElements <= FEW_CONTROLS)) {
|
|
110
|
-
risks.push({
|
|
111
|
-
kind: "canvasRendered",
|
|
112
|
-
detail: `A canvas covers about ${Math.round(fingerprint.canvasViewportShare * 100)}% of the viewport (${Math.round(fingerprint.largestCanvasArea)} px²).`,
|
|
113
|
-
effect: "Controls drawn into a canvas have no element behind them. Nothing on that surface can be enumerated or " +
|
|
114
|
-
"clicked, and any element reported from inside it is fallback markup that is not on screen.",
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
if (fingerprint.openShadowRoots > 0) {
|
|
118
|
-
risks.push({
|
|
119
|
-
kind: "shadowRoot",
|
|
120
|
-
detail: `${fingerprint.openShadowRoots} open shadow root${fingerprint.openShadowRoots === 1 ? "" : "s"}, holding ${fingerprint.shadowInteractiveElements} interactive element${fingerprint.shadowInteractiveElements === 1 ? "" : "s"}.`,
|
|
121
|
-
effect: "These can be driven this session but cannot be given a stable selector, so none of them can be saved to a " +
|
|
122
|
-
"scenario and replayed.",
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
if (fingerprint.childFrames > fingerprint.crossOriginChildFrames) {
|
|
126
|
-
risks.push({
|
|
127
|
-
kind: "childFrame",
|
|
128
|
-
detail: `${fingerprint.childFrames - fingerprint.crossOriginChildFrames} same-origin frame${fingerprint.childFrames - fingerprint.crossOriginChildFrames === 1 ? "" : "s"} on the page.`,
|
|
129
|
-
effect: "Their contents are enumerated and drivable, but an element inside a frame is given no page-level " +
|
|
130
|
-
"selector — the scenario format has no field to name a frame — so a flow through one cannot be saved " +
|
|
131
|
-
"or replayed.",
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
if (fingerprint.crossOriginChildFrames > 0) {
|
|
135
|
-
risks.push({
|
|
136
|
-
kind: "crossOriginFrame",
|
|
137
|
-
detail: `${fingerprint.crossOriginChildFrames} frame${fingerprint.crossOriginChildFrames === 1 ? "" : "s"} from another origin.`,
|
|
138
|
-
effect: "An embedded third-party surface — payment, auth or chat, typically. It is outside the origin this session " +
|
|
139
|
-
"was consented for, so it is not entered even when it could be.",
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
if (fingerprint.scrollableRegions > 0) {
|
|
143
|
-
risks.push({
|
|
144
|
-
kind: "virtualizedRegion",
|
|
145
|
-
detail: `${fingerprint.scrollableRegions} region${fingerprint.scrollableRegions === 1 ? "" : "s"} scroll independently of the page.`,
|
|
146
|
-
effect: "A windowed list renders only what is in view and destroys what it leaves, so no single snapshot can ever " +
|
|
147
|
-
"contain all of it and a handle taken before a scroll may not survive one.",
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
if (fingerprint.documentHeightRatio >= TALL_DOCUMENT) {
|
|
151
|
-
risks.push({
|
|
152
|
-
kind: "belowTheFold",
|
|
153
|
-
detail: `The document is about ${fingerprint.documentHeightRatio.toFixed(1)}× the viewport height.`,
|
|
154
|
-
effect: "Most of the page was never scrolled to. What is below the fold is unvisited, not absent.",
|
|
155
|
-
});
|
|
156
|
-
}
|
|
157
|
-
if (fingerprint.clientSideRouting === true) {
|
|
158
|
-
risks.push({
|
|
159
|
-
kind: "clientSideRouting",
|
|
160
|
-
detail: "The page changes history without loading a document.",
|
|
161
|
-
effect: "Screens are reached by clicking rather than by URL, so a screen nobody clicked toward was never seen and " +
|
|
162
|
-
"does not appear as a missing page anywhere.",
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
return { band: bandFor(risks), risks };
|
|
166
|
-
}
|
|
167
|
-
function bandFor(risks) {
|
|
168
|
-
if (risks.length === 0)
|
|
169
|
-
return "full";
|
|
170
|
-
const kinds = new Set(risks.map((r) => r.kind));
|
|
171
|
-
if (kinds.has("challenge"))
|
|
172
|
-
return "blocked";
|
|
173
|
-
// A covered or modal-blocked app is `low`, not `partial`: unlike a shadow
|
|
174
|
-
// root or a frame, nothing on the page is operable while it holds.
|
|
175
|
-
if (kinds.has("canvasRendered") || kinds.has("authWall") || kinds.has("overlay") || kinds.has("inertSubtree"))
|
|
176
|
-
return "low";
|
|
177
|
-
return "partial";
|
|
178
|
-
}
|
|
179
|
-
const BAND_SENTENCE = {
|
|
180
|
-
full: "Nothing on this page was recognised as a barrier to reaching it. That is an estimate made before driving anything, not a measurement of what was reached.",
|
|
181
|
-
partial: "Parts of this application are expected to be out of reach. This is an estimate made before driving anything; the reachability report at the end of the session is the measurement.",
|
|
182
|
-
low: "Most of this application is expected to be out of reach. This is an estimate made before driving anything; the reachability report at the end of the session is the measurement.",
|
|
183
|
-
blocked: "This screen is behind a challenge Descry does not attempt to pass. Anything behind it is not analysable — which is a different statement from finding nothing wrong with it.",
|
|
184
|
-
};
|
|
185
|
-
export function reachEstimateNotes(estimate, notProbedRouting = false) {
|
|
186
|
-
const notes = [`Reach estimate: ${estimate.band}. ${BAND_SENTENCE[estimate.band]}`];
|
|
187
|
-
for (const risk of estimate.risks)
|
|
188
|
-
notes.push(`${risk.kind}: ${risk.detail} ${risk.effect}`);
|
|
189
|
-
if (notProbedRouting) {
|
|
190
|
-
notes.push("Whether this application routes on the client was not probed — one static look cannot tell that from a " +
|
|
191
|
-
"server-rendered page. If it does route on the client, screens are reached by clicking rather than by URL, " +
|
|
192
|
-
"and a screen nobody clicked toward is missing from every number here without appearing as a missing page.");
|
|
193
|
-
}
|
|
194
|
-
if (estimate.risks.some((r) => r.kind === "shadowRoot")) {
|
|
195
|
-
notes.push("Only open shadow roots are counted. A closed shadow root cannot be enumerated at all, so its contents are " +
|
|
196
|
-
"neither counted here nor reported as absent — if this application uses one, its controls are missing from " +
|
|
197
|
-
"every number in this session.");
|
|
198
|
-
}
|
|
199
|
-
return notes;
|
|
200
|
-
}
|
|
201
|
-
//# sourceMappingURL=capability-probe.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"capability-probe.js","sourceRoot":"","sources":["../../src/browser/capability-probe.ts"],"names":[],"mappings":"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"}
|