Ariver
2026-08-31 cae8575c671f1cc09f3e4c049c8a30b7a6414160
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
import AppKit
import ApplicationServices
import Foundation
 
enum ProbeFailure: Error {
    case read
    case dataInvalid
    case limit
}
 
enum ProbeValue<Value> {
    case value(Value)
    case absent
    case invalid
}
 
enum SourceDiagnosis: String, CaseIterable {
    case sourceZero = "SOURCE_ZERO"
    case sourceMultiple = "SOURCE_MULTIPLE"
    case traversalLimit = "SOURCE_TRAVERSAL_LIMIT"
    case traversalDataInvalid = "SOURCE_TRAVERSAL_DATA_INVALID"
    case traversalReadError = "SOURCE_TRAVERSAL_READ_ERROR"
    case sourceWindowIDAbsentOrInvalid = "SOURCE_WINDOW_ID_ABSENT_OR_INVALID"
    case otherWindowIDAbsentOrInvalid = "OTHER_WINDOW_ID_ABSENT_OR_INVALID"
    case duplicateWindowIdentity = "DUPLICATE_WINDOW_IDENTITY"
    case sourcePositionAbsentOrInvalid = "SOURCE_POSITION_ABSENT_OR_INVALID"
    case sourceSizeAbsentOrInvalid = "SOURCE_SIZE_ABSENT_OR_INVALID"
    case sourceGeometryNonfiniteOrNonpositive = "SOURCE_GEOMETRY_NONFINITE_OR_NONPOSITIVE"
    case sourceMinimizedAbsentOrInvalid = "SOURCE_MINIMIZED_ABSENT_OR_INVALID"
    case sourceWindowReadError = "SOURCE_WINDOW_READ_ERROR"
    case sourceWindowReady = "SOURCE_WINDOW_READY"
 
    var line: String { "finder_source=\(rawValue)" }
}
 
func classifySourceWindow(
    matchCounts: Result<[Int], ProbeFailure>,
    windowIDs: [() -> Result<ProbeValue<Int64>, ProbeFailure>],
    position: () -> Result<ProbeValue<CGPoint>, ProbeFailure>,
    size: () -> Result<ProbeValue<CGSize>, ProbeFailure>,
    minimized: () -> Result<ProbeValue<Bool>, ProbeFailure>
) -> SourceDiagnosis {
    let counts: [Int]
    switch matchCounts {
    case .failure(.limit): return .traversalLimit
    case .failure(.dataInvalid): return .traversalDataInvalid
    case .failure(.read): return .traversalReadError
    case .success(let value): counts = value
    }
    guard counts.count == windowIDs.count, counts.allSatisfy({ $0 >= 0 }) else {
        return .traversalDataInvalid
    }
    let total = counts.reduce(0, +)
    guard total > 0 else { return .sourceZero }
    guard total == 1, let sourceIndex = counts.firstIndex(of: 1) else { return .sourceMultiple }
 
    let sourceID: Int64
    switch windowIDs[sourceIndex]() {
    case .failure: return .sourceWindowReadError
    case .success(.absent), .success(.invalid): return .sourceWindowIDAbsentOrInvalid
    case .success(.value(let value)): sourceID = value
    }
    let point: CGPoint
    switch position() {
    case .failure: return .sourceWindowReadError
    case .success(.absent), .success(.invalid): return .sourcePositionAbsentOrInvalid
    case .success(.value(let value)): point = value
    }
    let dimensions: CGSize
    switch size() {
    case .failure: return .sourceWindowReadError
    case .success(.absent), .success(.invalid): return .sourceSizeAbsentOrInvalid
    case .success(.value(let value)): dimensions = value
    }
    guard [point.x, point.y, dimensions.width, dimensions.height].allSatisfy(\.isFinite),
          dimensions.width > 0, dimensions.height > 0 else {
        return .sourceGeometryNonfiniteOrNonpositive
    }
    switch minimized() {
    case .failure: return .sourceWindowReadError
    case .success(.absent), .success(.invalid): return .sourceMinimizedAbsentOrInvalid
    case .success(.value): break
    }
    for (index, readID) in windowIDs.enumerated() where index != sourceIndex {
        switch readID() {
        case .failure: return .sourceWindowReadError
        case .success(.absent), .success(.invalid): return .otherWindowIDAbsentOrInvalid
        case .success(.value(let value)) where value == sourceID: return .duplicateWindowIdentity
        case .success(.value): break
        }
    }
    return .sourceWindowReady
}
 
