railmux 0.4.1.dev3__tar.gz → 0.4.1.dev4__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 (205) hide show
  1. {railmux-0.4.1.dev3/src/railmux.egg-info → railmux-0.4.1.dev4}/PKG-INFO +1 -1
  2. railmux-0.4.1.dev4/src/railmux/__init__.py +1 -0
  3. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/windows_attach_relay.py +26 -5
  4. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4/src/railmux.egg-info}/PKG-INFO +1 -1
  5. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_windows_attach_relay.py +114 -0
  6. railmux-0.4.1.dev3/src/railmux/__init__.py +0 -1
  7. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/LICENSE +0 -0
  8. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/MANIFEST.in +0 -0
  9. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/README.md +0 -0
  10. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/pyproject.toml +0 -0
  11. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/setup.cfg +0 -0
  12. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/__main__.py +0 -0
  13. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/atomic_file.py +0 -0
  14. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/background_index.py +0 -0
  15. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/cli.py +0 -0
  16. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/codex_index.py +0 -0
  17. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/config.py +0 -0
  18. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/config_cli.py +0 -0
  19. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/diagnostic_contract.py +0 -0
  20. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/diagnostics.py +0 -0
  21. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/discovery.py +0 -0
  22. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/display_transport.py +0 -0
  23. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/entrypoint.py +0 -0
  24. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/fast_display_client.py +0 -0
  25. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/fast_display_history.py +0 -0
  26. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/fast_display_input.py +0 -0
  27. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/fast_display_protocol.py +0 -0
  28. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/fast_display_server.py +0 -0
  29. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/favorites.py +0 -0
  30. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/fuzzy.py +0 -0
  31. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/help_workspace.py +0 -0
  32. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/launcher.py +0 -0
  33. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/legacy_sessions.py +0 -0
  34. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/local_clipboard.py +0 -0
  35. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/local_open.py +0 -0
  36. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/models.py +0 -0
  37. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/modes.py +0 -0
  38. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/mouse_manager.py +0 -0
  39. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/orphan_marker.py +0 -0
  40. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/pane_surface.py +0 -0
  41. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/path_codec.py +0 -0
  42. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/preview_pager.py +0 -0
  43. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/project_favorites.py +0 -0
  44. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/provider_paths.py +0 -0
  45. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/release_version.py +0 -0
  46. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/remote_config.py +0 -0
  47. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/renames.py +0 -0
  48. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/restart_state.py +0 -0
  49. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/runtime_config.py +0 -0
  50. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/scroll_agent.py +0 -0
  51. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/scroll_manager.py +0 -0
  52. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/selection_isolation.py +0 -0
  53. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/self_update.py +0 -0
  54. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/session_cache.py +0 -0
  55. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/session_index.py +0 -0
  56. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/session_lease.py +0 -0
  57. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/setting_contracts.py +0 -0
  58. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/settings.py +0 -0
  59. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/ssh_args.py +0 -0
  60. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/ssh_compat.py +0 -0
  61. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/ssh_display_diagnostics.py +0 -0
  62. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/ssh_doctor.py +0 -0
  63. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/ssh_preflight.py +0 -0
  64. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/system_deps.py +0 -0
  65. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/terminal_screen.py +0 -0
  66. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/terminal_status.py +0 -0
  67. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/tmux_binding_manager.py +0 -0
  68. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/tmux_capabilities.py +0 -0
  69. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/tmux_ctl.py +0 -0
  70. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/tmux_health.py +0 -0
  71. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/tmux_server.py +0 -0
  72. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/tool_panes.py +0 -0
  73. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/transcript.py +0 -0
  74. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/ui/__init__.py +0 -0
  75. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/ui/_widgets.py +0 -0
  76. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/ui/app.py +0 -0
  77. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/ui/keymap.py +0 -0
  78. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/ui/modals.py +0 -0
  79. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/ui/projects_pane.py +0 -0
  80. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/ui/running_pane.py +0 -0
  81. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/ui/sessions_pane.py +0 -0
  82. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/ui/sidebar.py +0 -0
  83. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/ui/statusbar.py +0 -0
  84. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/ui/workspace.py +0 -0
  85. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/windows_bootstrap.py +0 -0
  86. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/windows_install_log.py +0 -0
  87. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/windows_msys2.py +0 -0
  88. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/windows_pacman.py +0 -0
  89. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/windows_paths.py +0 -0
  90. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/windows_tmux_lifecycle.py +0 -0
  91. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux/windows_ui_transition.py +0 -0
  92. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux.egg-info/SOURCES.txt +0 -0
  93. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux.egg-info/dependency_links.txt +0 -0
  94. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux.egg-info/entry_points.txt +0 -0
  95. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux.egg-info/requires.txt +0 -0
  96. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/src/railmux.egg-info/top_level.txt +0 -0
  97. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/app_test_harness.py +0 -0
  98. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_agent_workspace.py +0 -0
  99. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_app_codex_placeholder.py +0 -0
  100. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_app_quit.py +0 -0
  101. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_app_restart_restore.py +0 -0
  102. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_app_running_recovery.py +0 -0
  103. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_atomic_file.py +0 -0
  104. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_background_index.py +0 -0
  105. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_cli.py +0 -0
  106. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_code_map.py +0 -0
  107. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_codex_delete.py +0 -0
  108. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_codex_index.py +0 -0
  109. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_codex_lineage.py +0 -0
  110. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_codex_transcript.py +0 -0
  111. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_config.py +0 -0
  112. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_config_cli.py +0 -0
  113. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_denested_transport_benchmark.py +0 -0
  114. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_diagnostics.py +0 -0
  115. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_discovery.py +0 -0
  116. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_display_transport.py +0 -0
  117. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_fast_display_bootstrap.py +0 -0
  118. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_fast_display_history.py +0 -0
  119. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_fast_display_protocol.py +0 -0
  120. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_fast_display_selection.py +0 -0
  121. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_fast_display_server.py +0 -0
  122. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_fast_display_terminal.py +0 -0
  123. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_focus_highlight.py +0 -0
  124. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_fullscreen_binding.py +0 -0
  125. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_fuzzy.py +0 -0
  126. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_help_agent.py +0 -0
  127. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_help_workspace.py +0 -0
  128. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_history_cleanup.py +0 -0
  129. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_keymap.py +0 -0
  130. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_launcher.py +0 -0
  131. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_layout_profile.py +0 -0
  132. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_legacy_sessions.py +0 -0
  133. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_local_clipboard.py +0 -0
  134. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_local_open.py +0 -0
  135. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_modals.py +0 -0
  136. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_mode_selection.py +0 -0
  137. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_modes.py +0 -0
  138. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_mouse_manager.py +0 -0
  139. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_new_project.py +0 -0
  140. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_options.py +0 -0
  141. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_orphan_recovery.py +0 -0
  142. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_pane_surface.py +0 -0
  143. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_path_codec.py +0 -0
  144. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_preview_pager.py +0 -0
  145. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_project_favorites.py +0 -0
  146. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_projects_pane.py +0 -0
  147. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_provider_paths.py +0 -0
  148. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_release_notes.py +0 -0
  149. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_release_version.py +0 -0
  150. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_release_workflow.py +0 -0
  151. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_remote_config.py +0 -0
  152. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_renames.py +0 -0
  153. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_restart_state.py +0 -0
  154. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_running_pane.py +0 -0
  155. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_running_sort.py +0 -0
  156. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_runtime_config.py +0 -0
  157. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_scroll_agent.py +0 -0
  158. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_scroll_manager.py +0 -0
  159. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_selection_isolation.py +0 -0
  160. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_self_update.py +0 -0
  161. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_session_cache.py +0 -0
  162. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_session_index.py +0 -0
  163. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_session_lease.py +0 -0
  164. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_sessions_pane.py +0 -0
  165. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_setting_contracts.py +0 -0
  166. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_settings.py +0 -0
  167. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_sidebar.py +0 -0
  168. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_ssh_args.py +0 -0
  169. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_ssh_compat.py +0 -0
  170. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_ssh_display_benchmark.py +0 -0
  171. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_ssh_display_diagnostics.py +0 -0
  172. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_ssh_doctor.py +0 -0
  173. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_status.py +0 -0
  174. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_statusbar.py +0 -0
  175. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_system_deps.py +0 -0
  176. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_terminal_size.py +0 -0
  177. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_terminal_status.py +0 -0
  178. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_termux_local_touch.py +0 -0
  179. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_tmux_binding_manager.py +0 -0
  180. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_tmux_capabilities.py +0 -0
  181. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_tmux_ctl.py +0 -0
  182. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_tmux_health.py +0 -0
  183. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_tmux_integration.py +0 -0
  184. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_tmux_server.py +0 -0
  185. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_tmux_status.py +0 -0
  186. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_tool_panes.py +0 -0
  187. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_transcript.py +0 -0
  188. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_utf8_state.py +0 -0
  189. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_web_demo_recorder.py +0 -0
  190. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_wheel_smoke.py +0 -0
  191. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_widgets.py +0 -0
  192. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_windows_bootstrap.py +0 -0
  193. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_windows_install_log.py +0 -0
  194. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_windows_msys2.py +0 -0
  195. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_windows_pacman.py +0 -0
  196. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_windows_paths.py +0 -0
  197. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_windows_synchronized_screen.py +0 -0
  198. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_windows_tmux_lifecycle.py +0 -0
  199. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_windows_ui_transition.py +0 -0
  200. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_windows_wrapper_contract.py +0 -0
  201. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tests/test_yolo_prompt.py +0 -0
  202. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tools/denested_transport_benchmark.py +0 -0
  203. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tools/release_notes.py +0 -0
  204. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/tools/wheel_smoke.py +0 -0
  205. {railmux-0.4.1.dev3 → railmux-0.4.1.dev4}/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.dev3
