From f5eaa306efd65e730e8745029a68a42bd2018c9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Mon, 7 Sep 2026 13:12:53 +0200 Subject: [PATCH 1/8] refactor(capture-kit): relocate snapshot and recording zones into capture-kit Move the ADR 0019 end-state capture zones into @agent-device/capture-kit: - src/snapshot/** -> packages/capture-kit/src/snapshot/** (presentation, freshness, scroll-edge-state, ios-snapshot-runtime, android occlusion) - src/recording/** -> packages/capture-kit/src/recording/** - src/core/snapshot-{chrome,state,tree-ingestion,node-lookup}.ts -> packages/capture-kit/src/ - src/snapshot-quality/ test -> capture-kit presentation tree (directory retires with its last file) Pure renames: import re-pointing and gate updates follow in the next commit. The snapshot-desktop-surface test parks in src/__tests__/ because it pins the root eager-import-closure walker. --- .../capture-kit/src}/recording/__tests__/overlay.test.ts | 0 .../src}/recording/__tests__/recording-scripts.test.ts | 0 {src => packages/capture-kit/src}/recording/output-path.test.ts | 0 {src => packages/capture-kit/src}/recording/output-path.ts | 0 {src => packages/capture-kit/src}/recording/overlay.ts | 0 {src => packages/capture-kit/src}/recording/swift-cache.test.ts | 0 {src => packages/capture-kit/src}/recording/swift-cache.ts | 0 {src => packages/capture-kit/src}/recording/telemetry.ts | 0 {src => packages/capture-kit/src}/recording/video-webm.test.ts | 0 {src => packages/capture-kit/src}/recording/video-webm.ts | 0 {src => packages/capture-kit/src}/recording/video.test.ts | 0 {src => packages/capture-kit/src}/recording/video.ts | 0 .../capture-kit/src}/snapshot-chrome.test.ts | 0 {src/core => packages/capture-kit/src}/snapshot-chrome.ts | 0 .../capture-kit/src}/snapshot-node-lookup.test.ts | 0 {src/core => packages/capture-kit/src}/snapshot-node-lookup.ts | 0 {src/core => packages/capture-kit/src}/snapshot-state.ts | 0 .../capture-kit/src}/snapshot-tree-ingestion.test.ts | 0 {src/core => packages/capture-kit/src}/snapshot-tree-ingestion.ts | 0 .../__tests__/android-replacement-surface-occlusion.test.ts | 0 .../capture-kit/src}/snapshot/__tests__/ax-digest.test.ts | 0 .../capture-kit/src}/snapshot/__tests__/rect-coverage.test.ts | 0 .../snapshot/__tests__/scroll-edge-state-broad-selection.test.ts | 0 .../__tests__/scroll-edge-state-container-existence.test.ts | 0 .../src}/snapshot/__tests__/scroll-edge-state-fixtures.ts | 0 .../src}/snapshot/__tests__/scroll-edge-state-hidden-edge.test.ts | 0 .../__tests__/scroll-edge-state-pass-orchestration.test.ts | 0 .../src}/snapshot/__tests__/scroll-edge-state-scope.test.ts | 0 .../__tests__/scroll-edge-state-target-resolution.test.ts | 0 .../src}/snapshot/__tests__/snapshot-actions-identity.test.ts | 0 .../src}/snapshot/__tests__/snapshot-freshness-recovery.test.ts | 0 .../src}/snapshot/__tests__/snapshot-freshness.test.ts | 0 .../src}/snapshot/__tests__/snapshot-label-dedup.test.ts | 0 .../src}/snapshot/__tests__/snapshot-lines-custom-actions.test.ts | 0 .../src}/snapshot/__tests__/snapshot-lines-focused.test.ts | 0 .../src}/snapshot/__tests__/snapshot-timeout-policy.test.ts | 0 .../src}/snapshot/__tests__/snapshot-visibility-ios.test.ts | 0 .../src}/snapshot/__tests__/snapshot-visibility.test.ts | 0 .../src}/snapshot/android-replacement-surface-occlusion.ts | 0 .../capture-kit/src}/snapshot/ios-snapshot-runtime.ts | 0 {src => packages/capture-kit/src}/snapshot/rect-coverage.ts | 0 {src => packages/capture-kit/src}/snapshot/scroll-edge-state.ts | 0 .../capture-kit/src}/snapshot/scroll-edge-state/selection.ts | 0 .../capture-kit/src}/snapshot/snapshot-desktop-surface.ts | 0 {src => packages/capture-kit/src}/snapshot/snapshot-diff.ts | 0 {src => packages/capture-kit/src}/snapshot/snapshot-evidence.ts | 0 .../capture-kit/src}/snapshot/snapshot-freshness/android.ts | 0 .../capture-kit/src}/snapshot/snapshot-freshness/index.ts | 0 .../capture-kit/src}/snapshot/snapshot-freshness/recovery.ts | 0 .../capture-kit/src}/snapshot/snapshot-freshness/types.ts | 0 .../capture-kit/src}/snapshot/snapshot-label-dedup.ts | 0 {src => packages/capture-kit/src}/snapshot/snapshot-lines.ts | 0 {src => packages/capture-kit/src}/snapshot/snapshot-node-label.ts | 0 .../src}/snapshot/snapshot-presentation/android/geometry.ts | 0 .../src}/snapshot/snapshot-presentation/android/helper.ts | 0 .../src}/snapshot/snapshot-presentation/android/labels.ts | 0 .../src}/snapshot/snapshot-presentation/android/predicates.ts | 0 .../snapshot/snapshot-presentation/android/structural-noise.ts | 0 .../src}/snapshot/snapshot-presentation/android/tree.ts | 0 .../src}/snapshot/snapshot-presentation/ios/action-shelf.test.ts | 0 .../src}/snapshot/snapshot-presentation/ios/rows.fixtures.ts | 0 .../src}/snapshot/snapshot-presentation/ios/rows.test.ts | 0 .../snapshot/snapshot-presentation/ios/transitions.fixtures.ts | 0 .../src}/snapshot/snapshot-presentation/quality-warnings.ts | 0 .../snapshot/snapshot-presentation/repeated-nav-subtree.test.ts | 0 .../src}/snapshot/snapshot-presentation/repeated-nav-subtree.ts | 0 .../src}/snapshot/snapshot-presentation/text-surface.test.ts | 0 .../src}/snapshot/snapshot-presentation/text-surface.ts | 0 .../src/snapshot/snapshot-presentation}/warnings.test.ts | 0 .../capture-kit/src}/snapshot/snapshot-timeout-policy.ts | 0 {src => packages/capture-kit/src}/snapshot/snapshot-visibility.ts | 0 src/{snapshot => __tests__}/snapshot-desktop-surface.test.ts | 0 72 files changed, 0 insertions(+), 0 deletions(-) rename {src => packages/capture-kit/src}/recording/__tests__/overlay.test.ts (100%) rename {src => packages/capture-kit/src}/recording/__tests__/recording-scripts.test.ts (100%) rename {src => packages/capture-kit/src}/recording/output-path.test.ts (100%) rename {src => packages/capture-kit/src}/recording/output-path.ts (100%) rename {src => packages/capture-kit/src}/recording/overlay.ts (100%) rename {src => packages/capture-kit/src}/recording/swift-cache.test.ts (100%) rename {src => packages/capture-kit/src}/recording/swift-cache.ts (100%) rename {src => packages/capture-kit/src}/recording/telemetry.ts (100%) rename {src => packages/capture-kit/src}/recording/video-webm.test.ts (100%) rename {src => packages/capture-kit/src}/recording/video-webm.ts (100%) rename {src => packages/capture-kit/src}/recording/video.test.ts (100%) rename {src => packages/capture-kit/src}/recording/video.ts (100%) rename {src/core/__tests__ => packages/capture-kit/src}/snapshot-chrome.test.ts (100%) rename {src/core => packages/capture-kit/src}/snapshot-chrome.ts (100%) rename {src/core/__tests__ => packages/capture-kit/src}/snapshot-node-lookup.test.ts (100%) rename {src/core => packages/capture-kit/src}/snapshot-node-lookup.ts (100%) rename {src/core => packages/capture-kit/src}/snapshot-state.ts (100%) rename {src/core/__tests__ => packages/capture-kit/src}/snapshot-tree-ingestion.test.ts (100%) rename {src/core => packages/capture-kit/src}/snapshot-tree-ingestion.ts (100%) rename {src => packages/capture-kit/src}/snapshot/__tests__/android-replacement-surface-occlusion.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/__tests__/ax-digest.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/__tests__/rect-coverage.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/__tests__/scroll-edge-state-broad-selection.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/__tests__/scroll-edge-state-container-existence.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/__tests__/scroll-edge-state-fixtures.ts (100%) rename {src => packages/capture-kit/src}/snapshot/__tests__/scroll-edge-state-hidden-edge.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/__tests__/scroll-edge-state-pass-orchestration.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/__tests__/scroll-edge-state-scope.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/__tests__/scroll-edge-state-target-resolution.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/__tests__/snapshot-actions-identity.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/__tests__/snapshot-freshness-recovery.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/__tests__/snapshot-freshness.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/__tests__/snapshot-label-dedup.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/__tests__/snapshot-lines-custom-actions.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/__tests__/snapshot-lines-focused.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/__tests__/snapshot-timeout-policy.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/__tests__/snapshot-visibility-ios.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/__tests__/snapshot-visibility.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/android-replacement-surface-occlusion.ts (100%) rename {src => packages/capture-kit/src}/snapshot/ios-snapshot-runtime.ts (100%) rename {src => packages/capture-kit/src}/snapshot/rect-coverage.ts (100%) rename {src => packages/capture-kit/src}/snapshot/scroll-edge-state.ts (100%) rename {src => packages/capture-kit/src}/snapshot/scroll-edge-state/selection.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-desktop-surface.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-diff.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-evidence.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-freshness/android.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-freshness/index.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-freshness/recovery.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-freshness/types.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-label-dedup.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-lines.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-node-label.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-presentation/android/geometry.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-presentation/android/helper.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-presentation/android/labels.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-presentation/android/predicates.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-presentation/android/structural-noise.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-presentation/android/tree.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-presentation/ios/action-shelf.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-presentation/ios/rows.fixtures.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-presentation/ios/rows.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-presentation/ios/transitions.fixtures.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-presentation/quality-warnings.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-presentation/repeated-nav-subtree.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-presentation/repeated-nav-subtree.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-presentation/text-surface.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-presentation/text-surface.ts (100%) rename {src/snapshot-quality/__tests__ => packages/capture-kit/src/snapshot/snapshot-presentation}/warnings.test.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-timeout-policy.ts (100%) rename {src => packages/capture-kit/src}/snapshot/snapshot-visibility.ts (100%) rename src/{snapshot => __tests__}/snapshot-desktop-surface.test.ts (100%) diff --git a/src/recording/__tests__/overlay.test.ts b/packages/capture-kit/src/recording/__tests__/overlay.test.ts similarity index 100% rename from src/recording/__tests__/overlay.test.ts rename to packages/capture-kit/src/recording/__tests__/overlay.test.ts diff --git a/src/recording/__tests__/recording-scripts.test.ts b/packages/capture-kit/src/recording/__tests__/recording-scripts.test.ts similarity index 100% rename from src/recording/__tests__/recording-scripts.test.ts rename to packages/capture-kit/src/recording/__tests__/recording-scripts.test.ts diff --git a/src/recording/output-path.test.ts b/packages/capture-kit/src/recording/output-path.test.ts similarity index 100% rename from src/recording/output-path.test.ts rename to packages/capture-kit/src/recording/output-path.test.ts diff --git a/src/recording/output-path.ts b/packages/capture-kit/src/recording/output-path.ts similarity index 100% rename from src/recording/output-path.ts rename to packages/capture-kit/src/recording/output-path.ts diff --git a/src/recording/overlay.ts b/packages/capture-kit/src/recording/overlay.ts similarity index 100% rename from src/recording/overlay.ts rename to packages/capture-kit/src/recording/overlay.ts diff --git a/src/recording/swift-cache.test.ts b/packages/capture-kit/src/recording/swift-cache.test.ts similarity index 100% rename from src/recording/swift-cache.test.ts rename to packages/capture-kit/src/recording/swift-cache.test.ts diff --git a/src/recording/swift-cache.ts b/packages/capture-kit/src/recording/swift-cache.ts similarity index 100% rename from src/recording/swift-cache.ts rename to packages/capture-kit/src/recording/swift-cache.ts diff --git a/src/recording/telemetry.ts b/packages/capture-kit/src/recording/telemetry.ts similarity index 100% rename from src/recording/telemetry.ts rename to packages/capture-kit/src/recording/telemetry.ts diff --git a/src/recording/video-webm.test.ts b/packages/capture-kit/src/recording/video-webm.test.ts similarity index 100% rename from src/recording/video-webm.test.ts rename to packages/capture-kit/src/recording/video-webm.test.ts diff --git a/src/recording/video-webm.ts b/packages/capture-kit/src/recording/video-webm.ts similarity index 100% rename from src/recording/video-webm.ts rename to packages/capture-kit/src/recording/video-webm.ts diff --git a/src/recording/video.test.ts b/packages/capture-kit/src/recording/video.test.ts similarity index 100% rename from src/recording/video.test.ts rename to packages/capture-kit/src/recording/video.test.ts diff --git a/src/recording/video.ts b/packages/capture-kit/src/recording/video.ts similarity index 100% rename from src/recording/video.ts rename to packages/capture-kit/src/recording/video.ts diff --git a/src/core/__tests__/snapshot-chrome.test.ts b/packages/capture-kit/src/snapshot-chrome.test.ts similarity index 100% rename from src/core/__tests__/snapshot-chrome.test.ts rename to packages/capture-kit/src/snapshot-chrome.test.ts diff --git a/src/core/snapshot-chrome.ts b/packages/capture-kit/src/snapshot-chrome.ts similarity index 100% rename from src/core/snapshot-chrome.ts rename to packages/capture-kit/src/snapshot-chrome.ts diff --git a/src/core/__tests__/snapshot-node-lookup.test.ts b/packages/capture-kit/src/snapshot-node-lookup.test.ts similarity index 100% rename from src/core/__tests__/snapshot-node-lookup.test.ts rename to packages/capture-kit/src/snapshot-node-lookup.test.ts diff --git a/src/core/snapshot-node-lookup.ts b/packages/capture-kit/src/snapshot-node-lookup.ts similarity index 100% rename from src/core/snapshot-node-lookup.ts rename to packages/capture-kit/src/snapshot-node-lookup.ts diff --git a/src/core/snapshot-state.ts b/packages/capture-kit/src/snapshot-state.ts similarity index 100% rename from src/core/snapshot-state.ts rename to packages/capture-kit/src/snapshot-state.ts diff --git a/src/core/__tests__/snapshot-tree-ingestion.test.ts b/packages/capture-kit/src/snapshot-tree-ingestion.test.ts similarity index 100% rename from src/core/__tests__/snapshot-tree-ingestion.test.ts rename to packages/capture-kit/src/snapshot-tree-ingestion.test.ts diff --git a/src/core/snapshot-tree-ingestion.ts b/packages/capture-kit/src/snapshot-tree-ingestion.ts similarity index 100% rename from src/core/snapshot-tree-ingestion.ts rename to packages/capture-kit/src/snapshot-tree-ingestion.ts diff --git a/src/snapshot/__tests__/android-replacement-surface-occlusion.test.ts b/packages/capture-kit/src/snapshot/__tests__/android-replacement-surface-occlusion.test.ts similarity index 100% rename from src/snapshot/__tests__/android-replacement-surface-occlusion.test.ts rename to packages/capture-kit/src/snapshot/__tests__/android-replacement-surface-occlusion.test.ts diff --git a/src/snapshot/__tests__/ax-digest.test.ts b/packages/capture-kit/src/snapshot/__tests__/ax-digest.test.ts similarity index 100% rename from src/snapshot/__tests__/ax-digest.test.ts rename to packages/capture-kit/src/snapshot/__tests__/ax-digest.test.ts diff --git a/src/snapshot/__tests__/rect-coverage.test.ts b/packages/capture-kit/src/snapshot/__tests__/rect-coverage.test.ts similarity index 100% rename from src/snapshot/__tests__/rect-coverage.test.ts rename to packages/capture-kit/src/snapshot/__tests__/rect-coverage.test.ts diff --git a/src/snapshot/__tests__/scroll-edge-state-broad-selection.test.ts b/packages/capture-kit/src/snapshot/__tests__/scroll-edge-state-broad-selection.test.ts similarity index 100% rename from src/snapshot/__tests__/scroll-edge-state-broad-selection.test.ts rename to packages/capture-kit/src/snapshot/__tests__/scroll-edge-state-broad-selection.test.ts diff --git a/src/snapshot/__tests__/scroll-edge-state-container-existence.test.ts b/packages/capture-kit/src/snapshot/__tests__/scroll-edge-state-container-existence.test.ts similarity index 100% rename from src/snapshot/__tests__/scroll-edge-state-container-existence.test.ts rename to packages/capture-kit/src/snapshot/__tests__/scroll-edge-state-container-existence.test.ts diff --git a/src/snapshot/__tests__/scroll-edge-state-fixtures.ts b/packages/capture-kit/src/snapshot/__tests__/scroll-edge-state-fixtures.ts similarity index 100% rename from src/snapshot/__tests__/scroll-edge-state-fixtures.ts rename to packages/capture-kit/src/snapshot/__tests__/scroll-edge-state-fixtures.ts diff --git a/src/snapshot/__tests__/scroll-edge-state-hidden-edge.test.ts b/packages/capture-kit/src/snapshot/__tests__/scroll-edge-state-hidden-edge.test.ts similarity index 100% rename from src/snapshot/__tests__/scroll-edge-state-hidden-edge.test.ts rename to packages/capture-kit/src/snapshot/__tests__/scroll-edge-state-hidden-edge.test.ts diff --git a/src/snapshot/__tests__/scroll-edge-state-pass-orchestration.test.ts b/packages/capture-kit/src/snapshot/__tests__/scroll-edge-state-pass-orchestration.test.ts similarity index 100% rename from src/snapshot/__tests__/scroll-edge-state-pass-orchestration.test.ts rename to packages/capture-kit/src/snapshot/__tests__/scroll-edge-state-pass-orchestration.test.ts diff --git a/src/snapshot/__tests__/scroll-edge-state-scope.test.ts b/packages/capture-kit/src/snapshot/__tests__/scroll-edge-state-scope.test.ts similarity index 100% rename from src/snapshot/__tests__/scroll-edge-state-scope.test.ts rename to packages/capture-kit/src/snapshot/__tests__/scroll-edge-state-scope.test.ts diff --git a/src/snapshot/__tests__/scroll-edge-state-target-resolution.test.ts b/packages/capture-kit/src/snapshot/__tests__/scroll-edge-state-target-resolution.test.ts similarity index 100% rename from src/snapshot/__tests__/scroll-edge-state-target-resolution.test.ts rename to packages/capture-kit/src/snapshot/__tests__/scroll-edge-state-target-resolution.test.ts diff --git a/src/snapshot/__tests__/snapshot-actions-identity.test.ts b/packages/capture-kit/src/snapshot/__tests__/snapshot-actions-identity.test.ts similarity index 100% rename from src/snapshot/__tests__/snapshot-actions-identity.test.ts rename to packages/capture-kit/src/snapshot/__tests__/snapshot-actions-identity.test.ts diff --git a/src/snapshot/__tests__/snapshot-freshness-recovery.test.ts b/packages/capture-kit/src/snapshot/__tests__/snapshot-freshness-recovery.test.ts similarity index 100% rename from src/snapshot/__tests__/snapshot-freshness-recovery.test.ts rename to packages/capture-kit/src/snapshot/__tests__/snapshot-freshness-recovery.test.ts diff --git a/src/snapshot/__tests__/snapshot-freshness.test.ts b/packages/capture-kit/src/snapshot/__tests__/snapshot-freshness.test.ts similarity index 100% rename from src/snapshot/__tests__/snapshot-freshness.test.ts rename to packages/capture-kit/src/snapshot/__tests__/snapshot-freshness.test.ts diff --git a/src/snapshot/__tests__/snapshot-label-dedup.test.ts b/packages/capture-kit/src/snapshot/__tests__/snapshot-label-dedup.test.ts similarity index 100% rename from src/snapshot/__tests__/snapshot-label-dedup.test.ts rename to packages/capture-kit/src/snapshot/__tests__/snapshot-label-dedup.test.ts diff --git a/src/snapshot/__tests__/snapshot-lines-custom-actions.test.ts b/packages/capture-kit/src/snapshot/__tests__/snapshot-lines-custom-actions.test.ts similarity index 100% rename from src/snapshot/__tests__/snapshot-lines-custom-actions.test.ts rename to packages/capture-kit/src/snapshot/__tests__/snapshot-lines-custom-actions.test.ts diff --git a/src/snapshot/__tests__/snapshot-lines-focused.test.ts b/packages/capture-kit/src/snapshot/__tests__/snapshot-lines-focused.test.ts similarity index 100% rename from src/snapshot/__tests__/snapshot-lines-focused.test.ts rename to packages/capture-kit/src/snapshot/__tests__/snapshot-lines-focused.test.ts diff --git a/src/snapshot/__tests__/snapshot-timeout-policy.test.ts b/packages/capture-kit/src/snapshot/__tests__/snapshot-timeout-policy.test.ts similarity index 100% rename from src/snapshot/__tests__/snapshot-timeout-policy.test.ts rename to packages/capture-kit/src/snapshot/__tests__/snapshot-timeout-policy.test.ts diff --git a/src/snapshot/__tests__/snapshot-visibility-ios.test.ts b/packages/capture-kit/src/snapshot/__tests__/snapshot-visibility-ios.test.ts similarity index 100% rename from src/snapshot/__tests__/snapshot-visibility-ios.test.ts rename to packages/capture-kit/src/snapshot/__tests__/snapshot-visibility-ios.test.ts diff --git a/src/snapshot/__tests__/snapshot-visibility.test.ts b/packages/capture-kit/src/snapshot/__tests__/snapshot-visibility.test.ts similarity index 100% rename from src/snapshot/__tests__/snapshot-visibility.test.ts rename to packages/capture-kit/src/snapshot/__tests__/snapshot-visibility.test.ts diff --git a/src/snapshot/android-replacement-surface-occlusion.ts b/packages/capture-kit/src/snapshot/android-replacement-surface-occlusion.ts similarity index 100% rename from src/snapshot/android-replacement-surface-occlusion.ts rename to packages/capture-kit/src/snapshot/android-replacement-surface-occlusion.ts diff --git a/src/snapshot/ios-snapshot-runtime.ts b/packages/capture-kit/src/snapshot/ios-snapshot-runtime.ts similarity index 100% rename from src/snapshot/ios-snapshot-runtime.ts rename to packages/capture-kit/src/snapshot/ios-snapshot-runtime.ts diff --git a/src/snapshot/rect-coverage.ts b/packages/capture-kit/src/snapshot/rect-coverage.ts similarity index 100% rename from src/snapshot/rect-coverage.ts rename to packages/capture-kit/src/snapshot/rect-coverage.ts diff --git a/src/snapshot/scroll-edge-state.ts b/packages/capture-kit/src/snapshot/scroll-edge-state.ts similarity index 100% rename from src/snapshot/scroll-edge-state.ts rename to packages/capture-kit/src/snapshot/scroll-edge-state.ts diff --git a/src/snapshot/scroll-edge-state/selection.ts b/packages/capture-kit/src/snapshot/scroll-edge-state/selection.ts similarity index 100% rename from src/snapshot/scroll-edge-state/selection.ts rename to packages/capture-kit/src/snapshot/scroll-edge-state/selection.ts diff --git a/src/snapshot/snapshot-desktop-surface.ts b/packages/capture-kit/src/snapshot/snapshot-desktop-surface.ts similarity index 100% rename from src/snapshot/snapshot-desktop-surface.ts rename to packages/capture-kit/src/snapshot/snapshot-desktop-surface.ts diff --git a/src/snapshot/snapshot-diff.ts b/packages/capture-kit/src/snapshot/snapshot-diff.ts similarity index 100% rename from src/snapshot/snapshot-diff.ts rename to packages/capture-kit/src/snapshot/snapshot-diff.ts diff --git a/src/snapshot/snapshot-evidence.ts b/packages/capture-kit/src/snapshot/snapshot-evidence.ts similarity index 100% rename from src/snapshot/snapshot-evidence.ts rename to packages/capture-kit/src/snapshot/snapshot-evidence.ts diff --git a/src/snapshot/snapshot-freshness/android.ts b/packages/capture-kit/src/snapshot/snapshot-freshness/android.ts similarity index 100% rename from src/snapshot/snapshot-freshness/android.ts rename to packages/capture-kit/src/snapshot/snapshot-freshness/android.ts diff --git a/src/snapshot/snapshot-freshness/index.ts b/packages/capture-kit/src/snapshot/snapshot-freshness/index.ts similarity index 100% rename from src/snapshot/snapshot-freshness/index.ts rename to packages/capture-kit/src/snapshot/snapshot-freshness/index.ts diff --git a/src/snapshot/snapshot-freshness/recovery.ts b/packages/capture-kit/src/snapshot/snapshot-freshness/recovery.ts similarity index 100% rename from src/snapshot/snapshot-freshness/recovery.ts rename to packages/capture-kit/src/snapshot/snapshot-freshness/recovery.ts diff --git a/src/snapshot/snapshot-freshness/types.ts b/packages/capture-kit/src/snapshot/snapshot-freshness/types.ts similarity index 100% rename from src/snapshot/snapshot-freshness/types.ts rename to packages/capture-kit/src/snapshot/snapshot-freshness/types.ts diff --git a/src/snapshot/snapshot-label-dedup.ts b/packages/capture-kit/src/snapshot/snapshot-label-dedup.ts similarity index 100% rename from src/snapshot/snapshot-label-dedup.ts rename to packages/capture-kit/src/snapshot/snapshot-label-dedup.ts diff --git a/src/snapshot/snapshot-lines.ts b/packages/capture-kit/src/snapshot/snapshot-lines.ts similarity index 100% rename from src/snapshot/snapshot-lines.ts rename to packages/capture-kit/src/snapshot/snapshot-lines.ts diff --git a/src/snapshot/snapshot-node-label.ts b/packages/capture-kit/src/snapshot/snapshot-node-label.ts similarity index 100% rename from src/snapshot/snapshot-node-label.ts rename to packages/capture-kit/src/snapshot/snapshot-node-label.ts diff --git a/src/snapshot/snapshot-presentation/android/geometry.ts b/packages/capture-kit/src/snapshot/snapshot-presentation/android/geometry.ts similarity index 100% rename from src/snapshot/snapshot-presentation/android/geometry.ts rename to packages/capture-kit/src/snapshot/snapshot-presentation/android/geometry.ts diff --git a/src/snapshot/snapshot-presentation/android/helper.ts b/packages/capture-kit/src/snapshot/snapshot-presentation/android/helper.ts similarity index 100% rename from src/snapshot/snapshot-presentation/android/helper.ts rename to packages/capture-kit/src/snapshot/snapshot-presentation/android/helper.ts diff --git a/src/snapshot/snapshot-presentation/android/labels.ts b/packages/capture-kit/src/snapshot/snapshot-presentation/android/labels.ts similarity index 100% rename from src/snapshot/snapshot-presentation/android/labels.ts rename to packages/capture-kit/src/snapshot/snapshot-presentation/android/labels.ts diff --git a/src/snapshot/snapshot-presentation/android/predicates.ts b/packages/capture-kit/src/snapshot/snapshot-presentation/android/predicates.ts similarity index 100% rename from src/snapshot/snapshot-presentation/android/predicates.ts rename to packages/capture-kit/src/snapshot/snapshot-presentation/android/predicates.ts diff --git a/src/snapshot/snapshot-presentation/android/structural-noise.ts b/packages/capture-kit/src/snapshot/snapshot-presentation/android/structural-noise.ts similarity index 100% rename from src/snapshot/snapshot-presentation/android/structural-noise.ts rename to packages/capture-kit/src/snapshot/snapshot-presentation/android/structural-noise.ts diff --git a/src/snapshot/snapshot-presentation/android/tree.ts b/packages/capture-kit/src/snapshot/snapshot-presentation/android/tree.ts similarity index 100% rename from src/snapshot/snapshot-presentation/android/tree.ts rename to packages/capture-kit/src/snapshot/snapshot-presentation/android/tree.ts diff --git a/src/snapshot/snapshot-presentation/ios/action-shelf.test.ts b/packages/capture-kit/src/snapshot/snapshot-presentation/ios/action-shelf.test.ts similarity index 100% rename from src/snapshot/snapshot-presentation/ios/action-shelf.test.ts rename to packages/capture-kit/src/snapshot/snapshot-presentation/ios/action-shelf.test.ts diff --git a/src/snapshot/snapshot-presentation/ios/rows.fixtures.ts b/packages/capture-kit/src/snapshot/snapshot-presentation/ios/rows.fixtures.ts similarity index 100% rename from src/snapshot/snapshot-presentation/ios/rows.fixtures.ts rename to packages/capture-kit/src/snapshot/snapshot-presentation/ios/rows.fixtures.ts diff --git a/src/snapshot/snapshot-presentation/ios/rows.test.ts b/packages/capture-kit/src/snapshot/snapshot-presentation/ios/rows.test.ts similarity index 100% rename from src/snapshot/snapshot-presentation/ios/rows.test.ts rename to packages/capture-kit/src/snapshot/snapshot-presentation/ios/rows.test.ts diff --git a/src/snapshot/snapshot-presentation/ios/transitions.fixtures.ts b/packages/capture-kit/src/snapshot/snapshot-presentation/ios/transitions.fixtures.ts similarity index 100% rename from src/snapshot/snapshot-presentation/ios/transitions.fixtures.ts rename to packages/capture-kit/src/snapshot/snapshot-presentation/ios/transitions.fixtures.ts diff --git a/src/snapshot/snapshot-presentation/quality-warnings.ts b/packages/capture-kit/src/snapshot/snapshot-presentation/quality-warnings.ts similarity index 100% rename from src/snapshot/snapshot-presentation/quality-warnings.ts rename to packages/capture-kit/src/snapshot/snapshot-presentation/quality-warnings.ts diff --git a/src/snapshot/snapshot-presentation/repeated-nav-subtree.test.ts b/packages/capture-kit/src/snapshot/snapshot-presentation/repeated-nav-subtree.test.ts similarity index 100% rename from src/snapshot/snapshot-presentation/repeated-nav-subtree.test.ts rename to packages/capture-kit/src/snapshot/snapshot-presentation/repeated-nav-subtree.test.ts diff --git a/src/snapshot/snapshot-presentation/repeated-nav-subtree.ts b/packages/capture-kit/src/snapshot/snapshot-presentation/repeated-nav-subtree.ts similarity index 100% rename from src/snapshot/snapshot-presentation/repeated-nav-subtree.ts rename to packages/capture-kit/src/snapshot/snapshot-presentation/repeated-nav-subtree.ts diff --git a/src/snapshot/snapshot-presentation/text-surface.test.ts b/packages/capture-kit/src/snapshot/snapshot-presentation/text-surface.test.ts similarity index 100% rename from src/snapshot/snapshot-presentation/text-surface.test.ts rename to packages/capture-kit/src/snapshot/snapshot-presentation/text-surface.test.ts diff --git a/src/snapshot/snapshot-presentation/text-surface.ts b/packages/capture-kit/src/snapshot/snapshot-presentation/text-surface.ts similarity index 100% rename from src/snapshot/snapshot-presentation/text-surface.ts rename to packages/capture-kit/src/snapshot/snapshot-presentation/text-surface.ts diff --git a/src/snapshot-quality/__tests__/warnings.test.ts b/packages/capture-kit/src/snapshot/snapshot-presentation/warnings.test.ts similarity index 100% rename from src/snapshot-quality/__tests__/warnings.test.ts rename to packages/capture-kit/src/snapshot/snapshot-presentation/warnings.test.ts diff --git a/src/snapshot/snapshot-timeout-policy.ts b/packages/capture-kit/src/snapshot/snapshot-timeout-policy.ts similarity index 100% rename from src/snapshot/snapshot-timeout-policy.ts rename to packages/capture-kit/src/snapshot/snapshot-timeout-policy.ts diff --git a/src/snapshot/snapshot-visibility.ts b/packages/capture-kit/src/snapshot/snapshot-visibility.ts similarity index 100% rename from src/snapshot/snapshot-visibility.ts rename to packages/capture-kit/src/snapshot/snapshot-visibility.ts diff --git a/src/snapshot/snapshot-desktop-surface.test.ts b/src/__tests__/snapshot-desktop-surface.test.ts similarity index 100% rename from src/snapshot/snapshot-desktop-surface.test.ts rename to src/__tests__/snapshot-desktop-surface.test.ts From d0f66a63efaf52a6371335d069d1f380a287c8de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Mon, 7 Sep 2026 17:58:04 +0200 Subject: [PATCH 2/8] refactor(capture-kit): re-point capture and recording consumers to the new subpaths Rewires every consumer of the relocated snapshot/recording modules to the new @agent-device/capture-kit subpath exports, adds the 23 subpath entries to the capture-kit exports map, fixes the moved recording-scripts test's __dirname-relative paths for the deeper location, and records the completed migration in ADR 0019's end state. --- .../0019-request-bound-platform-runtime.md | 55 ++++------- packages/capture-kit/package.json | 92 +++++++++++++++++++ .../__tests__/test-utils/video-fixtures.ts | 8 ++ .../src/recording/__tests__/overlay.test.ts | 2 +- .../__tests__/recording-scripts.test.ts | 4 +- .../src/recording/swift-cache.test.ts | 2 +- .../src/recording/video-webm.test.ts | 2 +- .../capture-kit/src/recording/video.test.ts | 2 +- .../capture-kit/src/snapshot-chrome.test.ts | 2 +- .../src/snapshot-node-lookup.test.ts | 2 +- .../capture-kit/src/snapshot-node-lookup.ts | 2 +- packages/capture-kit/src/snapshot-state.ts | 10 +- .../src/snapshot-tree-ingestion.test.ts | 2 +- .../snapshot/__tests__/rect-coverage.test.ts | 3 +- .../snapshot-freshness-recovery.test.ts | 2 +- .../__tests__/snapshot-freshness.test.ts | 2 +- .../__tests__/snapshot-visibility-ios.test.ts | 2 +- .../src/snapshot/ios-snapshot-runtime.ts | 7 +- .../snapshot/scroll-edge-state/selection.ts | 2 +- .../ios/action-shelf.test.ts | 2 +- .../snapshot-presentation/ios/rows.test.ts | 2 +- .../snapshot-presentation/warnings.test.ts | 4 +- .../src/snapshot/snapshot-visibility.ts | 2 +- .../help-conformance-sample-producers.ts | 2 +- scripts/help-conformance-sample-outputs.mjs | 2 +- ...id-snapshot-capture-failure-reason.test.ts | 2 +- ...android-snapshot-occlusion-context.test.ts | 4 +- .../android-ui-hierarchy-scope.test.ts | 2 +- src/__tests__/android-ui-hierarchy.test.ts | 2 +- .../snapshot-desktop-surface.test.ts | 15 ++- src/commands/capture/output.ts | 2 +- src/commands/capture/runtime/snapshot.ts | 6 +- src/commands/interaction/output.ts | 2 +- src/commands/interaction/runtime/gestures.ts | 2 +- .../runtime/post-action-observation.ts | 2 +- .../interaction/runtime/resolution.ts | 2 +- .../runtime/selector-action-resolution.ts | 2 +- .../runtime/selector-read-shared.ts | 2 +- .../runtime/selector-read-utils.ts | 2 +- src/commands/interaction/runtime/settle.ts | 11 ++- src/commands/output/snapshot.test.ts | 2 +- src/commands/output/snapshot.ts | 9 +- .../snapshot-chrome-android-statusbar.test.ts | 5 +- src/core/__tests__/snapshot-state.test.ts | 2 +- src/core/interactors/android.ts | 2 +- src/daemon/__tests__/generic-settle.test.ts | 2 +- src/daemon/__tests__/snapshot-capture.test.ts | 2 +- src/daemon/__tests__/snapshot-diff.test.ts | 5 +- .../snapshot-presentation-transitions.test.ts | 4 +- .../snapshot-publication-membership.test.ts | 2 +- .../__tests__/snapshot-quality-latch.test.ts | 2 +- .../android-snapshot-timeout-evidence.ts | 2 +- src/daemon/deferred-interaction-outcome.ts | 2 +- .../__tests__/snapshot-handler.fixtures.ts | 2 +- .../handlers/record-runtime-response.ts | 2 +- src/daemon/handlers/record-runtime.ts | 2 +- src/daemon/interaction-outcome-policy.ts | 2 +- .../internal/__tests__/find.test.ts | 2 +- .../__tests__/interaction-get.test.ts | 2 +- .../interaction-ios-tap-outcome-fixtures.ts | 2 +- .../__tests__/interaction-settle.test.ts | 2 +- .../__tests__/interaction-touch-fixtures.ts | 2 +- .../internal/interaction-ios-tap-outcome.ts | 2 +- .../internal/session-replay-divergence.ts | 4 +- .../session-replay-target-classification.ts | 2 +- .../session-replay-target-verification.ts | 2 +- .../session-replay-video-recording.ts | 2 +- src/daemon/screenshot-crop.ts | 2 +- src/daemon/screenshot-runtime.ts | 2 +- src/daemon/scroll-runtime.ts | 2 +- src/daemon/selector-match-errors.ts | 2 +- src/daemon/selector-text-runtime.ts | 2 +- .../__tests__/session-open-existing.test.ts | 2 +- src/daemon/session-snapshot-freshness.ts | 2 +- src/daemon/session-state.ts | 2 +- src/daemon/snapshot-capture.ts | 6 +- src/daemon/snapshot-interactor-capture.ts | 3 +- src/daemon/snapshot-quality-latch.ts | 2 +- ...atform-runtime-android-observation-host.ts | 2 +- src/platform-runtime-operation-host.ts | 2 +- ...m-runtime-screen-recording-android-host.ts | 2 +- ...me-screen-recording-finalizer-host.test.ts | 8 +- ...runtime-screen-recording-finalizer-host.ts | 10 +- src/remote/daemon-artifacts.ts | 2 +- .../integration/live-device-e2e/assertions.ts | 2 +- ...oud-webdriver-provider-regressions.test.ts | 2 +- 86 files changed, 256 insertions(+), 147 deletions(-) create mode 100644 packages/capture-kit/src/__tests__/test-utils/video-fixtures.ts diff --git a/docs/adr/0019-request-bound-platform-runtime.md b/docs/adr/0019-request-bound-platform-runtime.md index 8894af5ec2..628d665b06 100644 --- a/docs/adr/0019-request-bound-platform-runtime.md +++ b/docs/adr/0019-request-bound-platform-runtime.md @@ -902,42 +902,25 @@ target, unverified**, not a derived number. The root files that remain are either declared host-port adapters (e.g. `adb-host`, bound only by its named root file per Decision §1) or mechanics whose wave has not landed yet — the two are not distinguished by filename and need per-file classification before a target is set. -- `src/recording`, `src/snapshot`, `src/snapshot-quality`, `src/screenshot-diff`. Corrected - 2026-09-03: `packages/capture-kit/src/` already has broad production ownership across - recording (`screen-recording-live-handle.ts`, `screen-recording-completion.ts`, - `screen-recording-options.ts`, consumed by `platform-android`/`platform-apple`/ - `platform-harmonyos`/`platform-web`'s `recording/runtime.ts`), screenshot/diff - (`png.ts`, `png-worker-client.ts`, imported by `src/screenshot-diff/screenshot-diff.ts`), - snapshot quality (`snapshot-quality-verdict.ts`, `snapshot-quality-backend-capabilities.ts` — - `src/snapshot-quality/` now holds only a cross-package regression test, no production file), - occlusion (`snapshot-occlusion.ts`), audio/app-log (`audio-probe-runtime.ts`, - `app-log-live-handle.ts`, consumed by `platform-android`, `platform-apple`, and - `provider-limrun`), and iOS acquisition/engine (`ios-snapshot-acquisition.ts`, - `ios-snapshot-planning.ts`, `ios-snapshot-engine/`, consumed by - `src/snapshot/ios-snapshot-runtime.ts`). ADR §1's amendment already assigns this capture - domain to `capture-kit`; the domain mechanics are migrated. What remains under `src/` in - these four directories, verified file-by-file at HEAD, is daemon-facing composition with no - existing package equivalent, not unmigrated capture mechanics: - - `src/recording/{output-path,overlay,swift-cache,telemetry,video,video-webm}.ts` — video - playability polling, overlay burn-in, telemetry persistence, and output-path resolution, - imported only by `src/platform-runtime-screen-recording-*.ts` and - `src/daemon/handlers/record-runtime*.ts`. Equivalent: none. - - `src/snapshot/ios-snapshot-runtime.ts` and `snapshot-visibility.ts` — composition over the - capture-kit acquisition/planning/engine/semantics calls above. Equivalent: capture-kit - (mechanics already migrated; these are the composition callers). - - `src/snapshot/{android-replacement-surface-occlusion,rect-coverage,scroll-edge-state, - snapshot-desktop-surface,snapshot-diff,snapshot-evidence,snapshot-label-dedup, - snapshot-lines,snapshot-node-label,snapshot-timeout-policy}.ts` — none import capture-kit. - `android-replacement-surface-occlusion.ts` implements a distinct Android-specific - footprint algorithm, not the generic viewport pruning in capture-kit's - `snapshot-occlusion.ts`. Equivalent: none. - - `src/snapshot-quality/__tests__/warnings.test.ts` — the sole survivor in that directory; - exercises `renderSnapshotQualityWarnings` (root) against capture-kit's - `readSnapshotQualityVerdict`. Equivalent: capture-kit (production logic fully migrated). - - `src/screenshot-diff/*.ts` (region split/overlay/summarization/component composition) — - pixel-diff computation and PNG decode/encode already call capture-kit's `png`/ - `png-worker-client`; the root files remain for daemon/CLI diff-report composition. - Equivalent: none (built atop already-migrated capture-kit mechanics). +- `src/recording`, `src/snapshot`, `src/snapshot-quality` — **migrated to + `packages/capture-kit/src/` (2026-09-07)**: the whole trees moved as-is (`recording/`, + `snapshot/` including its `snapshot-presentation/` and `snapshot-freshness/` subtrees), + together with the cross-package `warnings.test.ts` regression test. The four snapshot + modules from `src/core/` (`snapshot-chrome.ts`, `snapshot-state.ts`, + `snapshot-tree-ingestion.ts`, `snapshot-node-lookup.ts`, with their tests) joined the + package root. External consumers (daemon, commands, platform hosts, integration tests) + use package subpath exports (e.g. `@agent-device/capture-kit/snapshot-lines`, + `/recording-video`, `/ios-snapshot-runtime`); `snapshot-tree-ingestion` carries no + subpath because only `snapshot-state.ts` (same package) consumes it. Three tests stayed + at the root — `src/core/__tests__/snapshot-state.test.ts` and + `snapshot-chrome-android-statusbar.test.ts` (pinned to root-owned + `interaction-targeting` and the android UI-hierarchy fixtures) and + `src/__tests__/snapshot-desktop-surface.test.ts` (pinned to the root + eager-import-closure fixtures). +- `src/screenshot-diff/*.ts` (region split/overlay/summarization/component composition) — + pixel-diff computation and PNG decode/encode already call capture-kit's `png`/ + `png-worker-client`; the root files remain for daemon/CLI diff-report composition. + Equivalent: none (built atop already-migrated capture-kit mechanics). - `src/provider-device-runtime.ts`, `src/provider-device-runtimes.ts`, `src/provider-limrun-runtime.ts`, `src/provider-webdriver.ts`. Mostly already thin: the bulk of WebDriver and Limrun provider logic lives in `packages/provider-webdriver/src/` and diff --git a/packages/capture-kit/package.json b/packages/capture-kit/package.json index 143068b171..9642a156a1 100644 --- a/packages/capture-kit/package.json +++ b/packages/capture-kit/package.json @@ -14,6 +14,10 @@ "types": "./src/index.ts", "default": "./src/index.ts" }, + "./android-replacement-surface-occlusion": { + "types": "./src/snapshot/android-replacement-surface-occlusion.ts", + "default": "./src/snapshot/android-replacement-surface-occlusion.ts" + }, "./durable-capture": { "types": "./src/durable-capture/index.ts", "default": "./src/durable-capture/index.ts" @@ -34,6 +38,10 @@ "types": "./src/ios-snapshot-planning.ts", "default": "./src/ios-snapshot-planning.ts" }, + "./ios-snapshot-runtime": { + "types": "./src/snapshot/ios-snapshot-runtime.ts", + "default": "./src/snapshot/ios-snapshot-runtime.ts" + }, "./mobile-snapshot-semantics": { "types": "./src/mobile-snapshot-semantics.ts", "default": "./src/mobile-snapshot-semantics.ts" @@ -66,10 +74,34 @@ "types": "./src/post-gesture-stability.ts", "default": "./src/post-gesture-stability.ts" }, + "./quality-warnings": { + "types": "./src/snapshot/snapshot-presentation/quality-warnings.ts", + "default": "./src/snapshot/snapshot-presentation/quality-warnings.ts" + }, "./react-native-overlay": { "types": "./src/react-native-overlay.ts", "default": "./src/react-native-overlay.ts" }, + "./recording-output-path": { + "types": "./src/recording/output-path.ts", + "default": "./src/recording/output-path.ts" + }, + "./recording-overlay": { + "types": "./src/recording/overlay.ts", + "default": "./src/recording/overlay.ts" + }, + "./recording-telemetry": { + "types": "./src/recording/telemetry.ts", + "default": "./src/recording/telemetry.ts" + }, + "./recording-video": { + "types": "./src/recording/video.ts", + "default": "./src/recording/video.ts" + }, + "./repeated-nav-subtree": { + "types": "./src/snapshot/snapshot-presentation/repeated-nav-subtree.ts", + "default": "./src/snapshot/snapshot-presentation/repeated-nav-subtree.ts" + }, "./screenshot-density": { "types": "./src/screenshot-density.ts", "default": "./src/screenshot-density.ts" @@ -82,14 +114,58 @@ "types": "./src/screenshot-overlay.ts", "default": "./src/screenshot-overlay.ts" }, + "./scroll-edge-state": { + "types": "./src/snapshot/scroll-edge-state.ts", + "default": "./src/snapshot/scroll-edge-state.ts" + }, + "./snapshot-chrome": { + "types": "./src/snapshot-chrome.ts", + "default": "./src/snapshot-chrome.ts" + }, "./snapshot-desktop-projection": { "types": "./src/snapshot-desktop-projection.ts", "default": "./src/snapshot-desktop-projection.ts" }, + "./snapshot-desktop-surface": { + "types": "./src/snapshot/snapshot-desktop-surface.ts", + "default": "./src/snapshot/snapshot-desktop-surface.ts" + }, + "./snapshot-diff": { + "types": "./src/snapshot/snapshot-diff.ts", + "default": "./src/snapshot/snapshot-diff.ts" + }, + "./snapshot-evidence": { + "types": "./src/snapshot/snapshot-evidence.ts", + "default": "./src/snapshot/snapshot-evidence.ts" + }, + "./snapshot-freshness": { + "types": "./src/snapshot/snapshot-freshness/index.ts", + "default": "./src/snapshot/snapshot-freshness/index.ts" + }, + "./snapshot-label-dedup": { + "types": "./src/snapshot/snapshot-label-dedup.ts", + "default": "./src/snapshot/snapshot-label-dedup.ts" + }, + "./snapshot-lines": { + "types": "./src/snapshot/snapshot-lines.ts", + "default": "./src/snapshot/snapshot-lines.ts" + }, + "./snapshot-node-lookup": { + "types": "./src/snapshot-node-lookup.ts", + "default": "./src/snapshot-node-lookup.ts" + }, "./snapshot-occlusion": { "types": "./src/snapshot-occlusion.ts", "default": "./src/snapshot-occlusion.ts" }, + "./snapshot-presentation-android-helper": { + "types": "./src/snapshot/snapshot-presentation/android/helper.ts", + "default": "./src/snapshot/snapshot-presentation/android/helper.ts" + }, + "./snapshot-presentation-ios-transitions-fixtures": { + "types": "./src/snapshot/snapshot-presentation/ios/transitions.fixtures.ts", + "default": "./src/snapshot/snapshot-presentation/ios/transitions.fixtures.ts" + }, "./snapshot-quality-backend-capabilities": { "types": "./src/snapshot-quality-backend-capabilities.ts", "default": "./src/snapshot-quality-backend-capabilities.ts" @@ -101,6 +177,22 @@ "./snapshot-rect-projection": { "types": "./src/snapshot-rect-projection.ts", "default": "./src/snapshot-rect-projection.ts" + }, + "./snapshot-state": { + "types": "./src/snapshot-state.ts", + "default": "./src/snapshot-state.ts" + }, + "./snapshot-timeout-policy": { + "types": "./src/snapshot/snapshot-timeout-policy.ts", + "default": "./src/snapshot/snapshot-timeout-policy.ts" + }, + "./snapshot-visibility": { + "types": "./src/snapshot/snapshot-visibility.ts", + "default": "./src/snapshot/snapshot-visibility.ts" + }, + "./text-surface": { + "types": "./src/snapshot/snapshot-presentation/text-surface.ts", + "default": "./src/snapshot/snapshot-presentation/text-surface.ts" } }, "devDependencies": { diff --git a/packages/capture-kit/src/__tests__/test-utils/video-fixtures.ts b/packages/capture-kit/src/__tests__/test-utils/video-fixtures.ts new file mode 100644 index 0000000000..54f1beba63 --- /dev/null +++ b/packages/capture-kit/src/__tests__/test-utils/video-fixtures.ts @@ -0,0 +1,8 @@ +export function likelyPlayableWebmContainer(): Buffer { + // One 16x16 VP8 keyframe generated by ffmpeg. Unlike a marker-only synthetic fixture, + // ffprobe identifies this as a WebM video stream with a 40ms duration. + return Buffer.from( + 'GkXfo59ChoEBQveBAULygQRC84EIQoKEd2VibUKHgQJChYECGFOAZwEAAAAAAAHpEU2bdLpNu4tTq4QVSalmU6yBoU27i1OrhBZUrmtTrIHYTbuMU6uEElTDZ1OsggElTbuMU6uEHFO7a1OsggHT7AEAAAAAAABZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVSalmsirXsYMPQkBNgI1MYXZmNjIuMTIuMTAxV0GNTGF2ZjYyLjEyLjEwMUSJiEBEAAAAAAAAFlSua8iuAQAAAAAAAD/XgQFzxYgNIomR4viG6pyBACK1nIN1bmSIgQCGhVZfVlA4g4EBI+ODhAJiWgDgkLCBELqBEJqBAlWwhFW5gQESVMNn/HNzoGPAgGfImkWjh0VOQ09ERVJEh41MYXZmNjIuMTIuMTAxc3PWY8CLY8WIDSKJkeL4hupnyKFFo4dFTkNPREVSRIeUTGF2YzYyLjI4LjEwMSBsaWJ2cHhnyKFFo4hEVVJBVElPTkSHkzAwOjAwOjAwLjA0MDAwMDAwMAAfQ7Z1qOeBAKOjgQAAgBACAJ0BKhAAEAAARwiFhYiFhIgCAgAMDWAA/v+rUIAcU7trkbuPs4EAt4r3gQHxggGm8IED', + 'base64', + ); +} diff --git a/packages/capture-kit/src/recording/__tests__/overlay.test.ts b/packages/capture-kit/src/recording/__tests__/overlay.test.ts index b5b7f924b4..aabd5b73e8 100644 --- a/packages/capture-kit/src/recording/__tests__/overlay.test.ts +++ b/packages/capture-kit/src/recording/__tests__/overlay.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, expect, test, vi } from 'vitest'; import fs from 'node:fs'; import path from 'node:path'; -import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; +import { mkdtempForTestSync } from '../../tmp-dir.fixtures.ts'; vi.mock('@agent-device/host-kit/command', async (importOriginal) => { const fs = await import('node:fs'); diff --git a/packages/capture-kit/src/recording/__tests__/recording-scripts.test.ts b/packages/capture-kit/src/recording/__tests__/recording-scripts.test.ts index 5f230feff1..05f9466475 100644 --- a/packages/capture-kit/src/recording/__tests__/recording-scripts.test.ts +++ b/packages/capture-kit/src/recording/__tests__/recording-scripts.test.ts @@ -8,9 +8,9 @@ import { getRecordingOverlaySupportWarning } from '../overlay.ts'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const recordingScriptsDir = path.resolve( __dirname, - '../../../apple/runner/AgentDeviceRunner/RecordingScripts', + '../../../../../apple/runner/AgentDeviceRunner/RecordingScripts', ); -const recordingTestSupportDir = path.resolve(__dirname, '../../../test/integration/support'); +const recordingTestSupportDir = path.resolve(__dirname, '../../../../../test/integration/support'); const SWIFT_TYPECHECK_TIMEOUT_MS = 60_000; let swiftCompilerPath = 'swiftc'; let swiftSdkPath = ''; diff --git a/packages/capture-kit/src/recording/swift-cache.test.ts b/packages/capture-kit/src/recording/swift-cache.test.ts index 10fa03408b..f3d765ae14 100644 --- a/packages/capture-kit/src/recording/swift-cache.test.ts +++ b/packages/capture-kit/src/recording/swift-cache.test.ts @@ -1,7 +1,7 @@ import { afterEach, beforeEach, expect, test, vi } from 'vitest'; import fs from 'node:fs'; import path from 'node:path'; -import { mkdtempForTestSync } from '../__tests__/test-utils/tmp-dir.ts'; +import { mkdtempForTestSync } from '../tmp-dir.fixtures.ts'; vi.mock(import('@agent-device/host-kit/command'), async (importOriginal) => ({ ...(await importOriginal()), diff --git a/packages/capture-kit/src/recording/video-webm.test.ts b/packages/capture-kit/src/recording/video-webm.test.ts index afbde5cd8e..6492b2feea 100644 --- a/packages/capture-kit/src/recording/video-webm.test.ts +++ b/packages/capture-kit/src/recording/video-webm.test.ts @@ -2,7 +2,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { expect, test } from 'vitest'; import { likelyPlayableWebmContainer } from '../__tests__/test-utils/video-fixtures.ts'; -import { mkdtempForTestSync } from '../__tests__/test-utils/tmp-dir.ts'; +import { mkdtempForTestSync } from '../tmp-dir.fixtures.ts'; import { hasPlayableWebmStructure } from './video-webm.ts'; const directory = mkdtempForTestSync('agent-device-video-webm-structure-'); diff --git a/packages/capture-kit/src/recording/video.test.ts b/packages/capture-kit/src/recording/video.test.ts index 0d035ad5a3..d075ec0d7a 100644 --- a/packages/capture-kit/src/recording/video.test.ts +++ b/packages/capture-kit/src/recording/video.test.ts @@ -2,7 +2,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { expect, test } from 'vitest'; import { likelyPlayableWebmContainer } from '../__tests__/test-utils/video-fixtures.ts'; -import { mkdtempForTestSync } from '../__tests__/test-utils/tmp-dir.ts'; +import { mkdtempForTestSync } from '../tmp-dir.fixtures.ts'; import { isPlayableVideo } from './video.ts'; const directory = mkdtempForTestSync('agent-device-video-webm-'); diff --git a/packages/capture-kit/src/snapshot-chrome.test.ts b/packages/capture-kit/src/snapshot-chrome.test.ts index 0edae38f59..55bd3e54e0 100644 --- a/packages/capture-kit/src/snapshot-chrome.test.ts +++ b/packages/capture-kit/src/snapshot-chrome.test.ts @@ -1,7 +1,7 @@ import { test } from 'vitest'; import assert from 'node:assert/strict'; import { attachRefs, type RawSnapshotNode, type SnapshotNode } from '@agent-device/kernel/snapshot'; -import { collectSettleChromeRefs } from '../snapshot-chrome.ts'; +import { collectSettleChromeRefs } from './snapshot-chrome.ts'; function refFor(nodes: SnapshotNode[], label: string): string { const node = nodes.find((candidate) => candidate.label === label); diff --git a/packages/capture-kit/src/snapshot-node-lookup.test.ts b/packages/capture-kit/src/snapshot-node-lookup.test.ts index c0424106c7..cfdb9ec2de 100644 --- a/packages/capture-kit/src/snapshot-node-lookup.test.ts +++ b/packages/capture-kit/src/snapshot-node-lookup.test.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict'; import { test } from 'vitest'; import { attachRefs } from '@agent-device/kernel/snapshot'; -import { findNodeByLabel, resolveRefLabel } from '../snapshot-node-lookup.ts'; +import { findNodeByLabel, resolveRefLabel } from './snapshot-node-lookup.ts'; test('findNodeByLabel matches label, value, and identifier case-insensitively', () => { const nodes = attachRefs([ diff --git a/packages/capture-kit/src/snapshot-node-lookup.ts b/packages/capture-kit/src/snapshot-node-lookup.ts index 43e0bca4a5..13cbeaf434 100644 --- a/packages/capture-kit/src/snapshot-node-lookup.ts +++ b/packages/capture-kit/src/snapshot-node-lookup.ts @@ -1,6 +1,6 @@ import type { SnapshotState } from '@agent-device/kernel/snapshot'; import { extractNodeText, isMeaningfulLabel } from '@agent-device/contracts/snapshot'; -import { findNodeByLabel } from '../snapshot/snapshot-node-label.ts'; +import { findNodeByLabel } from './snapshot/snapshot-node-label.ts'; export { findNodeByLabel }; diff --git a/packages/capture-kit/src/snapshot-state.ts b/packages/capture-kit/src/snapshot-state.ts index 2e6183d0c8..95e3e3c060 100644 --- a/packages/capture-kit/src/snapshot-state.ts +++ b/packages/capture-kit/src/snapshot-state.ts @@ -17,11 +17,11 @@ import { import { annotateCoveredSnapshotNodes, annotateSnapshotNodesCoveredByPolicy, -} from '@agent-device/capture-kit/snapshot-occlusion'; -import { coveredAndroidReplacementNodeIndexes } from '../snapshot/android-replacement-surface-occlusion.ts'; -import { scopeSnapshotNodes } from '@agent-device/capture-kit/snapshot-desktop-projection'; -import { normalizeSnapshotTree, pruneGroupNodes } from '../core/snapshot-tree-ingestion.ts'; -import { iosSnapshotComparisonIdentityKey } from '@agent-device/capture-kit/ios-snapshot-planning'; +} from './snapshot-occlusion.ts'; +import { coveredAndroidReplacementNodeIndexes } from './snapshot/android-replacement-surface-occlusion.ts'; +import { scopeSnapshotNodes } from './snapshot-desktop-projection.ts'; +import { normalizeSnapshotTree, pruneGroupNodes } from './snapshot-tree-ingestion.ts'; +import { iosSnapshotComparisonIdentityKey } from './ios-snapshot-planning.ts'; import type { IosSnapshotComparisonIdentity } from '@agent-device/contracts/ios-snapshot'; /** diff --git a/packages/capture-kit/src/snapshot-tree-ingestion.test.ts b/packages/capture-kit/src/snapshot-tree-ingestion.test.ts index 03b3379df2..9ce916a2c0 100644 --- a/packages/capture-kit/src/snapshot-tree-ingestion.test.ts +++ b/packages/capture-kit/src/snapshot-tree-ingestion.test.ts @@ -1,6 +1,6 @@ import assert from 'node:assert/strict'; import { test } from 'vitest'; -import { normalizeSnapshotTree, pruneGroupNodes } from '../snapshot-tree-ingestion.ts'; +import { normalizeSnapshotTree, pruneGroupNodes } from './snapshot-tree-ingestion.ts'; test('pruneGroupNodes drops unlabeled group wrappers and rebalances depth', () => { const raw = [ diff --git a/packages/capture-kit/src/snapshot/__tests__/rect-coverage.test.ts b/packages/capture-kit/src/snapshot/__tests__/rect-coverage.test.ts index f86d38e699..6e9a3f97d7 100644 --- a/packages/capture-kit/src/snapshot/__tests__/rect-coverage.test.ts +++ b/packages/capture-kit/src/snapshot/__tests__/rect-coverage.test.ts @@ -1,9 +1,10 @@ import type { Rect } from '@agent-device/kernel/snapshot'; import fc from 'fast-check'; import { expect, test } from 'vitest'; -import { PROPERTY_RUNS } from '../../__tests__/test-utils/property-arbitraries.ts'; import { unionCoverage } from '../rect-coverage.ts'; +const PROPERTY_RUNS = 100; + const smallRect = fc.record({ x: fc.integer({ min: -4, max: 20 }), y: fc.integer({ min: -4, max: 20 }), diff --git a/packages/capture-kit/src/snapshot/__tests__/snapshot-freshness-recovery.test.ts b/packages/capture-kit/src/snapshot/__tests__/snapshot-freshness-recovery.test.ts index f90a49038d..14b0174b76 100644 --- a/packages/capture-kit/src/snapshot/__tests__/snapshot-freshness-recovery.test.ts +++ b/packages/capture-kit/src/snapshot/__tests__/snapshot-freshness-recovery.test.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict'; import { test, vi } from 'vitest'; import type { SnapshotCaptureAnnotations } from '@agent-device/contracts/capture'; -import { makeSnapshotState } from '../../__tests__/test-utils/snapshot-builders.ts'; +import { makeSnapshotState } from '../../snapshot-state.fixtures.ts'; import { captureFreshnessRecoveredAttempt } from '../snapshot-freshness/recovery.ts'; import type { SnapshotFreshnessReason, diff --git a/packages/capture-kit/src/snapshot/__tests__/snapshot-freshness.test.ts b/packages/capture-kit/src/snapshot/__tests__/snapshot-freshness.test.ts index 3510714bd4..7a07719d73 100644 --- a/packages/capture-kit/src/snapshot/__tests__/snapshot-freshness.test.ts +++ b/packages/capture-kit/src/snapshot/__tests__/snapshot-freshness.test.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict'; import { test } from 'vitest'; import type { RawSnapshotNode } from '@agent-device/kernel/snapshot'; -import { makeSnapshotState } from '../../__tests__/test-utils/snapshot-builders.ts'; +import { makeSnapshotState } from '../../snapshot-state.fixtures.ts'; import { androidFreshnessReason, buildSnapshotSignatures, diff --git a/packages/capture-kit/src/snapshot/__tests__/snapshot-visibility-ios.test.ts b/packages/capture-kit/src/snapshot/__tests__/snapshot-visibility-ios.test.ts index 79e9e16bb4..8a8f405ced 100644 --- a/packages/capture-kit/src/snapshot/__tests__/snapshot-visibility-ios.test.ts +++ b/packages/capture-kit/src/snapshot/__tests__/snapshot-visibility-ios.test.ts @@ -1,7 +1,7 @@ import { expect, test } from 'vitest'; import { attachRefs, type RawSnapshotNode } from '@agent-device/kernel/snapshot'; import { buildSnapshotVisibility } from '../snapshot-visibility.ts'; -import { presentIosInteractiveSnapshot } from '@agent-device/capture-kit/ios-snapshot-engine'; +import { presentIosInteractiveSnapshot } from '../../ios-snapshot-engine/index.ts'; function buildSnapshotState(data: { nodes?: RawSnapshotNode[]; backend?: 'xctest' }) { return { diff --git a/packages/capture-kit/src/snapshot/ios-snapshot-runtime.ts b/packages/capture-kit/src/snapshot/ios-snapshot-runtime.ts index aaa0a3ad41..d905b815d9 100644 --- a/packages/capture-kit/src/snapshot/ios-snapshot-runtime.ts +++ b/packages/capture-kit/src/snapshot/ios-snapshot-runtime.ts @@ -2,11 +2,8 @@ import { IosSnapshotEngineError, publishIosSnapshot, toIosSnapshotEngineErrorDetails, -} from '@agent-device/capture-kit/ios-snapshot-engine'; -import { - createIosSnapshotRequest, - deriveIosCaptureHint, -} from '@agent-device/capture-kit/ios-snapshot-planning'; +} from '../ios-snapshot-engine/index.ts'; +import { createIosSnapshotRequest, deriveIosCaptureHint } from '../ios-snapshot-planning.ts'; import type { IosAcquisitionResidue, IosSnapshotFact, diff --git a/packages/capture-kit/src/snapshot/scroll-edge-state/selection.ts b/packages/capture-kit/src/snapshot/scroll-edge-state/selection.ts index ac3cb97fe3..4a8fefd456 100644 --- a/packages/capture-kit/src/snapshot/scroll-edge-state/selection.ts +++ b/packages/capture-kit/src/snapshot/scroll-edge-state/selection.ts @@ -1,4 +1,4 @@ -import { deriveMobileSnapshotHiddenContentHints } from '@agent-device/capture-kit/mobile-snapshot-semantics'; +import { deriveMobileSnapshotHiddenContentHints } from '../../mobile-snapshot-semantics.ts'; import { createSnapshotVisibility, isScrollableNodeLike, diff --git a/packages/capture-kit/src/snapshot/snapshot-presentation/ios/action-shelf.test.ts b/packages/capture-kit/src/snapshot/snapshot-presentation/ios/action-shelf.test.ts index 7625505c14..b335722621 100644 --- a/packages/capture-kit/src/snapshot/snapshot-presentation/ios/action-shelf.test.ts +++ b/packages/capture-kit/src/snapshot/snapshot-presentation/ios/action-shelf.test.ts @@ -1,5 +1,5 @@ import { expect, test } from 'vitest'; -import { presentIosInteractiveSnapshot } from '@agent-device/capture-kit/ios-snapshot-engine'; +import { presentIosInteractiveSnapshot } from '../../../ios-snapshot-engine/index.ts'; import { closedComposerWithRetainedActionShelfNodes, closedComposerWithRetainedRegularTreeActionNodes, diff --git a/packages/capture-kit/src/snapshot/snapshot-presentation/ios/rows.test.ts b/packages/capture-kit/src/snapshot/snapshot-presentation/ios/rows.test.ts index 5700da810f..1fe9ab67bf 100644 --- a/packages/capture-kit/src/snapshot/snapshot-presentation/ios/rows.test.ts +++ b/packages/capture-kit/src/snapshot/snapshot-presentation/ios/rows.test.ts @@ -1,6 +1,6 @@ import { expect, test } from 'vitest'; import { elementClassicRoomListNodes, legitimatelyLabeledCellNodes } from './rows.fixtures.ts'; -import { presentIosInteractiveSnapshot } from '@agent-device/capture-kit/ios-snapshot-engine'; +import { presentIosInteractiveSnapshot } from '../../../ios-snapshot-engine/index.ts'; test('iOS row presentation associates generic room cells with their descendant titles', () => { const nodes = presentIosInteractiveSnapshot(elementClassicRoomListNodes); diff --git a/packages/capture-kit/src/snapshot/snapshot-presentation/warnings.test.ts b/packages/capture-kit/src/snapshot/snapshot-presentation/warnings.test.ts index 0c7f96ec9f..217134a837 100644 --- a/packages/capture-kit/src/snapshot/snapshot-presentation/warnings.test.ts +++ b/packages/capture-kit/src/snapshot/snapshot-presentation/warnings.test.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict'; import { test } from 'vitest'; -import { readSnapshotQualityVerdict } from '@agent-device/capture-kit/snapshot-quality-verdict'; -import { renderSnapshotQualityWarnings } from '../../snapshot/snapshot-presentation/quality-warnings.ts'; +import { readSnapshotQualityVerdict } from '../../snapshot-quality-verdict.ts'; +import { renderSnapshotQualityWarnings } from './quality-warnings.ts'; const sharedRecoveryReason = 'iOS XCTest snapshot failed while serializing the accessibility tree. Error kAXErrorIllegalArgument getting snapshot for element '; diff --git a/packages/capture-kit/src/snapshot/snapshot-visibility.ts b/packages/capture-kit/src/snapshot/snapshot-visibility.ts index 6e96565d62..e5b942c1c2 100644 --- a/packages/capture-kit/src/snapshot/snapshot-visibility.ts +++ b/packages/capture-kit/src/snapshot/snapshot-visibility.ts @@ -1,4 +1,4 @@ -import { buildMobileSnapshotPresentation } from '@agent-device/capture-kit/mobile-snapshot-semantics'; +import { buildMobileSnapshotPresentation } from '../mobile-snapshot-semantics.ts'; import { usesMobileSnapshotPresentation, type SnapshotState, diff --git a/scripts/__tests__/help-conformance-sample-producers.ts b/scripts/__tests__/help-conformance-sample-producers.ts index 1f3471a4b9..cfceef7429 100644 --- a/scripts/__tests__/help-conformance-sample-producers.ts +++ b/scripts/__tests__/help-conformance-sample-producers.ts @@ -35,7 +35,7 @@ import type { ConnectVerification } from '../../src/cli/connection/connect-provi import type { RemoteConnectionState } from '../../src/remote/remote-connection-state.ts'; import { AppError, normalizeError } from '@agent-device/kernel/errors'; import type { SnapshotQualityVerdict } from '@agent-device/kernel/snapshot'; -import { renderSnapshotQualityWarnings } from '../../src/snapshot/snapshot-presentation/quality-warnings.ts'; +import { renderSnapshotQualityWarnings } from '@agent-device/capture-kit/quality-warnings'; import { printHumanError } from '../../src/commands/output/error.ts'; import { formatSnapshotText } from '../../src/commands/output/snapshot.ts'; diff --git a/scripts/help-conformance-sample-outputs.mjs b/scripts/help-conformance-sample-outputs.mjs index 7336d0bb99..f56ce9f36b 100644 --- a/scripts/help-conformance-sample-outputs.mjs +++ b/scripts/help-conformance-sample-outputs.mjs @@ -72,7 +72,7 @@ hint: The UI kept changing for the whole settle budget (animation, carousel, or // Recovered snapshot: the private-ax fallback fired but still exposed // actionable refs. Warning wording is renderSnapshotQualityWarnings -// (src/snapshot/snapshot-presentation/quality-warnings.ts); lines are the structured snapshot +// (packages/capture-kit/src/snapshot/snapshot-presentation/quality-warnings.ts); lines are the structured snapshot // renderer (src/commands/output/snapshot.ts formatSnapshotText). export const PRIVATE_AX_RECOVERY_SAMPLE = { command: 'agent-device snapshot -i', diff --git a/src/__tests__/android-snapshot-capture-failure-reason.test.ts b/src/__tests__/android-snapshot-capture-failure-reason.test.ts index b2146a655a..f44145255a 100644 --- a/src/__tests__/android-snapshot-capture-failure-reason.test.ts +++ b/src/__tests__/android-snapshot-capture-failure-reason.test.ts @@ -11,7 +11,7 @@ import { resetAndroidSnapshotHelperSessions, } from '@agent-device/platform-android/mechanics'; import { ANDROID_SNAPSHOT_HELPER_FIXTURE_ARTIFACT } from './test-utils/android-snapshot-helper.ts'; -import { isAndroidSnapshotTimeoutError } from '../snapshot/snapshot-timeout-policy.ts'; +import { isAndroidSnapshotTimeoutError } from '@agent-device/capture-kit/snapshot-timeout-policy'; import '../platform-runtime-android-adb-host.ts'; /** diff --git a/src/__tests__/android-snapshot-occlusion-context.test.ts b/src/__tests__/android-snapshot-occlusion-context.test.ts index 02236b86a5..d3d18fd561 100644 --- a/src/__tests__/android-snapshot-occlusion-context.test.ts +++ b/src/__tests__/android-snapshot-occlusion-context.test.ts @@ -9,8 +9,8 @@ import { snapshotAndroid, type AndroidAdbExecutor, } from '@agent-device/platform-android/mechanics'; -import { buildSnapshotState } from '../core/snapshot-state.ts'; -import { coveredAndroidReplacementNodeIndexes } from '../snapshot/android-replacement-surface-occlusion.ts'; +import { buildSnapshotState } from '@agent-device/capture-kit/snapshot-state'; +import { coveredAndroidReplacementNodeIndexes } from '@agent-device/capture-kit/android-replacement-surface-occlusion'; import { ANDROID_SNAPSHOT_HELPER_FIXTURE_ARTIFACT, androidSnapshotHelperOutput, diff --git a/src/__tests__/android-ui-hierarchy-scope.test.ts b/src/__tests__/android-ui-hierarchy-scope.test.ts index 3f76e14c53..a74f7e0adf 100644 --- a/src/__tests__/android-ui-hierarchy-scope.test.ts +++ b/src/__tests__/android-ui-hierarchy-scope.test.ts @@ -2,7 +2,7 @@ import { test } from 'vitest'; import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; -import { buildSnapshotState } from '../core/snapshot-state.ts'; +import { buildSnapshotState } from '@agent-device/capture-kit/snapshot-state'; import { parseUiHierarchy } from './test-utils/android-ui-hierarchy-fixtures.ts'; import { AndroidSnapshotPresentationFailure, diff --git a/src/__tests__/android-ui-hierarchy.test.ts b/src/__tests__/android-ui-hierarchy.test.ts index dbb39d272e..be05a59936 100644 --- a/src/__tests__/android-ui-hierarchy.test.ts +++ b/src/__tests__/android-ui-hierarchy.test.ts @@ -1,6 +1,6 @@ import { test } from 'vitest'; import assert from 'node:assert/strict'; -import { buildSnapshotState } from '../core/snapshot-state.ts'; +import { buildSnapshotState } from '@agent-device/capture-kit/snapshot-state'; import { createSnapshotVisibility } from '@agent-device/contracts/snapshot'; import { androidSnapshotPublicationInput, diff --git a/src/__tests__/snapshot-desktop-surface.test.ts b/src/__tests__/snapshot-desktop-surface.test.ts index e91fba64f3..d55d3869cd 100644 --- a/src/__tests__/snapshot-desktop-surface.test.ts +++ b/src/__tests__/snapshot-desktop-surface.test.ts @@ -11,7 +11,7 @@ const { captureLinuxSurfaceSnapshot, captureMacOsSurfaceSnapshot } = vi.hoisted( vi.mock('@agent-device/platform-linux', () => ({ captureLinuxSurfaceSnapshot })); -import { createSnapshotRuntimeHost } from './snapshot-desktop-surface.ts'; +import { createSnapshotRuntimeHost } from '@agent-device/capture-kit/snapshot-desktop-surface'; const macosDevice = { id: 'desktop', @@ -41,8 +41,17 @@ function createHost() { } test('desktop snapshot host keeps iOS presentation outside its eager import closure', () => { - const closure = eagerClosureOf(path.join(import.meta.dirname, 'snapshot-desktop-surface.ts')); - expect(closure).not.toContain(path.join(import.meta.dirname, 'ios-snapshot-runtime.ts')); + const entry = path.resolve( + import.meta.dirname, + '../../packages/capture-kit/src/snapshot/snapshot-desktop-surface.ts', + ); + const closure = eagerClosureOf(entry); + expect(closure).not.toContain( + path.resolve( + import.meta.dirname, + '../../packages/capture-kit/src/snapshot/ios-snapshot-runtime.ts', + ), + ); }); test('Apple snapshot host preserves non-app macOS surface capture and menubar identity', async () => { diff --git a/src/commands/capture/output.ts b/src/commands/capture/output.ts index 82bb54dd45..58d55b67c8 100644 --- a/src/commands/capture/output.ts +++ b/src/commands/capture/output.ts @@ -1,5 +1,5 @@ import type { CaptureSnapshotResult } from '@agent-device/contracts/client'; -import { dedupeInheritedSnapshotLabels } from '../../snapshot/snapshot-label-dedup.ts'; +import { dedupeInheritedSnapshotLabels } from '@agent-device/capture-kit/snapshot-label-dedup'; import { formatSnapshotText } from '../output/snapshot.ts'; import type { CliOutput } from '../command-contract.ts'; import { messageOutput, type CliOutputFormatter } from '../output-common.ts'; diff --git a/src/commands/capture/runtime/snapshot.ts b/src/commands/capture/runtime/snapshot.ts index 5ae5477f95..1d551e0422 100644 --- a/src/commands/capture/runtime/snapshot.ts +++ b/src/commands/capture/runtime/snapshot.ts @@ -20,9 +20,9 @@ import type { AgentDeviceRuntime, CommandSessionRecord } from '../../../runtime- import { buildSnapshotDiff, countSnapshotComparableLines, -} from '../../../snapshot/snapshot-diff.ts'; -import { renderSnapshotQualityWarnings } from '../../../snapshot/snapshot-presentation/quality-warnings.ts'; -import { buildSnapshotVisibility } from '../../../snapshot/snapshot-visibility.ts'; +} from '@agent-device/capture-kit/snapshot-diff'; +import { renderSnapshotQualityWarnings } from '@agent-device/capture-kit/quality-warnings'; +import { buildSnapshotVisibility } from '@agent-device/capture-kit/snapshot-visibility'; import { ANDROID_SYSTEM_SURFACE_DISCLOSURE } from '../../../core/android-system-surface-disclosure.ts'; import { formatReactNativeOverlayWarning } from '../../react-native/overlay.ts'; import { now } from '../../runtime-common.ts'; diff --git a/src/commands/interaction/output.ts b/src/commands/interaction/output.ts index 2e19675669..5bb19b46c8 100644 --- a/src/commands/interaction/output.ts +++ b/src/commands/interaction/output.ts @@ -1,7 +1,7 @@ import type { CommandRequestResult } from '@agent-device/contracts/client'; import type { SnapshotNode } from '@agent-device/kernel/snapshot'; import type { CliOutput } from '../command-contract.ts'; -import { displayLabel, formatRole } from '../../snapshot/snapshot-lines.ts'; +import { displayLabel, formatRole } from '@agent-device/capture-kit/snapshot-lines'; import { readCommandMessage } from '@agent-device/kernel/success-text'; import { messageCliOutput, diff --git a/src/commands/interaction/runtime/gestures.ts b/src/commands/interaction/runtime/gestures.ts index e04f564a83..6e6ff24912 100644 --- a/src/commands/interaction/runtime/gestures.ts +++ b/src/commands/interaction/runtime/gestures.ts @@ -26,7 +26,7 @@ import { type ScrollEdge, type ScrollEdgeState, type ScrollEdgeTarget, -} from '../../../snapshot/scroll-edge-state.ts'; +} from '@agent-device/capture-kit/scroll-edge-state'; import { successText } from '@agent-device/kernel/success-text'; import { requireIntInRange } from '../../../core/validation.ts'; import { toBackendContext } from '../../runtime-common.ts'; diff --git a/src/commands/interaction/runtime/post-action-observation.ts b/src/commands/interaction/runtime/post-action-observation.ts index c6157d0d13..78ca16ff4b 100644 --- a/src/commands/interaction/runtime/post-action-observation.ts +++ b/src/commands/interaction/runtime/post-action-observation.ts @@ -1,6 +1,6 @@ import type { SnapshotNode } from '@agent-device/kernel/snapshot'; import type { AgentDeviceRuntime, CommandContext } from '../../../runtime-contract.ts'; -import { summarizeAxEvidence } from '../../../snapshot/snapshot-evidence.ts'; +import { summarizeAxEvidence } from '@agent-device/capture-kit/snapshot-evidence'; import type { InteractionEvidence, ResolvedInteractionTarget, diff --git a/src/commands/interaction/runtime/resolution.ts b/src/commands/interaction/runtime/resolution.ts index 473e33dfad..1beded2dd9 100644 --- a/src/commands/interaction/runtime/resolution.ts +++ b/src/commands/interaction/runtime/resolution.ts @@ -26,7 +26,7 @@ import { } from '../../../core/selector-pipeline-policy.ts'; import { resolvePressRecordingTarget } from '../../../core/press-retarget.ts'; import { requireSnapshotSession } from './selector-read-shared.ts'; -import { findNodeByLabel, resolveRefLabel } from '../../../core/snapshot-node-lookup.ts'; +import { findNodeByLabel, resolveRefLabel } from '@agent-device/capture-kit/snapshot-node-lookup'; import { containsPoint } from '@agent-device/kernel/rect'; import { createSnapshotVisibility, normalizeType } from '@agent-device/contracts/snapshot'; import { diff --git a/src/commands/interaction/runtime/selector-action-resolution.ts b/src/commands/interaction/runtime/selector-action-resolution.ts index 31dd0da68f..c9521b4d31 100644 --- a/src/commands/interaction/runtime/selector-action-resolution.ts +++ b/src/commands/interaction/runtime/selector-action-resolution.ts @@ -5,7 +5,7 @@ import type { SelectorResolution } from '@agent-device/selectors'; import { classifyActionableTouchCandidates } from '../../../core/interaction-targeting.ts'; import { listSelectorPipelineMatches } from '../../../core/selector-pipeline.ts'; import type { ActingPipelinePolicy } from '../../../core/selector-pipeline-policy.ts'; -import { formatSnapshotLine } from '../../../snapshot/snapshot-lines.ts'; +import { formatSnapshotLine } from '@agent-device/capture-kit/snapshot-lines'; const AMBIGUOUS_ACTION_CANDIDATE_LIMIT = 5; diff --git a/src/commands/interaction/runtime/selector-read-shared.ts b/src/commands/interaction/runtime/selector-read-shared.ts index 09dc8bfb5b..91244bb8c4 100644 --- a/src/commands/interaction/runtime/selector-read-shared.ts +++ b/src/commands/interaction/runtime/selector-read-shared.ts @@ -12,7 +12,7 @@ import type { } from '@agent-device/kernel/snapshot'; import { findNodeByRef, normalizeRef } from '@agent-device/kernel/snapshot'; import { isSparseSnapshotQualityVerdict } from '@agent-device/capture-kit/snapshot-quality-verdict'; -import { extractReadableText } from '../../../snapshot/snapshot-presentation/text-surface.ts'; +import { extractReadableText } from '@agent-device/capture-kit/text-surface'; import { now, toBackendContext } from '../../runtime-common.ts'; import { findNodeByLabel } from './selector-read-utils.ts'; import type { SelectorSnapshotInput } from '../../command-input.ts'; diff --git a/src/commands/interaction/runtime/selector-read-utils.ts b/src/commands/interaction/runtime/selector-read-utils.ts index 89d2b0393b..94f3311226 100644 --- a/src/commands/interaction/runtime/selector-read-utils.ts +++ b/src/commands/interaction/runtime/selector-read-utils.ts @@ -3,7 +3,7 @@ import type { RefTarget, SelectorTarget } from '@agent-device/contracts/interact import { AppError } from '@agent-device/kernel/errors'; import type { FindLocator } from '@agent-device/selectors'; -export { findNodeByLabel, resolveRefLabel } from '../../../core/snapshot-node-lookup.ts'; +export { findNodeByLabel, resolveRefLabel } from '@agent-device/capture-kit/snapshot-node-lookup'; function shouldScopeFind(locator: string): boolean { return locator === 'text' || locator === 'label' || locator === 'any'; diff --git a/src/commands/interaction/runtime/settle.ts b/src/commands/interaction/runtime/settle.ts index d5cac4b064..855162d50c 100644 --- a/src/commands/interaction/runtime/settle.ts +++ b/src/commands/interaction/runtime/settle.ts @@ -5,10 +5,13 @@ import type { CommandSessionRecord, } from '../../../runtime-contract.ts'; import { isSparseSnapshotQualityVerdict } from '@agent-device/capture-kit/snapshot-quality-verdict'; -import { buildSnapshotDiff } from '../../../snapshot/snapshot-diff.ts'; -import { displayLabel, formatRole } from '../../../snapshot/snapshot-lines.ts'; -import { collectSettleChromeRefs, withoutSettleChrome } from '../../../core/snapshot-chrome.ts'; -import { summarizeAxEvidence } from '../../../snapshot/snapshot-evidence.ts'; +import { buildSnapshotDiff } from '@agent-device/capture-kit/snapshot-diff'; +import { displayLabel, formatRole } from '@agent-device/capture-kit/snapshot-lines'; +import { + collectSettleChromeRefs, + withoutSettleChrome, +} from '@agent-device/capture-kit/snapshot-chrome'; +import { summarizeAxEvidence } from '@agent-device/capture-kit/snapshot-evidence'; import type { InteractionEvidence, ResolvedInteractionTarget, diff --git a/src/commands/output/snapshot.test.ts b/src/commands/output/snapshot.test.ts index e12a3242cb..b818e5f864 100644 --- a/src/commands/output/snapshot.test.ts +++ b/src/commands/output/snapshot.test.ts @@ -1,7 +1,7 @@ import { test } from 'vitest'; import assert from 'node:assert/strict'; import { formatSnapshotText } from './snapshot.ts'; -import { formatRole, formatSnapshotLine } from '../../snapshot/snapshot-lines.ts'; +import { formatRole, formatSnapshotLine } from '@agent-device/capture-kit/snapshot-lines'; import { withNoColor } from '../../__tests__/test-utils/color.ts'; test('formatRole falls back for object prototype role names', () => { diff --git a/src/commands/output/snapshot.ts b/src/commands/output/snapshot.ts index 23ac3f82ba..ad9fe08b83 100644 --- a/src/commands/output/snapshot.ts +++ b/src/commands/output/snapshot.ts @@ -1,9 +1,12 @@ import { buildAndroidHelperPresentationInput, type AndroidHelperPresentationInput, -} from '../../snapshot/snapshot-presentation/android/helper.ts'; -import { detectPossibleRepeatedNavSubtree } from '../../snapshot/snapshot-presentation/repeated-nav-subtree.ts'; -import { buildSnapshotDisplayLines, formatSnapshotLine } from '../../snapshot/snapshot-lines.ts'; +} from '@agent-device/capture-kit/snapshot-presentation-android-helper'; +import { detectPossibleRepeatedNavSubtree } from '@agent-device/capture-kit/repeated-nav-subtree'; +import { + buildSnapshotDisplayLines, + formatSnapshotLine, +} from '@agent-device/capture-kit/snapshot-lines'; import { isSnapshotBackend, usesMobileSnapshotPresentation, diff --git a/src/core/__tests__/snapshot-chrome-android-statusbar.test.ts b/src/core/__tests__/snapshot-chrome-android-statusbar.test.ts index 84e56e6800..4c1896b0ab 100644 --- a/src/core/__tests__/snapshot-chrome-android-statusbar.test.ts +++ b/src/core/__tests__/snapshot-chrome-android-statusbar.test.ts @@ -1,7 +1,10 @@ import { test } from 'vitest'; import assert from 'node:assert/strict'; import { attachRefs, type RawSnapshotNode, type SnapshotNode } from '@agent-device/kernel/snapshot'; -import { collectSettleChromeRefs, withoutSettleChrome } from '../snapshot-chrome.ts'; +import { + collectSettleChromeRefs, + withoutSettleChrome, +} from '@agent-device/capture-kit/snapshot-chrome'; import { ANDROID_IME_CAPTURE_RAW_NODES, ANDROID_QS_SHADE_CAPTURE_RAW_NODES, diff --git a/src/core/__tests__/snapshot-state.test.ts b/src/core/__tests__/snapshot-state.test.ts index 4094929d1d..b358273d26 100644 --- a/src/core/__tests__/snapshot-state.test.ts +++ b/src/core/__tests__/snapshot-state.test.ts @@ -1,5 +1,5 @@ import { expect, test } from 'vitest'; -import { buildSnapshotState } from '../snapshot-state.ts'; +import { buildSnapshotState } from '@agent-device/capture-kit/snapshot-state'; import { resolveActionableTouchResolution } from '../interaction-targeting.ts'; import { createSnapshotVisibility } from '@agent-device/contracts/snapshot'; import { attachSnapshotOcclusionContextEvidence } from '@agent-device/contracts/capture'; diff --git a/src/core/interactors/android.ts b/src/core/interactors/android.ts index 58d4b2223a..a641b0db0c 100644 --- a/src/core/interactors/android.ts +++ b/src/core/interactors/android.ts @@ -34,7 +34,7 @@ import { withDiagnosticTimer } from '@agent-device/host-kit/diagnostics'; import { withMethodScope } from '@agent-device/kernel/scoped-provider'; import type { DeviceInfo } from '@agent-device/kernel/device'; import type { Interactor, RunnerContext } from '@agent-device/contracts/interactor-types'; -import { buildSnapshotState } from '../snapshot-state.ts'; +import { buildSnapshotState } from '@agent-device/capture-kit/snapshot-state'; /** * `appBundleId` is present exactly for app-backed daemon sessions, whose teardown releases the diff --git a/src/daemon/__tests__/generic-settle.test.ts b/src/daemon/__tests__/generic-settle.test.ts index fb67b7463f..d2896b5ee6 100644 --- a/src/daemon/__tests__/generic-settle.test.ts +++ b/src/daemon/__tests__/generic-settle.test.ts @@ -7,7 +7,7 @@ import { setSessionSnapshot } from '../session-snapshot.ts'; import type { SessionStore } from '../session-store.ts'; import type { DaemonRequest, DaemonResponse } from '../daemon-request.ts'; import type { SessionState } from '../session-state.ts'; -import { buildSnapshotState } from '../../core/snapshot-state.ts'; +import { buildSnapshotState } from '@agent-device/capture-kit/snapshot-state'; // #1638 `--settle` on the GENERIC daemon route (scroll/back): the settled diff, // its refs, and the ref-frame/generation dance are the same contract the touch diff --git a/src/daemon/__tests__/snapshot-capture.test.ts b/src/daemon/__tests__/snapshot-capture.test.ts index d9d82f1332..3f24b8729c 100644 --- a/src/daemon/__tests__/snapshot-capture.test.ts +++ b/src/daemon/__tests__/snapshot-capture.test.ts @@ -1,6 +1,6 @@ import { expect, test, vi } from 'vitest'; import { captureSnapshotData } from '../snapshot-capture.ts'; -import { buildSnapshotVisibility } from '../../snapshot/snapshot-visibility.ts'; +import { buildSnapshotVisibility } from '@agent-device/capture-kit/snapshot-visibility'; import { ANDROID_EMULATOR, IOS_SIMULATOR, diff --git a/src/daemon/__tests__/snapshot-diff.test.ts b/src/daemon/__tests__/snapshot-diff.test.ts index 76b88afb07..ea3ab10ad6 100644 --- a/src/daemon/__tests__/snapshot-diff.test.ts +++ b/src/daemon/__tests__/snapshot-diff.test.ts @@ -1,7 +1,10 @@ import fc from 'fast-check'; import { test } from 'vitest'; import assert from 'node:assert/strict'; -import { buildSnapshotDiff, countSnapshotComparableLines } from '../../snapshot/snapshot-diff.ts'; +import { + buildSnapshotDiff, + countSnapshotComparableLines, +} from '@agent-device/capture-kit/snapshot-diff'; import { buildNodes as nodes } from '../../__tests__/test-utils/snapshot-builders.ts'; import { PROPERTY_RUNS_SMALL, diff --git a/src/daemon/__tests__/snapshot-presentation-transitions.test.ts b/src/daemon/__tests__/snapshot-presentation-transitions.test.ts index 9b96e46abb..564926c643 100644 --- a/src/daemon/__tests__/snapshot-presentation-transitions.test.ts +++ b/src/daemon/__tests__/snapshot-presentation-transitions.test.ts @@ -1,9 +1,9 @@ import { expect, test } from 'vitest'; import { makeSnapshotState } from '../../__tests__/test-utils/snapshot-builders.ts'; import { createInteractionDevice } from '../../commands/interaction/runtime/__tests__/test-utils/index.ts'; -import { buildSnapshotState } from '../../core/snapshot-state.ts'; +import { buildSnapshotState } from '@agent-device/capture-kit/snapshot-state'; import { presentIosInteractiveSnapshot } from '@agent-device/capture-kit/ios-snapshot-engine'; -import { navigationTitleWithAppProvidedDetailsAffordanceNodes } from '../../snapshot/snapshot-presentation/ios/transitions.fixtures.ts'; +import { navigationTitleWithAppProvidedDetailsAffordanceNodes } from '@agent-device/capture-kit/snapshot-presentation-ios-transitions-fixtures'; test('the daemon publishes engine transitions without reapplying runner-owned scope', () => { const snapshot = buildSnapshotState( diff --git a/src/daemon/__tests__/snapshot-publication-membership.test.ts b/src/daemon/__tests__/snapshot-publication-membership.test.ts index 6f7fcfca8f..6d523ee32f 100644 --- a/src/daemon/__tests__/snapshot-publication-membership.test.ts +++ b/src/daemon/__tests__/snapshot-publication-membership.test.ts @@ -1,7 +1,7 @@ import { expect, test } from 'vitest'; import type { RawSnapshotNode } from '@agent-device/kernel/snapshot'; import { presentIosInteractiveSnapshot } from '@agent-device/capture-kit/ios-snapshot-engine'; -import { buildSnapshotState } from '../../core/snapshot-state.ts'; +import { buildSnapshotState } from '@agent-device/capture-kit/snapshot-state'; // End-to-end publication-membership contract for the acquire/present design (#1797, external // review pass 4 finding 1), exercised through the production interface. Runner presentation owns diff --git a/src/daemon/__tests__/snapshot-quality-latch.test.ts b/src/daemon/__tests__/snapshot-quality-latch.test.ts index 1f7f00a852..9885fb8365 100644 --- a/src/daemon/__tests__/snapshot-quality-latch.test.ts +++ b/src/daemon/__tests__/snapshot-quality-latch.test.ts @@ -6,7 +6,7 @@ import { makeIosSession } from '../../__tests__/test-utils/session-factories.ts' import { recoveredSnapshotQualityWarning, renderSnapshotQualityWarnings, -} from '../../snapshot/snapshot-presentation/quality-warnings.ts'; +} from '@agent-device/capture-kit/quality-warnings'; import { applyRecoveredWarningLatch, resolveRecoveredWarningLatch, diff --git a/src/daemon/android-snapshot-timeout-evidence.ts b/src/daemon/android-snapshot-timeout-evidence.ts index 09fc192eda..c09dd33686 100644 --- a/src/daemon/android-snapshot-timeout-evidence.ts +++ b/src/daemon/android-snapshot-timeout-evidence.ts @@ -13,7 +13,7 @@ import { snapshotTimeoutEvidenceWithoutOverlaySource, type SnapshotTimeoutEvidence, } from './snapshot-timeout-evidence.ts'; -import { isAndroidSnapshotTimeoutError } from '../snapshot/snapshot-timeout-policy.ts'; +import { isAndroidSnapshotTimeoutError } from '@agent-device/capture-kit/snapshot-timeout-policy'; import { contextFromFlags } from './context.ts'; import { annotateScreenshotWithRefs } from '@agent-device/capture-kit/screenshot-overlay'; import { screenshotExecutionFromContext } from './screenshot-runtime.ts'; diff --git a/src/daemon/deferred-interaction-outcome.ts b/src/daemon/deferred-interaction-outcome.ts index 19ada9f225..411fb1b7d5 100644 --- a/src/daemon/deferred-interaction-outcome.ts +++ b/src/daemon/deferred-interaction-outcome.ts @@ -12,7 +12,7 @@ import { import { isNavigationSensitiveAction, type SnapshotFreshnessMode, -} from '../snapshot/snapshot-freshness/index.ts'; +} from '@agent-device/capture-kit/snapshot-freshness'; import { withGestureNoEffectWarning } from './gesture-no-effect.ts'; import { areInteractionSurfaceSignaturesStable, diff --git a/src/daemon/handlers/__tests__/snapshot-handler.fixtures.ts b/src/daemon/handlers/__tests__/snapshot-handler.fixtures.ts index d2625485e3..60d9d1ffd8 100644 --- a/src/daemon/handlers/__tests__/snapshot-handler.fixtures.ts +++ b/src/daemon/handlers/__tests__/snapshot-handler.fixtures.ts @@ -3,7 +3,7 @@ import { mkdtempForTestSync } from '../../../__tests__/test-utils/tmp-dir.ts'; import { buildNodes } from '../../../__tests__/test-utils/snapshot-builders.ts'; import type { ProviderDeviceRuntime } from '@agent-device/contracts/device'; import type { RawSnapshotNode, SnapshotNode } from '@agent-device/kernel/snapshot'; -import { buildSnapshotSignatures } from '../../../snapshot/snapshot-freshness/index.ts'; +import { buildSnapshotSignatures } from '@agent-device/capture-kit/snapshot-freshness'; import type { BindDeviceRuntime, InspectDeviceRuntimeFacts, diff --git a/src/daemon/handlers/record-runtime-response.ts b/src/daemon/handlers/record-runtime-response.ts index a14e46300b..cfb52a580e 100644 --- a/src/daemon/handlers/record-runtime-response.ts +++ b/src/daemon/handlers/record-runtime-response.ts @@ -6,7 +6,7 @@ import type { } from '@agent-device/contracts/screen-recording-runtime'; import type { RuntimeOperationUnavailability } from '@agent-device/contracts/platform-runtime'; import type { DaemonArtifact, DaemonResponse } from '../daemon-request.ts'; -import { deriveRecordingTelemetryPath } from '../../recording/telemetry.ts'; +import { deriveRecordingTelemetryPath } from '@agent-device/capture-kit/recording-telemetry'; export function buildRecordingStartResponse( snapshot: ScreenRecordingLiveSnapshot, diff --git a/src/daemon/handlers/record-runtime.ts b/src/daemon/handlers/record-runtime.ts index e909b00a98..36f82ebbab 100644 --- a/src/daemon/handlers/record-runtime.ts +++ b/src/daemon/handlers/record-runtime.ts @@ -31,7 +31,7 @@ import { prepareRecordingRequest, readRecordingScope, } from './record-runtime-request.ts'; -import { resolveRecordingOutputPaths } from '../../recording/output-path.ts'; +import { resolveRecordingOutputPaths } from '@agent-device/capture-kit/recording-output-path'; import { buildRecordingStartResponse, buildRecordingStartedAction, diff --git a/src/daemon/interaction-outcome-policy.ts b/src/daemon/interaction-outcome-policy.ts index d0a6abee62..3de9938efa 100644 --- a/src/daemon/interaction-outcome-policy.ts +++ b/src/daemon/interaction-outcome-policy.ts @@ -1,7 +1,7 @@ import type { CommandFlags } from '@agent-device/contracts/command'; import { isMobilePlatform } from '@agent-device/kernel/device'; import type { SnapshotNode, SnapshotState } from '@agent-device/kernel/snapshot'; -import { collectKeyboardChromeRefs } from '../core/snapshot-chrome.ts'; +import { collectKeyboardChromeRefs } from '@agent-device/capture-kit/snapshot-chrome'; import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { isViewportRootNode } from '@agent-device/contracts/snapshot'; import { contextFromFlags, type DaemonCommandContext } from './context.ts'; diff --git a/src/daemon/interaction/internal/__tests__/find.test.ts b/src/daemon/interaction/internal/__tests__/find.test.ts index dbe002eab7..3a6a056017 100644 --- a/src/daemon/interaction/internal/__tests__/find.test.ts +++ b/src/daemon/interaction/internal/__tests__/find.test.ts @@ -4,7 +4,7 @@ import { handleInteractionCommands } from '../../index.ts'; import type { CommandFlags } from '@agent-device/contracts/command'; import type { DaemonRequest, DaemonResponse } from '../../../daemon-request.ts'; import type { SessionState } from '../../../session-state.ts'; -import { buildSnapshotSignatures } from '../../../../snapshot/snapshot-freshness/index.ts'; +import { buildSnapshotSignatures } from '@agent-device/capture-kit/snapshot-freshness'; import { makeSessionStore } from '../../../../__tests__/test-utils/store-factory.ts'; import { makeIosSession as makeSession, diff --git a/src/daemon/interaction/internal/__tests__/interaction-get.test.ts b/src/daemon/interaction/internal/__tests__/interaction-get.test.ts index 205bc5f802..0b287b4cf7 100644 --- a/src/daemon/interaction/internal/__tests__/interaction-get.test.ts +++ b/src/daemon/interaction/internal/__tests__/interaction-get.test.ts @@ -10,7 +10,7 @@ import { makeSessionStore } from '../../../../__tests__/test-utils/store-factory import { expireRefFrame } from '../../../ref-frame.ts'; import { setSessionSnapshot, STALE_SNAPSHOT_REFS_WARNING } from '../../../session-snapshot.ts'; import { handleInteractionCommands } from '../../index.ts'; -import { buildSnapshotState } from '../../../../core/snapshot-state.ts'; +import { buildSnapshotState } from '@agent-device/capture-kit/snapshot-state'; import { contextFromFlags, makeSession, diff --git a/src/daemon/interaction/internal/__tests__/interaction-ios-tap-outcome-fixtures.ts b/src/daemon/interaction/internal/__tests__/interaction-ios-tap-outcome-fixtures.ts index 4eae6be621..4574dc36c7 100644 --- a/src/daemon/interaction/internal/__tests__/interaction-ios-tap-outcome-fixtures.ts +++ b/src/daemon/interaction/internal/__tests__/interaction-ios-tap-outcome-fixtures.ts @@ -1,5 +1,5 @@ import type { RawSnapshotNode } from '@agent-device/kernel/snapshot'; -import { buildSnapshotState } from '../../../../core/snapshot-state.ts'; +import { buildSnapshotState } from '@agent-device/capture-kit/snapshot-state'; export const profileNodes: RawSnapshotNode[] = [ { diff --git a/src/daemon/interaction/internal/__tests__/interaction-settle.test.ts b/src/daemon/interaction/internal/__tests__/interaction-settle.test.ts index 3b07a0f2c8..66acb3966c 100644 --- a/src/daemon/interaction/internal/__tests__/interaction-settle.test.ts +++ b/src/daemon/interaction/internal/__tests__/interaction-settle.test.ts @@ -4,7 +4,7 @@ import { test, expect, vi, beforeEach } from 'vitest'; import { createInteractionRuntime, handleInteractionCommands } from '../../index.ts'; import type { SessionStore } from '../../../session-store.ts'; import type { SessionState } from '../../../session-state.ts'; -import { buildSnapshotState } from '../../../../core/snapshot-state.ts'; +import { buildSnapshotState } from '@agent-device/capture-kit/snapshot-state'; import { setSessionSnapshot } from '../../../session-snapshot.ts'; import { activateCompleteRefFrame, expireRefFrame, refFrameState } from '../../../ref-frame.ts'; import { makeSessionStore } from '../../../../__tests__/test-utils/store-factory.ts'; diff --git a/src/daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts b/src/daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts index a48f36973f..e29b555739 100644 --- a/src/daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts +++ b/src/daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts @@ -11,7 +11,7 @@ import type { SessionStore } from '../../../session-store.ts'; import type { SessionState } from '../../../session-state.ts'; import { handleInteractionCommands } from '../../index.ts'; import { getRuntimeBindings } from '../../../__tests__/interaction-get-runtime-fixture.ts'; -import { buildSnapshotState } from '../../../../core/snapshot-state.ts'; +import { buildSnapshotState } from '@agent-device/capture-kit/snapshot-state'; /** * Shared factories for the interaction touch handler tests. Named pure diff --git a/src/daemon/interaction/internal/interaction-ios-tap-outcome.ts b/src/daemon/interaction/internal/interaction-ios-tap-outcome.ts index 4a56c864d9..167fa75ad9 100644 --- a/src/daemon/interaction/internal/interaction-ios-tap-outcome.ts +++ b/src/daemon/interaction/internal/interaction-ios-tap-outcome.ts @@ -6,7 +6,7 @@ import { isSparseSnapshotQualityVerdict, preferredSnapshotBackendForVerdict, } from '@agent-device/capture-kit/snapshot-quality-verdict'; -import { summarizeAxEvidence } from '../../../snapshot/snapshot-evidence.ts'; +import { summarizeAxEvidence } from '@agent-device/capture-kit/snapshot-evidence'; import { getRequestSignal } from '@agent-device/host-kit/request'; import { isLocalIosRunnerSession } from '../../direct-ios-selector.ts'; import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; diff --git a/src/daemon/replay/internal/session-replay-divergence.ts b/src/daemon/replay/internal/session-replay-divergence.ts index 0c2046735e..9a33f080dc 100644 --- a/src/daemon/replay/internal/session-replay-divergence.ts +++ b/src/daemon/replay/internal/session-replay-divergence.ts @@ -3,14 +3,14 @@ import type { CommandFlags } from '@agent-device/contracts/command'; import { sleep } from '@agent-device/host-kit/retry'; import { isUnreadableCaptureContentError } from '@agent-device/contracts/android-snapshot-quality'; import { isSparseSnapshotQualityVerdict } from '@agent-device/capture-kit/snapshot-quality-verdict'; -import { displayLabel, formatRole } from '../../../snapshot/snapshot-lines.ts'; +import { displayLabel, formatRole } from '@agent-device/capture-kit/snapshot-lines'; import type { ResponseLevel } from '@agent-device/kernel/contracts'; import type { DaemonError } from '@agent-device/kernel/errors'; import type { SnapshotNode } from '@agent-device/kernel/snapshot'; import { captureSnapshot } from '../../snapshot-capture.ts'; import { collectReplaySelectorCandidates } from './session-replay-heal.ts'; import { buildSelectorCandidates, resolveReplaySuggestionCandidate } from '@agent-device/selectors'; -import { collectSettleChromeRefs } from '../../../core/snapshot-chrome.ts'; +import { collectSettleChromeRefs } from '@agent-device/capture-kit/snapshot-chrome'; import { buildAndPersistReplayDivergenceResume } from './session-replay-resume.ts'; import { formatDivergenceActionLabel, isTouchTargetCommand } from '@agent-device/ad-script'; import { diff --git a/src/daemon/replay/internal/session-replay-target-classification.ts b/src/daemon/replay/internal/session-replay-target-classification.ts index 23113aeb06..3cdaee3011 100644 --- a/src/daemon/replay/internal/session-replay-target-classification.ts +++ b/src/daemon/replay/internal/session-replay-target-classification.ts @@ -32,7 +32,7 @@ import type { Platform, PublicPlatform } from '@agent-device/kernel/device'; import { findNodeByRef, normalizeRef, type SnapshotNode } from '@agent-device/kernel/snapshot'; -import { findNodeByLabel } from '../../../core/snapshot-node-lookup.ts'; +import { findNodeByLabel } from '@agent-device/capture-kit/snapshot-node-lookup'; import { annotationLocalIdentity, buildAncestryChain, diff --git a/src/daemon/replay/internal/session-replay-target-verification.ts b/src/daemon/replay/internal/session-replay-target-verification.ts index 62b48449db..345e1233bd 100644 --- a/src/daemon/replay/internal/session-replay-target-verification.ts +++ b/src/daemon/replay/internal/session-replay-target-verification.ts @@ -3,7 +3,7 @@ import type { ResponseLevel } from '@agent-device/kernel/contracts'; import type { DaemonError } from '@agent-device/kernel/errors'; import type { Platform, PublicPlatform } from '@agent-device/kernel/device'; import type { SnapshotNode } from '@agent-device/kernel/snapshot'; -import { displayLabel, formatRole } from '../../../snapshot/snapshot-lines.ts'; +import { displayLabel, formatRole } from '@agent-device/capture-kit/snapshot-lines'; import { annotationLocalIdentity, formatDivergenceActionLabel, diff --git a/src/daemon/replay/internal/session-replay-video-recording.ts b/src/daemon/replay/internal/session-replay-video-recording.ts index 7ef42e43c2..2f173d94f3 100644 --- a/src/daemon/replay/internal/session-replay-video-recording.ts +++ b/src/daemon/replay/internal/session-replay-video-recording.ts @@ -12,7 +12,7 @@ import type { import { defaultRecordingPath, recordingExtensionForPlatform, -} from '../../../recording/output-path.ts'; +} from '@agent-device/capture-kit/recording-output-path'; const REPLAY_TEST_VIDEO_RECORDING_PREROLL_MS = 1_000; const REPLAY_TEST_VIDEO_RECORDING_TAIL_MS = 3_000; diff --git a/src/daemon/screenshot-crop.ts b/src/daemon/screenshot-crop.ts index 8c4bfee3b1..655052da67 100644 --- a/src/daemon/screenshot-crop.ts +++ b/src/daemon/screenshot-crop.ts @@ -12,7 +12,7 @@ import { resolveScreenshotRectSpace, resolveSnapshotBounds, } from '@agent-device/capture-kit/snapshot-rect-projection'; -import { buildSnapshotState } from '../core/snapshot-state.ts'; +import { buildSnapshotState } from '@agent-device/capture-kit/snapshot-state'; import { SELECTOR_PIPELINE_POLICIES } from '../core/selector-pipeline-policy.ts'; import { resolveSelectorPipeline } from '../core/selector-pipeline.ts'; import type { DaemonCommandContext } from './context.ts'; diff --git a/src/daemon/screenshot-runtime.ts b/src/daemon/screenshot-runtime.ts index 3ed058941e..76feecab47 100644 --- a/src/daemon/screenshot-runtime.ts +++ b/src/daemon/screenshot-runtime.ts @@ -21,7 +21,7 @@ import { import { runtimeExecutionFromContext } from './snapshot-runtime-capture-input.ts'; import type { DaemonCommandContext } from './context.ts'; import { captureSnapshotData } from './snapshot-capture.ts'; -import { buildSnapshotState } from '../core/snapshot-state.ts'; +import { buildSnapshotState } from '@agent-device/capture-kit/snapshot-state'; import type { RecordedGenericRequest, ResolvedGenericExecution, diff --git a/src/daemon/scroll-runtime.ts b/src/daemon/scroll-runtime.ts index 0f84b80e0e..39c4d66825 100644 --- a/src/daemon/scroll-runtime.ts +++ b/src/daemon/scroll-runtime.ts @@ -21,7 +21,7 @@ import { runScrollEdgePasses, type ScrollEdge, type ScrollEdgeState, -} from '../snapshot/scroll-edge-state.ts'; +} from '@agent-device/capture-kit/scroll-edge-state'; import { withSuccessText } from '@agent-device/kernel/success-text'; import type { DaemonCommandContext } from './context.ts'; import { errorResponse } from './response.ts'; diff --git a/src/daemon/selector-match-errors.ts b/src/daemon/selector-match-errors.ts index 0ea915981c..ad58b837af 100644 --- a/src/daemon/selector-match-errors.ts +++ b/src/daemon/selector-match-errors.ts @@ -1,6 +1,6 @@ import type { FindLocator } from '@agent-device/selectors'; import type { SnapshotState } from '@agent-device/kernel/snapshot'; -import { formatSnapshotLine } from '../snapshot/snapshot-lines.ts'; +import { formatSnapshotLine } from '@agent-device/capture-kit/snapshot-lines'; import type { ElementMatchCandidateDetails } from '@agent-device/kernel/errors'; import type { DaemonResponse } from './daemon-request.ts'; import { errorResponse } from './response.ts'; diff --git a/src/daemon/selector-text-runtime.ts b/src/daemon/selector-text-runtime.ts index 69c702ffc0..2881b3414e 100644 --- a/src/daemon/selector-text-runtime.ts +++ b/src/daemon/selector-text-runtime.ts @@ -12,7 +12,7 @@ import type { SessionSurface } from '@agent-device/contracts/session'; import { extractReadableText, prefersValueForReadableText, -} from '../snapshot/snapshot-presentation/text-surface.ts'; +} from '@agent-device/capture-kit/text-surface'; import type { BoundContextFromFlags } from './context.ts'; import { resolveRectCenter } from '@agent-device/kernel/rect-center'; diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-open-existing.test.ts b/src/daemon/session-lifecycle/internal/__tests__/session-open-existing.test.ts index 0566831d08..346ee7460c 100644 --- a/src/daemon/session-lifecycle/internal/__tests__/session-open-existing.test.ts +++ b/src/daemon/session-lifecycle/internal/__tests__/session-open-existing.test.ts @@ -1,7 +1,7 @@ import { test, expect } from 'vitest'; import * as os from 'node:os'; import * as path from 'node:path'; -import { buildSnapshotSignatures } from '../../../../snapshot/snapshot-freshness/index.ts'; +import { buildSnapshotSignatures } from '@agent-device/capture-kit/snapshot-freshness'; import { AppError } from '@agent-device/kernel/errors'; import { mockLifecycleDispatch as mockDispatch, diff --git a/src/daemon/session-snapshot-freshness.ts b/src/daemon/session-snapshot-freshness.ts index c7c441796d..ca93c7c73e 100644 --- a/src/daemon/session-snapshot-freshness.ts +++ b/src/daemon/session-snapshot-freshness.ts @@ -10,7 +10,7 @@ import { type SnapshotFreshnessAttemptShape, type SnapshotFreshnessMode, type SnapshotFreshnessWindow, -} from '../snapshot/snapshot-freshness/index.ts'; +} from '@agent-device/capture-kit/snapshot-freshness'; import type { SessionState } from './session-state.ts'; /** diff --git a/src/daemon/session-state.ts b/src/daemon/session-state.ts index 4f5185c992..7a3c13d87d 100644 --- a/src/daemon/session-state.ts +++ b/src/daemon/session-state.ts @@ -15,7 +15,7 @@ import type { } from '@agent-device/kernel/contracts'; import type { DeviceInfo } from '@agent-device/kernel/device'; import type { SnapshotState } from '@agent-device/kernel/snapshot'; -import type { SnapshotFreshnessWindow } from '../snapshot/snapshot-freshness/index.ts'; +import type { SnapshotFreshnessWindow } from '@agent-device/capture-kit/snapshot-freshness'; import type { RefFrame } from './ref-frame-slot.ts'; import type { SessionScriptPublicationState } from './session-script-publication-state.ts'; diff --git a/src/daemon/snapshot-capture.ts b/src/daemon/snapshot-capture.ts index c764fed3d7..d07e24ffec 100644 --- a/src/daemon/snapshot-capture.ts +++ b/src/daemon/snapshot-capture.ts @@ -13,11 +13,11 @@ import { type SnapshotCaptureProvenance, type SnapshotState, } from '@agent-device/kernel/snapshot'; -import { resolveRefLabel } from '../core/snapshot-node-lookup.ts'; +import { resolveRefLabel } from '@agent-device/capture-kit/snapshot-node-lookup'; import { captureSnapshotWithInteractor } from './snapshot-interactor-capture.ts'; -import { buildSnapshotState } from '../core/snapshot-state.ts'; +import { buildSnapshotState } from '@agent-device/capture-kit/snapshot-state'; import { clearAndroidSnapshotFreshness } from './session-snapshot-freshness.ts'; -import type { SnapshotFreshnessMode } from '../snapshot/snapshot-freshness/index.ts'; +import type { SnapshotFreshnessMode } from '@agent-device/capture-kit/snapshot-freshness'; import { contextFromFlags } from './context.ts'; import { resolveDeferredInteractionOutcome } from './deferred-interaction-outcome.ts'; import { createInteractionRetryTap } from './interaction-retry-tap.ts'; diff --git a/src/daemon/snapshot-interactor-capture.ts b/src/daemon/snapshot-interactor-capture.ts index 2e177a35d9..bbaa1e8661 100644 --- a/src/daemon/snapshot-interactor-capture.ts +++ b/src/daemon/snapshot-interactor-capture.ts @@ -23,6 +23,7 @@ export async function captureSnapshotWithInteractor(params: { const interactor = await getInteractor(params.device, params.runnerContext); const result = await interactor.snapshot(params.options); if (!('stage' in result)) return result; - const { presentIosSnapshotAcquisition } = await import('../snapshot/ios-snapshot-runtime.ts'); + const { presentIosSnapshotAcquisition } = + await import('@agent-device/capture-kit/ios-snapshot-runtime'); return await presentIosSnapshotAcquisition(result, params.options); } diff --git a/src/daemon/snapshot-quality-latch.ts b/src/daemon/snapshot-quality-latch.ts index a478631292..3b46fc031b 100644 --- a/src/daemon/snapshot-quality-latch.ts +++ b/src/daemon/snapshot-quality-latch.ts @@ -1,5 +1,5 @@ import type { SnapshotQualityVerdict } from '@agent-device/kernel/snapshot'; -import { recoveredSnapshotQualityWarning } from '../snapshot/snapshot-presentation/quality-warnings.ts'; +import { recoveredSnapshotQualityWarning } from '@agent-device/capture-kit/quality-warnings'; import type { DaemonResponseData } from './daemon-request.ts'; import type { SessionState } from './session-state.ts'; diff --git a/src/platform-runtime-android-observation-host.ts b/src/platform-runtime-android-observation-host.ts index 7df14a10fd..49f5befe89 100644 --- a/src/platform-runtime-android-observation-host.ts +++ b/src/platform-runtime-android-observation-host.ts @@ -10,7 +10,7 @@ export function createAndroidObservationHost(): AndroidObservationHost { }, async readSnapshotNodes(device) { const { snapshotAndroid, androidSnapshotPublicationInput } = await loadAndroidMechanics(); - const { buildSnapshotState } = await import('./core/snapshot-state.ts'); + const { buildSnapshotState } = await import('@agent-device/capture-kit/snapshot-state'); const rawSnapshot = await snapshotAndroid(device, { interactiveOnly: false }); return buildSnapshotState(androidSnapshotPublicationInput(rawSnapshot), undefined).nodes; }, diff --git a/src/platform-runtime-operation-host.ts b/src/platform-runtime-operation-host.ts index eb6ea1f396..5a06f2de29 100644 --- a/src/platform-runtime-operation-host.ts +++ b/src/platform-runtime-operation-host.ts @@ -34,7 +34,7 @@ import { createAndroidApplicationTools } from './platform-runtime-android-applic import { createLocalApplicationInteractorHost } from './platform-runtime-local-application-interactors.ts'; import { createApplicationResourceLifecycle } from './platform-runtime-application-resources.ts'; -export { createSnapshotRuntimeHost } from './snapshot/snapshot-desktop-surface.ts'; +export { createSnapshotRuntimeHost } from '@agent-device/capture-kit/snapshot-desktop-surface'; export async function loadMacOsSurfaceSnapshot( options: CaptureSnapshotInput['options'], diff --git a/src/platform-runtime-screen-recording-android-host.ts b/src/platform-runtime-screen-recording-android-host.ts index b1b0a433fc..35eaa3d18a 100644 --- a/src/platform-runtime-screen-recording-android-host.ts +++ b/src/platform-runtime-screen-recording-android-host.ts @@ -5,7 +5,7 @@ import type { } from '@agent-device/contracts/screen-recording-runtime-host'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { shellQuote } from '@agent-device/host-kit/command'; -import { isPlayableVideo } from './recording/video.ts'; +import { isPlayableVideo } from '@agent-device/capture-kit/recording-video'; import { loadAndroidMechanics } from './platform-runtime-android-mechanics.ts'; const ANDROID_MANIFEST_NAME = 'agent-device-recording-active.json'; diff --git a/src/platform-runtime-screen-recording-finalizer-host.test.ts b/src/platform-runtime-screen-recording-finalizer-host.test.ts index 048c6b60a6..24ac64e549 100644 --- a/src/platform-runtime-screen-recording-finalizer-host.test.ts +++ b/src/platform-runtime-screen-recording-finalizer-host.test.ts @@ -7,13 +7,15 @@ const video = vi.hoisted(() => ({ isPlayable: vi.fn(async () => true), })); const telemetry = vi.hoisted(() => vi.fn(() => '/tmp/capture.telemetry.json')); -vi.mock('./recording/video.ts', () => ({ +vi.mock('@agent-device/capture-kit/recording-video', () => ({ waitForStableFile: video.stable, waitForPlayableVideo: video.playable, isPlayableVideo: video.isPlayable, })); -vi.mock('./recording/telemetry.ts', () => ({ persistRecordingTelemetry: telemetry })); -vi.mock('./recording/overlay.ts', () => ({ +vi.mock('@agent-device/capture-kit/recording-telemetry', () => ({ + persistRecordingTelemetry: telemetry, +})); +vi.mock('@agent-device/capture-kit/recording-overlay', () => ({ getRecordingOverlaySupportWarning: () => undefined, overlayRecordingTouches: vi.fn(async () => {}), trimRecordingStart: vi.fn(async () => {}), diff --git a/src/platform-runtime-screen-recording-finalizer-host.ts b/src/platform-runtime-screen-recording-finalizer-host.ts index aa73034d7a..296094677b 100644 --- a/src/platform-runtime-screen-recording-finalizer-host.ts +++ b/src/platform-runtime-screen-recording-finalizer-host.ts @@ -3,9 +3,13 @@ import { getRecordingOverlaySupportWarning, overlayRecordingTouches, trimRecordingStart, -} from './recording/overlay.ts'; -import { persistRecordingTelemetry } from './recording/telemetry.ts'; -import { isPlayableVideo, waitForPlayableVideo, waitForStableFile } from './recording/video.ts'; +} from '@agent-device/capture-kit/recording-overlay'; +import { persistRecordingTelemetry } from '@agent-device/capture-kit/recording-telemetry'; +import { + isPlayableVideo, + waitForPlayableVideo, + waitForStableFile, +} from '@agent-device/capture-kit/recording-video'; export function createScreenRecordingFinalizer(): ScreenRecordingRuntimeHost['finalize'] { return Object.freeze({ complete: finalizeScreenRecording }); diff --git a/src/remote/daemon-artifacts.ts b/src/remote/daemon-artifacts.ts index 37b3a8a3ff..c99a848f7b 100644 --- a/src/remote/daemon-artifacts.ts +++ b/src/remote/daemon-artifacts.ts @@ -5,7 +5,7 @@ import type { DaemonArtifact, DaemonRequest, DaemonResponse } from '../daemon/da import { appendRecordingExtensionWhenMissing, recordingExtensionForPlatform, -} from '../recording/output-path.ts'; +} from '@agent-device/capture-kit/recording-output-path'; import { uploadArtifact } from './upload-client.ts'; import { createStderrUploadProgressReporter, type UploadProgressSink } from './upload-progress.ts'; diff --git a/test/integration/live-device-e2e/assertions.ts b/test/integration/live-device-e2e/assertions.ts index 0fd8d1df36..f04447da17 100644 --- a/test/integration/live-device-e2e/assertions.ts +++ b/test/integration/live-device-e2e/assertions.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import { assertPngFile } from '../provider-scenarios/assertions.ts'; -import { isPlayableVideo } from '../../../src/recording/video.ts'; +import { isPlayableVideo } from '@agent-device/capture-kit/recording-video'; import type { CliJsonResult } from '../cli-json.ts'; import type { LiveDeviceContext } from './runtime.ts'; diff --git a/test/integration/provider-scenarios/cloud-webdriver-provider-regressions.test.ts b/test/integration/provider-scenarios/cloud-webdriver-provider-regressions.test.ts index 4c59bf7621..e990c63c67 100644 --- a/test/integration/provider-scenarios/cloud-webdriver-provider-regressions.test.ts +++ b/test/integration/provider-scenarios/cloud-webdriver-provider-regressions.test.ts @@ -12,7 +12,7 @@ import type { DeviceLease } from '@agent-device/contracts/device'; import type { PlatformRuntimeHost } from '@agent-device/contracts/platform-runtime-operations'; import { createProviderDeviceRuntimeRequestProviders } from '../../../src/provider-device-runtime.ts'; import type { DaemonRequest } from '../../../src/daemon/daemon-request.ts'; -import * as iosSnapshotRuntime from '../../../src/snapshot/ios-snapshot-runtime.ts'; +import * as iosSnapshotRuntime from '@agent-device/capture-kit/ios-snapshot-runtime'; import { createProviderScenarioHarness, withProviderScenarioResource, From 26d6d2003d60769a932c5d216bbe0f825f849cd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Mon, 7 Sep 2026 17:58:09 +0200 Subject: [PATCH 3/8] chore(gates): align layering, mutation, fallow and CI gates with the capture-kit relocation Moves the executable-policy roots, presentation-owner constant, zone ranks, authority fixture, mutation sharding globs, stryker aliases, fallow baselines and the iOS workflow's android-owned paths-ignore entry onto the new packages/capture-kit paths, and extends the planted-red coverage to the new presentation-owner subpath. --- .github/workflows/ios.yml | 2 +- fallow-baselines/health.json | 10 ++++---- scripts/depgraph/model.test.ts | 22 ++++++++++++------ scripts/layering/architecture-ownership.ts | 2 +- .../contracts-implementation-policy.ts | 2 +- scripts/layering/model.test.ts | 2 +- scripts/layering/model.ts | 2 -- scripts/layering/package-boundaries.test.ts | 23 +++++++++++++++++++ ...vider-snapshot-presentation-policy.test.ts | 20 ++++++++++++++++ .../provider-snapshot-presentation-policy.ts | 13 ++++++----- .../snapshot-presentation-boundary.test.ts | 6 ++--- scripts/mutation/modules.ts | 10 ++++++-- scripts/mutation/selection.test.ts | 9 ++++++-- stryker.config.json | 4 ++-- 14 files changed, 94 insertions(+), 33 deletions(-) diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index c34aad9a15..207a9f3228 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -29,7 +29,7 @@ on: - 'packages/*/src/**/*.test.ts' - 'packages/*/src/**/__tests__/**/*.ts' - 'packages/platform-android/src/**' - - 'src/snapshot/snapshot-presentation/android/**' + - 'packages/capture-kit/src/snapshot/snapshot-presentation/android/**' - 'packages/platform-harmonyos/src/**' - 'packages/platform-linux/src/**' - 'packages/platform-vega/src/**' diff --git a/fallow-baselines/health.json b/fallow-baselines/health.json index 3f25e1070c..0dd017e755 100644 --- a/fallow-baselines/health.json +++ b/fallow-baselines/health.json @@ -456,7 +456,7 @@ "count": 2 } }, - "src/snapshot/snapshot-lines.ts": { + "packages/capture-kit/src/snapshot/snapshot-lines.ts": { "crap_moderate": { "count": 1 } @@ -471,12 +471,12 @@ "count": 1 } }, - "src/snapshot/scroll-edge-state.ts": { + "packages/capture-kit/src/snapshot/scroll-edge-state.ts": { "crap_moderate": { "count": 1 } }, - "src/snapshot/snapshot-presentation/text-surface.ts": { + "packages/capture-kit/src/snapshot/snapshot-presentation/text-surface.ts": { "crap_high": { "count": 1 } @@ -550,7 +550,7 @@ "packages/kernel/src/success-text.ts:high impact", "src/cli.ts:complexity", "src/commands/interaction/output.ts:high impact", - "src/snapshot/snapshot-lines.ts:high impact", + "packages/capture-kit/src/snapshot/snapshot-lines.ts:high impact", "packages/kernel/src/rect-center.ts:high impact", "packages/platform-apple/src/core/app-launch.ts:complexity", "packages/kernel/src/record.ts:high impact", @@ -562,7 +562,7 @@ "src/client/screenshot-result.ts:high impact", "packages/platform-web/src/json-utils.ts:high impact", "packages/platform-android/src/settings.ts:complexity", - "src/snapshot/snapshot-presentation/text-surface.ts:high impact", + "packages/capture-kit/src/snapshot/snapshot-presentation/text-surface.ts:high impact", "src/daemon/handlers/session-test-sharding.ts:high impact", "src/daemon/replay/internal/native-command.ts:complexity", "packages/platform-apple/src/core/debug-symbols/utils.ts:high impact", diff --git a/scripts/depgraph/model.test.ts b/scripts/depgraph/model.test.ts index bcd2197c1f..a9f807c664 100644 --- a/scripts/depgraph/model.test.ts +++ b/scripts/depgraph/model.test.ts @@ -46,9 +46,9 @@ function authorityFixture(): Map { "import { SessionStore } from './session-store.ts';", ].join('\n'), 'src/daemon/type-consumer.ts': "import type { SessionStore } from './session-store.ts';\n", - 'src/snapshot/policy-consumer.ts': [ - "import type { SessionState } from '../daemon/session-state.ts';", - "import type { SessionRef } from '../daemon/session-state.ts';", + 'packages/capture-kit/src/snapshot/policy-consumer.ts': [ + "import type { SessionState } from '../../../../src/daemon/session-state.ts';", + "import type { SessionRef } from '../../../../src/daemon/session-state.ts';", "import './ordinary-target.ts';", ].join('\n'), 'src/daemon/ordinary-consumer.ts': [ @@ -62,7 +62,7 @@ function authorityFixture(): Map { 'src/daemon/session-script-publication-capability.ts': 'export function isSessionRecording() {}\n', 'src/daemon/session-state-store.ts': 'export const SessionState = 1;\n', - 'src/snapshot/ordinary-target.ts': 'export const ordinary = 1;\n', + 'packages/capture-kit/src/snapshot/ordinary-target.ts': 'export const ordinary = 1;\n', 'packages/contracts/src/facades/client.ts': 'export type ClientShape = string;\n', 'packages/contracts/src/facades/capture.ts': 'export type CaptureShape = string;\n', 'packages/contracts/src/facades/replay.ts': 'export type ReplayShape = string;\n', @@ -108,7 +108,11 @@ test('authority overlay uses declared roots and symbols, keeps kind separate, an labels: ['live-state-authority'], }); assert.deepEqual( - graphEdge(graph, 'src/snapshot/policy-consumer.ts', 'src/snapshot/ordinary-target.ts'), + graphEdge( + graph, + 'packages/capture-kit/src/snapshot/policy-consumer.ts', + 'packages/capture-kit/src/snapshot/ordinary-target.ts', + ), { kind: 'value', labels: ['executable-policy'] }, ); assert.deepEqual( @@ -122,12 +126,16 @@ test('authority overlay uses declared roots and symbols, keeps kind separate, an const stateEdges = resolveImportEdges(files, authorityWorkspaceTargets()).filter( (edge) => - edge.file === 'src/snapshot/policy-consumer.ts' && + edge.file === 'packages/capture-kit/src/snapshot/policy-consumer.ts' && edge.target === 'src/daemon/session-state.ts', ); assert.equal(stateEdges.length, 2, 'the fixture must exercise raw same-pair imports'); assert.deepEqual( - graphEdge(graph, 'src/snapshot/policy-consumer.ts', 'src/daemon/session-state.ts'), + graphEdge( + graph, + 'packages/capture-kit/src/snapshot/policy-consumer.ts', + 'src/daemon/session-state.ts', + ), { kind: 'type', labels: ['live-state-shape', 'executable-policy'], diff --git a/scripts/layering/architecture-ownership.ts b/scripts/layering/architecture-ownership.ts index 67fee19e8c..252259ee6c 100644 --- a/scripts/layering/architecture-ownership.ts +++ b/scripts/layering/architecture-ownership.ts @@ -235,7 +235,7 @@ export const ARCHITECTURE_OWNERSHIP = { { name: 'snapshot-policy', kind: 'executable-policy', - roots: ['src/snapshot/'], + roots: ['packages/capture-kit/src/snapshot/'], forbiddenTargetRoots: ['src/daemon/'], }, ], diff --git a/scripts/layering/contracts-implementation-policy.ts b/scripts/layering/contracts-implementation-policy.ts index 0c522a5a27..41cb4f72c0 100644 --- a/scripts/layering/contracts-implementation-policy.ts +++ b/scripts/layering/contracts-implementation-policy.ts @@ -56,7 +56,7 @@ export function contractsImplementationAuthorityViolations( violation( file.path, 1, - 'contracts may not own snapshot quality warning rendering; that presentation policy belongs in src/snapshot/snapshot-presentation', + 'contracts may not own snapshot quality warning rendering; that presentation policy belongs in packages/capture-kit/src/snapshot/snapshot-presentation', ), ); } diff --git a/scripts/layering/model.test.ts b/scripts/layering/model.test.ts index 9189058527..14e4a4ab79 100644 --- a/scripts/layering/model.test.ts +++ b/scripts/layering/model.test.ts @@ -253,7 +253,7 @@ test('classifyZone separates the ranked spine from intentionally-unranked zones' // Every satellite zone joined the spine; only the composition root stays out, because R2 // forbids daemon/ from importing commands/ so the files that wire them cannot be ranked. assert.equal(classifyZone('mcp'), 'ranked'); - assert.equal(classifyZone('snapshot'), 'ranked'); + assert.equal(classifyZone('screenshot-diff'), 'ranked'); // A zone that is neither ranked nor listed peripheral must be flagged, never // silently treated as back-edge-free. assert.equal(classifyZone('not-a-real-zone'), 'unclassified'); diff --git a/scripts/layering/model.ts b/scripts/layering/model.ts index 841cf9de82..c81820d552 100644 --- a/scripts/layering/model.ts +++ b/scripts/layering/model.ts @@ -41,13 +41,11 @@ const TARGET_DAG_RANK = new Map([ ['command-registry', 1], ['contracts', 1], ['maestro', 1], - ['recording', 1], ['replay-test', 1], ['request', 1], ['screenshot-diff', 1], ['selectors', 1], ['session-journal', 1], - ['snapshot', 1], ['core', 2], ['cli-schema', 3], ['commands', 3], diff --git a/scripts/layering/package-boundaries.test.ts b/scripts/layering/package-boundaries.test.ts index 48f3373db6..1a19ad44ea 100644 --- a/scripts/layering/package-boundaries.test.ts +++ b/scripts/layering/package-boundaries.test.ts @@ -392,11 +392,13 @@ test('the real tree parses, declares, and passes R11', () => { ); assert.deepEqual([...captureKitPackage.exportTargets.keys()].sort(), [ '@agent-device/capture-kit', + '@agent-device/capture-kit/android-replacement-surface-occlusion', '@agent-device/capture-kit/durable-capture', '@agent-device/capture-kit/durable-json', '@agent-device/capture-kit/ios-snapshot-acquisition', '@agent-device/capture-kit/ios-snapshot-engine', '@agent-device/capture-kit/ios-snapshot-planning', + '@agent-device/capture-kit/ios-snapshot-runtime', '@agent-device/capture-kit/mobile-snapshot-semantics', '@agent-device/capture-kit/png', '@agent-device/capture-kit/png-crop', @@ -405,15 +407,36 @@ test('the real tree parses, declares, and passes R11', () => { '@agent-device/capture-kit/png-size', '@agent-device/capture-kit/png-worker-client', '@agent-device/capture-kit/post-gesture-stability', + '@agent-device/capture-kit/quality-warnings', '@agent-device/capture-kit/react-native-overlay', + '@agent-device/capture-kit/recording-output-path', + '@agent-device/capture-kit/recording-overlay', + '@agent-device/capture-kit/recording-telemetry', + '@agent-device/capture-kit/recording-video', + '@agent-device/capture-kit/repeated-nav-subtree', '@agent-device/capture-kit/screenshot-density', '@agent-device/capture-kit/screenshot-diff-pixels', '@agent-device/capture-kit/screenshot-overlay', + '@agent-device/capture-kit/scroll-edge-state', + '@agent-device/capture-kit/snapshot-chrome', '@agent-device/capture-kit/snapshot-desktop-projection', + '@agent-device/capture-kit/snapshot-desktop-surface', + '@agent-device/capture-kit/snapshot-diff', + '@agent-device/capture-kit/snapshot-evidence', + '@agent-device/capture-kit/snapshot-freshness', + '@agent-device/capture-kit/snapshot-label-dedup', + '@agent-device/capture-kit/snapshot-lines', + '@agent-device/capture-kit/snapshot-node-lookup', '@agent-device/capture-kit/snapshot-occlusion', + '@agent-device/capture-kit/snapshot-presentation-android-helper', + '@agent-device/capture-kit/snapshot-presentation-ios-transitions-fixtures', '@agent-device/capture-kit/snapshot-quality-backend-capabilities', '@agent-device/capture-kit/snapshot-quality-verdict', '@agent-device/capture-kit/snapshot-rect-projection', + '@agent-device/capture-kit/snapshot-state', + '@agent-device/capture-kit/snapshot-timeout-policy', + '@agent-device/capture-kit/snapshot-visibility', + '@agent-device/capture-kit/text-surface', ]); const provisionKitPackage = packages.find((pkg) => pkg.name === '@agent-device/provision-kit'); diff --git a/scripts/layering/provider-snapshot-presentation-policy.test.ts b/scripts/layering/provider-snapshot-presentation-policy.test.ts index f8d94634fc..1d0bb8a082 100644 --- a/scripts/layering/provider-snapshot-presentation-policy.test.ts +++ b/scripts/layering/provider-snapshot-presentation-policy.test.ts @@ -57,6 +57,26 @@ test('R73 rejects an out-of-adapter provider presentation import', () => { ); }); +test('R73 rejects a provider import of the capture-kit presentation runtime subpath', () => { + const result = violations( + new Map([ + [ + providerHelper, + `import { presentIosSnapshot } from '@agent-device/capture-kit/ios-snapshot-runtime';\nvoid presentIosSnapshot;\n`, + ], + ]), + ); + assert.ok( + result.some( + (entry) => + entry.rule === PROVIDER_SNAPSHOT_PRESENTATION_RULE && + entry.file === providerHelper && + entry.message.includes(IOS_SNAPSHOT_PRESENTATION_OWNER), + ), + JSON.stringify(result), + ); +}); + for (const planted of [ { name: 'a planted provider residue discard', diff --git a/scripts/layering/provider-snapshot-presentation-policy.ts b/scripts/layering/provider-snapshot-presentation-policy.ts index 0649dd0260..45a9902ea6 100644 --- a/scripts/layering/provider-snapshot-presentation-policy.ts +++ b/scripts/layering/provider-snapshot-presentation-policy.ts @@ -1,7 +1,7 @@ // Catches: a provider-* package acquiring an iOS snapshot outside the capture-kit acquisition -// entrypoint, or presenting it outside src/snapshot/ios-snapshot-runtime.ts — the exact split -// R72's engine convergence closed for the runner layer, mirrored here one layer up for the -// provider packages that call into it. +// entrypoint, or presenting it outside packages/capture-kit/src/snapshot/ios-snapshot-runtime.ts +// — the exact split R72's engine convergence closed for the runner layer, mirrored here one +// layer up for the provider packages that call into it. // Evidence: 7ee1a5ded7 (#2233) carried provider acquisitions through this one presentation // owner, the change this policy was written to hold in place. // Cost: 195 LOC (111 rule + 84 test). @@ -9,7 +9,7 @@ // reaching presentation only through @agent-device/capture-kit/ios-snapshot-acquisition, and // never constructing, discarding, or reassigning acquisition residue, no longer matter. An // exports map cannot replace it: it restricts external specifiers, not the transitive walk -// into src/snapshot/ or a provider-local `residue` property or assignment. +// into packages/capture-kit/src/snapshot/ or a provider-local `residue` property or assignment. import { parseSync } from 'oxc-parser'; import type { LayeringViolation, ResolvedImportEdge } from './model.ts'; @@ -18,7 +18,8 @@ import { memberPath, propertyName, visitAst } from './layering-ast.ts'; export const PROVIDER_SNAPSHOT_PRESENTATION_RULE = 'R73 provider-snapshot-presentation-ownership'; export const IOS_SNAPSHOT_ACQUISITION_ENTRYPOINT = '@agent-device/capture-kit/ios-snapshot-acquisition'; -export const IOS_SNAPSHOT_PRESENTATION_OWNER = 'src/snapshot/ios-snapshot-runtime.ts'; +export const IOS_SNAPSHOT_PRESENTATION_OWNER = + 'packages/capture-kit/src/snapshot/ios-snapshot-runtime.ts'; const PROVIDER_SOURCE = /^packages\/provider-[^/]+\/src\//; const IOS_SNAPSHOT_CAPTURE_KIT_ROOT = 'packages/capture-kit/src/ios-snapshot-'; @@ -109,7 +110,7 @@ function residueViolations(providerFile: string, source: string): LayeringViolat function isPresentationTarget(target: string): boolean { return ( target === IOS_SNAPSHOT_PRESENTATION_OWNER || - target.startsWith('src/snapshot/') || + target.startsWith('packages/capture-kit/src/snapshot/') || (target.startsWith(IOS_SNAPSHOT_CAPTURE_KIT_ROOT) && target !== 'packages/capture-kit/src/ios-snapshot-acquisition.ts') ); diff --git a/scripts/layering/snapshot-presentation-boundary.test.ts b/scripts/layering/snapshot-presentation-boundary.test.ts index 9f62dff59a..ac87036c95 100644 --- a/scripts/layering/snapshot-presentation-boundary.test.ts +++ b/scripts/layering/snapshot-presentation-boundary.test.ts @@ -52,12 +52,12 @@ test('the boundary reports a facet module that reaches back into the daemon', () const sources = new Map([ ['src/daemon/types.ts', 'export type SessionState = { id: string };\n'], [ - 'src/snapshot/snapshot-freshness/android.ts', - "import type { SessionState } from '../../daemon/types.ts';\nexport type X = SessionState;\n", + 'packages/capture-kit/src/snapshot/snapshot-freshness/android.ts', + "import type { SessionState } from '../../../../../src/daemon/types.ts';\nexport type X = SessionState;\n", ], ]); assert.deepEqual(daemonImportsFromSnapshotFacet(sources), [ - 'src/snapshot/snapshot-freshness/android.ts:1 -> src/daemon/types.ts', + 'packages/capture-kit/src/snapshot/snapshot-freshness/android.ts:1 -> src/daemon/types.ts', ]); }); diff --git a/scripts/mutation/modules.ts b/scripts/mutation/modules.ts index 9b3b9c5bdc..beed008978 100644 --- a/scripts/mutation/modules.ts +++ b/scripts/mutation/modules.ts @@ -61,8 +61,14 @@ export const KERNEL_MODULES: readonly KernelModule[] = [ { id: 'scroll-edge-state', label: 'Scroll edge-state detection', - mutate: ['src/snapshot/scroll-edge-state.ts', 'src/snapshot/scroll-edge-state/**/*.ts'], - owns: ['src/snapshot/scroll-edge-state.ts', 'src/snapshot/scroll-edge-state/'], + mutate: [ + 'packages/capture-kit/src/snapshot/scroll-edge-state.ts', + 'packages/capture-kit/src/snapshot/scroll-edge-state/**/*.ts', + ], + owns: [ + 'packages/capture-kit/src/snapshot/scroll-edge-state.ts', + 'packages/capture-kit/src/snapshot/scroll-edge-state/', + ], }, { id: 'selectors', diff --git a/scripts/mutation/selection.test.ts b/scripts/mutation/selection.test.ts index 0d04f1eb44..95b602a7e1 100644 --- a/scripts/mutation/selection.test.ts +++ b/scripts/mutation/selection.test.ts @@ -80,9 +80,14 @@ test('a lane-tooling diff selects real mutants', () => { // The weekly sweep is the kernel report; selecting on derived ownership would // run the full ten-shard sweep on most PRs for a report nobody gates on. test('a kernel diff selects nothing — only a harness diff spends mutants', () => { - const dir = worktreeWithCommit('kernel', ['src/snapshot/scroll-edge-state.ts']); + const dir = worktreeWithCommit('kernel', [ + 'packages/capture-kit/src/snapshot/scroll-edge-state.ts', + ]); assert.deepEqual(listAffected(dir), []); - assert.deepEqual(affectedMatrixFor(['src/snapshot/scroll-edge-state.ts']), []); + assert.deepEqual( + affectedMatrixFor(['packages/capture-kit/src/snapshot/scroll-edge-state.ts']), + [], + ); }); test('a docs-only diff selects nothing', () => { diff --git a/stryker.config.json b/stryker.config.json index 1a2c7bb0bf..f8154a4c27 100644 --- a/stryker.config.json +++ b/stryker.config.json @@ -34,8 +34,8 @@ "packages/kernel/src/errors.ts", "src/daemon/ref-frame.ts", "src/commands/interaction/runtime/settle.ts", - "src/snapshot/scroll-edge-state.ts", - "src/snapshot/scroll-edge-state/**/*.ts", + "packages/capture-kit/src/snapshot/scroll-edge-state.ts", + "packages/capture-kit/src/snapshot/scroll-edge-state/**/*.ts", "packages/selectors/src/**/*.ts", "!packages/selectors/src/**/*.test.ts", "!packages/selectors/src/internal/__tests__/**", From ff7da9bb7ddd94879148f47119af3c1293881761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Mon, 7 Sep 2026 18:09:02 +0200 Subject: [PATCH 4/8] chore: point capture-domain source-of-truth comments at the relocated capture-kit modules --- packages/contracts/src/android-system-chrome.ts | 2 +- packages/selectors/src/internal/parse.ts | 2 +- src/daemon/__tests__/interaction-outcome-policy.test.ts | 2 +- src/daemon/__tests__/post-gesture-stabilization-fixtures.ts | 2 +- src/daemon/android-snapshot-timeout-evidence.ts | 2 +- src/daemon/session-snapshot-freshness.ts | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/contracts/src/android-system-chrome.ts b/packages/contracts/src/android-system-chrome.ts index d5e934c30b..df634f1ca4 100644 --- a/packages/contracts/src/android-system-chrome.ts +++ b/packages/contracts/src/android-system-chrome.ts @@ -2,7 +2,7 @@ import type { SnapshotNode } from '@agent-device/kernel/snapshot'; /** * Android status-bar/navigation-bar chrome identity, shared by the settle-chrome - * classifier (`core/snapshot-chrome.ts`) and the helper content classifier + * classifier (`packages/capture-kit/src/snapshot-chrome.ts`) and the helper content classifier * (`packages/platform-android/src/snapshot-content-recovery.ts`). SystemUI also hosts actionable * overlays — volume panel, media pickers, the shade itself — so chrome is never a * package-level fact: only the status/nav-bar container's subtree is chrome. diff --git a/packages/selectors/src/internal/parse.ts b/packages/selectors/src/internal/parse.ts index c4d95717a2..84cd0a2897 100644 --- a/packages/selectors/src/internal/parse.ts +++ b/packages/selectors/src/internal/parse.ts @@ -56,7 +56,7 @@ export const SELECTOR_KEY_NAMES: readonly SelectorKey[] = [...ALL_KEYS]; // Role/element-type words that show up as accessibility roles, not selector keys (e.g. the // `button` in `button="Push Article"`). Superset of the ROLE_LABELS vocabulary in -// src/snapshot/snapshot-lines.ts (plus a few common role words like list/tab/alert/dialog/header, +// packages/capture-kit/src/snapshot/snapshot-lines.ts (plus a few common role words like list/tab/alert/dialog/header, // minus valid selector keys such as `text`, which ALL_KEYS short-circuits before this set is // consulted), kept locally to avoid a selectors -> snapshot layering dependency. Drifts silently // if ROLE_LABELS grows; that's fine here since this only sharpens a hint, not validates anything. diff --git a/src/daemon/__tests__/interaction-outcome-policy.test.ts b/src/daemon/__tests__/interaction-outcome-policy.test.ts index 4005e90eaa..7dfbcef361 100644 --- a/src/daemon/__tests__/interaction-outcome-policy.test.ts +++ b/src/daemon/__tests__/interaction-outcome-policy.test.ts @@ -195,7 +195,7 @@ test('classifyBaselineSurfaceEvidence excludes the keyboard container from discr // #1563 review, finding 2: a container-only exclusion still misses keyboard // DESCENDANTS (individual keys) and SIBLINGS (assistant buttons like "Next // keyboard"/"Dictate", which live outside the container per -// src/core/snapshot-chrome.ts's collectKeyboardChrome doc comment — a +// packages/capture-kit/src/snapshot-chrome.ts's collectKeyboardChrome doc comment — a // container-descendant walk alone provably misses them, hence the whole- // window classification that module reuses here via collectKeyboardChromeRefs). test('classifyBaselineSurfaceEvidence excludes keyboard DESCENDANTS and window SIBLINGS, not just the container, from discriminating overlap', () => { diff --git a/src/daemon/__tests__/post-gesture-stabilization-fixtures.ts b/src/daemon/__tests__/post-gesture-stabilization-fixtures.ts index ae24ca5fea..17fb1c1d44 100644 --- a/src/daemon/__tests__/post-gesture-stabilization-fixtures.ts +++ b/src/daemon/__tests__/post-gesture-stabilization-fixtures.ts @@ -118,7 +118,7 @@ export function applicationRootNode() { * `[Keyboard]` container PLUS a sibling "Next keyboard" assistant button * under the SAME window — a container-descendant-only walk provably misses * the sibling (see `collectKeyboardChrome`'s doc comment in - * src/core/snapshot-chrome.ts, the source of truth this fixture's shape is + * packages/capture-kit/src/snapshot-chrome.ts, the source of truth this fixture's shape is * drawn from: "a SIBLING subtree holding the 'Next keyboard' and 'Dictate' * buttons — siblings of the container, so a container-descendant walk alone * provably misses them"). Neither entry is the container itself, so sharing diff --git a/src/daemon/android-snapshot-timeout-evidence.ts b/src/daemon/android-snapshot-timeout-evidence.ts index c09dd33686..039d3bb7e5 100644 --- a/src/daemon/android-snapshot-timeout-evidence.ts +++ b/src/daemon/android-snapshot-timeout-evidence.ts @@ -27,7 +27,7 @@ import { * * The two things that are not daemon assembly moved out: whether a failure is the * accessibility-timeout shape is a policy - * (`src/snapshot/snapshot-timeout-policy.ts`), and the published evidence shape is + * (`packages/capture-kit/src/snapshot/snapshot-timeout-policy.ts`), and the published evidence shape is * vocabulary (`src/daemon/snapshot-timeout-evidence.ts`, whose only consumer is this * module). What remains here is the ordering that * genuinely needs the daemon: resolving a bound screenshot runtime, writing the artifact, diff --git a/src/daemon/session-snapshot-freshness.ts b/src/daemon/session-snapshot-freshness.ts index ca93c7c73e..a61eadc56d 100644 --- a/src/daemon/session-snapshot-freshness.ts +++ b/src/daemon/session-snapshot-freshness.ts @@ -17,7 +17,7 @@ import type { SessionState } from './session-state.ts'; * Session binding for the neutral snapshot-freshness facet (#1983). * * The staleness policy, its thresholds and the recovery loop live in - * `src/snapshot/snapshot-freshness/`. What stays here is the part that is genuinely daemon + * `packages/capture-kit/src/snapshot/snapshot-freshness/`. What stays here is the part that is genuinely daemon * assembly: reading and retiring the window that hangs off store-owned `SessionState`, and * choosing the comparison baseline from session snapshot lineage. This module is the declared * R7 owner of `SessionState.androidSnapshotFreshness`. From cae78c03e4739bf95c8cc5f580d1dc243dd46180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 8 Sep 2026 08:25:09 +0200 Subject: [PATCH 5/8] test: point shutdown recording mock at capture-kit and cover interactor acquisition presentation --- .../snapshot-interactor-capture.test.ts | 76 +++++++++++++++++++ .../session-close-shutdown.fixtures.ts | 2 +- 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 src/daemon/__tests__/snapshot-interactor-capture.test.ts diff --git a/src/daemon/__tests__/snapshot-interactor-capture.test.ts b/src/daemon/__tests__/snapshot-interactor-capture.test.ts new file mode 100644 index 0000000000..7b1cc37315 --- /dev/null +++ b/src/daemon/__tests__/snapshot-interactor-capture.test.ts @@ -0,0 +1,76 @@ +import { expect, test, vi } from 'vitest'; +import type { + Interactor, + SnapshotOptions, + SnapshotResult, + SnapshotRuntimeAcquiredResult, +} from '@agent-device/contracts/interactor-types'; +import { IOS_SIMULATOR } from '../../__tests__/test-utils/device-fixtures.ts'; +import { captureSnapshotWithInteractor } from '../snapshot-interactor-capture.ts'; + +const getInteractor = vi.hoisted(() => vi.fn()); +vi.mock('../../core/interactors.ts', () => ({ getInteractor })); + +const presentIosSnapshotAcquisition = vi.hoisted(() => vi.fn()); +vi.mock('@agent-device/capture-kit/ios-snapshot-runtime', () => ({ + presentIosSnapshotAcquisition, +})); + +const presented: SnapshotResult = { backend: 'xctest', producer: 'simulator-ax-bridge', nodes: [] }; + +const acquired: SnapshotRuntimeAcquiredResult = { + stage: 'acquired', + acquisition: { + producer: 'simulator-ax-bridge', + intent: 'full', + nodes: [], + viewport: { kind: 'missing', reason: 'not-supported' }, + lineage: {}, + residue: [], + }, +}; + +function interactorReturning(result: SnapshotResult | SnapshotRuntimeAcquiredResult): Interactor { + return { snapshot: async () => result } as unknown as Interactor; +} + +test('a presented snapshot passes through without the acquisition presenter', async () => { + getInteractor.mockReset(); + presentIosSnapshotAcquisition.mockReset(); + getInteractor.mockResolvedValue(interactorReturning(presented)); + + const options: SnapshotOptions = { interactiveOnly: true }; + await expect( + captureSnapshotWithInteractor({ + device: IOS_SIMULATOR, + runnerContext: {}, + options, + }), + ).resolves.toEqual(presented); + + expect(presentIosSnapshotAcquisition).not.toHaveBeenCalled(); +}); + +test('an acquired snapshot is presented through the capture-kit runtime', async () => { + getInteractor.mockReset(); + presentIosSnapshotAcquisition.mockReset(); + getInteractor.mockResolvedValue(interactorReturning(acquired)); + const rePresented: SnapshotResult = { + backend: 'xctest', + producer: 'simulator-ax-bridge', + nodes: [], + }; + presentIosSnapshotAcquisition.mockReturnValue(rePresented); + + const options: SnapshotOptions = {}; + await expect( + captureSnapshotWithInteractor({ + device: IOS_SIMULATOR, + runnerContext: {}, + options, + }), + ).resolves.toBe(rePresented); + + expect(presentIosSnapshotAcquisition).toHaveBeenCalledOnce(); + expect(presentIosSnapshotAcquisition).toHaveBeenCalledWith(acquired, options); +}); diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-close-shutdown.fixtures.ts b/src/daemon/session-lifecycle/internal/__tests__/session-close-shutdown.fixtures.ts index 8b241646f7..03c4b3c10c 100644 --- a/src/daemon/session-lifecycle/internal/__tests__/session-close-shutdown.fixtures.ts +++ b/src/daemon/session-lifecycle/internal/__tests__/session-close-shutdown.fixtures.ts @@ -42,7 +42,7 @@ vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { stopAndroidSnapshotHelperSessionForDevice: vi.fn(async () => {}), }; }); -vi.mock('../../../../recording/video.ts', () => ({ +vi.mock('@agent-device/capture-kit/recording-video', () => ({ waitForStableFile: vi.fn(async () => {}), isPlayableVideo: vi.fn(async () => true), })); From d8745840a212137801677ea8a51b877f74669689 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 8 Sep 2026 10:44:50 +0200 Subject: [PATCH 6/8] test(capture-kit): update upstream presentation test imports --- src/core/__tests__/ios-snapshot-presentation-once.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/__tests__/ios-snapshot-presentation-once.test.ts b/src/core/__tests__/ios-snapshot-presentation-once.test.ts index 8263ee477b..08889c0e97 100644 --- a/src/core/__tests__/ios-snapshot-presentation-once.test.ts +++ b/src/core/__tests__/ios-snapshot-presentation-once.test.ts @@ -6,8 +6,8 @@ import type { } from '@agent-device/contracts/ios-snapshot'; import type { SnapshotRuntimeAcquiredResult } from '@agent-device/contracts/interactor-types'; import type { RawSnapshotNode, Rect } from '@agent-device/kernel/snapshot'; -import { presentIosSnapshotAcquisition } from '../../snapshot/ios-snapshot-runtime.ts'; -import { buildSnapshotState } from '../snapshot-state.ts'; +import { presentIosSnapshotAcquisition } from '@agent-device/capture-kit/ios-snapshot-runtime'; +import { buildSnapshotState } from '@agent-device/capture-kit/snapshot-state'; /** * #2188 invariant 2: geometric presentation happens exactly ONCE per capture. Before #2199 the From 770c206a1e8327f0c00a2adceaf2514f425e6c97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 8 Sep 2026 10:46:47 +0200 Subject: [PATCH 7/8] chore(gates): follow relocated snapshot assembly in R74 --- scripts/layering/snapshot-assembly-presentation-policy.test.ts | 2 +- scripts/layering/snapshot-assembly-presentation-policy.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/layering/snapshot-assembly-presentation-policy.test.ts b/scripts/layering/snapshot-assembly-presentation-policy.test.ts index 0eb79731b9..2ebe1f675a 100644 --- a/scripts/layering/snapshot-assembly-presentation-policy.test.ts +++ b/scripts/layering/snapshot-assembly-presentation-policy.test.ts @@ -12,7 +12,7 @@ import { workspaceSpecifierTargets } from './package-boundaries.ts'; import { listTrackedProductionSources } from './tracked-sources.ts'; const repoRoot = path.resolve(import.meta.dirname, '../..'); -const assemblyFile = 'src/core/snapshot-state.ts'; +const assemblyFile = 'packages/capture-kit/src/snapshot-state.ts'; const producerAdapter = 'packages/platform-apple/src/snapshot-source/adapter.ts'; function currentSources(overrides: ReadonlyMap = new Map()): Map { diff --git a/scripts/layering/snapshot-assembly-presentation-policy.ts b/scripts/layering/snapshot-assembly-presentation-policy.ts index e801e48732..b93f795933 100644 --- a/scripts/layering/snapshot-assembly-presentation-policy.ts +++ b/scripts/layering/snapshot-assembly-presentation-policy.ts @@ -25,7 +25,7 @@ export const SNAPSHOT_ASSEMBLY_PRESENTATION_RULE = 'R74 snapshot-assembly-presen * refs; it does not present, and it does not know which channel it is holding. */ export const SNAPSHOT_ASSEMBLY_FILES: readonly string[] = [ - 'src/core/snapshot-state.ts', + 'packages/capture-kit/src/snapshot-state.ts', 'src/daemon/snapshot-capture.ts', ]; From cc17cf16174598762853387e1538188a2ae96e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 8 Sep 2026 10:53:57 +0200 Subject: [PATCH 8/8] test(daemon): freeze prewarm deadline assertion clocks --- .../__tests__/session-open-url-prewarm.test.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-open-url-prewarm.test.ts b/src/daemon/session-lifecycle/internal/__tests__/session-open-url-prewarm.test.ts index 25fa02b6ea..8b296734d4 100644 --- a/src/daemon/session-lifecycle/internal/__tests__/session-open-url-prewarm.test.ts +++ b/src/daemon/session-lifecycle/internal/__tests__/session-open-url-prewarm.test.ts @@ -565,7 +565,13 @@ test('open iOS URL without app bundle id skips runner prewarm', async () => { expect(mockPrewarmIosRunnerSession).not.toHaveBeenCalled(); }); -test('prepare ios-runner starts the XCTest runner on an explicit iOS selector', async () => { +test('prepare ios-runner starts the XCTest runner on an explicit iOS selector', async ({ + onTestFinished, +}) => { + vi.useFakeTimers({ toFake: ['Date'] }); + onTestFinished(() => { + vi.useRealTimers(); + }); const sessionStore = makeSessionStore('agent-device-session-open-url-prewarm-'); const sessionName = 'prepare-ios-runner'; mockResolveTargetDevice.mockResolvedValue({ @@ -688,7 +694,13 @@ test('prepare ios-runner explains overlapping timing fields with additive parts' } }); -test('prepare ios-runner starts the XCTest runner on an explicit macOS selector', async () => { +test('prepare ios-runner starts the XCTest runner on an explicit macOS selector', async ({ + onTestFinished, +}) => { + vi.useFakeTimers({ toFake: ['Date'] }); + onTestFinished(() => { + vi.useRealTimers(); + }); const sessionStore = makeSessionStore('agent-device-session-open-url-prewarm-'); const sessionName = 'prepare-macos-runner'; mockResolveTargetDevice.mockResolvedValue({