func selfTest() -> Int32 {
    typealias IDRead = () -> Result<ProbeValue<Int64>, ProbeFailure>
    let goodPosition = CGPoint(x: 10, y: 20)
    let goodSize = CGSize(width: 500, height: 320)
    func classify(
        counts: Result<[Int], ProbeFailure> = .success([1]),
        ids: [IDRead] = [{ .success(.value(7)) }],
        position: @escaping () -> Result<ProbeValue<CGPoint>, ProbeFailure> = { .success(.value(CGPoint(x: 10, y: 20))) },
        size: @escaping () -> Result<ProbeValue<CGSize>, ProbeFailure> = { .success(.value(CGSize(width: 500, height: 320))) },
        minimized: @escaping () -> Result<ProbeValue<Bool>, ProbeFailure> = { .success(.value(false)) }
    ) -> SourceDiagnosis {
        classifySourceWindow(matchCounts: counts, windowIDs: ids, position: position, size: size, minimized: minimized)
    }
    let cases: [(SourceDiagnosis, SourceDiagnosis)] = [
        (.sourceWindowReady, classify()),
        (.sourceZero, classify(counts: .success([0]))),
        (.sourceMultiple, classify(counts: .success([1, 1]), ids: [{ .success(.value(7)) }, { .success(.value(8)) }])),
        (.sourceMultiple, classify(counts: .success([2]))),
        (.traversalLimit, classify(counts: .failure(.limit))),
        (.traversalDataInvalid, classify(counts: .failure(.dataInvalid))),
        (.traversalReadError, classify(counts: .failure(.read))),
        (.traversalDataInvalid, classify(counts: .success([1, 0]), ids: [{ .success(.value(7)) }])),
        (.sourceWindowIDAbsentOrInvalid, classify(ids: [{ .success(.absent) }])),
        (.sourceWindowIDAbsentOrInvalid, classify(ids: [{ .success(.invalid) }])),
        (.sourceWindowReadError, classify(ids: [{ .failure(.read) }])),
        (.sourcePositionAbsentOrInvalid, classify(position: { .success(.absent) })),
        (.sourcePositionAbsentOrInvalid, classify(position: { .success(.invalid) })),
        (.sourceWindowReadError, classify(position: { .failure(.read) })),
        (.sourceSizeAbsentOrInvalid, classify(size: { .success(.absent) })),
        (.sourceSizeAbsentOrInvalid, classify(size: { .success(.invalid) })),
        (.sourceWindowReadError, classify(size: { .failure(.read) })),
        (.sourceGeometryNonfiniteOrNonpositive, classify(position: { .success(.value(CGPoint(x: CGFloat.nan, y: 0))) })),
        (.sourceGeometryNonfiniteOrNonpositive, classify(size: { .success(.value(CGSize(width: 0, height: 1))) })),
        (.sourceGeometryNonfiniteOrNonpositive, classify(size: { .success(.value(CGSize(width: 1, height: CGFloat.infinity))) })),
        (.sourceMinimizedAbsentOrInvalid, classify(minimized: { .success(.absent) })),
        (.sourceMinimizedAbsentOrInvalid, classify(minimized: { .success(.invalid) })),
        (.sourceWindowReadError, classify(minimized: { .failure(.read) })),
        (.duplicateWindowIdentity, classify(
            counts: .success([1, 0]),
            ids: [{ .success(.value(7)) }, { .success(.value(7)) }]
        )),
        (.sourceWindowReadError, classify(
            counts: .success([1, 0]),
            ids: [{ .success(.value(7)) }, { .failure(.read) }]
        )),
        (.otherWindowIDAbsentOrInvalid, classify(
            counts: .success([1, 0]),
            ids: [{ .success(.value(7)) }, { .success(.absent) }]
        )),
        (.otherWindowIDAbsentOrInvalid, classify(
            counts: .success([1, 0]),
            ids: [{ .success(.value(7)) }, { .success(.invalid) }]
        )),
    ]
    var terminalReads = 0
    let terminal = classifySourceWindow(
        matchCounts: .success([1]),
        windowIDs: [{ terminalReads += 1; return .success(.absent) }],
        position: { terminalReads += 1; return .success(.value(goodPosition)) },
        size: { terminalReads += 1; return .success(.value(goodSize)) },
        minimized: { terminalReads += 1; return .success(.value(false)) }
    )
    var otherIDReads = 0
    let otherIDTerminal = classify(
        counts: .success([1, 0, 0]),
        ids: [
            { otherIDReads += 1; return .success(.value(7)) },
            { otherIDReads += 1; return .success(.absent) },
            { otherIDReads += 1; return .success(.value(9)) },
        ]
    )
    guard cases.allSatisfy({ $0.0 == $0.1 }),
          terminal == .sourceWindowIDAbsentOrInvalid,
          terminalReads == 1,
          otherIDTerminal == .otherWindowIDAbsentOrInvalid,
          otherIDReads == 2,
          SourceDiagnosis.allCases.allSatisfy({
              $0.line == "finder_source=\($0.rawValue)" && $0.line.split(separator: "\n").count == 1
          }) else { return 1 }
    print("self_test=PASS finder_source_diagnostics=true")
    return 0
}
 
