railmux 0.4.0.dev11__tar.gz → 0.4.0.dev12__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.dev12}/PKG-INFO +10 -4
  2. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/README.md +9 -3
  3. railmux-0.4.0.dev12/src/railmux/__init__.py +1 -0
  4. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/fast_display_server.py +29 -8
  5. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/tmux_ctl.py +8 -10
  6. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/tmux_server.py +22 -4
  7. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/ui/app.py +348 -145
  8. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/windows_install_log.py +16 -0
  9. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/windows_msys2.py +83 -10
  10. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12/src/railmux.egg-info}/PKG-INFO +10 -4
  11. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_codex_delete.py +134 -39
  12. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_codex_lineage.py +59 -11
  13. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_fast_full_window.py +73 -0
  14. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_focus_highlight.py +23 -3
  15. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_statusbar.py +25 -0
  16. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_tmux_ctl.py +4 -7
  17. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_tmux_integration.py +14 -6
  18. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_tmux_server.py +22 -0
  19. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_windows_install_log.py +13 -0
  20. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/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.dev12}/LICENSE +0 -0
  23. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/MANIFEST.in +0 -0
  24. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/pyproject.toml +0 -0
  25. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/setup.cfg +0 -0
  26. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/__main__.py +0 -0
  27. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/atomic_file.py +0 -0
  28. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/background_index.py +0 -0
  29. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/cli.py +0 -0
  30. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/codex_index.py +0 -0
  31. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/config.py +0 -0
  32. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/config_cli.py +0 -0
  33. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/diagnostics.py +0 -0
  34. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/discovery.py +0 -0
  35. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/display_transport.py +0 -0
  36. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/entrypoint.py +0 -0
  37. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/fast_display_client.py +0 -0
  38. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/fast_display_history.py +0 -0
  39. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/fast_display_input.py +0 -0
  40. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/fast_display_protocol.py +0 -0
  41. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/favorites.py +0 -0
  42. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/fuzzy.py +0 -0
  43. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/help_workspace.py +0 -0
  44. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/launcher.py +0 -0
  45. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/legacy_sessions.py +0 -0
  46. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/local_clipboard.py +0 -0
  47. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/local_open.py +0 -0
  48. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/models.py +0 -0
  49. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/modes.py +0 -0
  50. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/mouse_manager.py +0 -0
  51. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/orphan_marker.py +0 -0
  52. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/pane_surface.py +0 -0
  53. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/path_codec.py +0 -0
  54. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/provider_paths.py +0 -0
  55. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/remote_config.py +0 -0
  56. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/renames.py +0 -0
  57. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/restart_state.py +0 -0
  58. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/runtime_config.py +0 -0
  59. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/scroll_agent.py +0 -0
  60. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/scroll_manager.py +0 -0
  61. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/selection_isolation.py +0 -0
  62. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/self_update.py +0 -0
  63. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/session_cache.py +0 -0
  64. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/session_index.py +0 -0
  65. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/setting_contracts.py +0 -0
  66. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/settings.py +0 -0
  67. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/ssh_args.py +0 -0
  68. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/ssh_compat.py +0 -0
  69. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/ssh_display_diagnostics.py +0 -0
  70. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/ssh_doctor.py +0 -0
  71. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/system_deps.py +0 -0
  72. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/terminal_status.py +0 -0
  73. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/tmux_binding_manager.py +0 -0
  74. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/tmux_health.py +0 -0
  75. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/tool_panes.py +0 -0
  76. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/transcript.py +0 -0
  77. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/ui/__init__.py +0 -0
  78. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/ui/_widgets.py +0 -0
  79. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/ui/keymap.py +0 -0
  80. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/ui/modals.py +0 -0
  81. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/ui/projects_pane.py +0 -0
  82. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/ui/running_pane.py +0 -0
  83. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/ui/sessions_pane.py +0 -0
  84. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/ui/sidebar.py +0 -0
  85. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/ui/statusbar.py +0 -0
  86. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/ui/workspace.py +0 -0
  87. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/windows_bootstrap.py +0 -0
  88. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/windows_pacman.py +0 -0
  89. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux/windows_tmux_lifecycle.py +0 -0
  90. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux.egg-info/SOURCES.txt +0 -0
  91. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux.egg-info/dependency_links.txt +0 -0
  92. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux.egg-info/entry_points.txt +0 -0
  93. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux.egg-info/requires.txt +0 -0
  94. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/src/railmux.egg-info/top_level.txt +0 -0
  95. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_agent_workspace.py +0 -0
  96. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_atomic_file.py +0 -0
  97. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_background_index.py +0 -0
  98. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_cli.py +0 -0
  99. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_codex_index.py +0 -0
  100. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_codex_transcript.py +0 -0
  101. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_config.py +0 -0
  102. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_config_cli.py +0 -0
  103. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_denested_transport_benchmark.py +0 -0
  104. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_diagnostics.py +0 -0
  105. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_discovery.py +0 -0
  106. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_display_transport.py +0 -0
  107. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_fullscreen_binding.py +0 -0
  108. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_fuzzy.py +0 -0
  109. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_help_agent.py +0 -0
  110. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_help_workspace.py +0 -0
  111. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_history_cleanup.py +0 -0
  112. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_keymap.py +0 -0
  113. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_launcher.py +0 -0
  114. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_layout_profile.py +0 -0
  115. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_legacy_sessions.py +0 -0
  116. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_local_clipboard.py +0 -0
  117. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_local_open.py +0 -0
  118. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_modals.py +0 -0
  119. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_mode_selection.py +0 -0
  120. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_modes.py +0 -0
  121. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_mouse_manager.py +0 -0
  122. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_new_project.py +0 -0
  123. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_options.py +0 -0
  124. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_orphan_recovery.py +0 -0
  125. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_pane_surface.py +0 -0
  126. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_path_codec.py +0 -0
  127. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_projects_pane.py +0 -0
  128. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_provider_paths.py +0 -0
  129. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_release_notes.py +0 -0
  130. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_release_workflow.py +0 -0
  131. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_remote_config.py +0 -0
  132. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_renames.py +0 -0
  133. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_restart_state.py +0 -0
  134. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_running_pane.py +0 -0
  135. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_running_sort.py +0 -0
  136. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_runtime_config.py +0 -0
  137. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_scroll_agent.py +0 -0
  138. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_scroll_manager.py +0 -0
  139. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_selection_isolation.py +0 -0
  140. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_self_update.py +0 -0
  141. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_session_cache.py +0 -0
  142. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_session_index.py +0 -0
  143. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_sessions_pane.py +0 -0
  144. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_setting_contracts.py +0 -0
  145. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_settings.py +0 -0
  146. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_sidebar.py +0 -0
  147. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_soft_quit.py +0 -0
  148. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_ssh_args.py +0 -0
  149. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_ssh_compat.py +0 -0
  150. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_ssh_display_benchmark.py +0 -0
  151. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_ssh_display_diagnostics.py +0 -0
  152. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_ssh_doctor.py +0 -0
  153. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_status.py +0 -0
  154. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_system_deps.py +0 -0
  155. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_terminal_size.py +0 -0
  156. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_terminal_status.py +0 -0
  157. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_termux_local_touch.py +0 -0
  158. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_tmux_binding_manager.py +0 -0
  159. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_tmux_health.py +0 -0
  160. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_tmux_status.py +0 -0
  161. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_tool_panes.py +0 -0
  162. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_transcript.py +0 -0
  163. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_utf8_state.py +0 -0
  164. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_web_demo_recorder.py +0 -0
  165. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_wheel_smoke.py +0 -0
  166. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_widgets.py +0 -0
  167. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_windows_bootstrap.py +0 -0
  168. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_windows_pacman.py +0 -0
  169. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_windows_tmux_lifecycle.py +0 -0
  170. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_windows_wrapper_contract.py +0 -0
  171. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tests/test_yolo_prompt.py +0 -0
  172. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tools/denested_transport_benchmark.py +0 -0
  173. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/tools/release_notes.py +0 -0
  174. {railmux-0.4.0.dev11 → railmux-0.4.0.dev12}/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.dev12
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.dev12"
@@ -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):
@@ -307,11 +307,21 @@ def encode_transcript_source(
307
307
  ) -> str | None:
