Repository navigation
Conversation
Search windows and workspaces and run argument-free Defi commands from Raycast. The extension only runs the defi CLI with execFile and makes no network calls.
ApprovabilityVerdict: Needs Human Approval Macroscope's review found this PR requires human approval — Adds an optional Raycast interface to existing local Defi commands without changing the core app. New diagnostic suppressions and conditional test skips require human review; the supplied preview and bring-window findings also remain separately blocking. Needs human approval because:
Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more. |
ray build without -o writes into Raycast's extensions directory. Build into dist so Tinycast can add the folder, and document that route.
…sion Search Windows and Search Workspaces show where windows sit in the strip. Run Command sorts by use and turns the search text into widths and workspace targets. Moves confirm with a HUD, and Launch Defi is offered when Defi is not running.
Tinycast reads each command's bundle at launch, so building into its extensions folder updates the extension without reinstalling it.
Group windows by workspace, show each workspace's apps and number, give commands written titles and icons, and keep the strip behind ⌘D so the lists keep their full width.
| const rowHeight = (column.height - column.gap * (windows.length - 1)) / Math.max(windows.length, 1); | ||
| return windows.map((window, row) => { | ||
| const highlighted = window.id === highlightID; | ||
| const x = column.inset + index * (column.width + column.gap); | ||
| const y = column.inset + row * (rowHeight + column.gap); |
There was a problem hiding this comment.
🟡 Medium src/strip.ts:23
stripSVG emits negative-height tiles for columns with 12 or more windows, so the SVG no longer represents those windows with valid geometry. The fixed 6px gap consumes more than the 64px column height; scale the gap with the stack size and use that scaled gap for both tile sizing and positioning.
| const rowHeight = (column.height - column.gap * (windows.length - 1)) / Math.max(windows.length, 1); | |
| return windows.map((window, row) => { | |
| const highlighted = window.id === highlightID; | |
| const x = column.inset + index * (column.width + column.gap); | |
| const y = column.inset + row * (rowHeight + column.gap); | |
| const gap = Math.min(column.gap, column.height / windows.length / 2); | |
| const rowHeight = (column.height - gap * (windows.length - 1)) / windows.length; | |
| return windows.map((window, row) => { | |
| const highlighted = window.id === highlightID; | |
| const x = column.inset + index * (column.width + column.gap); | |
| const y = column.inset + row * (rowHeight + gap); |
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @contrib/raycast/src/strip.ts around lines 23-27:
`stripSVG` emits negative-height tiles for columns with 12 or more windows, so the SVG no longer represents those windows with valid geometry. The fixed 6px gap consumes more than the 64px column height; scale the gap with the stack size and use that scaled gap for both tile sizing and positioning.
Recover from every read failure in place, keep the last state while reloading, name the window each action moves, tag focused and floating windows, add a recent section, raw command subtitles and copy actions to Run Command, take its search as a launch argument, and pick Defi.app in the preferences.
Keep the secondary action the same on every row, follow defi subscribe while a list is open, filter windows by workspace, show configured workspace symbols, explain each command with its default shortcut, and guide a missing Defi install.
…nsion Hide cached rows on errors, reconnect the live stream after Defi starts, copy commands in the form [keys] accepts, show default shortcuts as glyphs, offer browsable rows for argument commands, keep the secondary action open when it has nothing to move, remember the window scope, and explain version mismatches.
…sion Add Show Windows to Search Workspaces, keep argument rows findable while searching, name each suggestion's default shortcut and effect, keep rows bare beside the side pane, word-match workspace names, word HUDs as results, and drop the live stream: launchers do not reliably run effect cleanups, which left defi subscribe running.
| onAction={() => | ||
| act( | ||
| window, | ||
| [["move-window-to-workspace-name", here.id]], |
There was a problem hiding this comment.
🟠 High src/window-list.tsx:199
“Bring to …” fails for an empty ordinary current workspace when the selected window is on another workspace of the same display, leaving the user switched away without moving the window. act focuses the window first, which deactivates and deletes the empty destination; the following move then targets the deleted here.id and fails with an unknown-workspace error. Preserve the destination across the focus step or use an atomic move that does not first deactivate it.
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @contrib/raycast/src/window-list.tsx around line 199:
“Bring to …” fails for an empty ordinary current workspace when the selected window is on another workspace of the same display, leaving the user switched away without moving the window. `act` focuses the window first, which deactivates and deletes the empty destination; the following move then targets the deleted `here.id` and fails with an unknown-workspace error. Preserve the destination across the focus step or use an atomic move that does not first deactivate it.
Show digit shortcuts only where Defi binds them, check a fresh read before moving, keep the launcher open while Defi launches, give every Search Commands row a copy as its secondary action, trim suggestions for short queries, start each launch on all workspaces, keep rows bare next to the side pane, and test the catalog against CONFIGURATION.md.
Tinycast flattens submenus, so ⌘↵ on Move to Workspace would have moved the window to the first workspace; push a list grouped by display instead. Describe each Search Commands row in its own words, name the window in its side pane, report read failures where they are seen, link releases for an old Defi, and add Refresh to Search Commands.
…tension Read the move targets afresh with the workspace row's app icons, name the focused window the same way in every command, title action sections, remember suggestions in Recent, show loading only when suggestions wait, read unversioned output and timeouts as clear errors, and draw the strip with six-digit colors.
Go to never second-guesses cached state, the move targets show errors and search apps, recent workspace suggestions are worded again from the live workspaces, the Search Commands pane gives the [keys] line, argument rows show examples, and the README lists each command's keys.
…tand-in keys Glob the .mts tests so Node 22 finds them, silence the typeless-package warning, and say in the pasted [keys] line when its key is a stand-in.
Capture the selected window with screencapture while the side pane is open, shrink it with sips, and show it as a data URI above the strip; the file is deleted as soon as it is read.
…cording A launcher without Screen Recording got no picture and no explanation; the pane now says so and offers to open the privacy setting.
Read each picture with defi window-preview, so the launcher captures nothing and needs no Screen Recording; an older Defi gets a hint to update.
Store README and changelog placeholder, the standard publish scripts instead of the Tinycast one, a catalog test that runs only next to a Defi checkout, and update advice that points to the Store.
|
Closing: the extension moves to the Raycast Store (raycast/extensions) instead of living under contrib/. The branch keeps the full history. |
Summary
A Raycast extension in
contrib/raycast/, next to the SketchyBar integration. It only runs thedefiCLI withexecFile(no shell, no network), so daemon and IPC stay unchanged. It also runs in Tinycast (npm run tinycastbuilds straight into its extensions folder).[keys]line to paste. Typing60,+10,h50,2or a workspace name offers the matching commands; it also takes that text as a root-search argument.Two host traps shaped the design: Tinycast flattens submenus (so moving uses a pushed list, never a submenu in the ⌘↵ slot) and does not run React effect cleanups (so there is no long-lived
defi subscribe; a first version leaked one process per opening).Evidence
npm test: 11/11 on Node 26 and Node 22.6 (parsing both real fixtures, unknown fields and versions, strip layout, suggestions and their[keys]forms, shortcut glyphs, and the whole catalog checked againstCONFIGURATION.md, which caught a planted wrong shortcut)npm run buildandnpm run lintpass;make verifypassesraycast/extensions(aerospace, brew, window-walker) went from 6.5/10 to 9.5/10Merge Danger
Door: two-way
Blast Radius: none. Nothing ships in the app; outside
contrib/raycastonly a README link changes.Needs CLI to go further: recent-focus order in
list-windows, a key-binding export, display names, column widths, and move/float/close by window ID (actions focus the window first, which briefly shows its workspace).Note
Add a Raycast extension for Defi window, workspace, and command search
contrib/raycast/with three Raycast commands: Search Windows, Search Workspaces, and Search Commands. All commands invoke the Defi CLI bundled inside the app; the app location can be set via an optional Defi App preference, with fallback search in/Applications.VersionMismatcherror and skipping malformed entries.VersionMismatchand strict version checks in parse.ts mean an older Defi app or newer extension format fails rather than degrading; checksupportedversions there if parsing breaks.Macroscope summarized 14e23f6.