feat: add --windows layout mode (separate tmux windows per provider)#145
Open
GuolongTang111 wants to merge 11 commits intobfly123:mainfrom
Open
feat: add --windows layout mode (separate tmux windows per provider)#145GuolongTang111 wants to merge 11 commits intobfly123:mainfrom
GuolongTang111 wants to merge 11 commits intobfly123:mainfrom
Conversation
- TmuxBackend: add new_window() and focus_pane() methods - TmuxBackend: extend create_pane() with layout_mode parameter - pane_registry: add get_layout_mode() accessor - ccb: add -w/--windows CLI flag and layout_mode to AILauncher - ccb_start_config: parse "layout" field from config JSON Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- run_up(): add windows-mode branch that creates new tmux windows per provider instead of split panes, with window renaming - WezTerm guard: exit with error if --windows used with non-tmux backend - cmd pane: always splits inside anchor window, even in windows mode - _start_provider/_start_*_tmux: thread layout_mode through to create_pane - test: update fake backend to accept layout_mode parameter Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Resume: detect stored vs current layout mode mismatch, skip pane reuse and launch fresh with warning when they differ - Registry: store layout_mode in all 6 provider upsert_registry calls - Optimize: reuse early config load to avoid duplicate file reads Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Config parsing: layout field validation, defaults, case handling - Registry: get_layout_mode accessor, persistence via upsert - TmuxBackend: create_pane routing (new_window vs split_pane) - new_window: session/name flags, failure handling - focus_pane: window switching, error cases Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- README.md: add flag table entry, config example, usage tips - README_zh.md: matching Chinese translations Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- new_window(): after creating window, also creates a linked session
(tmux new-session -d -t {main} -s {main}-{provider}) and points it
at the correct window for independent attach
- destroy_linked_session(): cleanup method for linked sessions
- AILauncher: track linked_sessions list, clean up on exit and kill
- Registry: store linked_sessions field for all providers
- Tests: 6 new tests for linked session create/destroy/failure
Users can now: tmux attach -t {session}-{provider} from any terminal
to view a provider independently.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The anchor provider runs in-place and was skipped by the linked session creation loop. Now the anchor window also gets its own linked session so all providers are independently attachable. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
tmux session groups cause #{session_name} to return a linked session
name instead of the original after the first linked session is created.
This caused chained names like 19-Claude-Codex instead of 19-Codex.
Fix: query #{session_name} once before any linked sessions exist, then
reuse that value for all providers. Move linked session creation out of
new_window() into run_up() where the pre-captured name is available.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove session_name/new-session/select-window stubs that were added for linked session creation which has since been moved out of new_window(). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove layout_mode parameter from 7 _start_* method signatures; read self.layout_mode directly (cmd pane hardcodes "panes") - Extract _create_linked_session() helper to deduplicate the new-session + select-window + append logic in run_up() - Extract _registry_base() helper to deduplicate the 6 identical registry dict constructions across _write_*_session methods No logic changes -- pure structural cleanup. 292 tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move the orchestration logic from the big if/else in run_up() into PanesLayout and WindowsLayout strategy classes. Extract get_session_name, rename_window, and create_linked_session as proper TmuxBackend methods instead of raw _tmux_run calls in the main script. Linked session lifecycle is now encapsulated in WindowsLayout. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary / 概要
-w/--windowsCLI flag and"layout": "windows"config option that creates each provider in its own tmux window instead of a split pane新增
-w/--windows命令行参数及"layout": "windows"配置项,每个 provider 独占一个 tmux 窗口而非拆分面板19-Claude,19-Codex) so users cantmux attach -t <session>-<Provider>from any terminal for independent viewports每个 provider 窗口创建一个 linked tmux session(如
19-Claude、19-Codex),可在任意终端独立连接cmd(shell) pane stays in the anchor window -- no separate window for a utility shellcmd(shell)面板保留在锚点窗口中,不单独创建窗口--windowsis used outside tmuxWezTerm 防护:在非 tmux 环境下使用
--windows时给出明确错误提示恢复时检测布局模式不匹配,给出提示并重新启动,避免混合状态
PanesLayout/WindowsLayoutstrategy classes for clean separation布局逻辑抽取为
PanesLayout/WindowsLayout策略类,职责清晰分离新增 41 个单元测试,全部 309 个测试通过
Changes / 改动
lib/layout.pyPanesLayout/WindowsLayout策略类lib/terminal.pynew_window(),focus_pane(),destroy_linked_session(),get_session_name(),rename_window(),create_linked_session()方法;create_pane()新增 layout_mode 参数lib/pane_registry.pyget_layout_mode()访问器lib/ccb_start_config.py"layout"字段解析与校验ccb--windows参数、AILauncher 管线、策略驱动的run_up()、WezTerm 防护、恢复不匹配检测、registry 写入 layout_mode、退出/kill 时清理 linked sessionstest/test_windows_layout.pytest/test_ccb_tmux_split.pyREADME.md/README_zh.mdBackwards compatible / 向后兼容
Default behavior unchanged --
layoutdefaults to"panes".默认行为不变,
layout默认值为"panes"。Test plan / 测试计划
test_windows_layout.py/ 41 个专项测试ccb start -w codex geminicreates separate tmux windows / 手动验证创建独立窗口tmux attach -t <session>-Codexattaches to individual provider / 手动验证独立连接ccb start codex gemini(without -w) still uses split panes / 手动验证默认仍为面板模式🤖 Generated with Claude Code