@kaeawc/auto-mobile 0.0.45 → 0.0.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +3 -3
  2. package/README.md.backup +3 -3
  3. package/dist/schemas/test-plan.schema.json +129 -6
  4. package/dist/schemas/tool-definitions.json +1720 -285
  5. package/dist/src/db/migrations/2026_07_24_000_device_locks.ts +27 -0
  6. package/dist/src/db/migrations/2026_07_27_000_session_tool_capabilities.ts +17 -0
  7. package/dist/src/index.js +388 -384
  8. package/dist/src/index.js.map +1 -1
  9. package/package.json +9 -7
  10. package/schemas/test-plan.schema.json +129 -6
  11. package/schemas/tool-definitions.json +1720 -285
  12. package/dist/ios/screen-capture/Package.swift +0 -35
  13. package/dist/ios/screen-capture/Sources/ScreenCaptureCore/AudioPcm16Encoder.swift +0 -22
  14. package/dist/ios/screen-capture/Sources/ScreenCaptureCore/CommandLineOptions.swift +0 -152
  15. package/dist/ios/screen-capture/Sources/ScreenCaptureCore/DeviceInfo.swift +0 -25
  16. package/dist/ios/screen-capture/Sources/ScreenCaptureCore/FrameProtocol.swift +0 -113
  17. package/dist/ios/screen-capture/Sources/ScreenCaptureCore/FrameWriter.swift +0 -62
  18. package/dist/ios/screen-capture/Sources/ScreenCaptureCore/SimulatorWindowInfo.swift +0 -51
  19. package/dist/ios/screen-capture/Sources/ScreenCaptureHelper/AudioSampleBuffer.swift +0 -41
  20. package/dist/ios/screen-capture/Sources/ScreenCaptureHelper/CMIOSystem.swift +0 -26
  21. package/dist/ios/screen-capture/Sources/ScreenCaptureHelper/DeviceCaptureSession.swift +0 -117
  22. package/dist/ios/screen-capture/Sources/ScreenCaptureHelper/DeviceDiscovery.swift +0 -29
  23. package/dist/ios/screen-capture/Sources/ScreenCaptureHelper/FrameWriter+PixelBuffer.swift +0 -25
  24. package/dist/ios/screen-capture/Sources/ScreenCaptureHelper/SimulatorCaptureSession.swift +0 -159
  25. package/dist/ios/screen-capture/Sources/ScreenCaptureHelper/SimulatorWindowDiscovery.swift +0 -37
  26. package/dist/ios/screen-capture/Sources/ScreenCaptureHelper/main.swift +0 -255
  27. package/dist/ios/screen-capture/Tests/ScreenCaptureCoreTests/AudioPcm16EncoderTests.swift +0 -17
  28. package/dist/ios/screen-capture/Tests/ScreenCaptureCoreTests/CommandLineOptionsTests.swift +0 -181
  29. package/dist/ios/screen-capture/Tests/ScreenCaptureCoreTests/DeviceInfoTests.swift +0 -35
  30. package/dist/ios/screen-capture/Tests/ScreenCaptureCoreTests/FrameProtocolTests.swift +0 -123
  31. package/dist/ios/screen-capture/Tests/ScreenCaptureCoreTests/FrameWriterTests.swift +0 -62
  32. package/dist/ios/screen-capture/Tests/ScreenCaptureCoreTests/SimulatorAudioCaptureAvailabilityTests.swift +0 -27
  33. package/dist/ios/screen-capture/Tests/ScreenCaptureCoreTests/SimulatorWindowInfoTests.swift +0 -40
