Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Tiny Swift CLI that reads the focused app's text selection via the macOS Accessibility API. Sutando.app's "drop context" action (hotkey configurable via `state/hotkeys.json`) shells out to this binary to capture what you have highlighted.
.claude/skills/sonichi-context-drop-ax-read/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-07 | ✗→✓ | ▲ Improved | -32% | 0% |
| case-02 | ✗→✓ | ▲ Improved | -17% | 0% |
| case-03 | ✗→✓ | ▲ Improved | -38% | 0% |
| case-04 | ✗→✓ | ▲ Improved | -59% | 0% |
| case-08 | ✗→✓ | ▲ Improved | -18% | 0% |
Tiny Swift CLI that reads the focused app's text selection via the macOS Accessibility API. Sutando.app's "drop context" action (hotkey configurable via state/hotkeys.json) shells out to this binary to capture what you have highlighted.
Runs once per invocation and emits a single JSON line on stdout:
json{"app":"Discord","window_title":"@sutando — Discord","url":"","selected":"the highlighted text","path":"ax"}
path values:
"ax" — AXSelectedText returned non-empty (native NSTextView path)"clipboard" — AX returned empty, Cmd+C fallback wrote new clipboard content"none" — both paths returned empty (or AX was denied)The Cmd+C fallback uses NSPasteboard.changeCount to distinguish "Cmd+C actually wrote something" from "clipboard already had content" — otherwise the previous clipboard contents would be silently reported as the new selection. The prior pasteboard string is restored after the probe so a failed-copy attempt doesn't corrupt the clipboard.
bashbash skills/context-drop/build.sh
Produces skills/context-drop/ax-read. The headless core's src/startup.sh does not build app-only helpers; compile this binary explicitly as part of the optional menu-bar app setup (or let the app packaging workflow build it).
LSUIElement=YES menu-bar agents (which Sutando.app is) have a TCC attribution chain that can misroute AX queries to the parent bundle even after a re-grant. A separately-signed CLI launched as a child gets its own clean trust binding, and the resulting AX queries succeed consistently. The binary is also reusable by any other tool that needs a one-shot selection read — voice agents, other hotkey handlers, automation scripts.
The first time ax-read runs it'll trigger the macOS Accessibility prompt for Sutando.app (its parent, who macOS attributes the AX queries to). Approve the prompt; the binding persists until the next codesign identity change. See PR #902 for the full TCC story.
personal-deictic skillThis skill emits the shared text-selection subset of personal-deictic's richer output. The private package additionally captures a screenshot of the focused window and the cursor position for deictic phrases ("this", "here") — those fields stay private. Output schemas overlap on the five fields Sutando.app's invokeAxRead consumes (app, window_title, url, selected, path); personal-deictic adds screenshot_path and cursor for the voice agent's read_selection tool.
Sutando.app::resolveAxReadPath() tries the private path first (when available) and falls back to this public binary, so users with the private skill keep their richer deictic captures while public users get the text-only path. If anything other than Sutando.app's dropContext ever spawns this public binary, it should not assume screenshot_path/cursor will be present — the contract is the five-field subset only.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-07 | fail→pass | 15,604 | 4,512 | -71% | 1 | 1 | 0% | 2,125 | 1,451 | -32% | 0 | 0 | — |
case-01 | fail→fail | 25,654 | 33,873 | +32% | 1 | 1 | 0% | 1,217 | 943 | -23% | 0 | 0 | — |
case-02 | fail→pass | 9,684 | 2,537 | -74% | 1 | 1 | 0% | 1,441 | 1,198 | -17% | 0 | 0 | — |
case-03 | fail→pass | 12,663 | 2,882 | -77% | 1 | 1 | 0% | 1,882 | 1,168 | -38% | 0 | 0 | — |
case-04 | fail→pass | 19,935 | 2,658 | -87% | 1 | 1 | 0% | 2,841 | 1,176 | -59% | 0 | 0 | — |
case-05 | pass→pass | 12,660 | 6,799 | -46% | 1 | 1 | 0% | 1,949 | 1,792 | -8% | 0 | 0 | — |
case-06 | pass→pass | 10,052 | 3,463 | -66% | 1 | 1 | 0% | 1,505 | 1,251 | -17% | 0 | 0 | — |
case-08 | fail→pass | 9,148 | 1,709 | -81% | 1 | 1 | 0% | 1,212 | 996 | -18% | 0 | 0 | — |
case-09 | pass→pass | 12,610 | 4,342 | -66% | 1 | 1 | 0% | 1,845 | 1,419 | -23% | 0 | 0 | — |
case-10 | fail→pass | 17,611 | 3,976 | -77% | 1 | 1 | 0% | 2,623 | 1,388 | -47% | 0 | 0 | — |
case-11 | pass→pass | 12,457 | 4,135 | -67% | 1 | 1 | 0% | 1,786 | 1,474 | -17% | 0 | 0 | — |
case-12 | fail→pass | 10,922 | 3,147 | -71% | 1 | 1 | 0% | 1,799 | 1,365 | -24% | 0 | 0 | — |
case-13 | pass→pass | 13,568 | 2,015 | -85% | 1 | 1 | 0% | 1,981 | 1,020 | -49% | 0 | 0 | — |
case-14 | pass→pass | 11,096 | 4,635 | -58% | 1 | 1 | 0% | 1,706 | 1,455 | -15% | 0 | 0 | — |
case-15 | fail→pass | 9,067 | 1,620 | -82% | 1 | 1 | 0% | 1,448 | 939 | -35% | 0 | 0 | — |
case-16 | pass→pass | 12,903 | 4,895 | -62% | 1 | 1 | 0% | 1,973 | 1,545 | -22% | 0 | 0 | — |
case-17 | fail→pass | 17,266 | 4,355 | -75% | 1 | 1 | 0% | 2,540 | 1,411 | -44% | 0 | 0 | — |
case-18 | fail→pass | 10,763 | 1,477 | -86% | 1 | 1 | 0% | 1,561 | 912 | -42% | 0 | 0 | — |
case-19 | pass→pass | 8,777 | 2,170 | -75% | 1 | 1 | 0% | 1,259 | 1,046 | -17% | 0 | 0 | — |
case-20 | pass→pass | 9,950 | 6,755 | -32% | 1 | 1 | 0% | 1,585 | 1,961 | +24% | 0 | 0 | — |
case-21 | pass→pass | 14,008 | 13,594 | -3% | 1 | 1 | 0% | 2,385 | 3,276 | +37% | 0 | 0 | — |
case-22 | pass→pass | 16,115 | 15,160 | -6% | 1 | 1 | 0% | 2,635 | 3,129 | +19% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 21 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +45 percentage points is the difference between those two pass rates over the 21 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.