railmux 0.4.0.dev11__tar.gz → 0.4.0.dev13__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. {railmux-0.4.0.dev11/src/railmux.egg-info → railmux-0.4.0.dev13}/PKG-INFO +10 -4
  2. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/README.md +9 -3
  3. railmux-0.4.0.dev13/src/railmux/__init__.py +1 -0
  4. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/fast_display_server.py +29 -8
  5. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/tmux_ctl.py +8 -10
  6. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/tmux_server.py +41 -6
  7. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/ui/app.py +348 -145
  8. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/windows_install_log.py +16 -0
  9. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/windows_msys2.py +83 -10
  10. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13/src/railmux.egg-info}/PKG-INFO +10 -4
  11. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_codex_delete.py +134 -39
  12. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_codex_lineage.py +59 -11
  13. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_fast_full_window.py +73 -0
  14. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_focus_highlight.py +23 -3
  15. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_statusbar.py +25 -0
  16. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_tmux_ctl.py +4 -7
  17. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_tmux_integration.py +14 -6
  18. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_tmux_server.py +48 -0
  19. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_windows_install_log.py +13 -0
  20. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_windows_msys2.py +230 -6
  21. railmux-0.4.0.dev11/src/railmux/__init__.py +0 -1
  22. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/LICENSE +0 -0
  23. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/MANIFEST.in +0 -0
  24. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/pyproject.toml +0 -0
  25. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/setup.cfg +0 -0
  26. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/__main__.py +0 -0
  27. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/atomic_file.py +0 -0
  28. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/background_index.py +0 -0
  29. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/cli.py +0 -0
  30. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/codex_index.py +0 -0
  31. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/config.py +0 -0
  32. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/config_cli.py +0 -0
  33. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/diagnostics.py +0 -0
  34. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/discovery.py +0 -0
  35. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/display_transport.py +0 -0
  36. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/entrypoint.py +0 -0
  37. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/fast_display_client.py +0 -0
  38. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/fast_display_history.py +0 -0
  39. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/fast_display_input.py +0 -0
  40. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/fast_display_protocol.py +0 -0
  41. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/favorites.py +0 -0
  42. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/fuzzy.py +0 -0
  43. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/help_workspace.py +0 -0
  44. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/launcher.py +0 -0
  45. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/legacy_sessions.py +0 -0
  46. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/local_clipboard.py +0 -0
  47. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/local_open.py +0 -0
  48. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/models.py +0 -0
  49. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/modes.py +0 -0
  50. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/mouse_manager.py +0 -0
  51. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/orphan_marker.py +0 -0
  52. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/pane_surface.py +0 -0
  53. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/path_codec.py +0 -0
  54. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/provider_paths.py +0 -0
  55. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/remote_config.py +0 -0
  56. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/renames.py +0 -0
  57. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/restart_state.py +0 -0
  58. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/runtime_config.py +0 -0
  59. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/scroll_agent.py +0 -0
  60. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/scroll_manager.py +0 -0
  61. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/selection_isolation.py +0 -0
  62. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/self_update.py +0 -0
  63. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/session_cache.py +0 -0
  64. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/session_index.py +0 -0
  65. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/setting_contracts.py +0 -0
  66. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/settings.py +0 -0
  67. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/ssh_args.py +0 -0
  68. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/ssh_compat.py +0 -0
  69. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/ssh_display_diagnostics.py +0 -0
  70. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/ssh_doctor.py +0 -0
  71. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/system_deps.py +0 -0
  72. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/terminal_status.py +0 -0
  73. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/tmux_binding_manager.py +0 -0
  74. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/tmux_health.py +0 -0
  75. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/tool_panes.py +0 -0
  76. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/transcript.py +0 -0
  77. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/ui/__init__.py +0 -0
  78. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/ui/_widgets.py +0 -0
  79. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/ui/keymap.py +0 -0
  80. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/ui/modals.py +0 -0
  81. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/ui/projects_pane.py +0 -0
  82. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/ui/running_pane.py +0 -0
  83. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/ui/sessions_pane.py +0 -0
  84. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/ui/sidebar.py +0 -0
  85. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/ui/statusbar.py +0 -0
  86. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/ui/workspace.py +0 -0
  87. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/windows_bootstrap.py +0 -0
  88. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/windows_pacman.py +0 -0
  89. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux/windows_tmux_lifecycle.py +0 -0
  90. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux.egg-info/SOURCES.txt +0 -0
  91. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux.egg-info/dependency_links.txt +0 -0
  92. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux.egg-info/entry_points.txt +0 -0
  93. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux.egg-info/requires.txt +0 -0
  94. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/src/railmux.egg-info/top_level.txt +0 -0
  95. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_agent_workspace.py +0 -0
  96. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_atomic_file.py +0 -0
  97. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_background_index.py +0 -0
  98. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_cli.py +0 -0
  99. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_codex_index.py +0 -0
  100. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_codex_transcript.py +0 -0
  101. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_config.py +0 -0
  102. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_config_cli.py +0 -0
  103. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_denested_transport_benchmark.py +0 -0
  104. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_diagnostics.py +0 -0
  105. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_discovery.py +0 -0
  106. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_display_transport.py +0 -0
  107. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_fullscreen_binding.py +0 -0
  108. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_fuzzy.py +0 -0
  109. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_help_agent.py +0 -0
  110. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_help_workspace.py +0 -0
  111. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_history_cleanup.py +0 -0
  112. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_keymap.py +0 -0
  113. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_launcher.py +0 -0
  114. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_layout_profile.py +0 -0
  115. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_legacy_sessions.py +0 -0
  116. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_local_clipboard.py +0 -0
  117. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_local_open.py +0 -0
  118. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_modals.py +0 -0
  119. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_mode_selection.py +0 -0
  120. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_modes.py +0 -0
  121. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_mouse_manager.py +0 -0
  122. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_new_project.py +0 -0
  123. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_options.py +0 -0
  124. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_orphan_recovery.py +0 -0
  125. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_pane_surface.py +0 -0
  126. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_path_codec.py +0 -0
  127. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_projects_pane.py +0 -0
  128. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_provider_paths.py +0 -0
  129. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_release_notes.py +0 -0
  130. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_release_workflow.py +0 -0
  131. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_remote_config.py +0 -0
  132. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_renames.py +0 -0
  133. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_restart_state.py +0 -0
  134. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_running_pane.py +0 -0
  135. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_running_sort.py +0 -0
  136. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_runtime_config.py +0 -0
  137. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_scroll_agent.py +0 -0
  138. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_scroll_manager.py +0 -0
  139. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_selection_isolation.py +0 -0
  140. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_self_update.py +0 -0
  141. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_session_cache.py +0 -0
  142. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_session_index.py +0 -0
  143. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_sessions_pane.py +0 -0
  144. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_setting_contracts.py +0 -0
  145. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_settings.py +0 -0
  146. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_sidebar.py +0 -0
  147. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_soft_quit.py +0 -0
  148. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_ssh_args.py +0 -0
  149. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_ssh_compat.py +0 -0
  150. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_ssh_display_benchmark.py +0 -0
  151. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_ssh_display_diagnostics.py +0 -0
  152. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_ssh_doctor.py +0 -0
  153. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_status.py +0 -0
  154. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_system_deps.py +0 -0
  155. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_terminal_size.py +0 -0
  156. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_terminal_status.py +0 -0
  157. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_termux_local_touch.py +0 -0
  158. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_tmux_binding_manager.py +0 -0
  159. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_tmux_health.py +0 -0
  160. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_tmux_status.py +0 -0
  161. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_tool_panes.py +0 -0
  162. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_transcript.py +0 -0
  163. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_utf8_state.py +0 -0
  164. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_web_demo_recorder.py +0 -0
  165. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_wheel_smoke.py +0 -0
  166. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_widgets.py +0 -0
  167. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_windows_bootstrap.py +0 -0
  168. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_windows_pacman.py +0 -0
  169. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_windows_tmux_lifecycle.py +0 -0
  170. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_windows_wrapper_contract.py +0 -0
  171. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tests/test_yolo_prompt.py +0 -0
  172. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tools/denested_transport_benchmark.py +0 -0
  173. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tools/release_notes.py +0 -0
  174. {railmux-0.4.0.dev11 → railmux-0.4.0.dev13}/tools/wheel_smoke.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: railmux
