Cursor will open a window per project and then leave you to live with that. CursorStack is the missing workspace layer. It groups those windows under a tab strip.
What it refuses to be
It does not embed Cursor, and it does not modify Cursor. The windows on screen are the real ones. Closing CursorStack leaves them open. Clicking another app hides the strip the way a normal window would.
The strip sits above Cursor’s title bar by default, so Cursor’s own search field still works. Settings can move it to the bottom, left, or right.
Why Accessibility
Finding, moving, resizing, and focusing another app’s windows means the Accessibility API. A sandboxed app cannot control windows owned by another process, so CursorStack is not App Sandboxed. Releases still use Hardened Runtime, Developer ID signing, and notarization.
That permission is the tradeoff. The app asks for it up front and says what it will not do: read source, modify Cursor, or upload window contents. Tab marks come from local status, whether a Cursor chat or a Claude Code session is running, finished, or waiting. Not from the message text.
There is no account and no backend. The only network request is Sparkle checking the public GitHub release feed. Groups persist on disk under Application Support. Global shortcuts switch tabs and can be changed. The public README, checked 2 Oct 2026, points at the 1.0.16 release.
A small lesson
The dashed tab was the detail that kept the model honest. A saved window that Cursor has not reopened yet should not pretend to be a live project. It asks you to reconnect. Removing it is explicit. I would rather show the gap than invent a window that is not there.
CursorStack is an independent project. It is not affiliated with, endorsed by, or sponsored by Anysphere. Cursor is a trademark of its owner.




