railmux 0.4.1.dev2__tar.gz → 0.4.1.dev3__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 (206) hide show
  1. {railmux-0.4.1.dev2/src/railmux.egg-info → railmux-0.4.1.dev3}/PKG-INFO +38 -31
  2. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/README.md +37 -30
  3. railmux-0.4.1.dev3/src/railmux/__init__.py +1 -0
  4. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/config.py +42 -14
  5. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/config_cli.py +47 -11
  6. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/fast_display_client.py +6 -7
  7. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/fast_display_history.py +145 -10
  8. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/fast_display_server.py +20 -124
  9. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/setting_contracts.py +34 -13
  10. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/settings.py +15 -9
  11. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/ui/app.py +13 -7
  12. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/ui/modals.py +16 -10
  13. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/ui/statusbar.py +2 -2
  14. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/windows_attach_relay.py +392 -74
  15. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3/src/railmux.egg-info}/PKG-INFO +38 -31
  16. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_config.py +25 -0
  17. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_config_cli.py +58 -2
  18. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_fast_display_server.py +16 -9
  19. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_focus_highlight.py +41 -0
  20. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_modals.py +2 -2
  21. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_options.py +4 -0
  22. railmux-0.4.1.dev3/tests/test_setting_contracts.py +50 -0
  23. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_settings.py +10 -1
  24. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_windows_attach_relay.py +340 -11
  25. railmux-0.4.1.dev2/src/railmux/__init__.py +0 -1
  26. railmux-0.4.1.dev2/tests/test_setting_contracts.py +0 -50
  27. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/LICENSE +0 -0
  28. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/MANIFEST.in +0 -0
  29. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/pyproject.toml +0 -0
  30. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/setup.cfg +0 -0
  31. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/__main__.py +0 -0
  32. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/atomic_file.py +0 -0
  33. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/background_index.py +0 -0
  34. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/cli.py +0 -0
  35. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/codex_index.py +0 -0
  36. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/diagnostic_contract.py +0 -0
  37. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/diagnostics.py +0 -0
  38. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/discovery.py +0 -0
  39. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/display_transport.py +0 -0
  40. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/entrypoint.py +0 -0
  41. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/fast_display_input.py +0 -0
  42. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/fast_display_protocol.py +0 -0
  43. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/favorites.py +0 -0
  44. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/fuzzy.py +0 -0
  45. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/help_workspace.py +0 -0
  46. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/launcher.py +0 -0
  47. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/legacy_sessions.py +0 -0
  48. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/local_clipboard.py +0 -0
  49. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/local_open.py +0 -0
  50. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/models.py +0 -0
  51. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/modes.py +0 -0
  52. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/mouse_manager.py +0 -0
  53. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/orphan_marker.py +0 -0
  54. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/pane_surface.py +0 -0
  55. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/path_codec.py +0 -0
  56. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/preview_pager.py +0 -0
  57. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/project_favorites.py +0 -0
  58. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/provider_paths.py +0 -0
  59. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/release_version.py +0 -0
  60. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/remote_config.py +0 -0
  61. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/renames.py +0 -0
  62. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/restart_state.py +0 -0
  63. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/runtime_config.py +0 -0
  64. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/scroll_agent.py +0 -0
  65. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/scroll_manager.py +0 -0
  66. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/selection_isolation.py +0 -0
  67. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/self_update.py +0 -0
  68. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/session_cache.py +0 -0
  69. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/session_index.py +0 -0
  70. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/session_lease.py +0 -0
  71. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/ssh_args.py +0 -0
  72. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/ssh_compat.py +0 -0
  73. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/ssh_display_diagnostics.py +0 -0
  74. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/ssh_doctor.py +0 -0
  75. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/ssh_preflight.py +0 -0
  76. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/system_deps.py +0 -0
  77. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/terminal_screen.py +0 -0
  78. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/terminal_status.py +0 -0
  79. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/tmux_binding_manager.py +0 -0
  80. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/tmux_capabilities.py +0 -0
  81. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/tmux_ctl.py +0 -0
  82. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/tmux_health.py +0 -0
  83. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/tmux_server.py +0 -0
  84. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/tool_panes.py +0 -0
  85. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/transcript.py +0 -0
  86. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/ui/__init__.py +0 -0
  87. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/ui/_widgets.py +0 -0
  88. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/ui/keymap.py +0 -0
  89. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/ui/projects_pane.py +0 -0
  90. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/ui/running_pane.py +0 -0
  91. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/ui/sessions_pane.py +0 -0
  92. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/ui/sidebar.py +0 -0
  93. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/ui/workspace.py +0 -0
  94. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/windows_bootstrap.py +0 -0
  95. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/windows_install_log.py +0 -0
  96. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/windows_msys2.py +0 -0
  97. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/windows_pacman.py +0 -0
  98. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/windows_paths.py +0 -0
  99. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/windows_tmux_lifecycle.py +0 -0
  100. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux/windows_ui_transition.py +0 -0
  101. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux.egg-info/SOURCES.txt +0 -0
  102. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux.egg-info/dependency_links.txt +0 -0
  103. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux.egg-info/entry_points.txt +0 -0
  104. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux.egg-info/requires.txt +0 -0
  105. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/src/railmux.egg-info/top_level.txt +0 -0
  106. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/app_test_harness.py +0 -0
  107. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_agent_workspace.py +0 -0
  108. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_app_codex_placeholder.py +0 -0
  109. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_app_quit.py +0 -0
  110. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_app_restart_restore.py +0 -0
  111. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_app_running_recovery.py +0 -0
  112. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_atomic_file.py +0 -0
  113. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_background_index.py +0 -0
  114. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_cli.py +0 -0
  115. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_code_map.py +0 -0
  116. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_codex_delete.py +0 -0
  117. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_codex_index.py +0 -0
  118. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_codex_lineage.py +0 -0
  119. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_codex_transcript.py +0 -0
  120. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_denested_transport_benchmark.py +0 -0
  121. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_diagnostics.py +0 -0
  122. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_discovery.py +0 -0
  123. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_display_transport.py +0 -0
  124. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_fast_display_bootstrap.py +0 -0
  125. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_fast_display_history.py +0 -0
  126. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_fast_display_protocol.py +0 -0
  127. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_fast_display_selection.py +0 -0
  128. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_fast_display_terminal.py +0 -0
  129. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_fullscreen_binding.py +0 -0
  130. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_fuzzy.py +0 -0
  131. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_help_agent.py +0 -0
  132. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_help_workspace.py +0 -0
  133. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_history_cleanup.py +0 -0
  134. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_keymap.py +0 -0
  135. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_launcher.py +0 -0
  136. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_layout_profile.py +0 -0
  137. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_legacy_sessions.py +0 -0
  138. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_local_clipboard.py +0 -0
  139. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_local_open.py +0 -0
  140. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_mode_selection.py +0 -0
  141. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_modes.py +0 -0
  142. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_mouse_manager.py +0 -0
  143. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_new_project.py +0 -0
  144. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_orphan_recovery.py +0 -0
  145. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_pane_surface.py +0 -0
  146. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_path_codec.py +0 -0
  147. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_preview_pager.py +0 -0
  148. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_project_favorites.py +0 -0
  149. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_projects_pane.py +0 -0
  150. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_provider_paths.py +0 -0
  151. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_release_notes.py +0 -0
  152. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_release_version.py +0 -0
  153. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_release_workflow.py +0 -0
  154. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_remote_config.py +0 -0
  155. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_renames.py +0 -0
  156. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_restart_state.py +0 -0
  157. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_running_pane.py +0 -0
  158. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_running_sort.py +0 -0
  159. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_runtime_config.py +0 -0
  160. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_scroll_agent.py +0 -0
  161. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_scroll_manager.py +0 -0
  162. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_selection_isolation.py +0 -0
  163. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_self_update.py +0 -0
  164. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_session_cache.py +0 -0
  165. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_session_index.py +0 -0
  166. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_session_lease.py +0 -0
  167. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_sessions_pane.py +0 -0
  168. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_sidebar.py +0 -0
  169. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_ssh_args.py +0 -0
  170. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_ssh_compat.py +0 -0
  171. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_ssh_display_benchmark.py +0 -0
  172. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_ssh_display_diagnostics.py +0 -0
  173. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_ssh_doctor.py +0 -0
  174. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_status.py +0 -0
  175. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_statusbar.py +0 -0
  176. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_system_deps.py +0 -0
  177. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_terminal_size.py +0 -0
  178. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_terminal_status.py +0 -0
  179. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_termux_local_touch.py +0 -0
  180. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_tmux_binding_manager.py +0 -0
  181. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_tmux_capabilities.py +0 -0
  182. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_tmux_ctl.py +0 -0
  183. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_tmux_health.py +0 -0
  184. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_tmux_integration.py +0 -0
  185. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_tmux_server.py +0 -0
  186. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_tmux_status.py +0 -0
  187. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_tool_panes.py +0 -0
  188. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_transcript.py +0 -0
  189. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_utf8_state.py +0 -0
  190. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_web_demo_recorder.py +0 -0
  191. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_wheel_smoke.py +0 -0
  192. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_widgets.py +0 -0
  193. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_windows_bootstrap.py +0 -0
  194. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_windows_install_log.py +0 -0
  195. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_windows_msys2.py +0 -0
  196. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_windows_pacman.py +0 -0
  197. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_windows_paths.py +0 -0
  198. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_windows_synchronized_screen.py +0 -0
  199. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_windows_tmux_lifecycle.py +0 -0
  200. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_windows_ui_transition.py +0 -0
  201. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_windows_wrapper_contract.py +0 -0
  202. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tests/test_yolo_prompt.py +0 -0
  203. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tools/denested_transport_benchmark.py +0 -0
  204. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tools/release_notes.py +0 -0
  205. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tools/wheel_smoke.py +0 -0
  206. {railmux-0.4.1.dev2 → railmux-0.4.1.dev3}/tools/windows_archive_smoke.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: railmux
