macOS workspace automation - launch IDE, terminal, and notes per project+branch.
Note: This is a personal project tailored to my workflow. Feel free to fork and adapt it to your needs rather than submitting PRs. The code is intentionally simple so you can modify it for your own setup.
git clone https://github.com/staskus/dreamspaces.git
cd dreamspaces
./install.sh# Setup dependencies and config
ds setup
# Edit your project presets
ds config
# Open a workspace
ds open woocommerce-ios feature/login
# Switch between workspaces (or use Shift+Space hotkey)
ds switch
# Close current workspace
ds close- Define project presets in
~/.config/dreamspaces/config.json - Run
ds open <project> [branch]to launch workspace - Dreamspaces creates a new macOS Space for your workspace
- Launches your IDE, terminal (with tmux session), and notes
- Arranges windows according to your layout config
- Switch between workspaces with
ds switchor the hotkey ds closecloses windows, kills tmux session, and removes the space
Edit ~/.config/dreamspaces/config.json:
{
"version": "0.1",
"hotkeys": {
"switch": { "mods": ["shift"], "key": "space" }
},
"layout": {
"ide": { "x": 0, "y": 0, "w": 0.5, "h": 0.6 },
"notes": { "x": 0, "y": 0.6, "w": 0.5, "h": 0.4 },
"terminal": { "x": 0.5, "y": 0, "w": 0.5, "h": 1.0 }
},
"projects": {
"my-project": {
"path": "~/Projects/my-project",
"baseBranch": "main",
"useWorktree": true,
"ide": { "app": "Xcode", "open": "MyProject.xcworkspace" },
"terminal": { "app": "iTerm", "tmux": true },
"notes": {
"vault": "MyVault",
"path": "~/Library/Mobile Documents/iCloud~md~obsidian/Documents/MyVault",
"folder": "Projects/my-project/branches"
}
}
}
}| Command | Description |
|---|---|
ds setup |
Install dependencies and create config |
ds open <project> [branch] |
Open workspace for project+branch |
ds close |
Close current workspace (keeps tmux session) |
ds close --cleanup |
Close and remove worktree + tmux session |
ds switch |
Switch between active workspaces |
ds list |
List active workspaces |
ds doctor |
Check system health and diagnose issues |
ds cleanup |
Remove orphaned workspace entries |
ds config |
Open config in editor |
Dreamspaces integrates with macOS applications to create development workspaces. Each category has supported apps with different requirements.
| App | Status | Notes |
|---|---|---|
| Cursor | ✅ Default | |
| Xcode | ✅ Supported | Use .xcworkspace path |
| VS Code | ✅ Supported | App name: Visual Studio Code |
"ide": { "app": "Cursor", "open": "." }
"ide": { "app": "Xcode", "open": "MyProject.xcworkspace" }| App | Status | Notes |
|---|---|---|
| iTerm | ✅ Default | Full AppleScript support |
| Terminal.app | ✅ Supported | macOS built-in |
| Warp, Alacritty, Kitty | ❌ Not supported | Fork to add |
"terminal": { "app": "iTerm", "tmux": true }tmux: truecreates persistent sessions that survive workspace switches- Sessions named
{project}-{branch}(with/→-)
| App | Status | Notes |
|---|---|---|
| Obsidian | ✅ Supported | Requires Advanced URI plugin |
| Notion, LogSeq, Apple Notes | ❌ Not supported | Fork to add |
"notes": {
"vault": "MyVault",
"folder": "Projects/my-project/branches",
"path": "~/Library/Mobile Documents/iCloud~md~obsidian/Documents/MyVault"
}Requirements:
- Install Advanced URI plugin in Obsidian (Settings → Community Plugins → Browse → "Advanced URI")
ds setupcan install this automatically
Features:
- Notes open in separate pop-out windows per workspace
- Auto-creates note file on first open with template
- Note files:
{branch}.mdin the specified folder
| App | Status | Notes |
|---|---|---|
| Google Chrome | ✅ Hardcoded | Opens URLs in new windows |
| Safari, Firefox, Arc | ❌ Not supported | Fork to add |
"urls": ["https://github.com/org/repo", "https://linear.app/team"]Fork the repo and modify for your needs:
- IDE: Edit
lib/core/apps.sh→apps_launch_ide()and add toideAppsinhammerspoon/spaces.lua - Terminal: Add AppleScript handling in
apps_launch_terminal() - Notes: Check if app has URL scheme support, add launcher function
- Browser: Modify
apps_launch_urls()to use your preferred browser
Configure hotkeys in config.json:
{
"hotkeys": {
"switch": { "mods": ["shift"], "key": "space" }
}
}Completions are installed automatically by ./install.sh.
Manual setup:
Zsh - Add to ~/.zshrc:
fpath=(/path/to/dreamspaces/completions $fpath)
autoload -Uz compinit && compinitBash - Add to ~/.bashrc:
source /path/to/dreamspaces/completions/ds.bashDreamspaces is made possible by these open source projects:
-
Hammerspoon (MIT License) macOS desktop automation with Lua scripting. Hammerspoon provides the window management, space control, and hotkey functionality that powers Dreamspaces. Copyright (c) 2014-2017 Steven Skoczen, Chris Jones, and contributors
-
tmux (ISC License) Terminal multiplexer for persistent terminal sessions. Each workspace gets its own tmux session that persists across switches. Copyright (c) 2007 Nicholas Marriott
-
jq (MIT License) Lightweight JSON processor used for parsing configuration and state files. Copyright (c) 2012 Stephen Dolan
- worktree-cli (MIT License)
Git worktree management CLI. When
useWorktree: trueis set, Dreamspaces uses this to create isolated branch directories. Copyright (c) John Lindquist
See Supported Apps for the full list. Currently:
- IDE: Cursor, Xcode, VS Code
- Terminal: iTerm, Terminal.app (with optional tmux)
- Notes: Obsidian (with Advanced URI plugin)
- Browser: Google Chrome
- macOS (tested on macOS 14+)
- Hammerspoon (installed by
ds setup) - tmux (installed by
ds setup) - jq (installed by
ds setup) - For git worktree support:
npm install -g @johnlindquist/worktree - For Obsidian notes in separate windows: Install the Advanced URI plugin
- Obsidian > Settings > Community Plugins > Browse > "Advanced URI" > Install & Enable
ds (CLI)
│
├── Hammerspoon (Lua)
│ ├── Space creation/removal (hs.spaces)
│ ├── Window arrangement (hs.window)
│ ├── Hotkey handling (hs.hotkey)
│ └── State management (JSON file)
│
├── tmux
│ └── Persistent terminal sessions per workspace
│
└── AppleScript
└── App-specific automation (iTerm, Obsidian, Chrome)
MIT
Special thanks to the Hammerspoon community for their excellent documentation and the hs.spaces module that makes macOS space management possible from scripts.