if CommandLine.arguments == [CommandLine.arguments[0], "--self-test"] { exit(selfTest()) }
guard CommandLine.arguments.count == 3,
      CommandLine.arguments[1] == "diagnose",
      !CommandLine.arguments[2].isEmpty else { exit(64) }
let exactSourceIdentifier = CommandLine.arguments[2]
 
func attribute(_ element: AXUIElement, _ name: String) -> Result<ProbeValue<CFTypeRef>, ProbeFailure> {
    var value: CFTypeRef?
    let error = AXUIElementCopyAttributeValue(element, name as CFString, &value)
    if error == .noValue || error == .attributeUnsupported { return .success(.absent) }
    guard error == .success else { return .failure(.read) }
    guard let value else { return .success(.invalid) }
    return .success(.value(value))
}
 
func stringValue(_ element: AXUIElement, _ name: String) -> Result<ProbeValue<String>, ProbeFailure> {
    switch attribute(element, name) {
    case .failure(let failure): return .failure(failure)
    case .success(.absent): return .success(.absent)
    case .success(.invalid): return .success(.invalid)
    case .success(.value(let value)):
        guard CFGetTypeID(value) == CFStringGetTypeID(), let result = value as? String else {
            return .success(.invalid)
        }
        return .success(.value(result))
    }
}
 
func windowID(_ element: AXUIElement) -> Result<ProbeValue<Int64>, ProbeFailure> {
    switch attribute(element, "AXWindowNumber") {
    case .failure(let failure): return .failure(failure)
    case .success(.absent): return .success(.absent)
    case .success(.invalid): return .success(.invalid)
    case .success(.value(let value)):
        guard CFGetTypeID(value) == CFNumberGetTypeID() else { return .success(.invalid) }
        var result: Int64 = 0
        guard CFNumberGetValue((value as! CFNumber), .sInt64Type, &result) else { return .success(.invalid) }
        return .success(.value(result))
    }
}
 
func pointValue(_ element: AXUIElement) -> Result<ProbeValue<CGPoint>, ProbeFailure> {
    switch attribute(element, kAXPositionAttribute) {
    case .failure(let failure): return .failure(failure)
    case .success(.absent): return .success(.absent)
    case .success(.invalid): return .success(.invalid)
    case .success(.value(let value)):
        guard CFGetTypeID(value) == AXValueGetTypeID() else { return .success(.invalid) }
        var point = CGPoint.zero
        guard AXValueGetValue(value as! AXValue, .cgPoint, &point) else { return .success(.invalid) }
        return .success(.value(point))
    }
}
 
func sizeValue(_ element: AXUIElement) -> Result<ProbeValue<CGSize>, ProbeFailure> {
    switch attribute(element, kAXSizeAttribute) {
    case .failure(let failure): return .failure(failure)
    case .success(.absent): return .success(.absent)
    case .success(.invalid): return .success(.invalid)
    case .success(.value(let value)):
        guard CFGetTypeID(value) == AXValueGetTypeID() else { return .success(.invalid) }
        var size = CGSize.zero
        guard AXValueGetValue(value as! AXValue, .cgSize, &size) else { return .success(.invalid) }
        return .success(.value(size))
    }
}
 
