cmux/tests_v2
Lawrence Chen 84af32c56e
Add cmux omo command for oh-my-openagent integration (#2087)
* Add `cmux omo` command for OpenCode + oh-my-openagent integration

Same pattern as `cmux claude-teams`: creates a tmux shim so
oh-my-openagent's TmuxSessionManager spawns agents as native cmux
splits instead of tmux panes. Sets TMUX/TMUX_PANE env vars, prepends
shim to PATH, and execs into opencode.

Closes https://github.com/manaflow-ai/cmux/issues/2085

* Auto-install oh-my-opencode plugin when running cmux omo

Before launching opencode, cmux omo now:
- Checks if oh-my-opencode is registered in ~/.config/opencode/opencode.json
- If not, creates/updates the config with the plugin entry
- Checks if the npm package is installed in node_modules
- If not, runs bun add (or npm install) to install it
- Then proceeds with tmux shim setup and exec

* Use shadow config dir to avoid modifying user's opencode setup

Instead of writing directly to ~/.config/opencode/opencode.json,
cmux omo now creates a shadow config at ~/.cmuxterm/omo-config/ that
layers oh-my-opencode on top of the user's existing config. Symlinks
node_modules, package.json, bun.lock, and plugin config from the
original dir. Sets OPENCODE_CONFIG_DIR to the shadow directory.

Running plain `opencode` remains unaffected.

* Add Agent Integrations docs section with Claude Code Teams and oh-my-opencode pages

Adds sectioned sidebar navigation to the docs site. The new Agent
Integrations section contains separate pages for cmux claude-teams and
cmux omo, documenting usage, tmux shim mechanics, directory layout,
environment variables, and the shadow config approach. Both pages
include a nightly-only warning. Full English and Japanese translations,
nav item keys added to all 19 locales.

* Remove uppercase from sidebar section headers

* Add more spacing above and below sidebar section headers

* Enable tmux mode in oh-my-opencode config, improve docs

- cmux omo now writes tmux.enabled=true to the shadow oh-my-opencode.json
  config. Without this, oh-my-openagent's TmuxSessionManager won't spawn
  visual panes even though $TMUX is set (the config defaults to false).
- Nightly warnings now link to /nightly instead of generic text.
- Added "What you get" section to oh-my-opencode docs explaining the
  visual pane behavior (auto-layout, idle cleanup, queueing).
- Added tmux.enabled step to first-run and how-it-works sections.

* Add terminal-notifier shim to route oh-my-openagent notifications to cmux

oh-my-openagent sends macOS notifications via terminal-notifier
(args: -title <t> -message <m> [-activate <id>]). The shim in
~/.cmuxterm/omo-bin/terminal-notifier intercepts these calls and
routes them through cmux notify, so notifications appear in cmux's
sidebar panel instead of as raw macOS notifications.

* Add pane geometry to tmux-compat for oh-my-openagent grid planning

oh-my-openagent's TmuxSessionManager needs pane geometry (columns,
rows, position, window dimensions) to decide where to spawn agent
panes. Without this data, agents run headlessly.

Server side:
- pane.list v2 response now includes pixel_frame, cell_size, columns,
  rows per pane, plus container_frame at the top level
- Uses BonsplitController.layoutSnapshot() for pixel geometry and
  ghostty_surface_size() for terminal grid dimensions

CLI side:
- tmuxEnrichContextWithGeometry() computes character-cell positions
  from pixel frames and cell dimensions for tmux format variables
  (pane_width, pane_height, pane_left, pane_top, pane_active,
  window_width, window_height)
- list-panes now resolves pane targets (%uuid) via tmuxResolvePaneTarget
  instead of failing with "Workspace not found"
- display-message enriched with geometry for format strings like
  #{pane_width},#{window_width}
- tmux -V now returns "tmux 3.4" (needed by oh-my-openagent's
  tmux-path-resolver verification)

* Add socket tests for tmux-compat pane geometry

6 tests verifying the geometry enrichment works end-to-end:
- pane.list returns pixel_frame, columns, rows, cell_size, container_frame
- tmux -V returns version string
- list-panes -F renders geometry format variables as integers
- list-panes -t %<uuid> resolves pane targets
- display -p renders pane_width and window_width
- After split, two panes have different positions and halved widths

All 6 pass on macmini (cmux-macmini).

* Handle tmux -V in shim script directly (no socket needed)

oh-my-openagent's tmux-path-resolver runs tmux -V to verify the binary
works. The __tmux-compat handler requires a socket connection, which
may not be established at verification time. Handle -V in the bash
shim directly to avoid the socket dependency.

* Lower default tmux pane min widths for cmux omo

