One launcher for every Cursor you run.
Isolated profiles — own settings, extensions, login, chat history — with live stats,
instant switching, and per-profile title bar colors so you never mix up Work and Personal again.
Features · Quick start · Terminal · How it works · Layout · Releasing · FAQ
A Mojo Layers project. Three native apps plus a terminal client, one profile format:
| Platform | Stack | Location | Launch |
|---|---|---|---|
| macOS | SwiftUI | Sources/ + build.sh |
./build.sh && open "build/Prism.app" |
| Windows | WPF / .NET 8 | windows/ |
dotnet build windows/CursorProfiles.csproj -c Release |
| Linux | GTK4 + libadwaita (Python) | linux/ |
python3 linux/prism.py |
| Terminal | Go + Bubble Tea | tui/ |
go run ./tui (or prism-tui) |
All three read and write the same ~/.cursor_profiles directory and .profiles.json metadata, so profiles roam across operating systems. Every number the UI shows is measured live — resident memory from ps, window counts from the on-screen window list, CPU from the kernel. Nothing is hardcoded.
- Profile grid — colorful cards with per-profile accent color and initial, disk size, and last-launched info
- Your original Cursor profile is protected — it shows up as a pinned Main Cursor card with a
BUILT-INbadge, launches Cursor exactly like opening it normally (no--user-data-dir), can be cloned into a new managed profile, and can never be deleted - Create / edit / duplicate / rename with per-profile launch defaults (memory limit, default project folder)
- Each profile is a separate
--user-data-dir: own settings, extensions, login, chat history. Existing profiles are picked up automatically
- One-click launch — double-click a card, or open the options popover for per-launch overrides (memory, project folder, force a new window)
- Drag & drop — drop any folder onto a card to open it with that profile
- Global Quick Switch — press ⌥Space from any app for the Spotlight-style palette;
⌘Kfocuses search,⌘Ncreates a profile - Menu bar dropdown — live per-profile stats, Focus/Start, Stop All, and one-click hub access without opening the main window
- Live resident memory per running profile (summed RSS) against its configured
--max-memorylimit, plus real total RAM for your Mac - Real on-screen window counts per profile — counted, never guessed
- Real system CPU % in the status bar
- Running detection with graceful quit (SIGTERM)
- Distinct title bar color per profile — merged into each profile's
User/settings.json(workbench.colorCustomizations+window.titleBarStyle: "custom"), visible in the window, Cmd+Tab, and Mission Control. Your own settings are preserved; only the title bar keys are touched - Pin, search, sort (name / recently used / size)
- Safe delete — profiles go to the Trash, never
rm -rf - Cursor auto-detection via Launch Services + well-known paths, with a custom-path override in Settings
- Light & dark mode that follow the system
macOS — requires macOS 14+ and the Xcode Command Line Tools (no full Xcode):
./build.sh
open "build/Prism.app"The build compiles the Swift sources, generates Prism.icns from assets/logo.png, assembles and ad-hoc signs the bundle. Optionally move it to /Applications:
cp -R "build/Prism.app" /Applications/Windows — requires the .NET 8 SDK:
dotnet build windows/CursorProfiles.csproj -c ReleaseSee windows/README.md — including how to pin per-profile taskbar shortcuts with their own icons.
Linux — requires GTK 4.10+, libadwaita 1.2+, and PyGObject (see linux/README.md for distro packages):
python3 linux/prism.pyEvery pull request to main rebuilds all three platforms automatically — see .github/workflows/pr.yml.
prism-tui is Prism for the terminal — same profiles, no app. List, filter,
launch, stop, create and delete profiles with live RSS and system stats.
See tui/README.md for keys.
npm i -g prism-tui # Node users
pipx install prism-tui # Python users
brew install --cask moderniselife/prism/prism-tui
winget install ModerniseLife.PrismTUIPackage registries go live with the first
tui-v*release — until then, run it from source (below). Binaries are already on the way.
Or grab a static binary from
GitHub releases — no
runtime needed anywhere. From source: go run ./tui (Go 1.23+).
First run opens unsigned on macOS Gatekeeper the same way as the
.appbelow: right-click → Open once. The Homebrew cask clears quarantine automatically.
~/.cursor_profiles/
.profiles.json # names, colors, launch defaults (shared across OSes)
Work/ # a full Cursor user-data-dir
Personal/ # another one — fully independent
Launching a profile runs Cursor with --user-data-dir <profile> --max-memory <limit>, so isolation is enforced by Cursor itself rather than by anything Prism fakes. The built-in profile launches with no --user-data-dir at all — byte-for-byte identical to opening Cursor normally.
Sources/CursorProfiles/
CursorProfilesApp.swift # App entry, hidden title bar, menu-bar extra, ⌥Space hotkey
ContentView.swift # Main hub: title bar, filters, grid, live status bar
ProfileCard.swift # Card UI, live memory bar, launch popover, drag & drop
ProfileEditorSheet.swift # Create/edit sheet with live preview
SpotlightCommandBar.swift # ⌥Space quick-switch palette
SettingsView.swift # Cursor path, defaults, storage
ProfileStore.swift # Metadata, CRUD, live RSS/CPU/window polling
SystemStats.swift # Real CPU/RAM/window measurement + global hotkey helpers
CursorLauncher.swift # Find/launch/quit Cursor processes
TitleBarColorizer.swift # Merges per-profile title bar colors into User/settings.json
PrismTheme.swift # Adaptive light/dark design system
MeshBackgroundView.swift # Ambient background
Models.swift # Profile model, palette, formatting helpers
assets/
logo.png # Source of truth for the logo + macOS app icon
tui/
main.go, store.go, # TUI: entry, profiles/persistence/launch/detect
stats.go, colorize.go, ui.go
npm/prism-tui/ # npm wrapper (downloads the release binary)
pypi/prism-tui/ # PyPI wrapper (platform wheels bundle it)
packaging/homebrew-cask/ # Prism.app cask template for the tap
Push a tag like tui-v1.2.3 and .github/workflows/release.yml
ships everything: GoReleaser binaries + checksums + the Homebrew TUI cask,
the signed Prism.app.zip, five platform wheels on PyPI, the npm package,
a Winget submission PR, and the tap's Prism.app cask update.
One-time setup before the first release:
- Create the empty
moderniselife/homebrew-prismtap repo. - Repo secrets:
TAP_GITHUB_TOKEN(classic PAT,reposcope),NPM_TOKEN(publish rights),PYPI_API_TOKEN,WINGET_TOKEN(classic PAT,public_reposcope), plus a fork ofmicrosoft/winget-pkgsundermoderniselife. - Winget's first version must be submitted by hand — the automation
refuses brand-new packages. Run
komac update ModerniseLife.PrismTUIonce against a published release, then automation takes over.
Why is there no "pin to Dock with a custom icon" feature?
An earlier build generated a wrapper .app per profile with its own icon. It was removed for two reasons:
- It didn't work while running. macOS shows the Dock icon of whatever bundle is actually running — since the wrapper just launches Cursor's real binary, open windows always showed Cursor's stock icon.
- It multiplied permission prompts. Each wrapper is a distinct app identity, and macOS ties Microphone/Camera/folder consent to whichever bundle launched Cursor — so every wrapper re-triggered Cursor's entire permission set as a brand-new app.
Title bar coloring replaces it: it only edits a JSON settings file — no new app identity, no signing, no permission implications. (Windows instead offers per-profile taskbar shortcuts, which are just .lnk pointers to the same Cursor.exe, so they dodge the identity problem.)
Does Prism spy on my code or phone home?
No. Everything is local: it reads ps output, the on-screen window list, and files under ~/.cursor_profiles. There is no network code, no analytics, no daemon.
CPU shows "—" sometimes?
System CPU % is computed from kernel deltas, which need two samples — the first poll after launch has nothing to diff against, so it shows a dash until the second one lands (~15s).