@@ -1,35 +0,0 @@
1
- import XCTest
2
- @testable import ScreenCaptureCore
3
-
4
- final class DeviceInfoTests: XCTestCase {
5
- func testRoundTripsThroughJSON() throws {
6
- let original = DeviceListResponse(devices: [
7
- DeviceInfo(
8
- uniqueID: "00008140-001A2B3C0AE2401E",
9
- localizedName: "iPhone",
10
- modelID: "iPhone15,2",
11
- manufacturer: "Apple"
12
- )
13
- ])
14
- let data = try JSONEncoder().encode(original)
15
- let decoded = try JSONDecoder().decode(DeviceListResponse.self, from: data)
16
- XCTAssertEqual(decoded, original)
17
- }
18
-
19
- func testJSONUsesExpectedKeys() throws {
20
- let device = DeviceInfo(
21
- uniqueID: "id",
22
- localizedName: "name",
23
- modelID: "model",
24
- manufacturer: "vendor"
25
- )
26
- let data = try JSONEncoder().encode(device)
27
- let json = try XCTUnwrap(
28
- JSONSerialization.jsonObject(with: data) as? [String: String]
29
- )
30
- XCTAssertEqual(json["uniqueID"], "id")
31
- XCTAssertEqual(json["localizedName"], "name")
32
- XCTAssertEqual(json["modelID"], "model")
33
- XCTAssertEqual(json["manufacturer"], "vendor")
34
- }
35
- }
@@ -1,123 +0,0 @@
1
- // swiftlint:disable force_unwrapping
2
- // Force-unwrap is idiomatic in test fixtures (fail fast on bad setup); disabled file-wide.
3
-
4
- import XCTest
5
- @testable import ScreenCaptureCore
6
-
7
- final class FrameProtocolTests: XCTestCase {
8
- func testEncodeAudioHeaderUsesReservedZeroWidthMarker() {
9
- let data = FrameProtocol.encodeAudioHeader(payloadLength: 320)
10
-
11
- XCTAssertEqual(data.count, FrameProtocol.headerSize)
12
- // Marker "AMF1" on the wire.
13
- XCTAssertEqual(Array(data.prefix(4)), [0x41, 0x4D, 0x46, 0x31])
14
- // Field bytes (offset 8): width=0, height=8000 (0x1F40), bytesPerRow=1, timestampMs=320 (0x140).
15
- XCTAssertEqual(Array(data[8..<24]), [
16
- 0, 0, 0, 0,
17
- 0x40, 0x1F, 0, 0,
18
- 1, 0, 0, 0,
19
- 0x40, 1, 0, 0,
20
- ])
21
- XCTAssertEqual(
22
- FrameProtocol.decodeHeader(data),
23
- FrameProtocol.Header(width: 0, height: 8_000, bytesPerRow: 1, timestampMs: 320)
24
- )
25
- }
26
-
27
- func testEncodeHeaderPlacesMarkerChecksumAndLittleEndianFields() {
28
- let header = FrameProtocol.Header(
29
- width: 0x01020304,
30
- height: 0x05060708,
31
- bytesPerRow: 0x090A0B0C,
32
- timestampMs: 0x0D0E0F10
33
- )
34
- let data = FrameProtocol.encodeHeader(header)
35
- XCTAssertEqual(data.count, FrameProtocol.headerSize)
36
- XCTAssertEqual(data.withUnsafeBytes { $0.loadUnaligned(as: UInt32.self).littleEndian }, FrameProtocol.magic)
37
- XCTAssertEqual(Array(data[8..<24]), [
38
- 0x04, 0x03, 0x02, 0x01,
39
- 0x08, 0x07, 0x06, 0x05,
40
- 0x0C, 0x0B, 0x0A, 0x09,
41
- 0x10, 0x0F, 0x0E, 0x0D,
42
- ])
43
- // The stored checksum matches the CRC-32 of the field bytes.
44
- let storedChecksum = data.dropFirst(4).withUnsafeBytes { $0.loadUnaligned(as: UInt32.self).littleEndian }
45
- XCTAssertEqual(storedChecksum, FrameProtocol.crc32(data.subdata(in: 8..<24)))
46
- XCTAssertEqual(FrameProtocol.decodeHeader(data), header)
47
- }
48
-
49
- func testCrc32MatchesStandardCheckVector() {
50
- // The canonical CRC-32 check value for the ASCII string "123456789",
51
- // shared with the TypeScript decoder so the two agree byte for byte.
52
- XCTAssertEqual(FrameProtocol.crc32(Data("123456789".utf8)), 0xCBF4_3926)
53
- }
54
-
55
- func testDecodeRejectsWrongMarker() {
56
- var data = FrameProtocol.encodeHeader(
57
- FrameProtocol.Header(width: 2, height: 2, bytesPerRow: 8, timestampMs: 1)
58
- )
59
- data[0] ^= 0xFF // corrupt the marker
60
- XCTAssertNil(FrameProtocol.decodeHeader(data))
61
- }
62
-
63
- func testDecodeRejectsWrongChecksum() {
64
- var data = FrameProtocol.encodeHeader(
65
- FrameProtocol.Header(width: 2, height: 2, bytesPerRow: 8, timestampMs: 1)
66
- )
67
- data[8] ^= 0xFF // corrupt a field without fixing the checksum
68
- XCTAssertNil(FrameProtocol.decodeHeader(data))
69
- }
70
-
71
- func testDecodeHeaderRoundTrip() {
72
- let header = FrameProtocol.Header(
73
- width: 1170,
74
- height: 2532,
75
- bytesPerRow: 4680,
76
- timestampMs: 1_234_567
77
- )
78
- let data = FrameProtocol.encodeHeader(header)
79
- XCTAssertEqual(FrameProtocol.decodeHeader(data), header)
80
- }
81
-
82
- func testDecodeRejectsShortBuffer() {
83
- let truncated = Data(repeating: 0, count: FrameProtocol.headerSize - 1)
84
- XCTAssertNil(FrameProtocol.decodeHeader(truncated))
85
- }
86
-
87
- /// Decoding a header from an unaligned buffer must not trap. The pre-fix
88
- /// `load(as:)` requires 4-byte alignment; feeding it a header at an odd
89
- /// address traps in debug (issue #3627). `loadUnaligned` decodes correctly.
90
- func testDecodeHeaderHandlesUnalignedBuffer() {
91
- let header = FrameProtocol.Header(
92
- width: 0x1122_3344,
93
- height: 0x5566_7788,
94
- bytesPerRow: 0x99AA_BBCC,
95
- timestampMs: 0xDDEE_FF00
96
- )
97
- let encoded = FrameProtocol.encodeHeader(header)
98
-
99
- // Place the 16 header bytes at an odd (unaligned) offset in a raw buffer.
100
- let raw = UnsafeMutableRawPointer.allocate(
101
- byteCount: FrameProtocol.headerSize + 1,
102
- alignment: 1
103
- )
104
- defer { raw.deallocate() }
105
- encoded.withUnsafeBytes { src in
106
- raw.advanced(by: 1).copyMemory(from: src.baseAddress!, byteCount: FrameProtocol.headerSize)
107
- }
108
- let unaligned = Data(
109
- bytesNoCopy: raw.advanced(by: 1),
110
- count: FrameProtocol.headerSize,
111
- deallocator: .none
112
- )
113
-
114
- XCTAssertEqual(FrameProtocol.decodeHeader(unaligned), header)
115
- }
116
-
117
- func testEncodeDecodeRoundTrip() {
118
- let header = FrameProtocol.Header(
119
- width: 1290, height: 2796, bytesPerRow: 5160, timestampMs: 123_456
120
- )
121
- XCTAssertEqual(FrameProtocol.decodeHeader(FrameProtocol.encodeHeader(header)), header)
122
- }
123
- }
@@ -1,62 +0,0 @@
1
- // swiftlint:disable force_unwrapping
2
- // Force-unwrap is idiomatic in test fixtures (fail fast on bad setup); disabled file-wide.
3
-
4
- import XCTest
5
- @testable import ScreenCaptureCore
6
-
7
- final class BufferSink: FrameSink {
8
- var data = Data()
9
- func write(_ chunk: Data) { data.append(chunk) }
10
- }
11
-
12
- final class FrameWriterTests: XCTestCase {
13
- func testWritesHeaderFollowedByPayload() {
14
- let sink = BufferSink()
15
- let start = Date(timeIntervalSince1970: 0)
16
- let writer = FrameWriter(sink: sink, startTime: start)
17
-
18
- let width = 2
19
- let height = 3
20
- let bytesPerRow = 8
21
- // 24 bytes of BGRA: 2px × 3 rows × 4 bytes
22
- let payload = Array(0..<UInt8(bytesPerRow * height))
23
-
24
- payload.withUnsafeBufferPointer { ptr in
25
- writer.write(
26
- width: width,
27
- height: height,
28
- bytesPerRow: bytesPerRow,
29
- baseAddress: UnsafeRawPointer(ptr.baseAddress!),
30
- timestamp: Date(timeIntervalSince1970: 0.5)
31
- )
32
- }
33
-
34
- XCTAssertEqual(sink.data.count, FrameProtocol.headerSize + bytesPerRow * height)
35
- let header = FrameProtocol.decodeHeader(sink.data.prefix(FrameProtocol.headerSize))
36
- XCTAssertEqual(header?.width, UInt32(width))
37
- XCTAssertEqual(header?.height, UInt32(height))
38
- XCTAssertEqual(header?.bytesPerRow, UInt32(bytesPerRow))
39
- XCTAssertEqual(header?.timestampMs, 500)
40
- XCTAssertEqual(Array(sink.data.dropFirst(FrameProtocol.headerSize)), payload)
41
- }
42
-
43
- func testTimestampClampedToZeroForPriorStartTime() {
44
- let sink = BufferSink()
45
- let writer = FrameWriter(
46
- sink: sink,
47
- startTime: Date(timeIntervalSince1970: 100)
48
- )
49
- let payload: [UInt8] = [0, 1, 2, 3]
50
- payload.withUnsafeBufferPointer { ptr in
51
- writer.write(
52
- width: 1,
53
- height: 1,
54
- bytesPerRow: 4,
55
- baseAddress: UnsafeRawPointer(ptr.baseAddress!),
56
- timestamp: Date(timeIntervalSince1970: 0)
57
- )
58
- }
59
- let header = FrameProtocol.decodeHeader(sink.data.prefix(FrameProtocol.headerSize))
60
- XCTAssertEqual(header?.timestampMs, 0)
61
- }
62
- }
@@ -1,27 +0,0 @@
1
- import XCTest
2
- @testable import ScreenCaptureCore
3
-
4
- final class SimulatorAudioCaptureAvailabilityTests: XCTestCase {
5
- func testAllowsAudioWhenExactlyOneSimulatorWindowIsVisible() {
6
- XCTAssertNil(SimulatorAudioCaptureAvailability.errorMessage(for: [window(id: 1)]))
7
- }
8
-
9
- func testRejectsAudioWhenMultipleSimulatorWindowsAreVisible() {
10
- XCTAssertEqual(
11
- SimulatorAudioCaptureAvailability.errorMessage(for: [window(id: 1), window(id: 2)]),
12
- "iOS Simulator audio capture requires exactly one visible Simulator window because ScreenCaptureKit cannot isolate audio to a selected Simulator window. Close other Simulator windows and try again."
13
- )
14
- }
15
-
16
- private func window(id: UInt32) -> SimulatorWindowInfo {
17
- SimulatorWindowInfo(
18
- windowID: id,
19
- title: "iPhone",
20
- applicationName: "Simulator",
21
- bundleIdentifier: simulatorBundleIdentifier,
22
- processID: 1,
23
- width: 390,
24
- height: 844
25
- )
26
- }
27
- }
@@ -1,40 +0,0 @@
1
- import XCTest
2
- @testable import ScreenCaptureCore
3
-
4
- final class SimulatorWindowInfoTests: XCTestCase {
5
- func testRoundTripsThroughJSON() throws {
6
- let original = SimulatorWindowListResponse(windows: [
7
- SimulatorWindowInfo(
8
- windowID: 12345,
9
- title: "iPhone 15 Pro — iOS 17.4",
10
- applicationName: "Simulator",
11
- bundleIdentifier: simulatorBundleIdentifier,
12
- processID: 4242,
13
- width: 1170,
14
- height: 2532
15
- )
16
- ])
17
- let data = try JSONEncoder().encode(original)
18
- let decoded = try JSONDecoder().decode(SimulatorWindowListResponse.self, from: data)
19
- XCTAssertEqual(decoded, original)
20
- }
21
-
22
- func testTitleMayBeNil() throws {
23
- let info = SimulatorWindowInfo(
24
- windowID: 1,
25
- title: nil,
26
- applicationName: "Simulator",
27
- bundleIdentifier: simulatorBundleIdentifier,
28
- processID: 1,
29
- width: 0,
30
- height: 0
31
- )
32
- let data = try JSONEncoder().encode(info)
33
- let decoded = try JSONDecoder().decode(SimulatorWindowInfo.self, from: data)
34
- XCTAssertNil(decoded.title)
35
- }
36
-
37
- func testSimulatorBundleIdentifierConstant() {
38
- XCTAssertEqual(simulatorBundleIdentifier, "com.apple.iphonesimulator")
39
- }
40
- }