3
- Version: 0.4.1.dev2
3
+ Version: 0.4.1.dev3
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
@@ -147,13 +147,13 @@ after showing the exact command and asking for confirmation. See
147
147
  requires a virtual environment.
148
148
 
149
149
  Preference prompts appear only when relevant—for updates, Codex auto-run,
150
- layout retention, or Claude history over `railmux ssh`. Persistent choices are
150
+ layout retention, or Claude history on a managed Windows/SSH display. Persistent choices are
151
151
  not permanent traps: press `o`, or choose **More → Options**, to change them
152
152
  later. One-time safety confirmations such as dependency installation and
153
153
  session deletion are intentionally asked at the action itself.
154
154
 
155
155
  For setup outside the full-screen UI, run `railmux config`; it edits the same
156
- settings as Options and also covers executable paths, SSH history capacity,
156
+ settings as Options and also covers executable paths, managed history capacity,
157
157
  and the runtime locale. Use `railmux config --remote your-server` to configure
158
158
  that host without opening or resizing its tmux workspace. See
159
159
  [Configuration](#configuration) for the complete interface.
@@ -198,9 +198,9 @@ SSH.
198
198
  |--------|--------|
199
199
  | Left-click (non-running) | Preview session history in the Target pane |
200
200
  | Left-click (running) | Switch the Target pane to that session |
201
- | Wheel over a live agent | Scroll its live terminal history (native locally, Railmux-managed over `railmux ssh`) |
201
+ | Wheel over a live agent | Scroll its live terminal history (Railmux-managed on native Windows and over `railmux ssh`; tmux/provider-native on POSIX/WSL local) |
202
202
  | Double-click | Open/attach in the Target pane and move focus there |
203
- | Right-click session | Context menu (Open, Preview, Info, Rename, Star, Copy title, Kill, Term, Delete) |
203
+ | Right-click session | Context menu (Open, Preview, Info, Rename, Star, Copy title, Term, Delete, plus Kill while running) |
204
204
  | Right-click project | Copy absolute path, Star/Unstar, Info, or open managed Term |
205
205
 
206
206
  Unavailable context-menu actions are hidden for the selected session state.
@@ -305,9 +305,9 @@ profile. The first Codex auto-run prompt uses the corresponding choices:
305
305
 
306
306
  Press `o`, or select **More → Options**, to change persistent behavior without
307
307
  editing TOML. **Layout retention**, **Codex auto-run**, and **Railmux updates**
308
- support **Always**, **Ask every time**, and **Never**. Claude history over
309
- `railmux ssh` supports **Local transcript**, **Ask on first scroll**, and
310
- **Claude native**. Use arrow keys plus
308
+ support **Always**, **Ask every time**, and **Never**. Claude history on
309
+ managed Windows/SSH displays supports **Railmux managed**, **Ask on first
310
+ scroll**, and **Claude native**. Use arrow keys plus
311
311
  `Enter`/`Space`, or click a choice with the mouse. Activating the already
312
312
  selected choice confirms and closes the screen; `Esc` or `o` also closes it.
313
313
  Layout changes do not resize the current workspace; Codex auto-run changes
@@ -409,12 +409,13 @@ are hidden. Codex rewind lineages and Claude Code `parentUuid` branches are
409
409
  projected onto the provider's current conversation: the retained prefix and
410
410
  replacement suffix remain visible, while the abandoned suffix is hidden.
411
411
 
412
- Scrolling a live agent does not enter Preview. Direct `railmux` uses the
413
- terminal/tmux scrolling behavior; `railmux ssh` keeps its own bounded,
414
- per-pane history and normally preserves the live terminal's captured styling.
412
+ Scrolling a live agent does not enter Preview. POSIX/WSL direct `railmux` uses
413
+ terminal/tmux scrolling; native Windows and `railmux ssh` use the shared
414
+ bounded per-pane history controller and normally preserve the live terminal's
415
+ captured styling.
415
416
  When Railmux confirms that a running Codex session advanced after rewind or
416
417
  steering, it leaves the live terminal untouched and advances only that pane's
417
- SSH history generation. The SSH history for that branched generation uses the
418
+ managed history generation. The history for that branched generation uses the
418
419
  canonical rollout so its abandoned suffix stays hidden.
419
420
 
420
421
  Preview opens at the latest activity in `less`; large sessions are limited to
@@ -565,11 +566,9 @@ agent_transport = "swap" # or "nested"
565
566
  [interaction]
566
567
  # Clicked paths in native Windows and railmux ssh: "ask", "internal", or "external"
567
568
  path_open = "ask"
568
-
569
- [ssh]
570
- # Local railmux ssh history cap (default: 10000; range: 2000-20000)
569
+ # Railmux-managed history cap (default: 10000; range: 2000-20000)
571
570
  history_lines = 10000
572
- # Claude Code wheel history: "ask", "local", or "native"
571
+ # Claude Code history on managed displays: "ask", "local", or "native"
573
572
  claude_history = "ask"
574
573
  ```
575
574
 
@@ -579,11 +578,15 @@ tmux environment.
579
578
 
580
579
  This is Railmux's only user settings file. Manual edits, `railmux config`, and
581
580
  the in-app Options screen share the same authority and preserve comments,
582
- formatting, order, and unknown keys. The local-only `ssh.history_lines` setting
583
- belongs to the machine that starts `railmux ssh`; `ssh.claude_history` belongs
584
- to the remote workspace. The shared `interaction.path_open` preference
585
- controls recognized paths in native Windows and `railmux ssh`. Current
586
- interactive preferences are also exposed in Options.
581
+ formatting, order, and unknown keys. `interaction.history_lines` belongs to
582
+ the display client: the native Windows machine for local Railmux, or the
583
+ machine that starts `railmux ssh`. `interaction.claude_history` belongs to the
584
+ workspace that runs Claude Code, so it is remote for `railmux ssh`. The
585
+ released `ssh.history_lines`, `ssh.claude_history`, and `ssh.path_open`
586
+ spellings are still read during upgrade, while new writes use `[interaction]`.
587
+ The shared `interaction.path_open` preference controls recognized paths in
588
+ native Windows and `railmux ssh`. Current interactive preferences are also
589
+ exposed in Options.
587
590
 
588
591
  Program and locale changes affect new Railmux-managed processes. They never
589
592
  restart, replace, or kill an existing tmux server or running agent. If a newly
@@ -762,28 +765,32 @@ only the local display and leaves remote agents running. Password or MFA input
762
765
  is supported during the initial connection, but automatic reconnect is
763
766
  non-interactive and asks you to rerun the command when authentication changes.
764
767
 
765
- #### History, Claude behavior, and copying
768
+ #### Managed history, Claude behavior, and copying
769
+
770
+ Native Windows and `railmux ssh` use the same responsive local history cache
771
+ inside agent panes. Each pane keeps its own position; live provider output
772
+ continues to drain behind a frozen viewport, and scrolling to the bottom,
773
+ pressing `Esc`, or typing returns that pane to current output. The default cap
774
+ is 10000 lines and the supported range is 2000-20000. POSIX/macOS SSH clients
775
+ move one row per decoded terminal wheel event; managed Windows clients use a
776
+ three-row step. Precision touchpads retain every event while adjacent paints
777
+ are coalesced. POSIX/WSL local Railmux keeps its existing tmux/provider-native
778
+ wheel behavior.
766
779
 
767
- Mouse-wheel and `Page Up` / `Page Down` browsing use a responsive local cache
768
- in agent panes. Each pane keeps its own position; scroll to the bottom, press
769
- `Esc`, or type to return that pane to live output. The default cap is 10000
770
- lines and the supported range is 2000-20000. POSIX/macOS clients move one row
771
- per decoded terminal wheel event; native Windows clients use the same common
772
- three-row step as local tmux/provider scrolling. Precision touchpads retain
773
- every event while adjacent paints are coalesced:
780
+ For a one-connection SSH override:
774
781
 
775
782
  ```bash
776
783
  railmux ssh --history-lines 10000 your-server
777
784
  ```
778
785
 
779
- Set `ssh.history_lines` persistently with `railmux config`. Reaching the
786
+ Set `interaction.history_lines` persistently with `railmux config`. Reaching the
780
787
  available top shows a one-time `History top` message. Higher caps use more local
781
788
  memory and do not change remote tmux's own history limit.
782
789
 
783
790
  Claude Code can use either Railmux's smooth read-only transcript or Claude's
784
791
  native clickable history. The first upward scroll asks which behavior to use,
785
792
  with **Always** and **this time** choices; change it later under **More →
786
- Options → Claude history in railmux ssh**.
793
+ Options → Claude managed history**.
787
794
 
788
795
  Dragging inside a visible agent pane selects and copies locally without tmux
789
796
  copy-mode. Selection stays within that pane and viewport. `Ctrl-B [` remains
@@ -104,13 +104,13 @@ after showing the exact command and asking for confirmation. See
104
104
  requires a virtual environment.
105
105
 
106
106
  Preference prompts appear only when relevant—for updates, Codex auto-run,
107
- layout retention, or Claude history over `railmux ssh`. Persistent choices are
107
+ layout retention, or Claude history on a managed Windows/SSH display. Persistent choices are
108
108
  not permanent traps: press `o`, or choose **More → Options**, to change them
109
109
  later. One-time safety confirmations such as dependency installation and
110
110
  session deletion are intentionally asked at the action itself.
111
111
 
112
112
  For setup outside the full-screen UI, run `railmux config`; it edits the same
113
- settings as Options and also covers executable paths, SSH history capacity,
113
+ settings as Options and also covers executable paths, managed history capacity,
114
114
  and the runtime locale. Use `railmux config --remote your-server` to configure
115
115
  that host without opening or resizing its tmux workspace. See
116
116
  [Configuration](#configuration) for the complete interface.
@@ -155,9 +155,9 @@ SSH.
155
155
  |--------|--------|
156
156
  | Left-click (non-running) | Preview session history in the Target pane |
157
157
  | Left-click (running) | Switch the Target pane to that session |
158
- | Wheel over a live agent | Scroll its live terminal history (native locally, Railmux-managed over `railmux ssh`) |
158
+ | Wheel over a live agent | Scroll its live terminal history (Railmux-managed on native Windows and over `railmux ssh`; tmux/provider-native on POSIX/WSL local) |
159
159
  | Double-click | Open/attach in the Target pane and move focus there |
160
- | Right-click session | Context menu (Open, Preview, Info, Rename, Star, Copy title, Kill, Term, Delete) |
160
+ | Right-click session | Context menu (Open, Preview, Info, Rename, Star, Copy title, Term, Delete, plus Kill while running) |
161
161
  | Right-click project | Copy absolute path, Star/Unstar, Info, or open managed Term |
162
162
 
163
163
  Unavailable context-menu actions are hidden for the selected session state.
@@ -262,9 +262,9 @@ profile. The first Codex auto-run prompt uses the corresponding choices:
262
262
 
263
263
  Press `o`, or select **More → Options**, to change persistent behavior without
264
264
  editing TOML. **Layout retention**, **Codex auto-run**, and **Railmux updates**
265
- support **Always**, **Ask every time**, and **Never**. Claude history over
266
- `railmux ssh` supports **Local transcript**, **Ask on first scroll**, and
267
- **Claude native**. Use arrow keys plus
265
+ support **Always**, **Ask every time**, and **Never**. Claude history on
266
+ managed Windows/SSH displays supports **Railmux managed**, **Ask on first
267
+ scroll**, and **Claude native**. Use arrow keys plus
268
268
  `Enter`/`Space`, or click a choice with the mouse. Activating the already
269
269
  selected choice confirms and closes the screen; `Esc` or `o` also closes it.
270
270
  Layout changes do not resize the current workspace; Codex auto-run changes
@@ -366,12 +366,13 @@ are hidden. Codex rewind lineages and Claude Code `parentUuid` branches are
366
366
  projected onto the provider's current conversation: the retained prefix and
367
367
  replacement suffix remain visible, while the abandoned suffix is hidden.
368
368
 
369
- Scrolling a live agent does not enter Preview. Direct `railmux` uses the
370
- terminal/tmux scrolling behavior; `railmux ssh` keeps its own bounded,
371
- per-pane history and normally preserves the live terminal's captured styling.
369
+ Scrolling a live agent does not enter Preview. POSIX/WSL direct `railmux` uses
370
+ terminal/tmux scrolling; native Windows and `railmux ssh` use the shared
371
+ bounded per-pane history controller and normally preserve the live terminal's
372
+ captured styling.
372
373
  When Railmux confirms that a running Codex session advanced after rewind or
373
374
  steering, it leaves the live terminal untouched and advances only that pane's
374
- SSH history generation. The SSH history for that branched generation uses the
375
+ managed history generation. The history for that branched generation uses the
375
376
  canonical rollout so its abandoned suffix stays hidden.
376
377
 
377
378
  Preview opens at the latest activity in `less`; large sessions are limited to
@@ -522,11 +523,9 @@ agent_transport = "swap" # or "nested"
522
523
  [interaction]
523
524
  # Clicked paths in native Windows and railmux ssh: "ask", "internal", or "external"
524
525
  path_open = "ask"
525
-
526
- [ssh]
527
- # Local railmux ssh history cap (default: 10000; range: 2000-20000)
526
+ # Railmux-managed history cap (default: 10000; range: 2000-20000)
528
527
  history_lines = 10000
529
- # Claude Code wheel history: "ask", "local", or "native"
528
+ # Claude Code history on managed displays: "ask", "local", or "native"
530
529
  claude_history = "ask"
531
530
  ```
532
531
 
@@ -536,11 +535,15 @@ tmux environment.
536
535
 
537
536
  This is Railmux's only user settings file. Manual edits, `railmux config`, and
538
537
  the in-app Options screen share the same authority and preserve comments,
539
- formatting, order, and unknown keys. The local-only `ssh.history_lines` setting
540
- belongs to the machine that starts `railmux ssh`; `ssh.claude_history` belongs
541
- to the remote workspace. The shared `interaction.path_open` preference
542
- controls recognized paths in native Windows and `railmux ssh`. Current
543
- interactive preferences are also exposed in Options.
538
+ formatting, order, and unknown keys. `interaction.history_lines` belongs to
539
+ the display client: the native Windows machine for local Railmux, or the
540
+ machine that starts `railmux ssh`. `interaction.claude_history` belongs to the
541
+ workspace that runs Claude Code, so it is remote for `railmux ssh`. The
542
+ released `ssh.history_lines`, `ssh.claude_history`, and `ssh.path_open`
543
+ spellings are still read during upgrade, while new writes use `[interaction]`.
544
+ The shared `interaction.path_open` preference controls recognized paths in
545
+ native Windows and `railmux ssh`. Current interactive preferences are also
546
+ exposed in Options.
544
547
 
545
548
  Program and locale changes affect new Railmux-managed processes. They never
546
549
  restart, replace, or kill an existing tmux server or running agent. If a newly
@@ -719,28 +722,32 @@ only the local display and leaves remote agents running. Password or MFA input
719
722
  is supported during the initial connection, but automatic reconnect is
720
723
  non-interactive and asks you to rerun the command when authentication changes.
721
724
 
722
- #### History, Claude behavior, and copying
725
+ #### Managed history, Claude behavior, and copying
726
+
727
+ Native Windows and `railmux ssh` use the same responsive local history cache
728
+ inside agent panes. Each pane keeps its own position; live provider output
729
+ continues to drain behind a frozen viewport, and scrolling to the bottom,
730
+ pressing `Esc`, or typing returns that pane to current output. The default cap
731
+ is 10000 lines and the supported range is 2000-20000. POSIX/macOS SSH clients
732
+ move one row per decoded terminal wheel event; managed Windows clients use a
733
+ three-row step. Precision touchpads retain every event while adjacent paints
734
+ are coalesced. POSIX/WSL local Railmux keeps its existing tmux/provider-native
735
+ wheel behavior.
723
736
 
724
- Mouse-wheel and `Page Up` / `Page Down` browsing use a responsive local cache
725
- in agent panes. Each pane keeps its own position; scroll to the bottom, press
726
- `Esc`, or type to return that pane to live output. The default cap is 10000
727
- lines and the supported range is 2000-20000. POSIX/macOS clients move one row
728
- per decoded terminal wheel event; native Windows clients use the same common
729
- three-row step as local tmux/provider scrolling. Precision touchpads retain
730
- every event while adjacent paints are coalesced:
737
+ For a one-connection SSH override:
731
738
 
732
739
  ```bash
733
740
  railmux ssh --history-lines 10000 your-server
734
741
  ```
735
742
 
736
- Set `ssh.history_lines` persistently with `railmux config`. Reaching the
743
+ Set `interaction.history_lines` persistently with `railmux config`. Reaching the
737
744
  available top shows a one-time `History top` message. Higher caps use more local
738
745
  memory and do not change remote tmux's own history limit.
739
746
 
740
747
  Claude Code can use either Railmux's smooth read-only transcript or Claude's
741
748
  native clickable history. The first upward scroll asks which behavior to use,
742
749
  with **Always** and **this time** choices; change it later under **More →
743
- Options → Claude history in railmux ssh**.
750
+ Options → Claude managed history**.
744
751
 
745
752
  Dragging inside a visible agent pane selects and copies locally without tmux
746
753
  copy-mode. Selection stays within that pane and viewport. `Ctrl-B [` remains
@@ -0,0 +1 @@
1
+ __version__ = "0.4.1.dev3"
@@ -12,9 +12,9 @@ except ModuleNotFoundError: # Python 3.9-3.10
12
12
  import tomli as tomllib
13
13
 
14
14
  from railmux.setting_contracts import (
15
- SSH_HISTORY_DEFAULT_LINES,
16
- SSH_HISTORY_MAX_LINES,
17
- SSH_HISTORY_MIN_LINES,
15
+ HISTORY_DEFAULT_LINES,
16
+ HISTORY_MAX_LINES,
17
+ HISTORY_MIN_LINES,
18
18
  bounds_for,
19
19
  choices_for,
20
20
  )
@@ -35,10 +35,20 @@ class Config:
35
35
  poll_interval_ms: int = 1000
36
36
  agent_transport: str = "swap"
37
37
  show_empty_projects: bool = False
38
- ssh_history_lines: int = SSH_HISTORY_DEFAULT_LINES
39
- ssh_claude_history: str = "ask"
38
+ history_lines: int = HISTORY_DEFAULT_LINES
39
+ claude_history: str = "ask"
40
40
  interaction_path_open: str = "ask"
41
41
 
42
+ @property
43
+ def ssh_history_lines(self) -> int:
44
+ """Compatibility alias for the released SSH-only setting name."""
45
+ return self.history_lines
46
+
47
+ @property
48
+ def ssh_claude_history(self) -> str:
49
+ """Compatibility alias for the released SSH-only setting name."""
50
+ return self.claude_history
51
+
42
52
  @property
43
53
  def ssh_path_open(self) -> str:
44
54
  """Compatibility alias for clients released before 0.4.0."""
@@ -148,24 +158,42 @@ def load_config(config_path: Path | None = None) -> Config:
148
158
  raise ConfigError(
149
159
  'live.agent_transport must be either "nested" or "swap"')
150
160
 
151
- history_lines = ssh.get("history_lines", SSH_HISTORY_DEFAULT_LINES)
152
- history_min, history_max = bounds_for("ssh.history_lines")
161
+ canonical_history_lines = "history_lines" in interaction
162
+ history_lines = interaction.get(
163
+ "history_lines",
164
+ ssh.get("history_lines", HISTORY_DEFAULT_LINES),
165
+ )
166
+ history_min, history_max = bounds_for("interaction.history_lines")
153
167
  if (
154
168
  not isinstance(history_lines, int)
155
169
  or isinstance(history_lines, bool)
156
170
  or not history_min <= history_lines <= history_max
157
171
  ):
158
172
  raise ConfigError(
159
- "ssh.history_lines must be an integer between "
160
- f"{SSH_HISTORY_MIN_LINES} and {SSH_HISTORY_MAX_LINES}"
173
+ (
174
+ "interaction.history_lines"
175
+ if canonical_history_lines
176
+ else "ssh.history_lines"
177
+ )
178
+ + " must be an integer between "
179
+ f"{HISTORY_MIN_LINES} and {HISTORY_MAX_LINES}"
161
180
  )
162
- claude_history = ssh.get("claude_history", "ask")
181
+ canonical_claude_history = "claude_history" in interaction
182
+ claude_history = interaction.get(
183
+ "claude_history",
184
+ ssh.get("claude_history", "ask"),
185
+ )
163
186
  if (
164
187
  not isinstance(claude_history, str)
165
- or claude_history not in choices_for("ssh.claude_history")
188
+ or claude_history not in choices_for("interaction.claude_history")
166
189
  ):
167
190
  raise ConfigError(
168
- 'ssh.claude_history must be "ask", "local", or "native"'
191
+ (
192
+ "interaction.claude_history"
193
+ if canonical_claude_history
194
+ else "ssh.claude_history"
195
+ )
196
+ + ' must be "ask", "local", or "native"'
169
197
  )
170
198
  # The transport-neutral key wins. The released SSH-only spelling remains
171
199
  # a read alias so an upgrade never silently forgets the user's choice.
@@ -188,7 +216,7 @@ def load_config(config_path: Path | None = None) -> Config:
188
216
  poll_interval_ms=poll_interval_ms,
189
217
  agent_transport=agent_transport,
190
218
  show_empty_projects=projects.get("show_empty_projects") is True,
191
- ssh_history_lines=history_lines,
192
- ssh_claude_history=claude_history,
219
+ history_lines=history_lines,
220
+ claude_history=claude_history,
193
221
  interaction_path_open=path_open,
194
222
  )
@@ -98,7 +98,7 @@ _BEHAVIOR_SETTINGS = (
98
98
  "set_update_policy",
99
99
  ),
100
100
  _PolicySetting(
101
- "Claude history in railmux ssh", "ssh", "claude_history",
101
+ "Claude managed history", "interaction", "claude_history",
102
102
  "claude_history_policy",
103
103
  (("local", "Always use smooth local history"),
104
104
  ("ask", "Ask on first upward scroll"),
@@ -119,7 +119,7 @@ _BEHAVIOR_KEYS = {
119
119
  "ui": ("layout_retention", "layout_profile"),
120
120
  "codex": ("auto_run",),
121
121
  "updates": ("auto_update",),
122
- "interaction": ("path_open",),
122
+ "interaction": ("history_lines", "claude_history", "path_open"),
123
123
  "ssh": ("history_lines", "claude_history", "path_open"),
124
124
  }
125
125
  _PROGRAM_KEYS = {
@@ -274,6 +274,23 @@ def _reset_one(
274
274
  _saved(settings.reset_keys({section: (key,)}), feedback)
275
275
 
276
276
 
277
+ def _reset_behavior_setting(
278
+ settings: Settings,
279
+ section: str,
280
+ key: str,
281
+ feedback: _Feedback,
282
+ ) -> None:
283
+ keys = {section: (key,)}
284
+ if section == "interaction" and key in {
285
+ "history_lines",
286
+ "claude_history",
287
+ "path_open",
288
+ }:
289
+ # Reset means default, not "reveal a released alias underneath".
290
+ keys["ssh"] = (key,)
291
+ _saved(settings.reset_keys(keys), feedback)
292
+
293
+
277
294
  def _edit_policy(
278
295
  item: _PolicySetting,
279
296
  stdin: TextIO,
@@ -311,7 +328,18 @@ def _edit_policy(
311
328
  if item.section == "ui" and item.key == "layout_retention"
312
329
  else (item.key,)
313
330
  )
314
- _saved(settings.reset_keys({item.section: reset_keys}), feedback)
331
+ if reset_keys == (item.key,):
332
+ _reset_behavior_setting(
333
+ settings,
334
+ item.section,
335
+ item.key,
336
+ feedback,
337
+ )
338
+ else:
339
+ _saved(
340
+ settings.reset_keys({item.section: reset_keys}),
341
+ feedback,
342
+ )
315
343
  return None
316
344
  if not choice.isdigit() or not 1 <= int(choice) <= len(item.choices):
317
345
  feedback.set("Choose one of the listed entries.", level="warning")
@@ -334,9 +362,9 @@ def _edit_history_lines(
334
362
  stdout,
335
363
  remote_context=remote_context,
336
364
  category="Behavior / Options",
337
- setting="railmux ssh history lines",
365
+ setting="managed history lines",
338
366
  )
339
- _write(stdout, f"Current: {config.ssh_history_lines}")
367
+ _write(stdout, f"Current: {config.history_lines}")
340
368
  _write(stdout)
341
369
  _write(stdout, "Enter 2000-20000, r to reset, b to go back, or q to exit.")
342
370
  _render_feedback(stdout, feedback)
@@ -347,7 +375,12 @@ def _edit_history_lines(
347
375
  return _EXIT
348
376
  settings = Settings()
349
377
  if value == "r":
350
- _reset_one(settings, "ssh", "history_lines", feedback)
378
+ _reset_behavior_setting(
379
+ settings,
380
+ "interaction",
381
+ "history_lines",
382
+ feedback,
383
+ )
351
384
  return None
352
385
  try:
353
386
  parsed = int(value)
@@ -357,7 +390,7 @@ def _edit_history_lines(
357
390
  level="error",
358
391
  )
359
392
  return None
360
- _saved(settings.set_ssh_history_lines(parsed), feedback)
393
+ _saved(settings.set_history_lines(parsed), feedback)
361
394
  return None
362
395
 
363
396
 
@@ -380,8 +413,8 @@ def _behavior_menu(
380
413
  ]
381
414
  labels = [item.title for item in _BEHAVIOR_SETTINGS]
382
415
  if not remote_context:
383
- current.append(str(config.ssh_history_lines))
384
- labels.append("railmux ssh history lines")
416
+ current.append(str(config.history_lines))
417
+ labels.append("Managed history lines")
385
418
  _render_category_header(
386
419
  stdout,
387
420
  remote_context=remote_context,
@@ -405,7 +438,10 @@ def _behavior_menu(
405
438
  if _confirm(stdin, stdout, "Reset every behavior option?"):
406
439
  behavior_keys = dict(_BEHAVIOR_KEYS)
407
440
  if remote_context:
408
- behavior_keys["interaction"] = ("path_open",)
441
+ behavior_keys["interaction"] = (
442
+ "claude_history",
443
+ "path_open",
444
+ )
409
445
  behavior_keys["ssh"] = ("claude_history", "path_open")
410
446
  _saved(settings.reset_keys(behavior_keys), feedback)
411
447
  continue
@@ -683,7 +719,7 @@ def _recover_invalid_config(
683
719
  def _managed_reset_keys(*, remote_context: bool) -> dict[str, tuple[str, ...]]:
684
720
  keys = dict(MANAGED_CONFIG_KEYS)
685
721
  if remote_context:
686
- keys["interaction"] = ("path_open",)
722
+ keys["interaction"] = ("claude_history", "path_open")
687
723
  keys["ssh"] = ("claude_history", "path_open")
688
724
  return keys
689
725
 
@@ -30,10 +30,9 @@ from typing import BinaryIO, Optional, Sequence
30
30
  from railmux import __version__, local_clipboard, local_open
31
31
  from railmux.config import (
32
32
  ConfigError,
33
- SSH_HISTORY_MAX_LINES,
34
- SSH_HISTORY_MIN_LINES,
35
33
  load_config,
36
34
  )
35
+ from railmux.setting_contracts import HISTORY_MAX_LINES, HISTORY_MIN_LINES
37
36
  from railmux.fast_display_history import (
38
37
  HistoryAction,
39
38
  LocalHistoryView,
@@ -2306,8 +2305,8 @@ def parse_args(argv: Optional[Sequence[str]] = None) -> argparse.Namespace:
2306
2305
  metavar="LINES",
2307
2306
  help=(
2308
2307
  "local agent history limit "
2309
- f"({SSH_HISTORY_MIN_LINES}-{SSH_HISTORY_MAX_LINES}; "
2310
- "default from [ssh].history_lines)"
2308
+ f"({HISTORY_MIN_LINES}-{HISTORY_MAX_LINES}; "
2309
+ "default from [interaction].history_lines)"
2311
2310
  ),
2312
2311
  )
2313
2312
  parser.add_argument(
@@ -2331,11 +2330,11 @@ def parse_args(argv: Optional[Sequence[str]] = None) -> argparse.Namespace:
2331
2330
  parser.error("--fps must be between 1 and 60")
2332
2331
  if (
2333
2332
  args.history_lines is not None
2334
- and not SSH_HISTORY_MIN_LINES <= args.history_lines <= SSH_HISTORY_MAX_LINES
2333
+ and not HISTORY_MIN_LINES <= args.history_lines <= HISTORY_MAX_LINES
2335
2334
  ):
2336
2335
  parser.error(
2337
2336
  "--history-lines must be between "
2338
- f"{SSH_HISTORY_MIN_LINES} and {SSH_HISTORY_MAX_LINES}"
2337
+ f"{HISTORY_MIN_LINES} and {HISTORY_MAX_LINES}"
2339
2338
  )
2340
2339
  return args
2341
2340
 
@@ -2352,7 +2351,7 @@ def run(args: argparse.Namespace) -> int:
2352
2351
  "or reset it"
2353
2352
  ) from exc
2354
2353
  history_limit = (
2355
- config.ssh_history_lines
2354
+ config.history_lines
2356
2355
  if args.history_lines is None
2357
2356
  else args.history_lines
2358
2357
  )