308
308
  """Encode an exact transcript hint for a displayed managed agent pane."""
309
309
  raw_path = str(path)
310
+ valid_name = (
311
+ path.name == f"{session_id}.jsonl"
312
+ if provider == "claude"
313
+ else (
314
+ path.name.startswith("rollout-")
315
+ and path.name.endswith(f"-{session_id}.jsonl")
316
+ )
317
+ if provider == "codex"
318
+ else False
319
+ )
310
320
  if (
311
- provider != "claude"
321
+ provider not in {"claude", "codex"}
312
322
  or not _SESSION_ID_RE.fullmatch(session_id)
313
323
  or not path.is_absolute()
314
- or path.name != f"{session_id}.jsonl"
324
+ or not valid_name
315
325
  or len(raw_path) > 4096
316
326
  ):
317
327
  return None
@@ -348,7 +358,7 @@ def decode_transcript_source(raw: str) -> TranscriptSource | None:
348
358
  raw_path = payload.get("path")
349
359
  if (
350
360
  payload.get("schema_version") != _TRANSCRIPT_SOURCE_SCHEMA
351
- or provider != "claude"
361
+ or provider not in {"claude", "codex"}
352
362
  or not isinstance(session_id, str)
353
363
  or not _SESSION_ID_RE.fullmatch(session_id)
354
364
  or not isinstance(raw_path, str)
@@ -357,7 +367,15 @@ def decode_transcript_source(raw: str) -> TranscriptSource | None:
357
367
  ):
358
368
  return None
359
369
  path = Path(raw_path)
360
- if not path.is_absolute() or path.name != f"{session_id}.jsonl":
370
+ valid_name = (
371
+ path.name == f"{session_id}.jsonl"
372
+ if provider == "claude"
373
+ else (
374
+ path.name.startswith("rollout-")
375
+ and path.name.endswith(f"-{session_id}.jsonl")
376
+ )
377
+ )
378
+ if not path.is_absolute() or not valid_name:
361
379
  return None
362
380
  return TranscriptSource(provider, session_id, path)
363
381