func boolValue(_ element: AXUIElement, _ name: String) -> Result<ProbeValue<Bool>, ProbeFailure> {
    switch attribute(element, name) {
    case .failure(let failure): return .failure(failure)
    case .success(.absent): return .success(.absent)
    case .success(.invalid): return .success(.invalid)
    case .success(.value(let value)):
        guard CFGetTypeID(value) == CFBooleanGetTypeID() else { return .success(.invalid) }
        return .success(.value(CFBooleanGetValue((value as! CFBoolean))))
    }
}
 
func children(_ element: AXUIElement) -> Result<ProbeValue<[AXUIElement]>, ProbeFailure> {
    switch attribute(element, kAXChildrenAttribute) {
    case .failure(let failure): return .failure(failure)
    case .success(.absent): return .success(.absent)
    case .success(.invalid): return .success(.invalid)
    case .success(.value(let value)):
        guard CFGetTypeID(value) == CFArrayGetTypeID(), let result = value as? [AXUIElement] else {
            return .success(.invalid)
        }
        return .success(.value(result))
    }
}
 
func countExactSource(_ element: AXUIElement, depth: Int = 0, visited: inout Int) throws -> Int {
    guard depth <= 14, visited < 20_000 else { throw ProbeFailure.limit }
    visited += 1
    let role: ProbeValue<String>
    switch stringValue(element, kAXRoleAttribute) {
    case .failure(let failure): throw failure
    case .success(let value): role = value
    }
    var count = 0
    if case .value(let roleValue) = role, roleValue == (kAXTextFieldRole as String) {
        switch stringValue(element, kAXValueAttribute) {
        case .failure(let failure): throw failure
        case .success(.invalid): throw ProbeFailure.dataInvalid
        case .success(.value(let value)) where value == exactSourceIdentifier: count += 1
        case .success: break
        }
    } else if case .invalid = role {
        throw ProbeFailure.dataInvalid
    }
    switch children(element) {
    case .failure(let failure): throw failure
    case .success(.invalid): throw ProbeFailure.dataInvalid
    case .success(.absent): break
    case .success(.value(let values)):
        for child in values { count += try countExactSource(child, depth: depth + 1, visited: &visited) }
    }
    return count
}
 
func emit(_ diagnosis: SourceDiagnosis) -> Never {
    print(diagnosis.line)
    exit(diagnosis == .sourceWindowReady ? 0 : 69)
}
 
guard let finder = NSRunningApplication.runningApplications(withBundleIdentifier: "com.apple.finder").first else {
    emit(.traversalReadError)
}
let app = AXUIElementCreateApplication(finder.processIdentifier)
let windows: [AXUIElement]
switch attribute(app, kAXWindowsAttribute) {
case .failure: emit(.traversalReadError)
case .success(.absent), .success(.invalid): emit(.traversalDataInvalid)
case .success(.value(let value)):
    guard CFGetTypeID(value) == CFArrayGetTypeID(), let typed = value as? [AXUIElement] else {
        emit(.traversalDataInvalid)
    }
    windows = typed
}
let matchCounts: Result<[Int], ProbeFailure>
do {
    var values: [Int] = []
    for window in windows {
        var visited = 0
        values.append(try countExactSource(window, visited: &visited))
    }
    matchCounts = .success(values)
} catch let failure as ProbeFailure {
    matchCounts = .failure(failure)
} catch {
    matchCounts = .failure(.read)
}
let sourceIndex: Int? = {
    guard case .success(let counts) = matchCounts, counts.reduce(0, +) == 1 else { return nil }
    return counts.firstIndex(of: 1)
}()
let diagnosis = classifySourceWindow(
    matchCounts: matchCounts,
    windowIDs: windows.map { window in { windowID(window) } },
    position: { sourceIndex.map { pointValue(windows[$0]) } ?? .success(.invalid) },
    size: { sourceIndex.map { sizeValue(windows[$0]) } ?? .success(.invalid) },
    minimized: { sourceIndex.map { boolValue(windows[$0], kAXMinimizedAttribute) } ?? .success(.invalid) }
)
emit(diagnosis)