Repository navigation
fix(overview): timeout hung ScreenCaptureKit calls #129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
bf95f4a
fix(overview): timeout hung ScreenCaptureKit calls
qeude 1c131cc
fix: address PR review feedback (#129)
qeude 5f2f29b
fix: address PR review feedback (#129)
qeude d9cd888
fix: address PR review feedback (#129)
qeude 9830218
fix: address PR review feedback (#129)
qeude 5bec1b8
fix: address PR review feedback (#129)
qeude d50b5dc
fix: address PR review feedback (#129)
qeude 44c31e1
Merge branch 'main' into t3/overview-captures
qeude File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| --- | ||
| name: verify-defi | ||
| description: Launch, drive and prove behavior of Defi, the macOS scrolling-columns window manager (defi-daemon plus the defi CLI). Use after any change to runtime, layout, overview, focus, parking or config to get evidence from the real daemon, not just unit tests. | ||
| --- | ||
|
|
||
| # Verify Defi | ||
|
|
||
| Defi is a per-user macOS daemon (`defi-daemon`) controlled by the `defi` CLI over a Unix socket. There is no web or simulator surface. The real surface is the installed daemon on the user's desktop, driven by `defi` commands and read back through `defi status`, `defi trace` and `defi list-workspaces --json`. Visual behavior needs Computer Use. | ||
|
|
||
| Rules that override convenience (from `AGENTS.md`): | ||
|
|
||
| - Exactly one `defi-daemon` per user session. Never `open -n`, never start a second binary by hand. | ||
| - You cannot run an isolated second instance. The instance lock is per user. Drive the one installed daemon, or stop it and replace it through the scripts below. | ||
| - Installation and desktop tests share one per-user desktop reservation. Scripts acquire it and exit 75 when busy. | ||
| - Restore the user's workspace and confirm one daemon before you finish. | ||
|
|
||
| ## Which tier to use | ||
|
|
||
| | Change | Tier | Command | | ||
| | --- | --- | --- | | ||
| | Docs only | none | check the diff | | ||
| | Code, tests, build config | local | `python3 script/verify.py local` | | ||
| | Daemon wiring, platform integration, desktop-visible | stage + desktop | `python3 script/verify.py local --stage` then `python3 script/verify.py desktop dist/verification/<run> --wait [--filter DesktopE2ETests/<test>]` | | ||
| | Animation, focus, parking, hotkeys, Dock/Command-Tab, overview visuals | all of the above plus live drive | sections below | | ||
|
|
||
| `verify.py local` never installs and forces `DEFI_E2E=0`. `desktop` installs the exact staged bundle, runs XCTest, and restores the session store. Zero executed or skipped tests count as incomplete, not pass. | ||
|
|
||
| ## Launch | ||
|
|
||
| The installed app is the unit under test. To put your change into it: | ||
|
|
||
| ```sh | ||
| python3 script/verify.py local --stage # prints dist/verification/<run> | ||
| python3 script/verify.py desktop dist/verification/<run> --wait | ||
| ``` | ||
|
|
||
| Signing must keep the installed designated requirement or macOS re-prompts for Accessibility and Screen Recording. If the identity is missing, set `DEFI_CODESIGN_IDENTITY` in the ignored `.env.local`. Do not choose another certificate. | ||
|
|
||
| Restart the installed build with `defi service restart`. Ready means `defi status` prints `running session=active` and `pgrep -x defi-daemon | wc -l` is 1. | ||
|
|
||
| ## Doctor | ||
|
|
||
| ```sh | ||
| .agents/skills/verify-defi/doctor.sh | ||
| ``` | ||
|
|
||
| Read-only. Prints daemon count, binary path and start time, session state, overview permission, preview counters, and which `defi` is first on `PATH`. Run it first, and again whenever behavior looks wrong. A daemon that has been up for many hours and reports `overviewReceivedPreviews=0` after an overview open is a wedged daemon, not a passing one. | ||
|
|
||
| ## Drive | ||
|
|
||
| Commands are plain CLI calls. Useful, real ones: | ||
|
|
||
| ```sh | ||
| defi toggle-overview # open or close the overview | ||
| defi focus-column left|right|first|last | ||
| defi focus-workspace up|down | ||
| defi focus-workspace-name dev # names come from list-workspaces | ||
| defi focus-workspace-position 2 | ||
| defi move-column left|right|first|last | ||
| defi cycle-width next|prev | ||
| defi --monitor 2 focus-workspace-name web | ||
| defi list-workspaces --json | ||
| defi status # one line of key=value counters | ||
| defi trace # recent timestamped runtime events | ||
| ``` | ||
|
|
||
| Note `defi workspace 2` selects a workspace by ID, not by position, so the daemon answers `unknown workspace: 2`. Use `focus-workspace-position` for a position. | ||
|
|
||
| Parse `defi status` by splitting on spaces and grepping `key=`. Do not scrape by column. | ||
|
|
||
| For real human timing, hotkeys and mouse behavior, hold the desktop reservation in an interactive shell (`python3 script/desktop_lock.py --wait bash`) and use Computer Use. Synthetic command bursts alone do not certify native focus or animation quality. | ||
|
|
||
| ## Evidence | ||
|
|
||
| Write evidence under `dist/verification/evidence-<yyyymmdd-hhmmss>/` (ignored by git, survives cleanup): | ||
|
|
||
| - `before.status`, `after.status` from `defi status` | ||
| - `trace.log` from `defi trace` covering the action | ||
| - `workspaces-before.json`, `workspaces-after.json` from `list-workspaces --json` | ||
| - screenshots from Computer Use for visual claims | ||
| - `/usr/bin/log show --last 2m --info --predicate 'subsystem == "com.quentin.defi"'` for logger output. In zsh `log` is a builtin, so call `/usr/bin/log`. | ||
|
|
||
| Proof standard: drive the user path (CLI command or real hotkey), capture the state before and after, and check the side effect in `status` counters or `list-workspaces`. A passing unit test is not proof of a desktop-visible change. For anything visual, correlate the screenshot with `status` and `trace`. | ||
|
|
||
| ## Cleanup | ||
|
|
||
| 1. Close any overview you opened (`defi toggle-overview` only if `overview=open`). | ||
| 2. Restore the initial workspace you recorded in `before.status` with `defi focus-workspace-name <name>`. | ||
| 3. Restore any config file you edited from your backup. Never leave `~/.config/defi/config.toml` changed. | ||
| 4. Exit the `desktop_lock.py` shell if you opened one. | ||
| 5. Run the doctor and confirm exactly one daemon. | ||
|
|
||
| Keep the evidence directory. | ||
|
|
||
| ## Feature map | ||
|
|
||
| See `features/README.md`. A proof that drives one entry point is incomplete when the map lists others. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| #!/usr/bin/env bash | ||
| # Read-only health check for the running Defi daemon. | ||
| set -u | ||
| echo "daemons: $(pgrep -u "$(id -u)" -x defi-daemon | wc -l | tr -d ' ')" | ||
| for pid in $(pgrep -u "$(id -u)" -x defi-daemon); do | ||
| ps -o pid=,lstart=,etime=,command= -p "$pid" | ||
| done | ||
| echo "defi on PATH: $(command -v defi || echo missing)" | ||
| if ! status="$(defi status 2>&1)"; then | ||
| echo "status: unreachable ($status)" | ||
| exit 1 | ||
| fi | ||
| echo "$status" | cut -d' ' -f1-3 | ||
| echo "$status" | tr ' ' '\n' | grep -E '^(session|workspace|overview|overviewPermission|overviewPreviews|overviewReceivedPreviews|overviewPreviewFailures|overviewCaptures|overviewSurface|hotkeys|observationFailures)=' | tr '\n' ' ' | ||
| echo |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| # Defi feature map | ||
|
|
||
| Maintained verification source for `verify-defi`. One file per user-facing feature. | ||
|
|
||
| | Feature | File | Primary proof | | ||
| | --- | --- | --- | | ||
| | Overview with window previews | [overview.md](overview.md) | `overviewReceivedPreviews > 0` and visible captures | | ||
| | Scrolling column navigation | [scrolling-navigation.md](scrolling-navigation.md) | focus and scroll converge, no rollback in trace | | ||
| | Virtual workspaces and parking | [workspaces.md](workspaces.md) | active workspace changes, inactive windows parked | | ||
| | Service lifecycle and single instance | [service-lifecycle.md](service-lifecycle.md) | restart keeps one daemon and the session store | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| # Overview with window previews | ||
|
|
||
| ## Sub-features | ||
|
|
||
| - Open and close with `toggle-overview` or the configured hotkey. | ||
| - Window previews captured through ScreenCaptureKit, with title and icon. | ||
| - Desktop background per monitor. | ||
| - Keyboard navigation and window moves inside the overview. | ||
| - Experimental surface transitions (`overview.experimental_surface_transitions`). | ||
|
|
||
| ## How to get to it (user POV) | ||
|
|
||
| Press the overview hotkey, or run `defi toggle-overview`. Requires Screen Recording permission and `overview.window_previews = true`. | ||
|
|
||
| ## Driving it with the defi CLI | ||
|
|
||
| ```sh | ||
| defi toggle-overview; sleep 3 | ||
| defi status | tr ' ' '\n' | grep -E '^overview(=|Permission|Captures|Previews|ReceivedPreviews|PreviewFailures|FirstPreviewMs)' | ||
| defi toggle-overview | ||
| ``` | ||
|
|
||
| Pass: `overview=open`, `overviewPermission=granted`, `overviewReceivedPreviews` greater than 0, `overviewFirstPreviewMs` a number. For visuals take a Computer Use screenshot while open and confirm cards show window content and the desktop background, not flat grey. | ||
|
|
||
| ## Gotchas | ||
|
|
||
| - Status is published on change. Read it a few seconds after opening; `overviewCaptures` is in-flight work and returns to 0. | ||
| - `overviewReceivedPreviews=0` with `overviewPreviewFailures=0` and no ScreenCaptureKit activity in the log means captures never started, usually a wedged daemon. `defi service restart` recovers it. Check `/usr/bin/log` for `overview-capture` errors. | ||
| - The overview can close on its own when focus changes; poll `overview=` rather than assuming it stayed open. | ||
| - Another covering test: `DesktopE2ETests/testOverviewShowsBothMonitorsBeforeLoadingPreviews`. |
28 changes: 28 additions & 0 deletions
28
.agents/skills/verify-defi/features/scrolling-navigation.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| # Scrolling column navigation | ||
|
|
||
| ## Sub-features | ||
|
|
||
| - Focus left/right/first/last column. | ||
| - Move column, cycle and maximize width. | ||
| - Speculative, latest-wins animation with position-only writes. | ||
|
|
||
| ## How to get to it (user POV) | ||
|
|
||
| Configured hotkeys, or the CLI. | ||
|
|
||
| ## Driving it with the defi CLI | ||
|
|
||
| ```sh | ||
| defi status > before.status | ||
| for i in 1 2 3; do defi focus-column right; done; defi focus-column left | ||
| sleep 1; defi status > after.status; defi trace > trace.log | ||
| ``` | ||
|
|
||
| Pass: `focused=` changes as expected, `animating=false`, `drift=0[]`, `droppedFrames=0`, `focusPending=false`. In `trace.log` no repeated corrections or rollbacks after the last command. | ||
|
|
||
| ## Gotchas | ||
|
|
||
| - With one column on the workspace nothing moves; check `list-workspaces --json` window counts first. | ||
| - Slow apps (`slowAppDetails`) legitimately settle later. Wait for `axPending=false`. | ||
| - Visual smoothness needs Computer Use with human-paced input, not a tight loop. | ||
| - Covering tests: `testHorizontalAnimationFrameWritesPositionWithoutSize`, `testRapidNativeFocusKeepsLatestIntent`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # Service lifecycle and single instance | ||
|
|
||
| ## Sub-features | ||
|
|
||
| - `defi service enable|disable|start|stop|restart|status`. | ||
| - Per-user instance lock before the IPC socket. | ||
| - Session store persistence across restart. | ||
|
|
||
| ## How to get to it (user POV) | ||
|
|
||
| Login item, or `defi service ...`. | ||
|
|
||
| ## Driving it with the defi CLI | ||
|
|
||
| ```sh | ||
| defi list-workspaces --json > before.json | ||
| defi service restart; sleep 5 | ||
| pgrep -u "$(id -u)" -x defi-daemon | wc -l | ||
| defi list-workspaces --json > after.json | ||
| diff <(jq -S .monitors before.json) <(jq -S .monitors after.json) && echo same | ||
| ``` | ||
|
|
||
| Pass: one daemon, `status` reachable, workspace identity and order preserved. | ||
|
|
||
| ## Gotchas | ||
|
|
||
| - Use `defi service restart`, never `open -n`. | ||
| - Restart interrupts any in-flight animation; do not run it during a Computer Use session you care about. | ||
| - Replacing the bundle needs the desktop reservation and an unchanged designated requirement. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| # Virtual workspaces and parking | ||
|
|
||
| ## Sub-features | ||
|
|
||
| - Named persistent workspaces from `[workspaces].names`, dynamic ordinary ones. | ||
| - Per-monitor workspace stacks. | ||
| - Inactive workspace windows parked offscreen through topology and Accessibility. | ||
| - Move column or window to a workspace or monitor. | ||
|
|
||
| ## How to get to it (user POV) | ||
|
|
||
| Workspace hotkeys, the menu bar item, or the CLI. | ||
|
|
||
| ## Driving it with the defi CLI | ||
|
|
||
| ```sh | ||
| defi list-workspaces --json > workspaces-before.json | ||
| defi focus-workspace-name web; sleep 1 | ||
| defi status | tr ' ' '\n' | grep -E '^(workspace|hidden|visibility|drift)=' | ||
| defi focus-workspace-name dev # restore the recorded initial workspace | ||
| ``` | ||
|
|
||
| Pass: `workspace=` equals the target, `hidden=` equals the parked window count, `drift=0[]`, and the JSON `active` flag moved. | ||
|
|
||
| ## Gotchas | ||
|
|
||
| - Names depend on the user's config; read them from `list-workspaces --json` first. | ||
| - `--monitor <n>` is 1-based display index, while `id` in JSON is the monitor ID. | ||
| - Always restore the initial workspace. | ||
| - Covering tests: `testFocusedWindowRemainsResolvableWhileParkedOffscreen`, `testUnhiddenOnePixelStripAnchorConvergesWithRealWindowFrame`. |
|
macroscopeapp[bot] marked this conversation as resolved.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.