{"id":48810328,"url":"https://github.com/joeyism/opencode-multiplexer-rs","last_synced_at":"2026-05-10T03:00:09.103Z","repository":{"id":351207743,"uuid":"1205549865","full_name":"joeyism/opencode-multiplexer-rs","owner":"joeyism","description":"Opencode Multiplexer","archived":false,"fork":false,"pushed_at":"2026-04-14T02:38:12.000Z","size":97,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-14T04:24:24.861Z","etag":null,"topics":["cargo","multiplexer","opencode","opencode-ai","opencode-plugin","rust","tui"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/joeyism.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-09T04:10:05.000Z","updated_at":"2026-04-14T02:37:51.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/joeyism/opencode-multiplexer-rs","commit_stats":null,"previous_names":["joeyism/opencode-multiplexer-rs"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/joeyism/opencode-multiplexer-rs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joeyism%2Fopencode-multiplexer-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joeyism%2Fopencode-multiplexer-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joeyism%2Fopencode-multiplexer-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joeyism%2Fopencode-multiplexer-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/joeyism","download_url":"https://codeload.github.com/joeyism/opencode-multiplexer-rs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joeyism%2Fopencode-multiplexer-rs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31785681,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T02:24:21.117Z","status":"ssl_error","status_checked_at":"2026-04-14T02:24:20.627Z","response_time":153,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cargo","multiplexer","opencode","opencode-ai","opencode-plugin","rust","tui"],"created_at":"2026-04-14T07:00:53.276Z","updated_at":"2026-05-10T03:00:09.089Z","avatar_url":"https://github.com/joeyism.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ocmux - Opencode Multiplexer\n\nA terminal multiplexer for managing [OpenCode](https://opencode.ai) sessions.\n\n\u003cp align=\"center\" width=\"100%\"\u003e\n\u003cvideo src=\"https://github.com/user-attachments/assets/93669f30-bb6c-4a71-935d-29541ee073ad\" width=\"80%\" controls\u003e\u003c/video\u003e\n\u003c/p\u003e\n\n## Feature Showcase\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eDiff View\u003c/b\u003e\u003c/summary\u003e\n\u003cp align=\"center\" width=\"100%\"\u003e\n\u003cvideo src=\"https://github.com/user-attachments/assets/70cc5f29-118c-4d96-b611-a7192d246205\" width=\"80%\" controls\u003e\u003c/video\u003e\n\u003c/p\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eVisual Mode\u003c/b\u003e\u003c/summary\u003e\n\u003cp align=\"center\" width=\"100%\"\u003e\n\u003cvideo src=\"https://github.com/user-attachments/assets/ac156ecc-e8b8-47ee-8bd0-7a0815b5b836\" width=\"80%\" controls\u003e\u003c/video\u003e\n\u003c/p\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eSidebar Layouts\u003c/b\u003e\u003c/summary\u003e\n\u003cp align=\"center\" width=\"100%\"\u003e\n\u003cvideo src=\"https://github.com/user-attachments/assets/2b2b4c2e-0739-4009-99bb-62e9de0d67f7\" width=\"80%\" controls\u003e\u003c/video\u003e\n\u003c/p\u003e\n\u003c/details\u003e\n\n## Table of Contents\n- [Install](#install)\n- [Usage](#usage)\n- [Keybindings](#keybindings)\n  - [Sidebar navigation](#sidebar-navigation)\n  - [Session actions](#session-actions)\n  - [Session picker](#session-picker)\n  - [Message history picker](#message-history-picker)\n  - [Conversation view](#conversation-view)\n  - [Diff view](#diff-view)\n  - [Visual mode](#visual-mode)\n  - [Shell mode](#shell-mode)\n  - [Sidebar layout](#sidebar-layout)\n- [Advanced workflows](#advanced-workflows)\n- [System behaviors](#system-behaviors)\n- [Configuration](#configuration)\n- [Notes](#notes)\n- [License](#license)\n\n## Install\n\n**Cargo:**\n\n```\ncargo install opencode-multiplexer\n```\n\n**Homebrew:**\n\n```\nbrew tap joeyism/ocmux\nbrew install ocmux\n```\n\n**Shell (macOS / Linux):**\n\n```\ncurl --proto '=https' --tlsv1.2 -LsSf https://github.com/joeyism/ocmux-rs/releases/latest/download/ocmux-rs-installer.sh | sh\n```\n\n## Usage\n\nRun `ocmux` in your terminal. The sidebar lists active OpenCode sessions sorted by most recently updated. The main pane shows the attached session's terminal output.\n\n- Press `Enter` to attach to a top-level session\n- Press `Tab` to expand/collapse child sessions\n- Press `v` to open a read-only conversation view (see below)\n- Press `s` to collapse the sidebar for more screen space\n- Click a sidebar row to select it\n\n## Keybindings\n\n### Sidebar navigation\n\n| Key      | Action                    |\n|----------|---------------------------|\n| `j` / `Down` | Move down             |\n| `k` / `Up`   | Move up               |\n| `Enter`  | Attach to session        |\n| `Tab`    | Expand/collapse children |\n| `s`      | Toggle sidebar collapse  |\n| `Ctrl-h` | Hide/show sidebar panel  |\n| `/`      | Open session picker     |\n| `r`      | Refresh active session   |\n| `?`      | Show help overlay        |\n| `q`      | Quit (confirm with `y`) |\n| `Ctrl-4` | Toggle focus sidebar/main |\n\n### Session actions\n\n| Key | Action                                |\n|-----|---------------------------------------|\n| `n` | Spawn new session                     |\n| `t` | Create git worktree + spawn           |\n| `v` | Open read-only conversation view       |\n| `d` | Open diff view for session             |\n| `f` | Show files modified by session        |\n| `!` | Drop into shell in session directory   |\n| `c` | Commit/push modified files            |\n| `h` | Open message history picker           |\n| `x` | Kill session (`y` confirm, `n`/`Esc` cancel) |\n\n### Session picker\n\nPress `/` to search and attach to any opencode session. The picker uses **fuzzy search** across repo, title, and directory fields. Live sessions (currently running) are marked with a green dot (`●`).\n\n| Key      | Action                    |\n|----------|---------------------------|\n| `↑` / `↓` | Move through list       |\n| `Enter`  | Attach to selected        |\n| `Backspace` | Delete last character |\n| any key  | Filter by fuzzy match     |\n| `Esc`    | Cancel picker            |\n\nThe footer shows `matched/total` counts. Results are sorted by live status first, then fuzzy match score, then recency.\n\n### Message history picker\n\nPress `h` to search past user messages and paste one into the active terminal session. The picker uses **fuzzy search** across session title and message text. The top table shows session name and message preview; selecting a row shows the full message below.\n\n| Key      | Action                    |\n|----------|---------------------------|\n| `↑` / `↓` | Move through list       |\n| `Enter`  | Paste selected message    |\n| `Backspace` | Delete last character |\n| any key  | Filter by fuzzy match     |\n| `Esc`    | Cancel picker            |\n\nThe footer shows `matched/total` counts. Results are sorted by fuzzy match score, then recency.\n\n### Conversation view\n\nPress `v` from the sidebar to open a read-only view of the session's conversation history. The view polls the opencode database every second and renders messages, markdown, syntax-highlighted code blocks, and tool call status.\n\n| Key      | Action                    |\n|----------|---------------------------|\n| `j` / `Down` | Scroll down           |\n| `k` / `Up`   | Scroll up             |\n| `G`      | Jump to end               |\n| `g`      | Jump to top               |\n| `Ctrl-u` | Page up                   |\n| `Ctrl-d` | Page down                 |\n| `/`      | Search conversation       |\n| `n`      | Next search match         |\n| `N`      | Previous search match     |\n| `q` / `v` / `Esc` | Close view       |\n\n**Auto-follow:** By default, the view stays at the bottom and scrolls automatically as new messages arrive. Scrolling up manually disengages follow mode. Jump to end (`G`) or page down at the bottom (`Ctrl-d`) to resume following.\n\n**Search:** Search is case-insensitive and incremental — type to filter, `Enter` to confirm. The search bar shows current match position (`1/5`). Pressing `/` again or `Esc` cancels.\n\nMouse scroll is supported.\n\n### Diff view\n\u003cp align=\"center\" width=\"100%\"\u003e\n\u003cvideo src=\"https://github.com/user-attachments/assets/70cc5f29-118c-4d96-b611-a7192d246205\" width=\"80%\" controls\u003e\u003c/video\u003e\n\u003c/p\u003e\n\nPress `d` from the sidebar to open a read-only view of the session's git diff. The view shows both tracked and untracked changes, preferring the opencode serve API when available and falling back to `git diff` otherwise.\n\nThe diff view uses a **cursor-based** navigation model (distinct from the scroll-based conversation view). The cursor determines the position for visual selection.\n\n| Key      | Action                    |\n|----------|---------------------------|\n| `j` / `Down` | Move cursor down      |\n| `k` / `Up`   | Move cursor up        |\n| `G`      | Jump to end               |\n| `g`      | Jump to top               |\n| `Ctrl-u` | Page up                   |\n| `Ctrl-d` | Page down                 |\n| `/`      | Search diff               |\n| `n`      | Next search match         |\n| `N`      | Previous search match     |\n| `v`      | Toggle visual selection   |\n| `Enter`  | Confirm selection \u0026 paste |\n| `Esc`    | Cancel selection / close  |\n| `q` / `d`| Close view                |\n\n**Search:** Case-insensitive, incremental. The search bar shows current/total matches. The `/` key is disabled while visual mode is active — cancel visual mode first to search.\n\nMouse scroll is supported.\n\n### Visual mode\n\u003cp align=\"center\" width=\"100%\"\u003e\n\u003cvideo src=\"https://github.com/user-attachments/assets/ac156ecc-e8b8-47ee-8bd0-7a0815b5b836\" width=\"80%\" controls\u003e\u003c/video\u003e\n\u003c/p\u003e\n\nVisual mode lets you select lines from the diff view and paste them as file references into the active terminal session.\n\nPress `v` from the diff view to enter visual mode. The current cursor line is marked as the anchor. Use `j`/`k` to move the cursor and highlight lines. Press `Enter` to confirm — this closes the diff, returns to the terminal, and pastes the selected lines into the chatbox.\n\n**Selection formatting:** Lines are grouped by file and formatted as `filepath:line` or `filepath:start-end` (e.g., `foo.rs:42-58`). Deleted files (`/dev/null`) are skipped. If the selection spans multiple files, each gets its own reference separated by spaces.\n\n| Key | Action |\n|-----|--------|\n| `v` | Toggle visual mode on/off |\n| `j` / `k` | Move cursor to expand/contract selection |\n| `Enter` | Confirm and paste into terminal |\n| `Esc` | Cancel visual mode (stays in diff view) |\n\n- Search (`/`) is disabled while visual mode is active\n- If no valid file references are in the selection, nothing is pasted\n\n### Shell mode\n\nPress `!` from the sidebar to drop into a shell in the selected session's working directory. The shell inherits the session's environment variables. Exit the shell normally (e.g., `exit` or `Ctrl-D`) to return to ocmux.\n\nThis works on **top-level sessions only** — child sessions do not support shell drop.\n\n### Sidebar layout\n\n\u003cp align=\"center\" width=\"100%\"\u003e\n\u003cvideo src=\"https://github.com/user-attachments/assets/2b2b4c2e-0739-4009-99bb-62e9de0d67f7\" width=\"80%\" controls\u003e\u003c/video\u003e\n\u003c/p\u003e\n\nThe sidebar has three states:\n\n| State | Key | Behavior |\n|-------|-----|----------|\n| Expanded | (default) | Full-width sidebar showing session tree, title, and status |\n| Collapsed | `s` | Sidebar shrinks to a narrow width (12 columns), showing only session names |\n| Hidden | `Ctrl-h` | Sidebar disappears entirely for maximum terminal space |\n\n- Toggle between expanded and collapsed with `s`\n- Toggle hidden with `Ctrl-h`\n- When the sidebar is hidden, `Ctrl-4` (focus toggle) will first unhide it before switching focus\n- The sidebar width when expanded is configurable via `sidebar_width` in config (default: 30)\n\n## Advanced workflows\n\n- **Inspect conversation output** — press `v` on any session (including child sessions) to watch the agent's progress in real-time without attaching to the PTY\n- **Inspect changed files** — press `d` to open a diff view of all changes made by a session (tracked and untracked)\n- **Inspect changed files (list)** — press `f` to see which files a session has created or modified. Press any key or `Esc` to close.\n- **Drop into a shell** — press `!` to open a shell in the selected session's working directory. The shell inherits the session's environment; exiting the shell returns to ocmux.\n- **Commit session changes** — press `c` to prompted for a commit message, then commit and push all modified files immediately.\n- **Search and attach** — press `/` to open the session picker, search across all opencode sessions, and attach to one.\n- **Reuse an earlier prompt** — press `h` to open the message history picker, search past user messages, and paste one into the active terminal session.\n- **Create a worktree** — press `t` to pick a repo directory, then enter a branch name (leave empty to spawn in the repo root without a worktree). A new worktree is created and a session is spawned in it.\n- **Spawn a session** — press `n` to pick a repo from discovered git repositories (see Configuration for search paths and depth), then spawn a new managed session in that directory.\n\n## System behaviors\n\n**Focus tracking** — When the ocmux window loses OS focus, the border dims to dark gray. When focus returns, the border resumes normal styling.\n\n**Sidebar sync** — When focus is on the terminal (attached session), the sidebar selection automatically tracks the active session. If the attached session exits, focus returns to the sidebar with a \"session exited\" footer message.\n\n**Notifications** — When `notifications: true` in config, ocmux sends desktop alerts on specific session transitions: `Working → Idle`, `Working → NeedsInput`, `Working → Error`. Each session has a 5-second cooldown between notifications. On macOS, `notify-rust` is used (which respects Do Not Disturb / Focus modes). On Linux, `notify-send` is used as a fallback. Notifications are suppressed while ocmux is the focused window.\n\n**Terminal features** — ocmux supports bracketed paste (safe paste of multi-line content), full special-key forwarding (arrows, Home, End, PageUp, PageDown, F-keys, etc.), and proper terminal resize on window changes.\n\n## Configuration\n\nKeybindings, sidebar width, desktop notifications, and repo search depth are configurable via `~/.config/ocmux/config.json`:\n\n```json\n{\n  \"sidebar_width\": 30,\n  \"notifications\": true,\n  \"spawn_maxdepth\": 5,\n  \"keybindings\": {\n    \"up\": \"k\",\n    \"down\": \"j\",\n    \"spawn\": \"n\",\n    \"kill\": \"x\",\n    \"help\": \"?\",\n    \"worktree\": \"t\",\n    \"quit\": \"q\",\n    \"view\": \"v\",\n    \"files\": \"f\",\n    \"diff\": \"d\",\n    \"history\": \"h\"\n  }\n}\n```\n\nKeybinding values are single characters. Default `sidebar_width` is `30`. Only the keys listed above are configurable; other bindings (`Enter`, `Tab`, `/`, `s`, `Ctrl-h`, `r`, `!`, `c`, `Ctrl-4`, arrows) are fixed.\n\n`notifications` controls desktop alerts. Defaults to `true`.\n\n`spawn_maxdepth` controls how deep `find` searches for git repos when spawning or creating worktrees. It searches `~/Programming`, `~/repos`, `~/projects`, and `~/code` (falling back to `~` if none exist). Defaults to `5`.\n\n## Notes\n\n- `Ctrl-4` is the actual focus toggle binding (hold `Ctrl` and press `4`)\n- `s` collapses the sidebar to a narrow width; `Ctrl-h` hides it entirely for maximum terminal space\n- `q` prompts for confirmation before quitting (`y` confirm, `n`/`Esc` cancel)\n- Child sessions are expandable and selectable in the sidebar, but `Enter` attach is not yet supported for child rows — use `v` to view their conversation instead\n- `c` and `!` operate on top-level sessions only\n- `r` refreshes the currently active session's PTY, not the selected sidebar row\n- Killing a managed session (`x`) also terminates its associated opencode serve daemon\n\n## License\n\nApache-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoeyism%2Fopencode-multiplexer-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoeyism%2Fopencode-multiplexer-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoeyism%2Fopencode-multiplexer-rs/lists"}