DeepSeek Harness Remote
DeepSeek Harness Remote 可将手机或另一台电脑与你运行 DeepSeek Harness 的电脑安全连接,随时随地继续你的工作,方便随时查看进度并继续工作。
AI 翻译
尚未收集仓库信息。
尚未检测到更新。GitHub 发布版本后会显示在这里。
Nine workspaces on one row of keys. A fast, free workspace manager for macOS: ⌘1–⌘9 to switch, ⌘⇧1–⌘⇧9 to move a window, and a Mission Control–style overview.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗curl -fsSL https://raw.githubusercontent.com/baney75/baneyspaces/main/install.sh | bash
A short walk through the live page at dbaney.com/baneyspaces:
macOS already has desktops. Switching between them takes a swipe and an animation, and a window can't be sent to one without dragging it through Mission Control. Tiling window managers fix that, then take over your layout in exchange.
BaneySpaces does the one part you wanted. Your windows stay exactly where you put them, at the size you made them. You just get nine places to put them and a key for each.
| Keys | What happens |
|---|---|
| ⌘1 – ⌘9 | Go to that workspace. |
| ⌘⇧1 – ⌘⇧9 | Send the front window to that workspace and follow it. |
| Mission Control key, or ⌃↑ | See all nine workspaces at once. |
Prefer to keep ⌘1 for your browser's first tab? Pick ⌃, ⌥ or ⌃⌥ in setup instead.
Press the Mission Control key (F3 on Apple keyboards) or ⌃↑, swipe up with three or four fingers on the trackpad (whichever your trackpad settings give Mission Control), or push the pointer into a hot corner you had set to Mission Control, and BaneySpaces shows all nine workspaces in the same 3×3 grid as the number keys, with every window's app and title. A swipe down, Esc or the same key again puts you back.
macOS's Mission Control is replaced, not joined. BaneySpaces switches it off in the Dock, so the
"Desktop" view never opens from the trackpad, a hot corner or the keys, and it remaps any hot corner
that was set to Mission Control to nothing and answers that corner itself. It saves what was there
first. To get Mission Control back, turn off Settings › Keys › Use BaneySpaces' overview instead of
Mission Control: every setting goes back exactly as it was. Quitting BaneySpaces and uninstalling
do the same, and the Dock restarts each time. If BaneySpaces stops without quitting (a crash, or
the app dragged to the Trash), a small launch agent puts Mission Control back once no BaneySpaces
has run for a minute (30 seconds after an update's restart that never came back). The agent stays
installed across quits, so macOS doesn't announce a new background item at every launch; it goes
when you turn the Settings switch off or uninstall, and does nothing while BaneySpaces isn't
holding Mission Control off. BaneySpaces
switches Mission Control off only after that agent is written, loaded and checked, and after what
was there is saved to disk; if either can't be done, Mission Control stays on and Settings says
why. If the agent is switched off later (the Background Item notice), BaneySpaces gives Mission
Control back instead of holding it off without a way back. Only a build that knows this takeover
counts as running: an older BaneySpaces started later does not keep Mission Control off. To get
Mission Control back yourself, turn off the Settings switch; if BaneySpaces isn't running, use
defaults delete com.apple.dock mcx-expose-disabled; killall Dock (and set any hot corner you had
on Mission Control back in System Settings). Doing that while BaneySpaces runs also works: it
notices within 20 seconds and switches its own overview off.
App Exposé (⌃↓) goes with Mission Control, and so does a Magic Mouse's two-finger double tap, which opens nothing while this is on. The trackpad swipe uses macOS's private trackpad framework, loaded when BaneySpaces starts and checked against the touches it gets; if macOS won't load it or reports touches in a layout BaneySpaces doesn't read, Settings says so and the other ways in still work. Only trackpads are watched, with each trackpad's own finger settings, and Show Desktop and pinch gestures aren't taken for a swipe.
The menu bar icon shows the number of the workspace you're on. Its menu lists the workspaces in use and one empty one to start fresh on, then Show All Workspaces, Find or Install an App…, Settings… (⌘,) and Quit BaneySpaces (⌘Q). Two more rows appear only while there is something to act on: N Agents Finished While You Were Away (a list; click one to go to it) and Update to …. Every switch, Bring Every Window Back, the update controls and About live in Settings, one click away.
Turn on Workspace Dock under Settings > Dock and the Dock shows your workspaces instead of your apps. Rest the pointer on the bottom edge of the screen and it slides up: a tile for each workspace in use, plus the one you're on, each with its apps and its number. Click an app's icon to go straight to that app (again for its next window), or the tile around it to go to the workspace. Rest on an app with several windows and a strip of them opens over it, each labeled with its title, to pick one; hover to see what's there. Right-click a tile to move the front window there, or an app to show or quit it (hold ⌥ for Force Quit). Drag an app's icon onto another tile to move its windows on that workspace there, or drag one window out of the strip to move just that one; drop it on the dashed tile to start a new workspace with it. Drag any window by its title bar down to a bottom dock and it comes up; let go on a tile (or the dashed one) and the window goes to that workspace, back where you picked it up. Dragging a file, link or image from another app brings the dock up too: hold it over an app's icon and that app's window comes forward, or over a tile and you go to that workspace, then drop it into the window. Drop a file or link on an app's icon and that app opens it, if it can. A tile with more than four apps shows three and a "+N"; rest on the "+N" to list the rest and click one. You stay where you are. The dashed tile goes to the first empty workspace, and the two small buttons at the end open the launcher and the overview of all nine.
It can sit on any side of the screen: choose Bottom, Left, Right or Top under Settings > Dock > Position on screen, or from the dock's right-click menu. At the top it sits under the menu bar and waits half a second before opening, so reaching for a menu doesn't bring it up. A dock with more tiles than the screen has room for shrinks to fit.
While it's on, the macOS Dock stays out of sight. BaneySpaces saves the Dock's own hiding
settings first and puts them back exactly when you turn the Workspace Dock off or quit. If
BaneySpaces ever crashed with it on, open BaneySpaces again (or run the uninstaller) and the
Dock comes back; by hand, defaults delete com.apple.dock autohide-delay; killall Dock gives the Dock its usual delay.
Settings › Appearance changes how every panel looks, and the open ones change as you click. Pick an accent (nine colors, System to follow macOS, or any color of your own), a palette for the nine workspace colors (Rainbow, Accent, Calm or Mono) and your own color for any one workspace, a panel style (Glass, Tinted or Solid) with an opacity slider, and a Small, Medium or Large Workspace Dock. White numbers stay readable: a workspace color that's too bright is dimmed. The defaults are the look BaneySpaces always had.
Themes and palettes. A theme is shape, type and motion; a palette is color; any theme takes any
palette, on every platform (spec/themes.md). BaneySpaces is the look above. Omarchy is
blocky like Omarchy's own Waybar and Hyprland: square corners, a solid 2 px border (your accent on
what's current), an opaque fill, no blur or shadow, a monospace font, numbered blocks for
workspaces, and fades only. Minimal is flat and small, with thin borders and a bar under each
workspace number. The palette is Auto (the panels' own dark look with your accent) or one of
Omarchy's 22. The dock, the "+N" list and window strip, ⌘Tab, the launcher, the overview, the menu bar
number and Settings all follow the theme, live. From a terminal:
baneyspaces set appearance.theme omarchy # or baneyspaces, minimal
baneyspaces set appearance.palette gruvbox # or auto
baneyspaces set dock.enabled false # or true
baneyspaces get # all three
Agents may change these too, from this Mac or, with the remote token, from another one
(BANEYSPACES_AGENT=<name> names the caller). Each change is logged in trace.log with who made it.
Workspace and window commands stay yours.
Turning the dock off (Settings › Dock, the menu bar item, or dock.enabled) leaves no dock window
at all: nothing comes up at the edge, the "+N" list never opens, and a window dragged to the bottom
edge is left alone. Dragging to the top, the workspace keys, ⌘Tab, the launcher, the overview, the
agent workspace and the menu bar number all keep working. Turn it back on and the dock returns the
next time the pointer rests on its edge.
macOS's ⌘Tab only reaches apps on the workspace you're on. In setup, set ⌘Tab switches to Apps on every workspace and it steps through every app with a window, most recently used first, each marked with the workspace it's on. Let go of ⌘ and you're on that app's window, wherever it is. Workspaces steps through workspaces instead. ⌘⇧Tab steps back; Esc cancels.
On an app with more than one window, hold Tab to open its window bar (the highlight stays put; a tap steps when you let go): each window by title (a browser's tab, a player's video) and workspace. Tab through it and let go to land on that window; hold Tab again to go back to the apps.
BaneySpaces knows what your coding agents are doing. On the Workspace Dock, a turning ring on an app's icon means a Claude Code or Grok session is working, a yellow ? means it's asking you something, a red ! means it stopped on an error, and an orange count means agents finished while you were looking somewhere else. When that happens in another app, a small notice says so in the corner of the screen; click it, or press ⌃⌘U, to go there. The menu bar icon counts them too. Click a badged app on the dock and you land on that agent's tab or split.
Agents report their state through hooks. Turn them on once, from setup (Dock tab) or with
baneyspaces hooks install, which adds them beside your own in ~/.claude/settings.json and
in ~/.grok/hooks. Without hooks BaneySpaces reads Claude's terminal title instead.
One box to open, find, install and remove apps, and find files, terminal tabs and splits, browser tabs and agent windows. ⌃⌘K opens it from any app. You can also open it from the menu bar menu (Find or Install an App…) or the Workspace Dock, or turn on ⌘Space opens the BaneySpaces launcher in setup to use it in place of Spotlight. Turning that off gives ⌘Space back to Spotlight, and so does quitting BaneySpaces.
tax 2025 or ret tax
finds 2025 Tax Return.pdf; words also break at _ and in camelCase). It searches your home folder, iCloud Drive and other cloud drives
through Spotlight, skipping Library, hidden folders and build folders such as node_modules.
Return opens the file, ⌘Return shows it in Finder. A folder Spotlight doesn't index
(System Settings › Spotlight) won't show up. The first time a file in Documents, Desktop,
Downloads or iCloud Drive comes up, macOS may ask to let BaneySpaces see that folder.!yt cats, !i sunsets, !w Erie, ,
, or the bang at the end (). Type to see them all;
Tab fills one in. A bang that isn't built in goes to DuckDuckGo, which knows thousands.
Agents: , , , , , .Add them in setup under Find and install apps › Your bangs: a trigger, a name, and the
search address with {q} where the words go. One with a built-in's trigger replaces it.
Scripts and agents can manage them from a terminal:
B=~/Applications/BaneySpaces.app/Contents/MacOS/BaneySpaces
$B --bangs add jira Jira 'https://acme.atlassian.net/browse/{q}'
$B --bangs add ask Claude 'https://claude.ai/new?q={q}' --agent
$B --bangs list
$B --bangs remove jira
They live in ~/Library/Application Support/BaneySpaces/bangs.json
([{"trigger": "jira", "name": "Jira", "url": "https://…/{q}", "agent": false}]). Only
https, http and Apple Maps addresses are accepted.
A window on another workspace isn't minimized, closed or moved. BaneySpaces hides its app, the same as ⌘H, so it drops out of sight and out of Mission Control while it keeps running and playing audio. When one app has windows on two workspaces, the window that doesn't belong here steps just off screen and comes back to the exact spot it left.
Requires macOS 13 Ventura or later, on Apple silicon or Intel. Two ways in:
In Terminal, one line. It downloads the ready-made app (a few MB, no developer tools),
checks that it is signed with BaneySpaces' release key, and copies it to ~/Applications (or
replaces the copy you already have, wherever it is):
curl -fsSL https://raw.githubusercontent.com/baney75/baneyspaces/main/install.sh | bash
From your browser: download BaneySpaces.dmg from the
latest release and drag BaneySpaces to
Applications. The first time you open it, macOS asks you to confirm in System Settings ›
Privacy & Security › Open Anyway, because BaneySpaces isn't notarized. The Terminal line
doesn't ask: a file downloaded by curl never gets that prompt. On its first launch from
Applications, BaneySpaces also does what the installer does: it turns AeroSpace's open-at-login
off, adds the baneyspaces command to ~/.local/bin and moves Ghostdeck to the Trash.
A release without the ready-made app (the Nightly build, old releases), or
BANEYSPACES_FROM_SOURCE=1, builds from source instead with Apple's free command line tools. If
the tools are missing, the installer opens Apple's installer for them first (about 1 GB, usually
5 to 15 minutes); paste the command again when that finishes. If the build fails, the installer
shows the error and where the full log is.
The ready-made app and a source build are signed with different certificates, and macOS ties the Accessibility permission to the signature. So if your BaneySpaces was built on your Mac, the installer and the updater keep building it from source (the same signature, the permission stays), as long as the command line tools are installed. Without them they replace it with the ready-made app, and macOS asks for the Accessibility permission once more.
Prefer to read the source first? Build it yourself:
git clone https://github.com/baney75/baneyspaces.git
cd baneyspaces
make install
Then a setup window opens. There is one thing you have to do:
Setup notices the switch within a moment, says BaneySpaces is on. Try ⌘2., and closes itself. Everything else is optional and already set sensibly:
If AeroSpace is running, setup shows a Quit AeroSpace step, since both want the same keys. The installer also quits it and turns off its open-at-login setting. AeroSpace stays installed.
Open Settings again any time with Settings… (⌘,) in the menu bar icon's menu, or by opening BaneySpaces from Finder or Spotlight.
BaneySpaces looks for a new version once a day and, when there is one, the menu bar menu shows Update to BaneySpaces … (the row is there only while a release is waiting) and so does Settings > Updates. Check by hand there with Check for Updates Now…. Nothing installs until you press Update Now in the window that shows what changed. The update installs the same way the first install did, into the folder the app is in. A stable release downloads the ready-made app; a Nightly build, or a copy that was built on your Mac (while the command line tools are installed), is built on your Mac, so the Accessibility permission carries over. Then BaneySpaces restarts and shows the release notes. If the update fails, BaneySpaces keeps running as it was and offers the log.
Pick what you follow under Settings > Updates:
The daily check asks GitHub's public release list and sends nothing about your Mac. Turn it off under Settings > Updates > Check for updates daily and use Check for Updates Now… instead.
macOS ties the Accessibility switch to the app's signature. If you reinstalled, or the local signing key had to be replaced, the switch can show on while macOS still says no. Setup spots this a few seconds after you click Allow and offers Fix Permission, which clears the old entry and asks again. By hand it is:
tccutil reset Accessibility com.baney.baneyspaces
If you turn the permission off while BaneySpaces is running, it brings every hidden window back, hands the shortcuts back to your other apps and reopens setup.
The same actions are open to scripts and other tools:
open baneyspaces://switch/2 # go to workspace 2
open baneyspaces://move/5 # send the front window to workspace 5
open baneyspaces://restore # bring every window back onto workspace 1
open baneyspaces://viewer # show or hide the overview
~/Library/Application Support/BaneySpaces/state.json always holds the current workspace and
the apps on each one.
The baneyspaces command (installed in ~/.local/bin) talks to BaneySpaces in a few milliseconds:
baneyspaces ls # every split, tab, agent and phone, with IDs
baneyspaces focus helium github # go to the best match, or an ID from ls
baneyspaces send <id> "npm test" # type into a Ghostty terminal, as if pasted
baneyspaces notify "Need a call" # light up the terminal this runs in
baneyspaces doctor # what's working and what isn't
baneyspaces skill install teaches Claude Code the same commands.
Turn on the agent workspace and agents get a workspace of their own (9 unless you pick another) to drive real apps on while you work on yours:
baneyspaces agent on # workspace 9 becomes the agent workspace
baneyspaces agent run --dir ~/Projects/atlas -- claude # a Claude Code session there
baneyspaces agent open TextEdit notes.txt # an app, or files in it, there
baneyspaces agent status # what's there, with window IDs
Three rules keep it from ever taking your screen. Its apps are parked out of view instead of
hidden, so agents can still click and type in them from behind. Nothing
on it coming forward takes you there: you go with ⌘9, its Dock tile or a launcher row. And a window
an agent opens in the background lands there, not on your workspace. agent run starts a
Ghostty of its own for the agent, a separate process from yours, so nothing the agent does
there can stall your terminals. scripts/agent-hands-probe.swift (phase 1) proves it on your Mac: an
agent's command runs there, and only your own keyboard and mouse change what you see.
BaneySpaces is also the hands agents use there. They read an app's accessibility tree, act on what's in
it and check the result, all on the agent workspace and never in the foreground. Cua's driver is no longer
used. The engine is agent-desktop (Apache-2.0), built from a
pinned commit by make install and linked into the app; the scope and focus guards, the evidence and the
MCP server are BaneySpaces'.
baneyspaces agent open TextEdit notes.txt # on the agent workspace; files only from the handoff folder; prints the window id
baneyspaces agent snapshot --app TextEdit -i # refs for what an agent can act on
baneyspaces agent type @s8f3k2p9:e2 "Hello" # act on a ref; the result carries what it read back
baneyspaces agent click|set-value|toggle|scroll|select|press <ref> …
baneyspaces agent find --window 4211 --role button --name Save
baneyspaces agent get @s8f3k2p9:e2 value # check from the live element
baneyspaces agent shot --window 4211 # one window as a PNG in BaneySpaces' shots folder, even while parked (needs Screen Recording)
baneyspaces agent windows # the windows an agent may use right now
claude mcp add baneyspaces -- baneyspaces mcp # the same tools over MCP, for Claude Code and Codex
You, not an agent, lend an app from your workspaces. baneyspaces agent lend Excel --for 20m shows a sheet in BaneySpaces
(Don't Lend is the default button) and only a real click on Lend lends it: a click posted by a program, or an
accessibility press, is refused, and running the command (or an agent running it) lends nothing by itself. Nothing sent
to the deck socket lends. Run the command again for an app that is lent and the sheet offers Take Back. A lend names
that process and its windows as they are then, is refused while you use the app (in_use: in front, or used in the last 30
seconds), ends after 30 minutes (up to 8 hours) or, if you gave --session, when that session ends, and is listed in
state.json and baneyspaces doctor. Agents can't lend: the MCP server has no such tool and an agent's lend answers
needs_lend. agent move moves only windows of apps BaneySpaces started for an agent; send your own window with its
workspace key. agent open starts only apps verified to run a separate copy that restores nothing of yours (TextEdit and
Preview on a file from the handoff folder, and Calculator); every other app, Finder, browsers and password managers
included, answers needs_sandbox, and a window of the agent's copy that shows a document from outside the handoff
folder, or an Open or Save panel, is off limits. The agent workspace protects you from accidents; it is not a security
boundary (see docs/agent-computer-use.md).
Every command prints one JSON envelope: {"ok":true,"data":{…}}, or {"ok":false,"error":{"code","message", "retry","suggestion"}} with retry one of safe, after_snapshot, never. Four rules, all enforced by the app:
an agent acts only on windows on the agent workspace or on an app you lent (anything else answers
outside_agent_workspace, and reads are refused the same way; scope is checked again right before every engine call);
an action never activates an app, raises a window, moves the pointer or posts a global keystroke (press answers
not_supported until keys can reach one background app); BaneySpaces ignores an app activation an agent action
caused, for the window the action worked on and only while it ran, so your workspace doesn't follow it and your own
windows of the same app still do; and every action returns what it verified from the exact window it targeted.
scripts/agent-hands-probe.swift proves the rest on your Mac: 200 actions in TextEdit (a temporary document) and
Calculator while it samples your front app, workspace, pointer, front window and any window
appearing on another workspace every 50 ms.
make build and make test build the engine first (Rust is needed once; scripts/build-engine.sh). The plan,
the rules and the phases are in docs/agent-computer-use.md.
Phones. Android phones (USB debugging on) and iPhones show in baneyspaces ls and the launcher the moment they're
plugged in. A row opens the phone's screen: scrcpy for Android, iPhone Mirroring for an iPhone.
Agents get baneyspaces phone ui (the screen's UI tree, to find a button by its text), tap,
swipe, type, key, shot and shell for Android. An iPhone is driven through its iPhone
Mirroring window: open it on the agent workspace and work it from behind like any other app.
Other machines. baneyspaces remote on lets your other machines send work to this one's
agent workspace over your tailnet: baneyspaces --on <host> agent run -- claude. It listens
only on this Mac's Tailscale address, every request needs the token from baneyspaces remote token, and a remote machine can only look and start agent work. It can't focus, type into
your terminals, open pages or move your windows. macOS's firewall has to allow BaneySpaces
incoming connections first.
BaneySpaces hides an app whose windows all sit on other workspaces, the way ⌘H does. macOS refuses background clicks and keystrokes to a hidden app, so tools that drive apps from behind can't use it until you switch back. Put the app under Settings > Automation > Keep usable by automation and its windows are parked just out of view instead, where those tools can still click and type.
Parked windows never slide across the screen: they move behind the windows of the workspace you go to, or while their app is hidden for a moment. Some apps animate every window move (Chromium browsers such as Helium take a quarter second); BaneySpaces notices that once and hides such an app as usual instead, and its menu entry says so.
make test # unit tests for the workspace model and screen math
make app # build/BaneySpaces.app
make install # build, install to ~/Applications, start
The app is signed with a local certificate that scripts/signing-identity.sh creates on first
build and keeps in its own keychain. Because the signature stays the same, macOS keeps the
Accessibility grant across rebuilds. The key is only replaced when it is truly unusable, and the
build says so, since a new key means allowing BaneySpaces again (setup's Fix Permission).
In BaneySpaces: Settings > General > Uninstall BaneySpaces…. Or in Terminal:
curl -fsSL https://raw.githubusercontent.com/baney75/baneyspaces/main/uninstall.sh | bash
Both run the same script. BaneySpaces quits first, which brings every hidden window and app back; if it won't quit, the uninstaller stops without deleting anything. Then it puts back what BaneySpaces changed:
~/.claude/settings.json: only BaneySpaces' hooks come out; your own hooks and
settings stay. Its first backup, from before BaneySpaces touched the file, stays beside it as
settings.json.baneyspaces-backup.Ghostdeck, which BaneySpaces replaced, isn't put back: the installer moved Ghostdeck.app to the Trash and its hooks became BaneySpaces' own, so both come out here.
And it removes the app, its login item, its Accessibility entry, its settings and local signing
key, the baneyspaces and ghostdeck commands in ~/.local/bin, its Grok hook file and its
agent skill. Running it twice is safe. If something can't be put back (say the app was already
emptied from the Trash, so the shortcuts can't be turned back on), it still removes the rest,
lists what needs a hand, and keeps its record of it.
MIT. See LICENSE.
No sponsors yet. Sponsor on GitHub and your name appears here automatically.
!gh baneyspaces!claude why is the sky bluecats !yt!!claude!chatgpt!pplx!grok!copilot!lechatclaude or codex and, if it's installed, the
launcher offers to start Claude Code or Codex in your terminal, in your home folder. That's
the app that opens .command files, or Ghostty, iTerm2, WezTerm or Warp when that's still
Terminal and one of them is installed.