swipium 1.0.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.
- package/LICENSE +21 -0
- package/README.md +295 -0
- package/dist/appMap/automationLink.js +74 -0
- package/dist/appMap/automationLink.js.map +1 -0
- package/dist/appMap/build.js +193 -0
- package/dist/appMap/build.js.map +1 -0
- package/dist/appMap/codeIndex.js +73 -0
- package/dist/appMap/codeIndex.js.map +1 -0
- package/dist/appMap/featureModel.js +83 -0
- package/dist/appMap/featureModel.js.map +1 -0
- package/dist/appMap/firstRunApply.js +131 -0
- package/dist/appMap/firstRunApply.js.map +1 -0
- package/dist/appMap/fsWalk.js +75 -0
- package/dist/appMap/fsWalk.js.map +1 -0
- package/dist/appMap/issues.js +227 -0
- package/dist/appMap/issues.js.map +1 -0
- package/dist/appMap/migrations.js +87 -0
- package/dist/appMap/migrations.js.map +1 -0
- package/dist/appMap/prelaunch.js +66 -0
- package/dist/appMap/prelaunch.js.map +1 -0
- package/dist/appMap/projectRegistry.js +70 -0
- package/dist/appMap/projectRegistry.js.map +1 -0
- package/dist/appMap/provenance.js +52 -0
- package/dist/appMap/provenance.js.map +1 -0
- package/dist/appMap/query.js +118 -0
- package/dist/appMap/query.js.map +1 -0
- package/dist/appMap/runtimeMerge.js +207 -0
- package/dist/appMap/runtimeMerge.js.map +1 -0
- package/dist/appMap/schema.js +65 -0
- package/dist/appMap/schema.js.map +1 -0
- package/dist/appMap/screenMatch.js +75 -0
- package/dist/appMap/screenMatch.js.map +1 -0
- package/dist/appMap/staticScan.js +614 -0
- package/dist/appMap/staticScan.js.map +1 -0
- package/dist/appMap/store.js +173 -0
- package/dist/appMap/store.js.map +1 -0
- package/dist/appMap/tsAstScan.js +184 -0
- package/dist/appMap/tsAstScan.js.map +1 -0
- package/dist/artifacts/bundletool.js +199 -0
- package/dist/artifacts/bundletool.js.map +1 -0
- package/dist/artifacts/resolve.js +388 -0
- package/dist/artifacts/resolve.js.map +1 -0
- package/dist/automationGen/appiumModel.js +129 -0
- package/dist/automationGen/appiumModel.js.map +1 -0
- package/dist/automationGen/ciEmitter.js +80 -0
- package/dist/automationGen/ciEmitter.js.map +1 -0
- package/dist/automationGen/jsEmitter.js +440 -0
- package/dist/automationGen/jsEmitter.js.map +1 -0
- package/dist/automationGen/packagePatch.js +56 -0
- package/dist/automationGen/packagePatch.js.map +1 -0
- package/dist/automationGen/projectProfile.js +317 -0
- package/dist/automationGen/projectProfile.js.map +1 -0
- package/dist/automationGen/pythonEmitter.js +386 -0
- package/dist/automationGen/pythonEmitter.js.map +1 -0
- package/dist/automationGen/readmeEmitter.js +66 -0
- package/dist/automationGen/readmeEmitter.js.map +1 -0
- package/dist/automationGen/suitePlan.js +94 -0
- package/dist/automationGen/suitePlan.js.map +1 -0
- package/dist/automationGen/validation.js +150 -0
- package/dist/automationGen/validation.js.map +1 -0
- package/dist/build/parseBuildLog.js +119 -0
- package/dist/build/parseBuildLog.js.map +1 -0
- package/dist/build/plan.js +150 -0
- package/dist/build/plan.js.map +1 -0
- package/dist/ci/preflight.js +85 -0
- package/dist/ci/preflight.js.map +1 -0
- package/dist/cli/init.js +105 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/scan.js +85 -0
- package/dist/cli/scan.js.map +1 -0
- package/dist/cli/suite.js +85 -0
- package/dist/cli/suite.js.map +1 -0
- package/dist/cli/verify.js +62 -0
- package/dist/cli/verify.js.map +1 -0
- package/dist/consent/consent.js +43 -0
- package/dist/consent/consent.js.map +1 -0
- package/dist/context/detect.js +156 -0
- package/dist/context/detect.js.map +1 -0
- package/dist/context/findApps.js +198 -0
- package/dist/context/findApps.js.map +1 -0
- package/dist/context/projectRoot.js +41 -0
- package/dist/context/projectRoot.js.map +1 -0
- package/dist/context/scan.js +167 -0
- package/dist/context/scan.js.map +1 -0
- package/dist/core/target.js +115 -0
- package/dist/core/target.js.map +1 -0
- package/dist/core/targetPlan.js +140 -0
- package/dist/core/targetPlan.js.map +1 -0
- package/dist/drivers/DirectDriver.js +228 -0
- package/dist/drivers/DirectDriver.js.map +1 -0
- package/dist/drivers/Driver.js +4 -0
- package/dist/drivers/Driver.js.map +1 -0
- package/dist/drivers/SimctlDriver.js +127 -0
- package/dist/drivers/SimctlDriver.js.map +1 -0
- package/dist/drivers/WdaDriver.js +250 -0
- package/dist/drivers/WdaDriver.js.map +1 -0
- package/dist/explore/candidates.js +93 -0
- package/dist/explore/candidates.js.map +1 -0
- package/dist/explore/graph.js +116 -0
- package/dist/explore/graph.js.map +1 -0
- package/dist/explore/memory.js +35 -0
- package/dist/explore/memory.js.map +1 -0
- package/dist/explore/planner.js +105 -0
- package/dist/explore/planner.js.map +1 -0
- package/dist/explore/policy.js +85 -0
- package/dist/explore/policy.js.map +1 -0
- package/dist/explore/runner.js +475 -0
- package/dist/explore/runner.js.map +1 -0
- package/dist/explore/signatures.js +35 -0
- package/dist/explore/signatures.js.map +1 -0
- package/dist/explore/suite.js +55 -0
- package/dist/explore/suite.js.map +1 -0
- package/dist/featureTesting/executionBootstrap.js +140 -0
- package/dist/featureTesting/executionBootstrap.js.map +1 -0
- package/dist/firstRun/authStateMachine.js +83 -0
- package/dist/firstRun/authStateMachine.js.map +1 -0
- package/dist/firstRun/classifyScreen.js +201 -0
- package/dist/firstRun/classifyScreen.js.map +1 -0
- package/dist/firstRun/firstRunPlanner.js +207 -0
- package/dist/firstRun/firstRunPlanner.js.map +1 -0
- package/dist/firstRun/firstRunRunner.js +331 -0
- package/dist/firstRun/firstRunRunner.js.map +1 -0
- package/dist/firstRun/generatedDataPolicy.js +215 -0
- package/dist/firstRun/generatedDataPolicy.js.map +1 -0
- package/dist/firstRun/inputPlanner.js +67 -0
- package/dist/firstRun/inputPlanner.js.map +1 -0
- package/dist/firstRun/onboardingStateMachine.js +46 -0
- package/dist/firstRun/onboardingStateMachine.js.map +1 -0
- package/dist/firstRun/paywallPolicy.js +54 -0
- package/dist/firstRun/paywallPolicy.js.map +1 -0
- package/dist/firstRun/types.js +7 -0
- package/dist/firstRun/types.js.map +1 -0
- package/dist/fixtures/catalog.js +131 -0
- package/dist/fixtures/catalog.js.map +1 -0
- package/dist/flows/discover.js +18 -0
- package/dist/flows/discover.js.map +1 -0
- package/dist/flows/generate.js +211 -0
- package/dist/flows/generate.js.map +1 -0
- package/dist/flows/lint.js +97 -0
- package/dist/flows/lint.js.map +1 -0
- package/dist/flows/pack.js +68 -0
- package/dist/flows/pack.js.map +1 -0
- package/dist/flows/run.js +738 -0
- package/dist/flows/run.js.map +1 -0
- package/dist/flows/schema.js +240 -0
- package/dist/flows/schema.js.map +1 -0
- package/dist/flows/seedExec.js +108 -0
- package/dist/flows/seedExec.js.map +1 -0
- package/dist/flows/templates.js +155 -0
- package/dist/flows/templates.js.map +1 -0
- package/dist/flows/waitGuards.js +12 -0
- package/dist/flows/waitGuards.js.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/ios/signing.js +182 -0
- package/dist/ios/signing.js.map +1 -0
- package/dist/issues/classify.js +186 -0
- package/dist/issues/classify.js.map +1 -0
- package/dist/issues/fingerprint.js +130 -0
- package/dist/issues/fingerprint.js.map +1 -0
- package/dist/issues/index.js +240 -0
- package/dist/issues/index.js.map +1 -0
- package/dist/issues/metrics.js +155 -0
- package/dist/issues/metrics.js.map +1 -0
- package/dist/issues/recurrence.js +193 -0
- package/dist/issues/recurrence.js.map +1 -0
- package/dist/issues/report.js +110 -0
- package/dist/issues/report.js.map +1 -0
- package/dist/issues/reportBridge.js +119 -0
- package/dist/issues/reportBridge.js.map +1 -0
- package/dist/issues/schema.js +90 -0
- package/dist/issues/schema.js.map +1 -0
- package/dist/issues/sourceRevision.js +108 -0
- package/dist/issues/sourceRevision.js.map +1 -0
- package/dist/issues/store.js +155 -0
- package/dist/issues/store.js.map +1 -0
- package/dist/lib/android.js +278 -0
- package/dist/lib/android.js.map +1 -0
- package/dist/lib/commandTemplate.js +55 -0
- package/dist/lib/commandTemplate.js.map +1 -0
- package/dist/lib/coordSpace.js +23 -0
- package/dist/lib/coordSpace.js.map +1 -0
- package/dist/lib/device.js +87 -0
- package/dist/lib/device.js.map +1 -0
- package/dist/lib/gitignore.js +22 -0
- package/dist/lib/gitignore.js.map +1 -0
- package/dist/lib/image.js +97 -0
- package/dist/lib/image.js.map +1 -0
- package/dist/lib/logger.js +8 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/metroState.js +45 -0
- package/dist/lib/metroState.js.map +1 -0
- package/dist/lib/needsInput.js +201 -0
- package/dist/lib/needsInput.js.map +1 -0
- package/dist/lib/png.js +103 -0
- package/dist/lib/png.js.map +1 -0
- package/dist/lib/redact.js +21 -0
- package/dist/lib/redact.js.map +1 -0
- package/dist/lib/result.js +87 -0
- package/dist/lib/result.js.map +1 -0
- package/dist/lib/schemaHash.js +65 -0
- package/dist/lib/schemaHash.js.map +1 -0
- package/dist/lib/sensitive.js +13 -0
- package/dist/lib/sensitive.js.map +1 -0
- package/dist/lib/simctl.js +149 -0
- package/dist/lib/simctl.js.map +1 -0
- package/dist/lib/spawn.js +144 -0
- package/dist/lib/spawn.js.map +1 -0
- package/dist/lib/wda.js +347 -0
- package/dist/lib/wda.js.map +1 -0
- package/dist/lib/wdaConfig.js +69 -0
- package/dist/lib/wdaConfig.js.map +1 -0
- package/dist/lib/wdaTune.js +58 -0
- package/dist/lib/wdaTune.js.map +1 -0
- package/dist/oracle/auth.js +22 -0
- package/dist/oracle/auth.js.map +1 -0
- package/dist/oracle/failures.js +193 -0
- package/dist/oracle/failures.js.map +1 -0
- package/dist/oracle/health.js +123 -0
- package/dist/oracle/health.js.map +1 -0
- package/dist/oracle/record.js +36 -0
- package/dist/oracle/record.js.map +1 -0
- package/dist/orchestration/envelope.js +52 -0
- package/dist/orchestration/envelope.js.map +1 -0
- package/dist/orchestration/goal.js +98 -0
- package/dist/orchestration/goal.js.map +1 -0
- package/dist/plan/plan.js +124 -0
- package/dist/plan/plan.js.map +1 -0
- package/dist/prompts/index.js +63 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/report/artifactManifest.js +44 -0
- package/dist/report/artifactManifest.js.map +1 -0
- package/dist/report/coverage.js +60 -0
- package/dist/report/coverage.js.map +1 -0
- package/dist/report/evidence.js +84 -0
- package/dist/report/evidence.js.map +1 -0
- package/dist/report/export.js +447 -0
- package/dist/report/export.js.map +1 -0
- package/dist/report/flake.js +61 -0
- package/dist/report/flake.js.map +1 -0
- package/dist/report/history.js +564 -0
- package/dist/report/history.js.map +1 -0
- package/dist/report/policy.js +98 -0
- package/dist/report/policy.js.map +1 -0
- package/dist/report/qaLevel.js +96 -0
- package/dist/report/qaLevel.js.map +1 -0
- package/dist/report/readiness.js +213 -0
- package/dist/report/readiness.js.map +1 -0
- package/dist/report/summary.js +42 -0
- package/dist/report/summary.js.map +1 -0
- package/dist/report/testCatalog.js +93 -0
- package/dist/report/testCatalog.js.map +1 -0
- package/dist/report/timing.js +37 -0
- package/dist/report/timing.js.map +1 -0
- package/dist/server.js +180 -0
- package/dist/server.js.map +1 -0
- package/dist/services/automationGenerate.js +60 -0
- package/dist/services/automationGenerate.js.map +1 -0
- package/dist/services/build.js +66 -0
- package/dist/services/build.js.map +1 -0
- package/dist/services/preflight.js +51 -0
- package/dist/services/preflight.js.map +1 -0
- package/dist/services/prepareAndroid.js +183 -0
- package/dist/services/prepareAndroid.js.map +1 -0
- package/dist/services/prepareIos.js +162 -0
- package/dist/services/prepareIos.js.map +1 -0
- package/dist/services/report.js +537 -0
- package/dist/services/report.js.map +1 -0
- package/dist/services/smoke.js +120 -0
- package/dist/services/smoke.js.map +1 -0
- package/dist/services/suiteGenerate.js +123 -0
- package/dist/services/suiteGenerate.js.map +1 -0
- package/dist/services/testSuiteKnowledge.js +150 -0
- package/dist/services/testSuiteKnowledge.js.map +1 -0
- package/dist/session/attach.js +47 -0
- package/dist/session/attach.js.map +1 -0
- package/dist/session/progress.js +56 -0
- package/dist/session/progress.js.map +1 -0
- package/dist/session/store.js +329 -0
- package/dist/session/store.js.map +1 -0
- package/dist/snapshot/overlays.js +132 -0
- package/dist/snapshot/overlays.js.map +1 -0
- package/dist/snapshot/parse.js +204 -0
- package/dist/snapshot/parse.js.map +1 -0
- package/dist/snapshot/present.js +12 -0
- package/dist/snapshot/present.js.map +1 -0
- package/dist/snapshot/settle.js +36 -0
- package/dist/snapshot/settle.js.map +1 -0
- package/dist/state/profile.js +318 -0
- package/dist/state/profile.js.map +1 -0
- package/dist/suite/compile.js +176 -0
- package/dist/suite/compile.js.map +1 -0
- package/dist/suite/lint.js +45 -0
- package/dist/suite/lint.js.map +1 -0
- package/dist/suite/pom.js +285 -0
- package/dist/suite/pom.js.map +1 -0
- package/dist/suite/testcase.js +87 -0
- package/dist/suite/testcase.js.map +1 -0
- package/dist/testSuite/generator.js +222 -0
- package/dist/testSuite/generator.js.map +1 -0
- package/dist/testSuite/history.js +44 -0
- package/dist/testSuite/history.js.map +1 -0
- package/dist/testSuite/issueLinks.js +96 -0
- package/dist/testSuite/issueLinks.js.map +1 -0
- package/dist/testSuite/merge.js +190 -0
- package/dist/testSuite/merge.js.map +1 -0
- package/dist/testSuite/schema.js +86 -0
- package/dist/testSuite/schema.js.map +1 -0
- package/dist/testSuite/store.js +116 -0
- package/dist/testSuite/store.js.map +1 -0
- package/dist/testSuite/traceability.js +55 -0
- package/dist/testSuite/traceability.js.map +1 -0
- package/dist/tools/act.js +457 -0
- package/dist/tools/act.js.map +1 -0
- package/dist/tools/agent.js +225 -0
- package/dist/tools/agent.js.map +1 -0
- package/dist/tools/appMap.js +317 -0
- package/dist/tools/appMap.js.map +1 -0
- package/dist/tools/assertVisual.js +74 -0
- package/dist/tools/assertVisual.js.map +1 -0
- package/dist/tools/automationGenerate.js +394 -0
- package/dist/tools/automationGenerate.js.map +1 -0
- package/dist/tools/capabilities.js +114 -0
- package/dist/tools/capabilities.js.map +1 -0
- package/dist/tools/clearOverlay.js +150 -0
- package/dist/tools/clearOverlay.js.map +1 -0
- package/dist/tools/detectContext.js +41 -0
- package/dist/tools/detectContext.js.map +1 -0
- package/dist/tools/doctor.js +116 -0
- package/dist/tools/doctor.js.map +1 -0
- package/dist/tools/explore.js +289 -0
- package/dist/tools/explore.js.map +1 -0
- package/dist/tools/firstRun.js +136 -0
- package/dist/tools/firstRun.js.map +1 -0
- package/dist/tools/flow.js +331 -0
- package/dist/tools/flow.js.map +1 -0
- package/dist/tools/flowGenerate.js +55 -0
- package/dist/tools/flowGenerate.js.map +1 -0
- package/dist/tools/getArtifact.js +39 -0
- package/dist/tools/getArtifact.js.map +1 -0
- package/dist/tools/health.js +41 -0
- package/dist/tools/health.js.map +1 -0
- package/dist/tools/ios.js +492 -0
- package/dist/tools/ios.js.map +1 -0
- package/dist/tools/jobs.js +20 -0
- package/dist/tools/jobs.js.map +1 -0
- package/dist/tools/network.js +50 -0
- package/dist/tools/network.js.map +1 -0
- package/dist/tools/note.js +69 -0
- package/dist/tools/note.js.map +1 -0
- package/dist/tools/plan.js +49 -0
- package/dist/tools/plan.js.map +1 -0
- package/dist/tools/prepareIosTarget.js +99 -0
- package/dist/tools/prepareIosTarget.js.map +1 -0
- package/dist/tools/prepareTarget.js +257 -0
- package/dist/tools/prepareTarget.js.map +1 -0
- package/dist/tools/report.js +42 -0
- package/dist/tools/report.js.map +1 -0
- package/dist/tools/screenRecord.js +24 -0
- package/dist/tools/screenRecord.js.map +1 -0
- package/dist/tools/screenshot.js +63 -0
- package/dist/tools/screenshot.js.map +1 -0
- package/dist/tools/smoke.js +39 -0
- package/dist/tools/smoke.js.map +1 -0
- package/dist/tools/snapshot.js +129 -0
- package/dist/tools/snapshot.js.map +1 -0
- package/dist/tools/startSession.js +169 -0
- package/dist/tools/startSession.js.map +1 -0
- package/dist/tools/state.js +87 -0
- package/dist/tools/state.js.map +1 -0
- package/dist/tools/suite.js +412 -0
- package/dist/tools/suite.js.map +1 -0
- package/dist/tools/testThis.js +774 -0
- package/dist/tools/testThis.js.map +1 -0
- package/dist/tools/wda.js +477 -0
- package/dist/tools/wda.js.map +1 -0
- package/dist/version.js +62 -0
- package/dist/version.js.map +1 -0
- package/dist/visual/ocr.js +72 -0
- package/dist/visual/ocr.js.map +1 -0
- package/dist/visual/provider.js +75 -0
- package/dist/visual/provider.js.map +1 -0
- package/docs/README.md +19 -0
- package/docs/assets/swipium-lockup-ink-on-light.png +0 -0
- package/docs/mcp-server.md +135 -0
- package/docs/tools.md +130 -0
- package/package.json +70 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
// Session + job + artifact store with DISK PERSISTENCE (DESIGN §3, M6).
|
|
2
|
+
// Live, non-serializable bits (driver, lastSnapshot, abort controllers) stay in memory;
|
|
3
|
+
// a serializable subset is written to <sessionDir>/state.json on every mutation, and a
|
|
4
|
+
// small registry under ~/.swipium/registry.json lets a fresh server instance reload
|
|
5
|
+
// prior sessions so artifacts/reports/job-status survive a server restart. (A restart does
|
|
6
|
+
// NOT resurrect a running child process — such jobs are marked failed on reload.)
|
|
7
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
8
|
+
import { mkdirSync, writeFileSync, readFileSync, existsSync } from 'node:fs';
|
|
9
|
+
import { join, resolve } from 'node:path';
|
|
10
|
+
import { homedir } from 'node:os';
|
|
11
|
+
import { DEFAULT_RESPONSE_MODE } from '../lib/result.js';
|
|
12
|
+
import { makeRedactor } from '../lib/redact.js';
|
|
13
|
+
// Phase 2.2 P1.6: budget classes (minutes) keyed by workflow ambition.
|
|
14
|
+
export const BUDGET_PROFILES = {
|
|
15
|
+
guardrail: 8, // guardrail/setup validation
|
|
16
|
+
login_smoke: 10, // login + one workflow
|
|
17
|
+
full_smoke: 15, // full authenticated smoke
|
|
18
|
+
install_smoke: 20, // install/boot/rebuild involved
|
|
19
|
+
};
|
|
20
|
+
// Security model (REQ-02): raw secret values (generated passwords/OTPs/tokens) must never touch
|
|
21
|
+
// disk. In memory we keep the raw value (for same-session reuse via inputValues), but the
|
|
22
|
+
// serialized form sent to state.json redacts secret values while preserving all reproducibility
|
|
23
|
+
// metadata (varName/field/generator/secret/artifactUri/timestamps). Non-secret generated values
|
|
24
|
+
// (e.g. a yopmail email) stay intact for evidence.
|
|
25
|
+
export function serializeGeneratedValues(records) {
|
|
26
|
+
return records.map((r) => (r.secret ? { ...r, value: '<redacted>' } : r));
|
|
27
|
+
}
|
|
28
|
+
export const DEFAULT_BUDGET = {
|
|
29
|
+
maxMinutes: 8,
|
|
30
|
+
maxActions: 20,
|
|
31
|
+
maxScreenshots: 8,
|
|
32
|
+
maxSnapshotFailures: 3,
|
|
33
|
+
maxNoChangeActions: 3,
|
|
34
|
+
};
|
|
35
|
+
const REGISTRY_DIR = join(homedir(), '.swipium');
|
|
36
|
+
const REGISTRY = join(REGISTRY_DIR, 'registry.json');
|
|
37
|
+
const TEXT_MIME_RE = /^(text\/[^;]+|application\/(json|xml|yaml|x-yaml|javascript|x-ndjson)|[^;]+\+(json|xml|yaml))(?:$|;)/i;
|
|
38
|
+
export function isTextArtifactMime(mime) {
|
|
39
|
+
return TEXT_MIME_RE.test(mime);
|
|
40
|
+
}
|
|
41
|
+
export function artifactDirectoryName(kind) {
|
|
42
|
+
switch (kind) {
|
|
43
|
+
case 'screenshot': return 'screenshots';
|
|
44
|
+
case 'recording': return 'videos';
|
|
45
|
+
case 'logs':
|
|
46
|
+
case 'logcat':
|
|
47
|
+
case 'metro':
|
|
48
|
+
case 'wda':
|
|
49
|
+
return 'logs';
|
|
50
|
+
default:
|
|
51
|
+
return kind;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function defaultSessionDir(root, id) {
|
|
55
|
+
const projectHash = createHash('sha256').update(resolve(root)).digest('hex').slice(0, 16);
|
|
56
|
+
return join(REGISTRY_DIR, 'runs', projectHash, id);
|
|
57
|
+
}
|
|
58
|
+
export class SessionStore {
|
|
59
|
+
sessions = new Map();
|
|
60
|
+
constructor() {
|
|
61
|
+
this.loadRegistry();
|
|
62
|
+
}
|
|
63
|
+
create(root, budget, opts) {
|
|
64
|
+
const id = randomUUID().slice(0, 8);
|
|
65
|
+
const dir = opts?.sessionDir ?? defaultSessionDir(root, id);
|
|
66
|
+
mkdirSync(dir, { recursive: true });
|
|
67
|
+
const now = Date.now();
|
|
68
|
+
const s = {
|
|
69
|
+
id, root, dir, createdAt: now, screenshotCount: 0,
|
|
70
|
+
mode: 'structured',
|
|
71
|
+
responseMode: opts?.responseMode ?? DEFAULT_RESPONSE_MODE,
|
|
72
|
+
sensitive: opts?.sensitive ?? false,
|
|
73
|
+
budget: { ...DEFAULT_BUDGET, ...(budget ?? {}) },
|
|
74
|
+
counters: { actions: 0, screenshots: 0, snapshotFailures: 0, noChangeActions: 0 },
|
|
75
|
+
envChanges: [], workarounds: [],
|
|
76
|
+
jobs: new Map(), artifacts: [], findings: [], notes: [], mutations: [], recordedActions: [],
|
|
77
|
+
fixtures: opts?.fixtures ?? [], auth: {}, milestones: { session_start: now }, budgetProfile: opts?.budgetProfile,
|
|
78
|
+
secrets: new Set(), inputs: [], generatedValues: [], inputValues: new Map(), aborts: new Map(),
|
|
79
|
+
};
|
|
80
|
+
this.sessions.set(id, s);
|
|
81
|
+
this.appendRegistry(id, dir);
|
|
82
|
+
this.persist(s);
|
|
83
|
+
return s;
|
|
84
|
+
}
|
|
85
|
+
get(id) {
|
|
86
|
+
return this.sessions.get(id);
|
|
87
|
+
}
|
|
88
|
+
list() {
|
|
89
|
+
return [...this.sessions.values()];
|
|
90
|
+
}
|
|
91
|
+
persist(s) {
|
|
92
|
+
try {
|
|
93
|
+
const state = {
|
|
94
|
+
id: s.id, root: s.root, dir: s.dir, createdAt: s.createdAt,
|
|
95
|
+
device: s.device, appId: s.appId, headless: s.headless, metroPid: s.metroPid, screenshotCount: s.screenshotCount,
|
|
96
|
+
network: s.network, envChanges: s.envChanges, workarounds: s.workarounds,
|
|
97
|
+
mode: s.mode, responseMode: s.responseMode, sensitive: s.sensitive, budget: s.budget, counters: s.counters,
|
|
98
|
+
jobs: [...s.jobs.values()], artifacts: s.artifacts, findings: s.findings, notes: s.notes, mutations: s.mutations, recordedActions: s.recordedActions,
|
|
99
|
+
fixtures: s.fixtures, auth: s.auth, milestones: s.milestones, budgetProfile: s.budgetProfile,
|
|
100
|
+
inputs: s.inputs, // METADATA only — never the values
|
|
101
|
+
generatedValues: serializeGeneratedValues(s.generatedValues), // secret raw values redacted before disk
|
|
102
|
+
exploration: s.exploration,
|
|
103
|
+
};
|
|
104
|
+
writeFileSync(join(s.dir, 'state.json'), JSON.stringify(state, null, 2));
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
/* best-effort */
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// ---- jobs ----
|
|
111
|
+
createJob(s, kind) {
|
|
112
|
+
const job = { jobId: randomUUID().slice(0, 8), kind, status: 'running', startedAt: Date.now(), artifactUris: [] };
|
|
113
|
+
s.jobs.set(job.jobId, job);
|
|
114
|
+
s.aborts.set(job.jobId, new AbortController());
|
|
115
|
+
this.persist(s);
|
|
116
|
+
return job;
|
|
117
|
+
}
|
|
118
|
+
abortSignal(s, jobId) {
|
|
119
|
+
return s.aborts.get(jobId)?.signal;
|
|
120
|
+
}
|
|
121
|
+
// ---- mode + budget + counters (Phase 1) ----
|
|
122
|
+
setMode(s, mode) {
|
|
123
|
+
s.mode = mode;
|
|
124
|
+
this.persist(s);
|
|
125
|
+
}
|
|
126
|
+
bump(s, key, by = 1) {
|
|
127
|
+
s.counters[key] += by;
|
|
128
|
+
this.persist(s);
|
|
129
|
+
}
|
|
130
|
+
/** Returns a stop reason if any budget is exhausted, else null. */
|
|
131
|
+
budgetStop(s) {
|
|
132
|
+
const c = s.counters;
|
|
133
|
+
const b = s.budget;
|
|
134
|
+
const mins = (Date.now() - s.createdAt) / 60000;
|
|
135
|
+
if (mins >= b.maxMinutes)
|
|
136
|
+
return `time budget reached (${mins.toFixed(1)}/${b.maxMinutes} min)`;
|
|
137
|
+
if (c.actions >= b.maxActions)
|
|
138
|
+
return `action budget reached (${c.actions}/${b.maxActions})`;
|
|
139
|
+
if (c.screenshots >= b.maxScreenshots)
|
|
140
|
+
return `screenshot budget reached (${c.screenshots}/${b.maxScreenshots})`;
|
|
141
|
+
if (c.noChangeActions >= b.maxNoChangeActions)
|
|
142
|
+
return `repeated no-change actions (${c.noChangeActions}/${b.maxNoChangeActions}) — likely wrong coords / disabled element / auth wall`;
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
updateJob(s, job, patch) {
|
|
146
|
+
Object.assign(job, patch);
|
|
147
|
+
this.persist(s);
|
|
148
|
+
}
|
|
149
|
+
/** Apply a patch ONLY while the job is still running — so a cancelled (or otherwise
|
|
150
|
+
* terminal) job is never overwritten back to done/failed by a racing worker. */
|
|
151
|
+
updateJobIfRunning(s, job, patch) {
|
|
152
|
+
const cur = s.jobs.get(job.jobId);
|
|
153
|
+
if (!cur || cur.status !== 'running')
|
|
154
|
+
return false;
|
|
155
|
+
Object.assign(cur, patch);
|
|
156
|
+
this.persist(s);
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
cancelJob(s, jobId) {
|
|
160
|
+
const j = s.jobs.get(jobId);
|
|
161
|
+
if (!j || j.status !== 'running')
|
|
162
|
+
return false;
|
|
163
|
+
s.aborts.get(jobId)?.abort();
|
|
164
|
+
j.status = 'cancelled';
|
|
165
|
+
j.endedAt = Date.now();
|
|
166
|
+
this.persist(s);
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
// ---- findings + artifacts ----
|
|
170
|
+
addFinding(s, f) {
|
|
171
|
+
s.findings.push(f);
|
|
172
|
+
this.persist(s);
|
|
173
|
+
}
|
|
174
|
+
addEnvChange(s, note) {
|
|
175
|
+
s.envChanges.push(`${new Date().toISOString()} ${note}`);
|
|
176
|
+
this.persist(s);
|
|
177
|
+
}
|
|
178
|
+
/** Record a safe fallback Swipium chose (roadmap §11 "workarounds attempted"). De-duped. */
|
|
179
|
+
addWorkaround(s, note) {
|
|
180
|
+
if (!s.workarounds.includes(note)) {
|
|
181
|
+
s.workarounds.push(note);
|
|
182
|
+
this.persist(s);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
addNote(s, note) {
|
|
186
|
+
s.notes.push(note);
|
|
187
|
+
this.persist(s);
|
|
188
|
+
}
|
|
189
|
+
recordMutation(s, mutation) {
|
|
190
|
+
const rec = { id: randomUUID().slice(0, 8), at: Date.now(), ...mutation };
|
|
191
|
+
s.mutations.push(rec);
|
|
192
|
+
if (s.mutations.length > 500)
|
|
193
|
+
s.mutations.splice(0, s.mutations.length - 500);
|
|
194
|
+
this.persist(s);
|
|
195
|
+
return rec;
|
|
196
|
+
}
|
|
197
|
+
/** Append an action-IR step (bounded) for qa_flow_generate. */
|
|
198
|
+
addRecordedAction(s, ra) {
|
|
199
|
+
s.recordedActions.push(ra);
|
|
200
|
+
if (s.recordedActions.length > 300)
|
|
201
|
+
s.recordedActions.splice(0, s.recordedActions.length - 300);
|
|
202
|
+
this.persist(s);
|
|
203
|
+
}
|
|
204
|
+
/** Record a phase-timing marker the first time it happens (Phase 2.2 P1.6). */
|
|
205
|
+
milestone(s, key) {
|
|
206
|
+
if (s.milestones[key] == null) {
|
|
207
|
+
s.milestones[key] = Date.now();
|
|
208
|
+
this.persist(s);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/** Add an accumulated duration marker in milliseconds for report timing diagnostics. */
|
|
212
|
+
addMilestoneDuration(s, key, ms) {
|
|
213
|
+
if (!Number.isFinite(ms) || ms < 0)
|
|
214
|
+
return;
|
|
215
|
+
s.milestones[key] = (s.milestones[key] ?? 0) + ms;
|
|
216
|
+
this.persist(s);
|
|
217
|
+
}
|
|
218
|
+
/** Merge an auth-state observation (Phase 2.2 P1.5). */
|
|
219
|
+
markAuth(s, patch) {
|
|
220
|
+
s.auth = { ...s.auth, ...patch };
|
|
221
|
+
this.persist(s);
|
|
222
|
+
}
|
|
223
|
+
/** Store a user-provided input (hardening P0.5). The VALUE stays in-memory only; secrets are
|
|
224
|
+
* added to the redaction set. Persists metadata so reports can say it was provided. */
|
|
225
|
+
setInput(s, varName, value, secret, source) {
|
|
226
|
+
s.inputValues.set(varName, value);
|
|
227
|
+
if (secret)
|
|
228
|
+
s.secrets.add(value);
|
|
229
|
+
const existing = s.inputs.find((i) => i.varName === varName);
|
|
230
|
+
if (existing) {
|
|
231
|
+
existing.secret = secret;
|
|
232
|
+
existing.source = source;
|
|
233
|
+
existing.at = Date.now();
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
s.inputs.push({ varName, secret, source, at: Date.now() });
|
|
237
|
+
}
|
|
238
|
+
this.persist(s);
|
|
239
|
+
}
|
|
240
|
+
/** Variable map (varName → value) for the flow runner. In-memory values only. */
|
|
241
|
+
inputVariables(s) {
|
|
242
|
+
return Object.fromEntries(s.inputValues);
|
|
243
|
+
}
|
|
244
|
+
/** Clear all stored input values (e.g. session close). Metadata is left for the report. */
|
|
245
|
+
clearInputValues(s) {
|
|
246
|
+
s.inputValues.clear();
|
|
247
|
+
}
|
|
248
|
+
/** Record the latest guided-exploration result (Phase 3.3) for qa_report. */
|
|
249
|
+
setExploration(s, rec) {
|
|
250
|
+
s.exploration = rec;
|
|
251
|
+
this.persist(s);
|
|
252
|
+
}
|
|
253
|
+
saveArtifact(s, kind, name, data, mime, label) {
|
|
254
|
+
const sub = join(s.dir, artifactDirectoryName(kind));
|
|
255
|
+
mkdirSync(sub, { recursive: true });
|
|
256
|
+
const path = join(sub, name);
|
|
257
|
+
const redact = makeRedactor(s.secrets);
|
|
258
|
+
const storedData = typeof data === 'string' && isTextArtifactMime(mime) ? (redact(data) ?? '') : data;
|
|
259
|
+
const storedLabel = label ? redact(label) : label;
|
|
260
|
+
writeFileSync(path, storedData);
|
|
261
|
+
const uri = `swipium://session/${s.id}/${kind}/${name}`;
|
|
262
|
+
s.artifacts.push({ uri, path, mime, kind, createdAt: Date.now(), label: storedLabel });
|
|
263
|
+
this.persist(s);
|
|
264
|
+
return uri;
|
|
265
|
+
}
|
|
266
|
+
findArtifact(uri) {
|
|
267
|
+
for (const s of this.sessions.values()) {
|
|
268
|
+
const rec = s.artifacts.find((a) => a.uri === uri);
|
|
269
|
+
if (rec)
|
|
270
|
+
return { session: s, rec };
|
|
271
|
+
}
|
|
272
|
+
return undefined;
|
|
273
|
+
}
|
|
274
|
+
// ---- persistence reload ----
|
|
275
|
+
loadRegistry() {
|
|
276
|
+
try {
|
|
277
|
+
if (!existsSync(REGISTRY))
|
|
278
|
+
return;
|
|
279
|
+
const reg = JSON.parse(readFileSync(REGISTRY, 'utf8'));
|
|
280
|
+
for (const { dir } of reg) {
|
|
281
|
+
const sp = join(dir, 'state.json');
|
|
282
|
+
if (!existsSync(sp))
|
|
283
|
+
continue;
|
|
284
|
+
try {
|
|
285
|
+
const st = JSON.parse(readFileSync(sp, 'utf8'));
|
|
286
|
+
const jobs = new Map((st.jobs ?? []).map((j) => [j.jobId, j]));
|
|
287
|
+
for (const j of jobs.values()) {
|
|
288
|
+
if (j.status === 'running') {
|
|
289
|
+
j.status = 'failed';
|
|
290
|
+
j.error = 'server restarted while job was running (child process gone)';
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
const s = {
|
|
294
|
+
id: st.id, root: st.root, dir: st.dir, createdAt: st.createdAt,
|
|
295
|
+
device: st.device, appId: st.appId, headless: st.headless, metroPid: st.metroPid, screenshotCount: st.screenshotCount ?? 0,
|
|
296
|
+
network: st.network, envChanges: st.envChanges ?? [], workarounds: st.workarounds ?? [],
|
|
297
|
+
mode: st.mode ?? 'structured',
|
|
298
|
+
responseMode: st.responseMode ?? DEFAULT_RESPONSE_MODE,
|
|
299
|
+
sensitive: st.sensitive ?? false,
|
|
300
|
+
budget: { ...DEFAULT_BUDGET, ...(st.budget ?? {}) },
|
|
301
|
+
counters: { actions: 0, screenshots: 0, snapshotFailures: 0, noChangeActions: 0, ...(st.counters ?? {}) },
|
|
302
|
+
jobs, artifacts: st.artifacts ?? [], findings: st.findings ?? [], notes: st.notes ?? [], mutations: st.mutations ?? [], recordedActions: st.recordedActions ?? [],
|
|
303
|
+
fixtures: st.fixtures ?? [], auth: st.auth ?? {}, milestones: st.milestones ?? { session_start: st.createdAt }, budgetProfile: st.budgetProfile,
|
|
304
|
+
secrets: new Set(), inputs: st.inputs ?? [], generatedValues: st.generatedValues ?? [], inputValues: new Map(), exploration: st.exploration, aborts: new Map(),
|
|
305
|
+
};
|
|
306
|
+
this.sessions.set(s.id, s);
|
|
307
|
+
}
|
|
308
|
+
catch {
|
|
309
|
+
/* skip a corrupt session */
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
catch {
|
|
314
|
+
/* no registry */
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
appendRegistry(id, dir) {
|
|
318
|
+
try {
|
|
319
|
+
mkdirSync(REGISTRY_DIR, { recursive: true });
|
|
320
|
+
const reg = existsSync(REGISTRY) ? JSON.parse(readFileSync(REGISTRY, 'utf8')) : [];
|
|
321
|
+
reg.push({ id, dir });
|
|
322
|
+
writeFileSync(REGISTRY, JSON.stringify(reg.slice(-200), null, 2));
|
|
323
|
+
}
|
|
324
|
+
catch {
|
|
325
|
+
/* best-effort */
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/session/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// Overlay detection + tap-obstruction analysis (Phase 2 CR4). Works from a single-window
|
|
2
|
+
// uiautomator dump (allNodes, DFS-ordered). Toasts are NOT in the dump (separate windows);
|
|
3
|
+
// keyboard + foreground-owner are detected by the caller via the driver and merged in.
|
|
4
|
+
import { boundsContain } from './parse.js';
|
|
5
|
+
const LOGBOX_RE = /open debugger|view warnings|LogBox|\b\d+ (warning|error)s?\b/i;
|
|
6
|
+
const REDBOX_RE = /unhandled (js|javascript) exception|render error|reload\b.*\bdismiss/i;
|
|
7
|
+
/** Overlays visible in the current window's UI tree (not toasts/IME/foreign — see callers). */
|
|
8
|
+
const DISMISS_RE = /close|dismiss|got it|ok\b|minimize|×|✕|✖/i;
|
|
9
|
+
/**
|
|
10
|
+
* Heuristic detector for persistent in-app debug banners / snackbars / toast-like RN views
|
|
11
|
+
* (RevenueCat debug banner, custom error toasts, etc.) that the id/class detectors miss.
|
|
12
|
+
* A banner is a wide, short, edge-pinned content block that is NOT the full screen.
|
|
13
|
+
*/
|
|
14
|
+
function detectBanners(allNodes, screen) {
|
|
15
|
+
if (!screen)
|
|
16
|
+
return [];
|
|
17
|
+
const [sw, sh] = screen;
|
|
18
|
+
if (!sw || !sh)
|
|
19
|
+
return [];
|
|
20
|
+
const out = [];
|
|
21
|
+
for (const n of allNodes) {
|
|
22
|
+
const [x1, y1, x2, y2] = n.bounds;
|
|
23
|
+
const w = x2 - x1;
|
|
24
|
+
const h = y2 - y1;
|
|
25
|
+
if (!(n.text || n.desc) || w <= 0 || h <= 0)
|
|
26
|
+
continue;
|
|
27
|
+
const wideEnough = w >= sw * 0.6;
|
|
28
|
+
const shortEnough = h <= sh * 0.22 && h >= sh * 0.02;
|
|
29
|
+
const atTop = y1 <= sh * 0.16;
|
|
30
|
+
const atBottom = y2 >= sh * 0.82;
|
|
31
|
+
const fullScreen = h >= sh * 0.85;
|
|
32
|
+
if (!wideEnough || !shortEnough || fullScreen || (!atTop && !atBottom))
|
|
33
|
+
continue;
|
|
34
|
+
const sub = allNodes.filter((m) => m.dfs >= n.dfs && m.dfs <= n.subtreeEnd);
|
|
35
|
+
const dismissible = sub.some((m) => (m.clickable || m.cls.includes('Button')) && DISMISS_RE.test(`${m.text} ${m.desc}`));
|
|
36
|
+
const label = (n.text || n.desc).trim().slice(0, 60);
|
|
37
|
+
out.push({ type: atBottom ? 'snackbar' : 'banner', detail: `${atBottom ? 'bottom snackbar/banner' : 'top banner'}: "${label}"`, bounds: n.bounds, dismissible });
|
|
38
|
+
}
|
|
39
|
+
const dedupe = (band) => {
|
|
40
|
+
const inBand = out.filter((o) => o.type === band);
|
|
41
|
+
return inBand.length ? [inBand[inBand.length - 1]] : [];
|
|
42
|
+
};
|
|
43
|
+
return [...dedupe('banner'), ...dedupe('snackbar')];
|
|
44
|
+
}
|
|
45
|
+
export function detectTreeOverlays(allNodes, screen) {
|
|
46
|
+
const out = [];
|
|
47
|
+
const text = (n) => `${n.text} ${n.desc}`;
|
|
48
|
+
const joined = allNodes.map(text).join(' ');
|
|
49
|
+
if (REDBOX_RE.test(joined)) {
|
|
50
|
+
out.push({ type: 'rn_redbox', detail: 'React Native redbox (fatal JS error) overlay' });
|
|
51
|
+
}
|
|
52
|
+
else if (LOGBOX_RE.test(joined)) {
|
|
53
|
+
const node = allNodes.find((n) => LOGBOX_RE.test(text(n)));
|
|
54
|
+
out.push({ type: 'rn_logbox', detail: 'React Native LogBox warning/error overlay', bounds: node?.bounds });
|
|
55
|
+
}
|
|
56
|
+
// Native AlertDialog (incl. the standard button ids).
|
|
57
|
+
const dlg = allNodes.find((n) => /AlertDialog|android:id\/(button1|alertTitle)/.test(`${n.cls} ${n.id}`));
|
|
58
|
+
if (dlg)
|
|
59
|
+
out.push({ type: 'native_dialog', detail: `native dialog (${dlg.cls.split('.').pop()})`, bounds: dlg.bounds });
|
|
60
|
+
// Material Snackbar (in-tree, by id).
|
|
61
|
+
const snack = allNodes.find((n) => /snackbar_text|snackbar_action/.test(n.id));
|
|
62
|
+
if (snack)
|
|
63
|
+
out.push({ type: 'snackbar', detail: 'Material snackbar', bounds: snack.bounds });
|
|
64
|
+
// Heuristic banners/snackbars the id/class checks miss (RN debug banners etc.), de-duped
|
|
65
|
+
// against the explicit detections above.
|
|
66
|
+
const haveSnack = out.some((o) => o.type === 'snackbar');
|
|
67
|
+
const haveRn = out.some((o) => o.type === 'rn_logbox' || o.type === 'rn_redbox');
|
|
68
|
+
for (const b of detectBanners(allNodes, screen)) {
|
|
69
|
+
if (b.type === 'snackbar' && haveSnack)
|
|
70
|
+
continue;
|
|
71
|
+
if (b.type === 'banner' && haveRn)
|
|
72
|
+
continue; // likely the LogBox banner already reported
|
|
73
|
+
out.push(b);
|
|
74
|
+
}
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
const UNABLE_TO_LOAD_RE = /unable to load script|loadJSBundleFromAssets|index\.android\.bundle|could not connect to development server/i;
|
|
78
|
+
/** Detect the RN red-box and whether it's the fatal "unable to load JS bundle" variant. */
|
|
79
|
+
export function detectRedBox(allNodes) {
|
|
80
|
+
const joined = allNodes.map((n) => `${n.text} ${n.desc}`).join(' ');
|
|
81
|
+
const present = REDBOX_RE.test(joined) || UNABLE_TO_LOAD_RE.test(joined);
|
|
82
|
+
return { present, unableToLoadScript: UNABLE_TO_LOAD_RE.test(joined) };
|
|
83
|
+
}
|
|
84
|
+
/** Classify the foreground owner string into an overlay class (system/foreign surfaces). */
|
|
85
|
+
export function classifyForeground(appId, foreground) {
|
|
86
|
+
if (appId && foreground.startsWith(appId))
|
|
87
|
+
return null;
|
|
88
|
+
if (/permissioncontroller/i.test(foreground))
|
|
89
|
+
return { type: 'permission_dialog', detail: foreground };
|
|
90
|
+
if (/accountpicker|account\.|gms/i.test(foreground))
|
|
91
|
+
return { type: 'account_picker', detail: foreground };
|
|
92
|
+
if (/launcher/i.test(foreground))
|
|
93
|
+
return null; // not an overlay — handled by health
|
|
94
|
+
if (/inputmethod/i.test(foreground))
|
|
95
|
+
return { type: 'keyboard', detail: foreground };
|
|
96
|
+
if (foreground && foreground !== 'unknown')
|
|
97
|
+
return { type: 'foreign_app', detail: foreground };
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Is the point (x,y) — typically the center of the intended target — covered by content
|
|
102
|
+
* drawn ON TOP of the target's subtree? Topmost = greatest DFS index among nodes containing
|
|
103
|
+
* the point; an obstruction is a topmost node OUTSIDE the target's subtree that carries
|
|
104
|
+
* visible content (text/desc/clickable or a known overlay class).
|
|
105
|
+
*/
|
|
106
|
+
export function obstructionAt(allNodes, target, x, y) {
|
|
107
|
+
const containing = allNodes.filter((n) => boundsContain(n.bounds, x, y));
|
|
108
|
+
if (containing.length === 0)
|
|
109
|
+
return { obstructed: false };
|
|
110
|
+
// Topmost = greatest DFS (pre-order) index among containing nodes. `drawing-order` is only
|
|
111
|
+
// meaningful among SIBLINGS (per-parent); comparing it globally across unrelated branches
|
|
112
|
+
// misclassifies, so we use DFS order as the safe global signal (later DFS = drawn later).
|
|
113
|
+
const topmost = containing.reduce((a, b) => (b.dfs > a.dfs ? b : a));
|
|
114
|
+
if (!target) {
|
|
115
|
+
// no known target → only flag if the topmost is clearly an overlay-ish content node
|
|
116
|
+
const looksOverlay = !!(topmost.text || topmost.desc) && topmost.isLeaf;
|
|
117
|
+
return looksOverlay ? { obstructed: false } : { obstructed: false };
|
|
118
|
+
}
|
|
119
|
+
const withinTarget = topmost.dfs >= target.dfs && topmost.dfs <= target.subtreeEnd;
|
|
120
|
+
const isAncestor = topmost.dfs <= target.dfs && topmost.subtreeEnd >= target.subtreeEnd;
|
|
121
|
+
if (withinTarget || isAncestor)
|
|
122
|
+
return { obstructed: false };
|
|
123
|
+
// topmost is outside the target subtree and on top → only an obstruction if it's real content
|
|
124
|
+
const realContent = !!(topmost.text || topmost.desc) || topmost.clickable;
|
|
125
|
+
if (!realContent)
|
|
126
|
+
return { obstructed: false };
|
|
127
|
+
return {
|
|
128
|
+
obstructed: true,
|
|
129
|
+
by: { cls: topmost.cls, id: topmost.id || undefined, text: (topmost.text || topmost.desc) || undefined, bounds: topmost.bounds },
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=overlays.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overlays.js","sourceRoot":"","sources":["../../src/snapshot/overlays.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,2FAA2F;AAC3F,uFAAuF;AAEvF,OAAO,EAAE,aAAa,EAAgB,MAAM,YAAY,CAAC;AAsBzD,MAAM,SAAS,GAAG,+DAA+D,CAAC;AAClF,MAAM,SAAS,GAAG,uEAAuE,CAAC;AAE1F,+FAA+F;AAC/F,MAAM,UAAU,GAAG,2CAA2C,CAAC;AAE/D;;;;GAIG;AACH,SAAS,aAAa,CAAC,QAAmB,EAAE,MAAyB;IACnE,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,CAAC;IAC1B,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;QAClC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;QAClB,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;QAClB,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,SAAS;QACtD,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,GAAG,GAAG,CAAC;QACjC,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC;QACrD,MAAM,KAAK,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;QAC9B,MAAM,QAAQ,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;QACjC,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC;QAClC,IAAI,CAAC,UAAU,IAAI,CAAC,WAAW,IAAI,UAAU,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC;YAAE,SAAS;QACjF,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC;QAC5E,MAAM,WAAW,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACzH,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACrD,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,YAAY,MAAM,KAAK,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC;IACnK,CAAC;IACD,MAAM,MAAM,GAAG,CAAC,IAAiB,EAAE,EAAE;QACnC,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;QAClD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1D,CAAC,CAAC;IACF,OAAO,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,QAAmB,EAAE,MAAyB;IAC/E,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,MAAM,IAAI,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IACnD,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAE9C,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,8CAA8C,EAAE,CAAC,CAAC;IAC1F,CAAC;SAAM,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3D,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,2CAA2C,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7G,CAAC;IAED,sDAAsD;IACtD,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,8CAA8C,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC1G,IAAI,GAAG;QAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,kBAAkB,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAExH,sCAAsC;IACtC,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,+BAA+B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/E,IAAI,KAAK;QAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAE7F,yFAAyF;IACzF,yCAAyC;IACzC,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC;IACjF,KAAK,MAAM,CAAC,IAAI,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC;QAChD,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU,IAAI,SAAS;YAAE,SAAS;QACjD,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM;YAAE,SAAS,CAAC,4CAA4C;QACzF,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACd,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,iBAAiB,GAAG,8GAA8G,CAAC;AAEzI,2FAA2F;AAC3F,MAAM,UAAU,YAAY,CAAC,QAAmB;IAC9C,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrE,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACzE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;AACzE,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,kBAAkB,CAAC,KAAyB,EAAE,UAAkB;IAC9E,IAAI,KAAK,IAAI,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACvD,IAAI,uBAAuB,CAAC,IAAI,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IACvG,IAAI,8BAA8B,CAAC,IAAI,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAC3G,IAAI,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,qCAAqC;IACpF,IAAI,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IACrF,IAAI,UAAU,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAC/F,OAAO,IAAI,CAAC;AACd,CAAC;AAOD;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,QAAmB,EAAE,MAA2B,EAAE,CAAS,EAAE,CAAS;IAClG,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACzE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IAC1D,2FAA2F;IAC3F,0FAA0F;IAC1F,0FAA0F;IAC1F,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,oFAAoF;QACpF,MAAM,YAAY,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC;QACxE,OAAO,YAAY,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IACtE,CAAC;IACD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,IAAI,MAAM,CAAC,UAAU,CAAC;IACnF,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC;IACxF,IAAI,YAAY,IAAI,UAAU;QAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IAC7D,8FAA8F;IAC9F,MAAM,WAAW,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,SAAS,CAAC;IAC1E,IAAI,CAAC,WAAW;QAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IAC/C,OAAO;QACL,UAAU,EAAE,IAAI;QAChB,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,SAAS,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;KACjI,CAAC;AACJ,CAAC"}
|