Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ jobs:
packages/platform-apple/src/snapshot-source/native-runtime.test.ts \
packages/platform-apple/src/foldable/fold-helper-cache.test.ts \
packages/platform-apple/src/foldable/simulator-hid-native.test.ts \
packages/capture-kit/src/recording/__tests__/recording-scripts.test.ts
packages/capture-kit/src/recording/__tests__/swift-cache-recording-scripts.test.ts
pnpm check:package -- --verify-snapshot-bridge-preparation

- name: Upload macOS artifacts
Expand Down
2 changes: 1 addition & 1 deletion docs/adr/0026-scroll-clip-authority.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ ledger is the shape to extend; a second parallel ledger would be a second source
compaction — the Settings tree legitimately drops rows under the chrome — or sit loose enough to wave
through a 74 → 20 collapse. The differential already asserts interactive ⊆ regular ⊆ raw; what it lacks
is coverage of the runner stage, since `assertProjectionSubsets`
(`ios-snapshot-engine/properties.test.ts`) builds acquired inputs only and the Swift differential drops
(`ios-snapshot-engine/engine-properties.test.ts`) builds acquired inputs only and the Swift differential drops
interactive cases. Extending it to `stage: 'presented'` is what makes any future shrinkage visible.

## Consequences and open evidence
Expand Down
4 changes: 2 additions & 2 deletions packages/capture-kit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -303,8 +303,8 @@
"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"
"types": "./src/ios-snapshot-engine/transitions.fixtures.ts",
"default": "./src/ios-snapshot-engine/transitions.fixtures.ts"
},
"./snapshot-quality-backend-capabilities": {
"types": "./src/snapshot-quality-backend-capabilities.ts",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect, test } from 'vitest';
import { buildIosInteractiveSnapshotPresentation } from '../../../ios-snapshot-engine/index.ts';
import { buildIosInteractiveSnapshotPresentation } from './semantic-index.ts';
import {
closedComposerWithRetainedActionShelfNodes,
closedComposerWithRetainedRegularTreeActionNodes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import fs from 'node:fs';
import assert from 'node:assert/strict';
import path from 'node:path';
import { test } from 'vitest';
import { IosSnapshotEngineError, presentIosSnapshot, publishIosSnapshot } from './index.ts';
import { presentIosSnapshot, publishIosSnapshot } from './engine.ts';
import { IosSnapshotEngineError } from './types.ts';
import {
canonicalNodes,
runTypeScriptCase,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
deriveIosCaptureHint,
} from '@agent-device/capture-kit/ios-snapshot-planning';
import type { RawSnapshotNode, Rect } from '@agent-device/kernel/snapshot';
import { presentIosSnapshot } from './index.ts';
import { presentIosSnapshot } from './engine.ts';

// ADR 0026: `REGULAR_ELIGIBLE_TYPES` (TypeScript) and `eligibleInteractiveTypes` (Swift) are one
// fact in two languages — the set that lets a scroll host survive regular projection so the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import {
import { canonicalNodes, runTypeScriptCase } from './conformance-harness.ts';
import { differentialBatchArbitrary } from './conformance-generator.ts';
import { acquisitionForGoldenCase, readIosSnapshotEngineFixture } from './conformance-fixture.ts';
import { IosSnapshotEngineError, presentIosSnapshot, publishIosSnapshot } from './index.ts';
import { presentIosSnapshot, publishIosSnapshot } from './engine.ts';
import { IosSnapshotEngineError } from './types.ts';

test('property: regular effective geometry stays within the viewport and actionability fails closed', () => {
fc.assert(fc.property(differentialBatchArbitrary, assertRegularCases), {
Expand Down
2 changes: 1 addition & 1 deletion packages/capture-kit/src/ios-snapshot-engine/projection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { normalizeType } from '@agent-device/contracts/snapshot';
import type { IosSnapshotFoldPolicy, IosSnapshotPresentationNode } from './types.ts';

// Kept in step with `eligibleInteractiveTypes` in SnapshotPresentationProjection.swift by
// ios-snapshot-engine/eligibility-parity.test.ts. Excludes `scrollarea`, which `isScrollableSnapshotType`
// ios-snapshot-engine/engine-eligibility-parity.test.ts. Excludes `scrollarea`, which `isScrollableSnapshotType`
// accepts but the iOS runner never emits (ADR 0026; macOS decision recorded in that test).
const REGULAR_ELIGIBLE_TYPES = new Set([
'button',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect, test } from 'vitest';
import { elementClassicRoomListNodes, legitimatelyLabeledCellNodes } from './rows.fixtures.ts';
import { buildIosInteractiveSnapshotPresentation } from '../../../ios-snapshot-engine/index.ts';
import { buildIosInteractiveSnapshotPresentation } from './semantic-index.ts';

test('iOS row presentation associates generic room cells with their descendant titles', () => {
const nodes = buildIosInteractiveSnapshotPresentation(elementClassicRoomListNodes).nodes;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect, test } from 'vitest';
import type { RawSnapshotNode } from '@agent-device/kernel/snapshot';
import { buildIosInteractiveSnapshotPresentation } from '@agent-device/capture-kit/ios-snapshot-engine';
import { buildIosInteractiveSnapshotPresentation } from './semantic-index.ts';

test('publishes an exact representative for every semantic source index', () => {
const nodes: RawSnapshotNode[] = [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect, test } from 'vitest';
import { attachRefs, type RawSnapshotNode } from '@agent-device/kernel/snapshot';
import { buildIosInteractiveSnapshotPresentation } from '@agent-device/capture-kit/ios-snapshot-engine';
import { buildIosInteractiveSnapshotPresentation } from './semantic-index.ts';

function buildSnapshotState(data: { nodes?: RawSnapshotNode[]; backend?: 'xctest' }) {
return {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { test } from 'vitest';
import assert from 'node:assert/strict';
import { AppError } from '@agent-device/kernel/errors';
import { CONTACT_SHEET_UNSUPPORTED_HOST_REASON } from '../contact-sheet-report.ts';
import { assertContactSheetHostSupport } from '../contact-sheet-frames.ts';

test('contact sheets are explicitly unsupported on non-macOS hosts', () => {
assert.throws(
() => assertContactSheetHostSupport('linux'),
(error: unknown) => {
return (
error instanceof AppError &&
error.code === 'UNSUPPORTED_OPERATION' &&
error.details?.reason === CONTACT_SHEET_UNSUPPORTED_HOST_REASON
);
},
);
assert.doesNotThrow(() => assertContactSheetHostSupport('darwin'));
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { test } from 'vitest';
import assert from 'node:assert/strict';
import { getRecordingOverlaySupportWarning } from '../overlay.ts';

test('recording overlays are explicitly unsupported on non-macOS hosts', () => {
assert.equal(
getRecordingOverlaySupportWarning('linux'),
'touch overlay burn-in is only available on macOS hosts; returning raw video plus gesture telemetry',
);
assert.equal(getRecordingOverlaySupportWarning('darwin'), undefined);
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { PNG } from 'pngjs';
import { runCmd } from '@agent-device/host-kit/command';
import { AppError } from '@agent-device/kernel/errors';
import { CONTACT_SHEET_UNSUPPORTED_HOST_REASON } from '../contact-sheet-report.ts';
import { assertContactSheetHostSupport } from '../contact-sheet-frames.ts';
import { getRecordingOverlaySupportWarning } from '../overlay.ts';
import { mkdtempForTest } from '../../tmp-dir.fixtures.ts';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
Expand Down Expand Up @@ -220,25 +216,3 @@ function assertTypechecked(outcomes: readonly TypecheckOutcome[], basename: stri
assert.ok(outcome, `${basename} was never typechecked`);
assert.equal(outcome.exitCode, 0, `${basename} should typecheck\n${outcome.stderr}`);
}

test('recording overlays are explicitly unsupported on non-macOS hosts', () => {
assert.equal(
getRecordingOverlaySupportWarning('linux'),
'touch overlay burn-in is only available on macOS hosts; returning raw video plus gesture telemetry',
);
assert.equal(getRecordingOverlaySupportWarning('darwin'), undefined);
});

test('contact sheets are explicitly unsupported on non-macOS hosts', () => {
assert.throws(
() => assertContactSheetHostSupport('linux'),
(error: unknown) => {
return (
error instanceof AppError &&
error.code === 'UNSUPPORTED_OPERATION' &&
error.details?.reason === CONTACT_SHEET_UNSUPPORTED_HOST_REASON
);
},
);
assert.doesNotThrow(() => assertContactSheetHostSupport('darwin'));
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import {
buildSnapshotSignatures,
isLikelySnapshotStuckOnPreviousRoute,
isLikelyStaleSnapshotDrop,
} from '../snapshot-freshness/android.ts';
import type { SnapshotFreshnessWindow } from '../snapshot-freshness/index.ts';
} from './android.ts';
import type { SnapshotFreshnessWindow } from './index.ts';

function labeledNodes(count: number, prefix = 'item'): RawSnapshotNode[] {
return Array.from({ length: count }, (_, index) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@ import assert from 'node:assert/strict';
import { test, vi } from 'vitest';
import type { SnapshotCaptureAnnotations } from '@agent-device/contracts/capture';
import { makeSnapshotState } from '../../snapshot-state.fixtures.ts';
import { captureFreshnessRecoveredAttempt } from '../snapshot-freshness/recovery.ts';
import type {
SnapshotFreshnessReason,
SnapshotFreshnessWindow,
} from '../snapshot-freshness/types.ts';
import { captureFreshnessRecoveredAttempt } from './recovery.ts';
import type { SnapshotFreshnessReason, SnapshotFreshnessWindow } from './types.ts';

type Attempt = {
snapshot: ReturnType<typeof makeSnapshotState>;
Expand Down
Loading