oh-my-openagent defaults: main_pane_min_width=120, agent_pane_min_width=40,
requiring 161+ columns. Most terminal windows are narrower, causing
decideSpawnActions to return canSpawn=false and defer agents forever.

cmux omo now sets: main_pane_min_width=60, agent_pane_min_width=30,
main_pane_size=50, requiring only 91 columns. Also moved tmux -V
handling into the bash shim to avoid needing a socket connection for
the version check.

* Resolve merge conflicts with main (main-vertical layout, focus param)

- Keep upstream main-vertical layout anchoring from #2119
- Keep upstream focus param (v2Bool) instead of no_focus
- Combine with our -d flag handling: -d sets focus=false
- Include customCommands nav item from main

* Implement select-layout equalize and resize-pane absolute width

When oh-my-openagent spawns agent panes, it calls select-layout
main-vertical after each split to redistribute panes evenly, then
resize-pane -x <columns> to set the main pane width. Both were
previously no-ops, causing cascading uneven splits.

Server side:
- Add workspace.equalize_splits v2 API that calls the existing
  TabManager.equalizeSplits (sets all dividers to 0.5)

CLI side:
- select-layout now calls workspace.equalize_splits before tracking
  main-vertical state
- resize-pane -x <columns> without directional flags now computes
  the pixel delta from current to desired width and resizes accordingly

* Fix equalize to use proportional divider positions

The previous equalize set all dividers to 0.5, which in a right-
recursive binary tree (from successive splits) gives 50/25/12.5/6.25%
instead of equal sizes.

New algorithm counts leaf panes on each side of each split and sets
the divider to N_left / (N_left + N_right). For 5 panes in a chain:
1/5, 1/4, 1/3, 1/2, giving each pane exactly 20%.

* Fix select-layout main-vertical to only equalize vertical splits

The proportional equalize was treating the top-level horizontal split
(main vs agent column) the same as vertical splits, setting the main
pane to 1/6 of the window with 5 agents.

For main-vertical layout, only equalize vertical splits (the agent
column), leaving the horizontal main/agent divider untouched. The
subsequent resize-pane -x handles the main pane width.

workspace.equalize_splits now accepts an optional orientation filter
("vertical" or "horizontal") to scope which splits get equalized.

* Re-equalize agent column after kill-pane

* Address PR review comments

- Fix cmux omo --help: remove omo from the help-bypass guard so
  --help shows usage text instead of trying to launch opencode
- Don't overwrite unreadable opencode.json: fail with an error
  instead of silently resetting to empty config
- Drain installer pipes concurrently before waitUntilExit to
  prevent deadlock from full pipe buffers during bun/npm install

