pos (point of service) is a thin CLI that drives cmux (cmuxterm.app — an interactive terminal multiplexer / window manager, built on ghostty) on top of tmux, so your terminal workspaces mirror what you're actually focused on. It turns a pile of terminal tabs into a focus-organized cockpit: open projects by focus area, fan them across the screen, hide everything but the one thing, and keep Claude Code sessions alive across crashes and reboots.
- Repo: https://github.com/glebis/pos
- Runtime: Python ≥ 3.12, stdlib-only (uv-managed). macOS.
- Status: 193 tests green · v0.1.0
Built for a personal setup, but the patterns (cmux socket scripting, tmux-backed durability, resume-aware Claude launch) are reusable.
- Concept
- Install
- Commands
- Claude session recovery
- Screen tiling with AeroSpace
- Shell completion
- Settings
- Raycast extension
- Development
- Related
- License
- More from Gleb
┌─ cmux = COCKPIT ────────────────┐ ┌─ tmux = ENGINE ROOM ──────────┐
│ interactive, focus-organized │ → │ detached sessions that must │
│ workspaces. You live here. │ │ outlive the GUI (jobs, Claude).│
└──────────────────────────────────┘ └────────────────────────────────┘
Workspaces are backed by tmux new-session -A (attach-or-create), so re-opening re-attaches a live session and tmux-resurrect/continuum restore them across reboots. A focus.toml manifest maps focus areas → projects.
git clone https://github.com/glebis/pos && cd pos
uv tool install --editable . # installs `pos` and `pos-cc` on PATHThe manifest lives at ~/.config/personal-os/focus.toml (override with POS_MANIFEST). pos must run inside a cmux terminal (cmux's socket control mode is cmux-processes-only).
Run pos --help for the full list. Every command is also driveable from the interactive TUI.
| Command | What it does |
|---|---|
pos i (alias pos interactive) |
full-screen curses cockpit: browse focuses → projects/sessions with the arrow keys, act on a selection with one keypress, and reach any command via a : palette |
Navigate with ↑↓/j k, switch panes with →/Tab, quit with q. Keypress actions on the selection: Enter open · l load (confirms) · c Claude Code · n new workspace · r remove (confirms). Press : (or p) for a fuzzy command palette over the whole command table — anything without a hotkey runs from there. The project pane shows each repo's branch, a * dirty marker, and a ● when it has a live session.
It's TTY-only by design: piped or agent invocation exits with a message, so the JSON output of the other commands is never disturbed. Destructive actions (load, rm) confirm before running, and each action shells out through the same code path as the CLI, so output is identical.
| Command | What it does |
|---|---|
pos |
list focus areas |
pos <focus> |
load a focus: open+pin its projects, close the rest (dry-run unless --apply) |
pos load <preset|focus|names…> [--apply] |
converge the workspace to a set (never closes running jobs or scratch) |
pos p [name] |
project index; or open project <name> |
pos open <path> |
open an ad-hoc workspace at <path> |
pos day [--date YYYYMMDD] |
hybrid daily pin: focus contexts + today's active projects from the daily note |
pos status [--json] |
git status across projects, grouped by focus |
pos sidecar [url] |
add a browser (url) or terminal sidecar to the current workspace |
pos yard run|ls|attach|kill |
the tmux "yard": detached long-running jobs |
| Command | What it does |
|---|---|
pos cc <focus> |
open a Claude Code workspace for <focus> that resumes its conversation after a cmux crash or reboot (see recovery) |
pos where |
print the current workspace + its backing tmux session |
| Command | What it does |
|---|---|
pos spread |
fan every workspace into its own dedicated cmux window |
pos tile |
spread, then grid the windows across the screen via AeroSpace |
pos gather |
inverse of spread/tile — merge all windows back into one |
pos solo [name] |
UltraFocus: hide every workspace but one — the current one, or [name] if given (toggle) |
pos sort |
reorder the window so pinned workspaces sit at the top |
| Command | What it does |
|---|---|
pos new <name> [path] |
open a tmux-backed workspace (a known project uses its manifest path) |
pos rename <old> <new> |
rename a live workspace |
pos rm <name> [--force] |
close a live workspace; refuses a non-tmux-backed one without --force |
| Command | What it does |
|---|---|
pos tmuxify [--apply] |
audit which workspaces are tmux-backed; convert idle shells in place (dry-run unless --apply) |
pos config [show | <key> <value>] |
core settings; bare runs an interactive walk |
pos completions [zsh|bash|fish] |
print a shell completion script |
pos cc <focus> launches Claude via the pos-cc wrapper instead of bare claude:
- It runs
claude --continuewhen the cwd already has a stored conversation (under~/.claude/projects/<cwd>/), else a freshclaude. The cwd is the resume key — no session-id bookkeeping. - It runs claude as a child (not
exec), so tmux-resurrect'spssave-strategy capturesclaude(one level below the pane) rather than claude's MCP-server children. @resurrect-processesmaps"claude->pos-cc", so a restored Claude pane rerunspos-ccin its saved cwd → the conversation resumes instead of starting fresh.
Net effect: a reboot restores your tmux sessions and drops you back into the same Claude conversation, per project.
Each cmux internal window is a real macOS window, so a tiling WM can arrange them. pos tile fans projects into windows and asks AeroSpace to grid them. AeroSpace is optional — pos config window_manager none makes pos tile spread-only. pos gather un-tiles.
AeroSpace is a system-wide tiling WM; running it manages your whole desktop. Quit it anytime to return to normal window behaviour.
pos completions zsh > ~/.zfunc/_pos # ensure ~/.zfunc is on fpath + compinit runs
pos completions bash > ~/.local/share/bash-completion/completions/pos
pos completions fish > ~/.config/fish/completions/pos.fishCandidates are dynamic (live focuses, projects, open workspaces, settings) via a hidden pos __list <kind>.
~/.config/personal-os/settings.toml (override with POS_SETTINGS):
| key | default | choices |
|---|---|---|
window_manager |
aerospace |
aerospace, none |
tile_layout |
tiles |
tiles, accordion, horizontal, vertical |
A Raycast front-end lives in raycast/. It's a thin client over the same JSON contract the CLI exposes (pos emits JSON whenever stdout isn't a TTY), so it just shells out and renders. Three commands:
- Pos: Focuses — browse focus areas; drill into a focus's projects.
- Pos: Project Status — every project grouped by focus, with git branch + dirty marker; open, launch Claude Code, load the focus, or copy the path.
- Pos: Run Command — fuzzy-pick any
poscommand and run it; commands taking arguments prompt for them.
It needs the pos CLI on your login shell's PATH (auto-detected via zsh -lc 'command -v pos', overridable in the extension's pos binary preference) and Node ≥ 20.
The extension is pending review for the Raycast Store. Until it's accepted you can run it locally — Raycast loads it as a development extension:
git clone https://github.com/glebis/pos && cd pos/raycast
npm install
npm run dev # builds, imports into Raycast, and watches for changesOpen Raycast and search "pos" — the three commands appear (tagged Development). Keep that npm run dev running while you use it; if Raycast asks for the dev server again after a restart, just re-run it. To stop, press Ctrl-C in that terminal.
Once the Store PR is merged, install it the normal way from the Raycast Store and you won't need the dev server. See raycast/README.md for development details.
uv run pytest -q # 193 testsPure logic (argv builders, planners, parsers) is separated from side-effecting cmux calls so most of the surface is unit-tested without a live socket.
See CONTRIBUTING.md for how to propose changes, SECURITY.md to report vulnerabilities, and CHANGELOG.md for release notes.
- cmux (
cmuxterm.app, com.cmuxterm.app) — the terminal multiplexerposdrives (third-party app, built on ghostty) - tmux · tmux-resurrect · tmux-continuum
- AeroSpace — tiling WM used by
pos tile - Claude Code — what
pos cclaunches with resume
Apache-2.0 © 2026 Gleb Kalinin. See AUTHORSHIP.md for the authorship record and NOTICE for attribution. The Raycast extension under raycast/ is MIT-licensed, as the Raycast Store requires.
I build focus tools, AI workflows, and write about creativity & tech.
- claude-skills — a library of Claude Code skills