3
- Version: 0.4.0.dev11
3
+ Version: 0.4.0.dev13
4
4
  Summary: Terminal UI to navigate, resume, and start Claude Code and Codex sessions
5
5
  Author-email: Rightglow <zhang.taian@foxmail.com>
6
6
  License-Expression: MIT
@@ -205,7 +205,7 @@ see [FAQ 1](#1-how-do-i-copy-text-from-the-agent-pane).
205
205
  | `r` | Rename the focused session |
206
206
  | `s` | Toggle star — starred sessions pinned to top with ⭐ |
207
207
  | `k` | Kill the running agent process (keeps session file) |
208
- | `d` | Delete the focused session (prompts for confirmation) |
208
+ | `d` | Delete the focused session (confirms, then finishes in background) |
209
209
  | `t` | Open or return to the managed terminal below the Target agent |
210
210
  | `T` | Return to that agent's managed Vim viewer, when open |
211
211
  | `m` | Switch agent mode (Claude Code ⇄ Codex) |
@@ -243,6 +243,11 @@ The rename popup starts with the current title pre-filled. Press
243
243
  `Ctrl-U` to clear the entire input, `Enter` to save a non-empty title, or `Esc`
244
244
  to cancel.
245
245
 
246
+ After a delete is confirmed, its popup closes immediately. The bottom-right
247
+ status shows **Deleting “session name”…** while Railmux stops the exact
248
+ provider session and removes its history in the background, then reports the
249
+ final result.
250
+
246
251
  Press `/` in Projects, Sessions, or Running to filter that section. Active
247
252
  filters are marked with `[filtered]` and survive a soft restart; reopening `/`
248
253
  shows the current value. Press `Ctrl-U` in the filter editor to clear it, then
@@ -375,8 +380,9 @@ internal context and encrypted reasoning are hidden. Codex rewind lineages and
375
380
  Claude Code `parentUuid` branches are projected onto the provider's current
376
381
  conversation: the retained prefix and replacement suffix remain visible, while
377
382
  the abandoned suffix is hidden. When Railmux observes a running Codex session
378
- advance to its rewind child, it also removes the abandoned terminal screen and
379
- tmux scrollback before Codex redraws the live pane.
383
+ advance after rewind or steering, it resets only the current terminal view
384
+ before Codex redraws. Retained tmux scrollback is not erased, and managed
385
+ history continues from the canonical rollout without its abandoned suffix.
380
386
 
381
387
  Preview opens at the latest activity in `less`; large sessions are limited to
382
388
  their latest 2,000 saved records. Press `/` to search, `n`/`N` to move between
@@ -162,7 +162,7 @@ see [FAQ 1](#1-how-do-i-copy-text-from-the-agent-pane).
162
162
  | `r` | Rename the focused session |
163
163
  | `s` | Toggle star — starred sessions pinned to top with ⭐ |
164
164
  | `k` | Kill the running agent process (keeps session file) |
165
- | `d` | Delete the focused session (prompts for confirmation) |
165
+ | `d` | Delete the focused session (confirms, then finishes in background) |
166
166
  | `t` | Open or return to the managed terminal below the Target agent |
167
167
  | `T` | Return to that agent's managed Vim viewer, when open |
168
168
  | `m` | Switch agent mode (Claude Code ⇄ Codex) |
@@ -200,6 +200,11 @@ The rename popup starts with the current title pre-filled. Press
200
200
  `Ctrl-U` to clear the entire input, `Enter` to save a non-empty title, or `Esc`
201
201
  to cancel.
202
202
 
203
+ After a delete is confirmed, its popup closes immediately. The bottom-right
204
+ status shows **Deleting “session name”…** while Railmux stops the exact
205
+ provider session and removes its history in the background, then reports the
206
+ final result.
207
+
203
208
  Press `/` in Projects, Sessions, or Running to filter that section. Active
204
209
  filters are marked with `[filtered]` and survive a soft restart; reopening `/`
205
210
  shows the current value. Press `Ctrl-U` in the filter editor to clear it, then
@@ -332,8 +337,9 @@ internal context and encrypted reasoning are hidden. Codex rewind lineages and
332
337
  Claude Code `parentUuid` branches are projected onto the provider's current
333
338
  conversation: the retained prefix and replacement suffix remain visible, while
334
339
  the abandoned suffix is hidden. When Railmux observes a running Codex session
335
- advance to its rewind child, it also removes the abandoned terminal screen and
336
- tmux scrollback before Codex redraws the live pane.
340
+ advance after rewind or steering, it resets only the current terminal view
341
+ before Codex redraws. Retained tmux scrollback is not erased, and managed
342
+ history continues from the canonical rollout without its abandoned suffix.
337
343
 
338
344
  Preview opens at the latest activity in `less`; large sessions are limited to
339
345
  their latest 2,000 saved records. Press `/` to search, `n`/`N` to move between
@@ -0,0 +1 @@
1
+ __version__ = "0.4.0.dev13"
@@ -403,6 +403,7 @@ class _PaneGeometry:
403
403
  alternate_on: bool = False
404
404
  transcript_source: str | None = None
405
405
  transcript_backed: bool = False
406
+ transcript_provider: str | None = None
406
407
  claude_history_policy: str = "ask"
407
408
  history_generation: int = 0
408
409
 
@@ -916,10 +917,11 @@ def _list_agent_panes(
916
917
  if history_pane_id is None:
917
918
  history_server = None
918
919
  transcript_marker = fields[14] or None
919
- transcript_backed = (
920
- transcript_marker is not None
921
- and tmux_server.decode_transcript_source(transcript_marker) is not None
920
+ transcript_locator = (
921
+ tmux_server.decode_transcript_source(transcript_marker)
922
+ if transcript_marker is not None else None
922
923
  )
924
+ transcript_backed = transcript_locator is not None
923
925
  if not transcript_backed and fields[11] == "1" and fields[12] == "1":
924
926
  transcript_backed, transcript_marker = _inferred_transcript_source(
925
927
  session_id=session_id,
@@ -933,6 +935,7 @@ def _list_agent_panes(
933
935
  opened = tmux_server.open_transcript_source(transcript_marker)
934
936
  transcript_backed = opened is not None
935
937
  if opened is not None:
938
+ transcript_locator = opened[0]
936
939
  os.close(opened[1])
937
940
  rows.append(
938
941
  (
@@ -951,6 +954,11 @@ def _list_agent_panes(
951
954
  alternate_on=fields[11] == "1",
952
955
  transcript_source=transcript_marker,
953
956
  transcript_backed=transcript_backed,
957
+ transcript_provider=(
958
+ transcript_locator.provider
959
+ if transcript_backed and transcript_locator is not None
960
+ else None
961
+ ),
954
962
  claude_history_policy=claude_history_policy,
955
963
  history_generation=_history_generation(fields[15]),
956
964
  ),
@@ -1267,7 +1275,9 @@ def _transcript_rows(
1267
1275
  return None
1268
1276
  formatted = "".join(
1269
1277
  transcript_renderer.format_transcript(
1270
- io.StringIO(raw), "claude", claude_native=True
1278
+ io.StringIO(raw),
1279
+ source.provider,
1280
+ claude_native=source.provider == "claude",
1271
1281
  )
1272
1282
  )
1273
1283
  rows, dropped = _wrap_transcript_rows(pyte, formatted, width)
@@ -1330,12 +1340,21 @@ def _capture_pane_history(
1330
1340
  # pane's current viewport merely to retain older scrollback.
1331
1341
  current_raw = raw_lines[-pane.height :]
1332
1342
  transcript_entry = None
1343
+ # ``None`` is retained only for old/test geometry that predates the
1344
+ # provider field; every validated live marker carries an explicit value.
1345
+ transcript_provider = pane.transcript_provider or "claude"
1333
1346
  if (
1334
1347
  pane.transcript_backed
1335
- and pane.claude_history_policy == "local"
1336
- and pane.alternate_on
1337
- and pane.history_size == 0
1338
1348
  and pane.transcript_source
1349
+ and (
1350
+ transcript_provider == "codex"
1351
+ or (
1352
+ transcript_provider == "claude"
1353
+ and pane.claude_history_policy == "local"
1354
+ and pane.alternate_on
1355
+ and pane.history_size == 0
1356
+ )
1357
+ )
1339
1358
  ):
1340
1359
  transcript_entry = _transcript_rows(
1341
1360
  pyte,
@@ -1387,7 +1406,9 @@ def _capture_pane_history(
1387
1406
  transcript_backed=transcript_used,
1388
1407
  transcript_available=pane.transcript_backed,
1389
1408
  history_choice_required=(
1390
- pane.transcript_backed and pane.claude_history_policy == "ask"
1409
+ pane.transcript_backed
1410
+ and transcript_provider == "claude"
1411
+ and pane.claude_history_policy == "ask"
1391
1412
  ),
1392
1413
  more_available=(
1393
1414
  budget_truncated
@@ -3457,14 +3457,15 @@ def exact_pane_alive(identity: PaneIdentity) -> bool:
3457
3457
  )
3458
3458
 
3459
3459
 
3460
- def reset_pane_history(identity: PaneIdentity) -> bool:
3461
- """Reset visible bytes and scrollback for the exact observed live pane.
3460
+ def reset_pane_view(identity: PaneIdentity) -> bool:
3461
+ """Reset visible terminal state without deleting retained scrollback.
3462
3462
 
3463
3463
  Revalidate the immutable session, pane process, and window before issuing
3464
- one tmux command queue that resets the terminal model and clears history.
3465
- Then send the pane's foreground process group an ordinary same-size
3466
- ``SIGWINCH`` so its TUI repaints and reasserts terminal modes without a
3467
- geometry change or injected keyboard input.
3464
+ tmux's terminal reset. Then send the pane's foreground process group an
3465
+ ordinary same-size ``SIGWINCH`` so its TUI repaints and reasserts terminal
3466
+ modes without a geometry change or injected keyboard input. The reset can
3467
+ push the old viewport into tmux history, but never destroys the retained
3468
+ prefix; managed history surfaces use the provider's canonical transcript.
3468
3469
  """
3469
3470
  current = pane_identity(identity.pane_id)
3470
3471
  if (current is None or current.dead
@@ -3474,10 +3475,7 @@ def reset_pane_history(identity: PaneIdentity) -> bool:
3474
3475
  return False
3475
3476
  try:
3476
3477
  subprocess.check_call(
3477
- [
3478
- "tmux", "send-keys", "-R", "-t", identity.pane_id,
3479
- ";", "clear-history", "-t", identity.pane_id,
3480
- ],
3478
+ ["tmux", "send-keys", "-R", "-t", identity.pane_id],
3481
3479
  stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
3482
3480
  )
3483
3481
  except (OSError, subprocess.CalledProcessError):
@@ -22,6 +22,8 @@ _SESSION_ID_RE = re.compile(r"[A-Za-z0-9-]{1,256}\Z")
22
22
  _HISTORY_SOURCE_SCHEMA = 1
23
23
  _TRANSCRIPT_SOURCE_SCHEMA = 1
24
24
  _MAX_TRANSCRIPT_SOURCE_BYTES = 8192
25
+ _DEFAULT_DISCOVERY_TIMEOUT = 2.0
26
+ _WINDOWS_DISCOVERY_TIMEOUT = 5.0
25
27
 
26
28
 
27
29
  class TmuxServerError(RuntimeError):
@@ -179,10 +181,25 @@ def current_target(
179
181
 
180
182
  def discover_target(
181
183
  *,
182
- timeout: float = 2.0,
184
+ timeout: float | None = None,
183
185
  env: Mapping[str, str] | None = None,
184
186
  ) -> TmuxServerTarget | None:
185
- """Resolve the live dedicated server without starting a new server."""
187
+ """Resolve the live dedicated server without starting a new server.
188
+
189
+ MSYS2 tmux can need slightly more than two seconds to classify an
190
+ abandoned AF_UNIX pathname as having no live server. Give only the
191
+ managed Windows wrapper enough time to receive that authoritative result;
192
+ explicit watchdog probes retain their caller-selected bounds.
193
+ """
194
+ if timeout is None:
195
+ from railmux.provider_paths import running_in_windows_wrapper
196
+
197
+ source = os.environ if env is None else env
198
+ timeout = (
199
+ _WINDOWS_DISCOVERY_TIMEOUT
200
+ if running_in_windows_wrapper(source)
201
+ else _DEFAULT_DISCOVERY_TIMEOUT
202
+ )
186
203
  return _discover_label_target(socket_label(env), timeout=timeout, env=env)
187
204
 
188
205
 
@@ -307,11 +324,21 @@ def encode_transcript_source(
307
324
  ) -> str | None:
308
325
  """Encode an exact transcript hint for a displayed managed agent pane."""
309
326
  raw_path = str(path)
327
+ valid_name = (
328
+ path.name == f"{session_id}.jsonl"
329
+ if provider == "claude"
330
+ else (
331
+ path.name.startswith("rollout-")
332
+ and path.name.endswith(f"-{session_id}.jsonl")
333
+ )
334
+ if provider == "codex"
335
+ else False
336
+ )
310
337
  if (
311
- provider != "claude"
338
+ provider not in {"claude", "codex"}
312
339
  or not _SESSION_ID_RE.fullmatch(session_id)
313
340
  or not path.is_absolute()
314
- or path.name != f"{session_id}.jsonl"
341
+ or not valid_name
315
342
  or len(raw_path) > 4096
316
343
  ):
317
344
  return None
@@ -348,7 +375,7 @@ def decode_transcript_source(raw: str) -> TranscriptSource | None:
348
375
  raw_path = payload.get("path")
349
376
  if (
350
377
  payload.get("schema_version") != _TRANSCRIPT_SOURCE_SCHEMA
351
- or provider != "claude"
378
+ or provider not in {"claude", "codex"}
352
379
  or not isinstance(session_id, str)
353
380
  or not _SESSION_ID_RE.fullmatch(session_id)
354
381
  or not isinstance(raw_path, str)
@@ -357,7 +384,15 @@ def decode_transcript_source(raw: str) -> TranscriptSource | None:
357
384
  ):
358
385
  return None
359
386
  path = Path(raw_path)
360
- if not path.is_absolute() or path.name != f"{session_id}.jsonl":
387
+ valid_name = (
388
+ path.name == f"{session_id}.jsonl"
389
+ if provider == "claude"
390
+ else (
391
+ path.name.startswith("rollout-")
392
+ and path.name.endswith(f"-{session_id}.jsonl")
393
+ )
394
+ )
395
+ if not path.is_absolute() or not valid_name:
361
396
  return None
362
397
  return TranscriptSource(provider, session_id, path)
363
398