3
+ Version: 0.4.1.dev4
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
@@ -0,0 +1 @@
1
+ __version__ = "0.4.1.dev4"
@@ -320,6 +320,22 @@ class _SemanticTerminalRenderer:
320
320
  and self._presentation_serial >= self._presentation_required_serial
321
321
  )
322
322
 
323
+ @property
324
+ def pointer_routing_stable(self) -> bool:
325
+ """Whether the last physical screen still has trusted pointer geometry.
326
+
327
+ An ordinary provider repaint can keep one terminal write in flight for
328
+ long enough to overlap several Windows wheel reports. That does not
329
+ invalidate the already visible pane layout. Explicit topology
330
+ transitions call :meth:`require_fresh_presentation` and remain
331
+ fail-closed until the matching newer frame is physically visible.
332
+ """
333
+ self._promote_presented_screen()
334
+ return bool(
335
+ self._screen is not None
336
+ and self._presentation_serial >= self._presentation_required_serial
337
+ )
338
+
323
339
  def require_fresh_presentation(self) -> None:
324
340
  """Fail pointer input closed until one newer frame is displayed."""
325
341
  required = self._presentation_serial + 1
@@ -1815,14 +1831,19 @@ class LocalPtyClient:
1815
1831
  part,
1816
1832
  logical_height=logical_height,