---------

Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
2026-03-26 16:07:59 -07:00
..
cmux.py Fallback stable socket listener to a user-scoped path (#1351) 2026-03-13 17:37:01 -07:00
pane_resize_test_support.py Fix ssh stack review regressions 2026-03-13 04:14:52 -07:00
test_browser_api_comprehensive.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_browser_api_extended_families.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_browser_api_p0.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_browser_api_unsupported_matrix.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_browser_cli_agent_port.py Merge pull request #972 from manaflow-ai/task-browser-open-trailing-json-flags 2026-03-05 22:39:14 -08:00
test_browser_cli_wait_and_screenshot.py Fix browser screenshot to return image URL (#936) 2026-03-05 19:09:29 -08:00
test_browser_custom_keybinds.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_browser_devtools_visibility_stability.py works 2026-03-10 19:18:30 -07:00
test_browser_file_url_load.py Fix local HTML file routing in open wrapper (#684) 2026-02-28 19:08:39 -08:00
test_browser_goto_split.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_browser_open_split_reuse_policy.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_browser_panel_stability.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_cli_browser_console_errors_text.py Add ssh stack regression tests 2026-03-13 07:29:18 -07:00
test_cli_global_flags_and_v1_error_contract.py Fix ssh stack review regressions 2026-03-13 04:14:52 -07:00
test_cli_id_format_defaults.py Remove index-based CLI APIs, make commands workspace-relative (#89) 2026-02-18 22:50:02 -08:00
test_cli_identify_ref_resolution.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_cli_new_workspace_background_metadata.py Fix background terminal startup for unfocused workspaces (#920) 2026-03-04 19:21:32 -08:00
test_cli_new_workspace_command_queue.py Start workspace command process before workspace is opened 2026-02-21 05:06:29 -08:00
test_cli_new_workspace_external_git_branch_refresh.py Address PR review feedback 2026-03-05 23:09:45 -08:00
test_cli_non_focus_commands_preserve_workspace.py Socket CLI: prevent focus stealing + add rename-tab and focus regressions 2026-02-21 02:21:27 -08:00
test_cli_sidebar_metadata_commands.py Add ssh stack regression tests 2026-03-13 07:29:18 -07:00
test_close_surface_selection.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_close_workspace_selection.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_command_palette_backspace_go_back.py Add command palette (Cmd+Shift+P) (#358) 2026-02-23 03:26:36 -08:00
test_command_palette_focus.py Add command palette (Cmd+Shift+P) (#358) 2026-02-23 03:26:36 -08:00
test_command_palette_focus_lock_workspace_spawn.py Add command palette (Cmd+Shift+P) (#358) 2026-02-23 03:26:36 -08:00
test_command_palette_fuzzy_ranking.py Add command palette (Cmd+Shift+P) (#358) 2026-02-23 03:26:36 -08:00
test_command_palette_modes.py Add command palette (Cmd+Shift+P) (#358) 2026-02-23 03:26:36 -08:00
test_command_palette_navigation_keys.py Add command palette (Cmd+Shift+P) (#358) 2026-02-23 03:26:36 -08:00
test_command_palette_rename_enter.py Add command palette (Cmd+Shift+P) (#358) 2026-02-23 03:26:36 -08:00
test_command_palette_rename_select_all.py Add command palette (Cmd+Shift+P) (#358) 2026-02-23 03:26:36 -08:00
test_command_palette_search_action_sync.py Add command palette (Cmd+Shift+P) (#358) 2026-02-23 03:26:36 -08:00
test_command_palette_search_typing_stability.py Add command palette (Cmd+Shift+P) (#358) 2026-02-23 03:26:36 -08:00
test_command_palette_shortcut_hint_sync.py Command palette caret uses white tint (#361) 2026-02-23 04:08:01 -08:00
test_command_palette_switcher_all_windows.py Show Cmd+P switcher results across all windows 2026-02-23 04:13:15 -08:00
test_command_palette_switcher_cross_workspace_surface_focus.py Add command palette (Cmd+Shift+P) (#358) 2026-02-23 03:26:36 -08:00
test_command_palette_switcher_renamed_surface.py Add command palette (Cmd+Shift+P) (#358) 2026-02-23 03:26:36 -08:00
test_command_palette_switcher_surface_precedence.py Add command palette (Cmd+Shift+P) (#358) 2026-02-23 03:26:36 -08:00
test_command_palette_switcher_type_labels.py Add command palette (Cmd+Shift+P) (#358) 2026-02-23 03:26:36 -08:00
test_command_palette_window_scope.py Fix Cmd+P/Cmd+Shift+P window routing (#413) 2026-02-23 20:08:21 -08:00
test_cpu_notifications.py Fallback stable socket listener to a user-scoped path (#1351) 2026-03-13 17:37:01 -07:00
test_cpu_usage.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_ctrl_enter_keybind.py Fallback stable socket listener to a user-scoped path (#1351) 2026-03-13 17:37:01 -07:00
test_ctrl_interactive.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_ctrl_socket.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_focus_notification_dismiss.py Revert "Fix notification unread persistence when workspaces regain focus (#971)" (#992) 2026-03-05 21:31:13 -08:00
test_initial_terminal_interactive_and_rendering.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_lint_swiftui_patterns.py Command palette caret uses white tint (#361) 2026-02-23 04:08:01 -08:00
test_nested_split_does_not_disappear.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_nested_split_no_arranged_subview_underflow.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_nested_split_no_detach_during_update.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_nested_split_panel_routing.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_nested_split_preserves_existing_split.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_new_tab_interactive_after_splits.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_new_tab_render_after_splits.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_notifications.py Revert "Fix notification unread persistence when workspaces regain focus (#971)" (#992) 2026-03-05 21:31:13 -08:00
test_pane_break_swap_preserve_focus.py Merge origin/main into pr-ssh-stack-main 2026-03-13 06:25:08 -07:00
test_pane_resize_preserves_ls_scrollback.py Fix ssh stack review regressions 2026-03-13 04:14:52 -07:00
test_pane_resize_preserves_visible_content.py Fix ssh stack review regressions 2026-03-13 04:14:52 -07:00
test_read_screen_capture_pane_parity.py Fix workspace routing for surface.read_text 2026-02-20 16:31:48 -08:00
test_rename_tab_cli_parity.py Reapply "Merge pull request #239 from manaflow-ai/issue-151-ssh-remote-port-proxying" 2026-03-12 15:54:26 -07:00
test_rename_window_workspace_parity.py Socket CLI: prevent focus stealing + add rename-tab and focus regressions 2026-02-21 02:21:27 -08:00
test_shortcut_window_scope.py Add command palette (Cmd+Shift+P) (#358) 2026-02-23 03:26:36 -08:00
test_signals_auto.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_split_cmd_d_ctrl_d_geometry_fuzz.py Add VM split-churn fuzz tests and harden portal reveal gating 2026-02-23 15:28:23 -08:00
test_split_cmd_d_ctrl_d_two_pane_frame_guard.py Add VM split-churn fuzz tests and harden portal reveal gating 2026-02-23 15:28:23 -08:00
test_split_cmd_shift_d_ctrl_d_no_portal_orphans.py Fix ghost terminal surface rebind after close (#808) 2026-03-03 15:20:42 -08:00
test_split_flash_and_layout.py Fix split blackout race and stabilize focus handoff 2026-02-19 17:10:27 -08:00
test_ssh_remote_browser_favicon_uses_proxy.py Add remote favicon proxy regression 2026-03-13 06:15:23 -07:00
test_ssh_remote_browser_move_rebinds_proxy.py Reapply "Merge pull request #239 from manaflow-ai/issue-151-ssh-remote-port-proxying" 2026-03-12 15:54:26 -07:00
test_ssh_remote_cli_metadata.py Fix ssh stack review regressions 2026-03-13 04:14:52 -07:00
test_ssh_remote_cli_relay.py Fix ssh stack review regressions 2026-03-13 04:14:52 -07:00
test_ssh_remote_daemon_resize_stdio.py Fix ssh stack review regressions 2026-03-13 04:14:52 -07:00
test_ssh_remote_docker_bootstrap_nonlogin_shell.py Reapply "Merge pull request #239 from manaflow-ai/issue-151-ssh-remote-port-proxying" 2026-03-12 15:54:26 -07:00
test_ssh_remote_docker_forwarding.py Reapply "Merge pull request #239 from manaflow-ai/issue-151-ssh-remote-port-proxying" 2026-03-12 15:54:26 -07:00
test_ssh_remote_docker_reconnect.py Reapply "Merge pull request #239 from manaflow-ai/issue-151-ssh-remote-port-proxying" 2026-03-12 15:54:26 -07:00
test_ssh_remote_interactive_cmux_command_regression.py Add ssh profile-noise regression 2026-03-13 07:08:09 -07:00
test_ssh_remote_last_surface_clears_remote_state.py Reapply "Merge pull request #239 from manaflow-ai/issue-151-ssh-remote-port-proxying" 2026-03-12 15:54:26 -07:00
test_ssh_remote_proxy_bind_conflict.py Fix ssh stack review regressions 2026-03-13 04:14:52 -07:00
test_ssh_remote_resize_scrollback_regression.py Reapply "Merge pull request #239 from manaflow-ai/issue-151-ssh-remote-port-proxying" 2026-03-12 15:54:26 -07:00
test_ssh_remote_second_session_mux_regression.py Fix ssh stack review regressions 2026-03-13 04:14:52 -07:00
test_ssh_remote_shell_integration.py Reapply "Merge pull request #239 from manaflow-ai/issue-151-ssh-remote-port-proxying" 2026-03-12 15:54:26 -07:00
test_ssh_remote_shortcuts_stay_remote.py Reapply "Merge pull request #239 from manaflow-ai/issue-151-ssh-remote-port-proxying" 2026-03-12 15:54:26 -07:00
test_surface_list_custom_titles.py Merge origin/main into pr-ssh-stack-main 2026-03-13 06:25:08 -07:00
test_surface_move_reorder_api.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_tab_dragging.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_tab_workspace_action_naming.py Fix Mark Tab as Unread no-op on focused tab (#249) 2026-02-20 23:07:52 -08:00
test_terminal_focus_routing.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_terminal_input_render_report.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_tmux_compat_geometry.py Add cmux omo command for oh-my-openagent integration (#2087) 2026-03-26 16:07:59 -07:00
test_tmux_compat_matrix.py Implement pane.resize divider control and verify in tmux matrix test (#223) 2026-02-20 18:40:37 -08:00
test_trigger_flash.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_update_timing.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_v1_panel_creation_preserves_focus.py Add regressions for v1 panel focus preservation 2026-03-13 21:55:45 -07:00
test_visual_screenshots.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_visual_typing_char_by_char.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_windows_api.py Fix frozen terminals after split churn (#12) 2026-02-13 16:45:31 -08:00
test_workspace_create_background_starts_terminal.py Fix SSH workspace priming and restore state 2026-03-13 20:01:26 -07:00
test_workspace_create_initial_env.py Reapply "Merge pull request #239 from manaflow-ai/issue-151-ssh-remote-port-proxying" 2026-03-12 15:54:26 -07:00
test_workspace_relative.py Remove index-based CLI APIs, make commands workspace-relative (#89) 2026-02-18 22:50:02 -08:00