Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
1be0561
docs: design Arc authorization diagnostics
hellosky0 Aug 3, 2026
99d6f97
docs: plan Arc authorization diagnostics
hellosky0 Aug 3, 2026
65dc16d
chore: ignore local worktrees
hellosky0 Aug 3, 2026
d65a65c
feat: model browser diagnostic outcomes
hellosky0 Aug 3, 2026
6a3d96f
fix: align diagnostic outcome evaluation
hellosky0 Aug 3, 2026
a7aebe5
test: cover diagnostic outcome precedence
hellosky0 Aug 3, 2026
3a5392f
feat: redact and render diagnostic reports
hellosky0 Aug 3, 2026
33f0b68
fix: redact diagnostic observations at capture
hellosky0 Aug 3, 2026
f62bd5d
fix: preserve diagnostic URL paths
hellosky0 Aug 3, 2026
ca98600
feat: collect browser recognition diagnostics
hellosky0 Aug 3, 2026
479172d
fix: keep browser diagnostics read only
hellosky0 Aug 3, 2026
49def5e
feat: expose one-shot browser diagnostics
hellosky0 Aug 3, 2026
775e6eb
fix: make diagnostic tasks cancellation aware
hellosky0 Aug 3, 2026
3302567
feat: show browser diagnostics in menu
hellosky0 Aug 3, 2026
7465a98
docs: design Arc popup fallback
hellosky0 Aug 4, 2026
b86f16c
docs: revise Arc fallback security design
hellosky0 Aug 4, 2026
972d8bb
docs: plan Arc origin diagnostics
hellosky0 Aug 4, 2026
666785e
feat: observe accessibility URLs for diagnostics
hellosky0 Aug 4, 2026
0bd5919
feat: report accessibility window structure
hellosky0 Aug 4, 2026
78b511d
docs: design origin-gated Arc autofill
hellosky0 Aug 4, 2026
c8f41bc
docs: plan origin-gated Arc autofill
hellosky0 Aug 4, 2026
ecfa4d4
feat: collect Arc authorization origin evidence
hellosky0 Aug 4, 2026
d5f387b
feat: gate untitled popup autofill on extension origin
hellosky0 Aug 4, 2026
dc8bed4
docs: design adaptive scan interval
hellosky0 Sep 2, 2026
c8826f8
feat: add adaptive scan schedule policy
hellosky0 Sep 7, 2026
319c2a0
perf: reduce idle browser scan frequency
hellosky0 Sep 8, 2026
02e3da3
docs: design screen recording permission feedback
hellosky0 Sep 8, 2026
7826dac
fix: guide denied screen recording permission to settings
hellosky0 Sep 8, 2026
d90de98
docs: design candidate-aware accessibility retries
hellosky0 Sep 9, 2026
fde03c3
docs: plan candidate-aware accessibility retries
hellosky0 Sep 9, 2026
6444a2a
docs: plan candidate-aware accessibility retries
hellosky0 Sep 9, 2026
131647c
perf: avoid repeated AX walks for stable windows
hellosky0 Sep 9, 2026
25162f6
feat: make idle scan interval configurable
hellosky0 Sep 9, 2026
c58c9a7
docs: design event-driven autofill monitoring
hellosky0 Sep 10, 2026
9110dc3
docs: plan event-driven autofill monitoring
hellosky0 Sep 10, 2026
c55200e
feat: coalesce event-driven autofill scans
hellosky0 Sep 10, 2026
e733f41
feat: observe browser accessibility events
hellosky0 Sep 10, 2026
464317c
perf: replace idle polling with event wake-ups
hellosky0 Sep 10, 2026
c95fdf7
fix: stop cancelled autofill work promptly
hellosky0 Sep 10, 2026
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.DS_Store
.build/
.worktrees/
dist/
*.xcuserstate
30 changes: 30 additions & 0 deletions Sources/ApplePasswordBridge/Accessibility.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
import AppKit
import ApplicationServices

enum AccessibilityValueNormalizer {
static func urlString(from value: Any?) -> String? {
if let string = value as? String { return string }
if let url = value as? URL { return url.absoluteString }
if let url = value as? NSURL { return url.absoluteString }
return nil
}

static func bool(from value: Any?) -> Bool? {
(value as? NSNumber)?.boolValue
}
}

struct AccessibilityNode {
let element: AXUIElement
let role: String
let text: String
let value: String?
let diagnosticURL: String?
let position: CGPoint?

var isTextInput: Bool {
Expand Down Expand Up @@ -58,11 +72,15 @@ enum AccessibilityTree {
let role = (copy(element, attribute: kAXRoleAttribute as CFString) as? String) ?? ""
let value = copy(element, attribute: kAXValueAttribute as CFString) as? String
let values = textAttributes.compactMap { copy(element, attribute: $0) as? String }
let diagnosticURL = AccessibilityValueNormalizer.urlString(
from: copy(element, attribute: "AXURL" as CFString)
)
result.append(AccessibilityNode(
element: element,
role: role,
text: values.joined(separator: "\n"),
value: value,
diagnosticURL: diagnosticURL,
position: point(element, attribute: kAXPositionAttribute as CFString)
))

Expand All @@ -80,6 +98,18 @@ enum AccessibilityTree {
copy(element, attribute: kAXTitleAttribute as CFString) as? String
}

static func role(of element: AXUIElement) -> String {
(copy(element, attribute: kAXRoleAttribute as CFString) as? String) ?? ""
}

static func subrole(of element: AXUIElement) -> String {
(copy(element, attribute: kAXSubroleAttribute as CFString) as? String) ?? ""
}

static func bool(_ element: AXUIElement, attribute: CFString) -> Bool {
AccessibilityValueNormalizer.bool(from: copy(element, attribute: attribute)) ?? false
}

static func focus(_ element: AXUIElement) -> Bool {
AXUIElementSetAttributeValue(
element,
Expand Down
Loading