Tags: gpu-cli/annotkit
Tags
v0.7.1 — the menu opens and closes without the pill jumping FIX - The toolbar pill is pinned to its panel's bottom-trailing corner instead of being centred in it (regression from v0.7.0's panel-sized-to-the-pill change). The panel grows the instant the mode flips and shrinks 0.3s later, so for that third of a second the centred pill sat 93pt from each edge of a 258pt panel rather than 14pt from the trailing one: closing collapsed it toward the middle and then snapped it 79pt right. The width animation is now the only thing that moves, and the same offset at mount (the generous unmeasured seed) is gone too. Also in this release, from v0.7.0: - A demo settings-screen app for practice and recordings (task demo). 233 unit tests, warning-free build, iOS simulator cross-compile clean, probe 11/11 phases PASS against a live AX tree.
v0.7.0 — a click on a pin edits its comment, in both tools VRT-u209. A comment written with the FRAME tool could be read and never edited: pins are hit-test-inert there so a drag can start on top of one (VRT-dp47), and that inertness had silently taken click-to-edit and hover-to-edit with it. A press is now routed by geometry at the catcher's release, gated on TRAVEL rather than on tool — a click on a pin edits it in either tool, a drag from a pin still draws its frame. The captured selection stays marked while the card is open (no new plumbing: the open card already won the attention tie, it just could never be opened in the tool the user was in). 230 unit tests, probe 11/11 phases PASS against a live AX tree, iOS module type-checks clean against the iPhoneOS SDK in Swift 6.
v0.6.0 — recallable selection marks, and four dogfooding fixes FEATURE - Recallable selection marks (VRT-pm3k): a captured frame comes back while you hover its numbered pin, or while its edit card is open. Filing a note leaves the surface exactly as it looked before. At most one mark is ever on screen. AnnotationNote.anchor (a point) becomes anchorRect + drawnRect, both UI-only — the serialized payload is byte-for-byte unchanged. FIXES - The first click on the overlay ACTS. AppKit discarded a mouse-down landing in a non-key panel; the first press only bought the panel focus, on every open, in both tools. - A drawn frame keeps its content across a scroll, live selection included, instead of detaching and describing whatever scrolled under it. - Shift+Enter inserts a line break instead of inserting nothing and discarding what was already typed. - The toolbar panel is sized to the pill (VRT-jiuo), so the host app's bottom-right corner is clickable again instead of a permanently dead 240x104 rect. Pins are inert in frame mode, so an element selection no longer blocks the frame tool. macOS only for the scroll correction; F1-F3 are shared. swift build -Xswiftc -warnings-as-errors clean, 218 tests green, AnnotKitOverlayProbe 13/13 phases PASS.
v0.4.0 — annotation fidelity Anchored, code-locating selectors (SelectorEngine anchors to the nearest identified ancestor; text= steps; no non-resolving #<slash/path> fallback). One AnnotationTargetRule (deepest actionable, else deepest meaningful) shared across the AX, NSView-tree, and iOS UIView sources. Geometric component isolation so .axCardSurface cards (id on a background sibling, not an ancestor) are reachable, plus ComponentLadderSource selection widening. Enriched AnnotationNote (component / elementRole / elementText / unseeded). 74 tests.
fix(session): a region -> element re-selection must drop the stale re… …gion offset select() assigned the new hit but the didSet only clears selectedRegionOffset when selected becomes NIL - the catcher stays active behind an open composer, so a dead click (region) followed by a click on a real element left the region's offset to leak onto the ELEMENT note (bogus **Region** line in the export). Reset the offset at the top of select(); regression test covers the transition. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
feat(resolver): positional specificity + region-fallback annotations The resolver now implements pure positional specificity: the DEEPEST meaningful node under the cursor wins (button at the button, card surface at the card padding, section at the section padding) - there is deliberately no depth-walking UI; cursor position IS the level selector. - deepestMeaningful replaces nearestIdentified + deepestNonContainer. The meaningful predicate counts AXValue: plain SwiftUI Text materializes AXStaticText with its string in AXValue and EMPTY title/description, so the old title-only notion of labeled walked past every text leaf and resolved its identified ancestor (the whole page) - the confirmed root cause of hovering card content highlighting the page. - Equal-area descent ties break toward CONTENT over seeded surface leaves (surfaces present as AXUnknown and are the least specific by construction). - REGION fallback: a click where NO node exists (decoration, dividers, gaps) is no longer dropped - AnnotationSession captures a synthetic region selection anchored to the nearest meaningful element (new RegionAnchorSource capability + AXIntrospection.regionAnchor), and AnnotationNote persists the new optional regionOffset (old files decode unchanged; element notes serialize unchanged). Markdown/JSON formatters render the region locator. Probe: +Phase 6 (specificity transitions incl. the previously-uncovered value-only text case + region fallback end-to-end). Tests: +region capture, +no-region-on-element-notes, +formatter region line, +old-shape decode round-trip (51 total). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fix(overlay): even idle pill inset, chrome-proof hit-test, hover-exit… … clearing, container surfaces Four fixes from the first real dogfood on VirgilHUD (all probe-covered): - Idle pill: EVEN 8pt inset around the single pencil button (concentric 44x44 capsule) instead of the 4-button row's 6/8pt padding, which read as lopsided. - Hit-test: window chrome is never an annotation target. The traffic lights are actionable AXButtons that passed the resolvers; rejected via subrole at chain level PLUS a geometric backstop (the zoom button nests a glyph AXGroup whose reported AX parent is the WINDOW, so a chain scan alone misses it). Also: descend to the SMALLEST containing child (AX order does not encode z-order), and never fall back to an unidentified structural group spanning the whole window (NSHostingView's root). - Hover: clear the highlight when the cursor leaves the catcher (HoverPhase .ended) — the last-hovered element used to stay highlighted after the cursor left the app. New AnnotationSession.clearHover() keeps selection untouched. - Containers: probed that a children-.contain group reports the UNION of its children as its AX frame (card padding dead to hover); the working pattern is a full-size clear background leaf carrying the identifier, validated by the new overlay-probe Phase 5. Probe: +Phase 4 (chrome exclusion through the expanded overlay, incl. positive control) and +Phase 5 (container surface body-hover), plus W1 window hygiene. Tests: +clearHover, +chrome-subrole predicate (47 total). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fix(overlay): mount on a caller-specified window + settle geometry af… …ter host layout Two robustness fixes for hosting the overlay on a real app: - Add Annotation.install(on:) / OverlayController.mount(on:) so a host can pass the EXACT window to annotate. The no-arg auto-picker (NSApp.mainWindow ?? keyWindow ?? first visible non-panel) can resolve to a floating NSPanel when several windows are visible (e.g. VirgilHUD's IconPanel instead of its Settings window), leaving the overlay in the wrong window's corner with a dead AX hit-test. - Re-sync the panel frame + axOrigin across runloop turns until the host frame settles, covering SwiftUI/content-sized hosts that grow to final size after attach without posting didMove/didResize. Adds a headless overlay-probe regression (host grows post-attach; pill + axOrigin track the final frame). 44 tests + both probes green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PreviousNext