1817
1833
  )
1818
- if not self._renderer.presentation_stable:
1834
+ routing_stable = self._renderer.presentation_stable or (
1835
+ event.wheel_direction != 0
1836
+ and self._renderer.pointer_routing_stable
1837
+ )
1838
+ if not routing_stable:
1819
1839
  if not self._selection.capturing and self._selection.cancel():
1820
1840
  self._renderer.set_selection(self._selection.segments())
1821
1841
  # A queued frame can already represent a new tmux pane topology
1822
- # while the user still sees the prior one. Dropping only pointer
1823
- # input during this bounded transition is safer than forwarding it
1824
- # to Quit or stock tmux copy-mode. A capture already owns an
1825
- # immutable visible snapshot and therefore keeps the whole gesture.
1842
+ # while the user still sees the prior one. Explicitly untrusted
1843
+ # geometry stays fail-closed; an ordinary content-only write may
1844
+ # still route wheel input against the last physical screen. A
1845
+ # capture already owns an immutable visible snapshot and therefore
1846
+ # keeps the whole gesture.
1826
1847
  if not self._selection.capturing:
1827
1848
  return
1828
1849
  if self._selection.capturing:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: railmux
3
- Version: 0.4.1.dev3
3
+ Version: 0.4.1.dev4
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
@@ -430,6 +430,114 @@ def test_local_windows_wheel_uses_shared_managed_history_without_tmux_copy_mode(
430
430
  child_socket.close()
431
431
 
432
432
 
433
+ def test_local_windows_real_sgr_wheel_survives_busy_content_paint():
434
+ proxy_socket, child_socket = socket.socketpair()
435
+ client = windows_attach_relay.LocalPtyClient.__new__(
436
+ windows_attach_relay.LocalPtyClient
437
+ )
438
+ client.master_fd = proxy_socket.detach()
439
+ client._session_id = "$4"
440
+ client._selection = LocalTextSelection()
441
+ client._routes = ()
442
+ client._routes_checked_at = time.monotonic()
443
+ client._path_prompt = None
444
+ client._path_prompt_mouse_button = None
445
+ _set_local_history_state(client)
446
+ _install_local_history_snapshot(
447
+ client,
448
+ HistorySnapshot(
449
+ 0,
450
+ "%8",
451
+ 0,
452
+ 0,
453
+ 20,
454
+ 2,
455
+ lines=tuple(f"row-{index}".encode() for index in range(8)),
456
+ ),
457
+ )
458
+ renderer = MagicMock()
459
+ renderer.presentation_stable = False
460
+ renderer.pointer_routing_stable = True
461
+ renderer.screen = SimpleNamespace(
462
+ width=20,
463
+ height=3,
464
+ cursor_x=1,
465
+ cursor_y=0,
466
+ rows=(b"live-0", b"live-1", b"status"),
467
+ )
468
+ renderer.surface.translate_mouse_event.side_effect = lambda event, **_kwargs: event
469
+ client._renderer = renderer
470
+ decoder = windows_attach_relay.TerminalInputDecoder()
471
+ child_socket.setblocking(False)
472
+ try:
473
+ parts = decoder.feed(b"\033[<64;2;1M")
474
+ assert len(parts) == 1
475
+ client._forward_input_part(parts[0])
476
+
477
+ assert client._history.active
478
+ renderer.set_history_overlays.assert_called_with(
479
+ client._history.overlays()
480
+ )
481
+ with pytest.raises(BlockingIOError):
482
+ child_socket.recv(64)
483
+ finally:
484
+ os.close(client.master_fd)
485
+ child_socket.close()
486
+
487
+
488
+ def test_local_windows_wheel_stays_fail_closed_during_topology_transition():
489
+ proxy_socket, child_socket = socket.socketpair()
490
+ client = windows_attach_relay.LocalPtyClient.__new__(
491
+ windows_attach_relay.LocalPtyClient
492
+ )
493
+ client.master_fd = proxy_socket.detach()
494
+ client._session_id = "$4"
495
+ client._selection = LocalTextSelection()
496
+ client._routes = ()
497
+ client._routes_checked_at = time.monotonic()
498
+ client._path_prompt = None
499
+ client._path_prompt_mouse_button = None
500
+ _set_local_history_state(client)
501
+ _install_local_history_snapshot(
502
+ client,
503
+ HistorySnapshot(
504
+ 0,
505
+ "%8",
506
+ 0,
507
+ 0,
508
+ 20,
509
+ 2,
510
+ lines=tuple(f"row-{index}".encode() for index in range(8)),
511
+ ),
512
+ )
513
+ renderer = MagicMock()
514
+ renderer.presentation_stable = False
515
+ renderer.pointer_routing_stable = False
516
+ renderer.screen = SimpleNamespace(
517
+ width=20,
518
+ height=3,
519
+ cursor_x=1,
520
+ cursor_y=0,
521
+ rows=(b"live-0", b"live-1", b"status"),
522
+ )
523
+ renderer.surface.translate_mouse_event.side_effect = lambda event, **_kwargs: event
524
+ client._renderer = renderer
525
+ decoder = windows_attach_relay.TerminalInputDecoder()
526
+ child_socket.setblocking(False)
527
+ try:
528
+ parts = decoder.feed(b"\033[<64;2;1M")
529
+ assert len(parts) == 1
530
+ client._forward_input_part(parts[0])
531
+
532
+ assert not client._history.active
533
+ renderer.set_history_overlays.assert_not_called()
534
+ with pytest.raises(BlockingIOError):
535
+ child_socket.recv(64)
536
+ finally:
537
+ os.close(client.master_fd)
538
+ child_socket.close()
539
+
540
+
433
541
  def test_local_windows_sidebar_wheel_stays_tmux_owned():
434
542
  proxy_socket, child_socket = socket.socketpair()
435
543
  client = windows_attach_relay.LocalPtyClient.__new__(
@@ -1199,18 +1307,24 @@ def test_semantic_renderer_hit_testing_waits_for_physical_frame(monkeypatch):
1199
1307
  assert renderer.screen is old_screen
1200
1308
  assert renderer.presentation_serial == old_serial
1201
1309
  assert renderer.presentation_stable is False
1310
+ # Ordinary content backpressure does not invalidate the pane geometry
1311
+ # of the frame that is still physically visible.
1312
+ assert renderer.pointer_routing_stable is True
1202
1313
 
1203
1314
  # A topology mutation requested while this already-queued frame is
1204
1315
  # writing must wait for one still-newer authoritative frame.
1205
1316
  renderer.require_fresh_presentation()
1317
+ assert renderer.pointer_routing_stable is False
1206
1318
  release.set()
1207
1319
  assert renderer.writer.wait_idle(1.0)
1208
1320
  assert renderer.presentation_stable is False
1321
+ assert renderer.pointer_routing_stable is False
1209
1322
  assert renderer.presentation_serial == old_serial + 1
1210
1323
  renderer.feed(b"\033[H\033[2KNEW-TOPOLOGY-VISIBLE")
1211
1324
  renderer.paint_due(3.0, force=True)
1212
1325
  assert renderer.writer.wait_idle(1.0)
1213
1326
  assert renderer.presentation_stable is True
1327
+ assert renderer.pointer_routing_stable is True
1214
1328
  assert b"NEW-TOPOLOGY-VISIBLE" in renderer.screen.rows[0]
1215
1329
  finally:
1216
1330
  release.set()
@@ -1 +0,0 @@
1
- __version__ = "0.4.1.dev3"
File without changes
File without changes
File without changes
File without changes