swarph-cli 0.48.1__tar.gz → 0.48.2__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 (337) hide show
  1. {swarph_cli-0.48.1/src/swarph_cli.egg-info → swarph_cli-0.48.2}/PKG-INFO +1 -1
  2. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/pyproject.toml +1 -1
  3. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/__init__.py +1 -1
  4. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/mesh.py +31 -12
  5. {swarph_cli-0.48.1 → swarph_cli-0.48.2/src/swarph_cli.egg-info}/PKG-INFO +1 -1
  6. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_tmux_wake_submit_verify.py +50 -4
  7. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/LICENSE +0 -0
  8. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/README.md +0 -0
  9. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/setup.cfg +0 -0
  10. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/__main__.py +0 -0
  11. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/bench/__init__.py +0 -0
  12. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/bench/backends.py +0 -0
  13. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/bench/pack.py +0 -0
  14. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/bench/prices.py +0 -0
  15. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/bench/quality.py +0 -0
  16. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/bench/refresh_prices.py +0 -0
  17. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/bench/runner.py +0 -0
  18. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/bench/validate.py +0 -0
  19. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/caller.py +0 -0
  20. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/capture/__init__.py +0 -0
  21. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/capture/harden.py +0 -0
  22. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/capture/lineage.py +0 -0
  23. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/capture/liveness.py +0 -0
  24. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/capture/manifest.py +0 -0
  25. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/capture/paths.py +0 -0
  26. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/capture/verify.py +0 -0
  27. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/cell.py +0 -0
  28. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/chain_token.py +0 -0
  29. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/__init__.py +0 -0
  30. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/_content.py +0 -0
  31. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/_display.py +0 -0
  32. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/_gateway_client.py +0 -0
  33. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/add.py +0 -0
  34. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/bench.py +0 -0
  35. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/board.py +0 -0
  36. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/board_merge_check.py +0 -0
  37. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/brain.py +0 -0
  38. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/brain_ask.py +0 -0
  39. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/cell.py +0 -0
  40. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/cell_selfcheck.py +0 -0
  41. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/channel.py +0 -0
  42. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/chat.py +0 -0
  43. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/codegraph.py +0 -0
  44. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/codegraph_hook.py +0 -0
  45. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/codex_hook_output.py +0 -0
  46. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/codex_waker.py +0 -0
  47. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/compress.py +0 -0
  48. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/daemon.py +0 -0
  49. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/event.py +0 -0
  50. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/gateway.py +0 -0
  51. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/gh_route.py +0 -0
  52. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/group.py +0 -0
  53. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/guide.py +0 -0
  54. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/highlight.py +0 -0
  55. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/hook_output.py +0 -0
  56. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/hooks.py +0 -0
  57. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/import_session.py +0 -0
  58. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/init.py +0 -0
  59. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/install_codex_hooks.py +0 -0
  60. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/install_hook.py +0 -0
  61. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/install_multiplexer.py +0 -0
  62. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/install_postcompact_hook.py +0 -0
  63. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/install_wake_hook.py +0 -0
  64. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/lane.py +0 -0
  65. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/mcp_server.py +0 -0
  66. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/memory.py +0 -0
  67. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/memory_emit_hook.py +0 -0
  68. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/memory_sync.py +0 -0
  69. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/monitor.py +0 -0
  70. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/okf_links.py +0 -0
  71. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/onboard.py +0 -0
  72. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/peer_reply_drain.py +0 -0
  73. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/postcompact_hook_output.py +0 -0
  74. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/protocol_handler.py +0 -0
  75. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/ratify.py +0 -0
  76. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/schedule.py +0 -0
  77. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/security.py +0 -0
  78. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/service.py +0 -0
  79. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/spawn.py +0 -0
  80. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/timeline.py +0 -0
  81. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/wake_hook_output.py +0 -0
  82. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/commands/watchdog.py +0 -0
  83. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/compress/__init__.py +0 -0
  84. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/compress/levers.py +0 -0
  85. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/compress/marker.py +0 -0
  86. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/compress/verify.py +0 -0
  87. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/console_safe.py +0 -0
  88. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/delivery_queue.py +0 -0
  89. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/gateway/__init__.py +0 -0
  90. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/gateway/feature_registry.py +0 -0
  91. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/gateway/lanes_control.py +0 -0
  92. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/gateway/schema.sql +0 -0
  93. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/gateway/server.py +0 -0
  94. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/gateway/services_control.py +0 -0
  95. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/gh_identity.py +0 -0
  96. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/guide/GUIDE.md +0 -0
  97. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/main.py +0 -0
  98. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/multiplexer.py +0 -0
  99. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/parsers/__init__.py +0 -0
  100. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/parsers/claude.py +0 -0
  101. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/payloads/postcompact/_shim.cmd +0 -0
  102. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/payloads/postcompact/postcompact-recall-grok.sh +0 -0
  103. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/payloads/postcompact/postcompact-recall.sh +0 -0
  104. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/payloads/postcompact/posttooluse-emit-antigravity.sh +0 -0
  105. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/payloads/postcompact/posttooluse-emit-claude.sh +0 -0
  106. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/payloads/postcompact/posttooluse-emit-grok.sh +0 -0
  107. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/payloads/postcompact/posttooluse-emit.sh +0 -0
  108. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/payloads/postcompact/posttooluse-recall.sh +0 -0
  109. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/payloads/postcompact/precompact-flag.sh +0 -0
  110. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/payloads/postcompact/preinvocation-recall-antigravity.sh +0 -0
  111. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/payloads/postcompact/sessionstart-recall.sh +0 -0
  112. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/peer_executor.py +0 -0
  113. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/peer_executor_windows.py +0 -0
  114. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/peer_reconciliation.py +0 -0
  115. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/peer_reply_outbox.py +0 -0
  116. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/peer_service_host.py +0 -0
  117. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/peer_service_payload.py +0 -0
  118. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/peer_service_reply.py +0 -0
  119. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/peer_staging.py +0 -0
  120. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/scripts/__init__.py +0 -0
  121. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/scripts/dm_notify_filter.py +0 -0
  122. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/scripts/ensure_monitor.sh +0 -0
  123. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/scripts/install_codex_waker_windows.ps1 +0 -0
  124. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/service/__init__.py +0 -0
  125. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/service/app.py +0 -0
  126. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/service/providers.py +0 -0
  127. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/session_bridge.py +0 -0
  128. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/stall_alert.py +0 -0
  129. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/systemd/codex-waker.default +0 -0
  130. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/systemd/peer-reply-drain.default +0 -0
  131. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/systemd/swarph-codex-outbox@.service +0 -0
  132. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/systemd/swarph-codex-outbox@.timer +0 -0
  133. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/systemd/swarph-codex-waker@.service +0 -0
  134. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/systemd/swarph-codex-waker@.timer +0 -0
  135. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/systemd/swarph-peer-reply-drain@.service +0 -0
  136. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/systemd/swarph-peer-reply-drain@.timer +0 -0
  137. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/systemd/swarph-watchdog.default +0 -0
  138. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/systemd/swarph-watchdog.service +0 -0
  139. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/systemd/swarph-watchdog.timer +0 -0
  140. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli/tokens.py +0 -0
  141. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli.egg-info/SOURCES.txt +0 -0
  142. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli.egg-info/dependency_links.txt +0 -0
  143. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli.egg-info/entry_points.txt +0 -0
  144. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli.egg-info/requires.txt +0 -0
  145. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/src/swarph_cli.egg-info/top_level.txt +0 -0
  146. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_124_register_merge.py +0 -0
  147. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_201_win32_bash_refusal.py +0 -0
  148. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_243_onboard_per_peer_token.py +0 -0
  149. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_307_task4_ask_reply.py +0 -0
  150. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_319_refusal_exit_codes.py +0 -0
  151. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_323_mistral_backend.py +0 -0
  152. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_397_gh_identity_router.py +0 -0
  153. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_397_router_preflight.py +0 -0
  154. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_467b_onboard_operator_credential.py +0 -0
  155. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_523_guide.py +0 -0
  156. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_524_conftest_hermeticity.py +0 -0
  157. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_532_accept_flag.py +0 -0
  158. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_535_version_capability.py +0 -0
  159. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_546_default_gateway.py +0 -0
  160. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_548_gateway_remainder.py +0 -0
  161. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_552_codegraph_gateway.py +0 -0
  162. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_555_relay_row_shape.py +0 -0
  163. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_556_relay_freshness.py +0 -0
  164. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_84_cli_labels.py +0 -0
  165. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_add_security_gate.py +0 -0
  166. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_artifact_add.py +0 -0
  167. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_artifact_hash.py +0 -0
  168. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_artifact_lib.py +0 -0
  169. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_artifact_mcp.py +0 -0
  170. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_artifact_skill.py +0 -0
  171. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_artifact_tool.py +0 -0
  172. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_artifact_uri.py +0 -0
  173. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_bench_backends.py +0 -0
  174. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_bench_command.py +0 -0
  175. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_bench_pack.py +0 -0
  176. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_bench_prices.py +0 -0
  177. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_bench_quality.py +0 -0
  178. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_bench_runner.py +0 -0
  179. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_bench_validate.py +0 -0
  180. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_board_card_thread.py +0 -0
  181. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_board_command.py +0 -0
  182. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_board_merge_check.py +0 -0
  183. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_board_obligation_close.py +0 -0
  184. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_brain_ask_command.py +0 -0
  185. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_brain_ask_env_diagnosis.py +0 -0
  186. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_brain_ask_identity_explicitness.py +0 -0
  187. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_brain_command.py +0 -0
  188. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_caller_meta_guard.py +0 -0
  189. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_capture_lineage.py +0 -0
  190. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_capture_liveness.py +0 -0
  191. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_capture_manifest.py +0 -0
  192. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_capture_paths.py +0 -0
  193. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_capture_security.py +0 -0
  194. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_cell_command_dispatch.py +0 -0
  195. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_cell_harden.py +0 -0
  196. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_cell_loader.py +0 -0
  197. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_cell_selfcheck.py +0 -0
  198. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_cell_verify.py +0 -0
  199. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_chain_token.py +0 -0
  200. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_channel_command.py +0 -0
  201. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_channel_poll_never_breaks_dms.py +0 -0
  202. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_channel_post.py +0 -0
  203. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_channel_wake_policy_filter.py +0 -0
  204. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_chat_command.py +0 -0
  205. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_claude_parser.py +0 -0
  206. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_claude_tmux_template.py +0 -0
  207. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_codegraph_caller_scope.py +0 -0
  208. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_codegraph_command.py +0 -0
  209. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_codegraph_hook.py +0 -0
  210. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_codegraph_mcp.py +0 -0
  211. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_codex_waker.py +0 -0
  212. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_compress_caller_convention.py +0 -0
  213. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_compress_command.py +0 -0
  214. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_compress_levers.py +0 -0
  215. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_compress_marker.py +0 -0
  216. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_compress_verify.py +0 -0
  217. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_console_encoding_e2e.py +0 -0
  218. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_content_composition.py +0 -0
  219. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_cursor_membrane.py +0 -0
  220. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_daemon_command.py +0 -0
  221. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_daemon_console_encoding.py +0 -0
  222. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_daemon_delivery.py +0 -0
  223. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_delivery_queue.py +0 -0
  224. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_display_sanitize.py +0 -0
  225. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_ensure_monitor_no_peer_default.py +0 -0
  226. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_event_emit.py +0 -0
  227. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_feature_to_uri.py +0 -0
  228. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_gateway_brain.py +0 -0
  229. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_gateway_client.py +0 -0
  230. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_gateway_command.py +0 -0
  231. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_gateway_message_idempotency.py +0 -0
  232. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_gh_route_doctor_mesh_name.py +0 -0
  233. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_group_command.py +0 -0
  234. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_heartbeat_check.py +0 -0
  235. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_highlight_command.py +0 -0
  236. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_hook_output.py +0 -0
  237. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_hooks_activity_marker.py +0 -0
  238. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_hooks_add.py +0 -0
  239. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_hooks_bundle.py +0 -0
  240. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_hooks_init.py +0 -0
  241. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_hooks_legacy_generation_removal.py +0 -0
  242. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_hooks_lifecycle.py +0 -0
  243. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_hooks_merge.py +0 -0
  244. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_hooks_verify.py +0 -0
  245. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_hooks_win32_bash_wrapper.py +0 -0
  246. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_hooks_win32_command_path.py +0 -0
  247. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_import_command.py +0 -0
  248. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_inbox_identity_provenance.py +0 -0
  249. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_init_command.py +0 -0
  250. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_init_provider_menu.py +0 -0
  251. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_install_codex_hooks.py +0 -0
  252. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_install_hook.py +0 -0
  253. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_install_multiplexer_command.py +0 -0
  254. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_install_postcompact_hook.py +0 -0
  255. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_install_wake_hook.py +0 -0
  256. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_lane_command.py +0 -0
  257. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_main.py +0 -0
  258. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_main_unknown_verb_guard.py +0 -0
  259. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_mcp_server.py +0 -0
  260. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_memory_command.py +0 -0
  261. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_memory_gateway.py +0 -0
  262. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_memory_sync.py +0 -0
  263. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_memory_sync_membrane.py +0 -0
  264. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_mesh_command.py +0 -0
  265. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_mesh_inbox_mark_read.py +0 -0
  266. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_mesh_inbox_sanitize.py +0 -0
  267. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_mesh_send_unknown_peer.py +0 -0
  268. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_mesh_sidecar.py +0 -0
  269. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_mesh_sidecar_cursor_decoupled.py +0 -0
  270. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_mesh_sidecar_wake_survives_read.py +0 -0
  271. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_meta_edge_identity.py +0 -0
  272. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_monitor_channel_poll.py +0 -0
  273. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_monitor_cli.py +0 -0
  274. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_monitor_daemon_collision.py +0 -0
  275. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_monitor_self_name_verification.py +0 -0
  276. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_monitor_state_split.py +0 -0
  277. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_multiplexer.py +0 -0
  278. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_muse_membrane.py +0 -0
  279. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_muse_own_cli.py +0 -0
  280. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_obligation_close_is_surfaced.py +0 -0
  281. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_okf_links.py +0 -0
  282. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_onboard_command.py +0 -0
  283. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_packaged_artifacts_exist.py +0 -0
  284. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_peer_executor.py +0 -0
  285. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_peer_executor_windows.py +0 -0
  286. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_peer_reply_drain_command.py +0 -0
  287. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_peer_reply_drain_supervisor.py +0 -0
  288. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_peer_reply_outbox.py +0 -0
  289. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_peer_reply_transport.py +0 -0
  290. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_peer_service_e2e.py +0 -0
  291. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_peer_service_host.py +0 -0
  292. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_peer_service_payload.py +0 -0
  293. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_peer_service_reply.py +0 -0
  294. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_postcompact_recall.py +0 -0
  295. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_process_liveness.py +0 -0
  296. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_protocol_handler.py +0 -0
  297. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_providers_isolation.py +0 -0
  298. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_ratify_command.py +0 -0
  299. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_repl_caller_convention.py +0 -0
  300. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_schedule_command.py +0 -0
  301. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_schedule_create_contract.py +0 -0
  302. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_security.py +0 -0
  303. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_service_app.py +0 -0
  304. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_service_command.py +0 -0
  305. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_service_providers.py +0 -0
  306. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_session_bridge_inject.py +0 -0
  307. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_session_bridge_probe.py +0 -0
  308. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_session_bridge_resolve.py +0 -0
  309. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_session_path_role_gate.py +0 -0
  310. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_shipped_units_match_the_cli.py +0 -0
  311. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_smoke_chat.py +0 -0
  312. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_smoke_one_shot.py +0 -0
  313. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_smoke_phase_5_5.py +0 -0
  314. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_spawn_base_hoist.py +0 -0
  315. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_spawn_command.py +0 -0
  316. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_spawn_identity_stamp.py +0 -0
  317. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_spawn_live_pin.py +0 -0
  318. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_spawn_mitosis_lineage.py +0 -0
  319. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_spawn_tmux_session.py +0 -0
  320. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_spawn_windows_relaunch.py +0 -0
  321. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_stall_alert.py +0 -0
  322. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_subprocess_decode_encoding.py +0 -0
  323. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_timeline_command.py +0 -0
  324. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_token_file_one_parser.py +0 -0
  325. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_token_precedence_explicit_first.py +0 -0
  326. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_unified_token_resolver.py +0 -0
  327. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_version_consistency.py +0 -0
  328. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_vibe_membrane.py +0 -0
  329. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_watchdog.py +0 -0
  330. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_watchdog_dm_wake.py +0 -0
  331. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_watchdog_dm_wake_cooldown.py +0 -0
  332. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_watchdog_dm_wake_wiring.py +0 -0
  333. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_watchdog_emit_health.py +0 -0
  334. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_watchdog_install_flags.py +0 -0
  335. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_watchdog_model_rung.py +0 -0
  336. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_watchdog_stale_peers.py +0 -0
  337. {swarph_cli-0.48.1 → swarph_cli-0.48.2}/tests/test_windows_waker_installer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: swarph-cli
3
- Version: 0.48.1
3
+ Version: 0.48.2
4
4
  Summary: The `swarph` binary — a multi-LLM CLI and mesh-gateway client + bundled server (`swarph gateway`): one-shot prompts across providers, interactive `chat`, multi-provider `spawn` (claude/codex/antigravity via a ProviderMembrane with subprocess billing-scrub), `mesh` send/inbox/register, `brain-ask` over the swarph-brain (gbrain) semantic memory, git-backed `assisted_memory`, per-invocation `gh` identity routing, a silent DM-wake hook, session `import`, and a stranded-session `watchdog`.
5
5
  Author: Pierre Samson, Claude Opus
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "swarph-cli"
7
- version = "0.48.1"
7
+ version = "0.48.2"
8
8
  description = "The `swarph` binary — a multi-LLM CLI and mesh-gateway client + bundled server (`swarph gateway`): one-shot prompts across providers, interactive `chat`, multi-provider `spawn` (claude/codex/antigravity via a ProviderMembrane with subprocess billing-scrub), `mesh` send/inbox/register, `brain-ask` over the swarph-brain (gbrain) semantic memory, git-backed `assisted_memory`, per-invocation `gh` identity routing, a silent DM-wake hook, session `import`, and a stranded-session `watchdog`."
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -16,6 +16,6 @@ The architecture splits CLI from substrate so:
16
16
 
17
17
  from __future__ import annotations
18
18
 
19
- __version__ = "0.48.1"
19
+ __version__ = "0.48.2"
20
20
 
21
21
  __all__ = ["__version__"]
@@ -1204,6 +1204,12 @@ class TmuxSink(Sink):
1204
1204
  # Module-global lookup on purpose: the sidecar regression suites patch
1205
1205
  # `mesh._tmux_wake`, and a `from`-import here would silently bypass them.
1206
1206
  ok = _tmux_wake(self.target)
1207
+ if ok is None:
1208
+ # The human ADOPTED the composer mid-settle (gpt-ops, #312 round
1209
+ # 5): the wake text never submitted as ours. DEFER — the cursor
1210
+ # must NOT advance, or the wake is silently lost when the human
1211
+ # never sends their line.
1212
+ return None
1207
1213
  if ok:
1208
1214
  led["wake_outstanding"] = True
1209
1215
  return True
@@ -1653,7 +1659,12 @@ def _composer_state(target: str) -> Optional[str]:
1653
1659
  if composer is None:
1654
1660
  return None
1655
1661
  content = composer[1:].strip()
1656
- if not content or content == _CURSOR_COMPOSER_PLACEHOLDER:
1662
+ # cursor right-aligns run-state hints ('ctrl+c to stop') on the composer
1663
+ # ROW, so the placeholder is a PREFIX of the line while the agent runs,
1664
+ # not the whole line. A human message beginning with the exact placeholder
1665
+ # text is the accepted false positive — the only failure it can produce
1666
+ # is an inject alongside contrived text, never a silent deferral.
1667
+ if not content or content.startswith(_CURSOR_COMPOSER_PLACEHOLDER):
1657
1668
  return "clear"
1658
1669
  # A human who types exactly 'check mesh' by hand is indistinguishable
1659
1670
  # from our own unsubmitted wake — and submitting it runs the same
@@ -1679,7 +1690,7 @@ def _tmux_enter(target: str) -> bool:
1679
1690
  return False
1680
1691
 
1681
1692
 
1682
- def _tmux_wake(target: str) -> bool:
1693
+ def _tmux_wake(target: str) -> Optional[bool]:
1683
1694
  """Inject the wake prompt and confirm it SUBMITTED (#533).
1684
1695
 
1685
1696
  Was: Codex's blind double-Enter, on the assumption that a second Enter in
@@ -1689,14 +1700,14 @@ def _tmux_wake(target: str) -> bool:
1689
1700
  prompt on cursor-lin, 2026-08-24, three times in a row.
1690
1701
 
1691
1702
  Now: inject, settle, then Enter-and-verify in a bounded loop — re-Enter
1692
- only while the prompt is OBSERVED still sitting in the composer. Codex's
1703
+ only while the composer is OBSERVED holding wake text alone. Codex's
1693
1704
  second Enter falls out naturally (it fires only when the first did not
1694
- submit). Returns True when the wake is no longer ours to drive: an
1695
- observed-clear composer (submitted), or a composer the human has ADOPTED
1696
- (wake text merged with their typing mid-settle — another Enter would
1697
- submit their line, so the loop stops and the busy-deferral owns the wake
1698
- from there). A wake we cannot confirm stays owed, because the cursor
1699
- advances only inside `if _tmux_wake(...)`. An UNREADABLE pane (capture
1705
+ submit). Three outcomes: True on an observed-clear composer (submitted);
1706
+ None when the human ADOPTED the composer mid-settle (wake text merged
1707
+ with their typing — another Enter would submit their line, so the loop
1708
+ stops, and the sink DEFERS: the cursor must not advance on a wake that
1709
+ never submitted as ours — gpt-ops, #312 round 5); False when the pane
1710
+ could not be verified (the wake stays owed). An UNREADABLE pane (capture
1700
1711
  failure) fails closed — no unverified retries, no claimed success; the
1701
1712
  wake stays owed and the ledger retries the whole wake later.
1702
1713
  """
@@ -1718,8 +1729,8 @@ def _tmux_wake(target: str) -> bool:
1718
1729
  text=True, encoding="utf-8", errors="replace",
1719
1730
  )
1720
1731
  time.sleep(_WAKE_SETTLE_S)
1721
- pending = _wake_still_pending(target)
1722
- if pending is None:
1732
+ state = _composer_state(target)
1733
+ if state is None:
1723
1734
  print(
1724
1735
  "[monitor] tmux wake unverifiable (capture failed); "
1725
1736
  "failing closed — wake stays owed",
@@ -1727,8 +1738,16 @@ def _tmux_wake(target: str) -> bool:
1727
1738
  flush=True,
1728
1739
  )
1729
1740
  return False
1730
- if not pending:
1741
+ if state == "clear":
1731
1742
  return True
1743
+ if state == "busy":
1744
+ # The human typed into the wake mid-settle (gpt-ops, #312
1745
+ # round 5): the wake text never submitted as ours, so this
1746
+ # must NOT acknowledge delivery — return None and let the
1747
+ # sink DEFER, keeping the cursor back so a later poll
1748
+ # retries the wake when the composer clears.
1749
+ return None
1750
+ # "wake": still sitting unsubmitted — loop another Enter.
1732
1751
  print(
1733
1752
  f"[monitor] tmux wake still unsubmitted after "
1734
1753
  f"{_WAKE_SUBMIT_ATTEMPTS} Enters; wake stays owed",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: swarph-cli
3
- Version: 0.48.1
3
+ Version: 0.48.2
4
4
  Summary: The `swarph` binary — a multi-LLM CLI and mesh-gateway client + bundled server (`swarph gateway`): one-shot prompts across providers, interactive `chat`, multi-provider `spawn` (claude/codex/antigravity via a ProviderMembrane with subprocess billing-scrub), `mesh` send/inbox/register, `brain-ask` over the swarph-brain (gbrain) semantic memory, git-backed `assisted_memory`, per-invocation `gh` identity routing, a silent DM-wake hook, session `import`, and a stranded-session `watchdog`.
5
5
  Author: Pierre Samson, Claude Opus
6
6
  License: MIT
@@ -377,18 +377,39 @@ def test_claude_history_prompt_above_composer(tmux):
377
377
 
378
378
 
379
379
  def test_merged_wake_and_human_text_stops_the_loop(tmux):
380
- """gpt-ops, PR #312 round 4: the human types DURING the settle — the
380
+ """gpt-ops, PR #312 rounds 4-5: the human types DURING the settle — the
381
381
  composer holds 'check mesh half-typed human line'. Pending must mean
382
382
  wake-ONLY: merged reads False, and the verify loop sends NO further
383
- Enter (it would submit the human's half-typed line, #403's shape). The
384
- wake is out of our hands; the busy-deferral owns it from there."""
383
+ Enter (it would submit the human's half-typed line, #403's shape). And
384
+ the wake must NOT be acknowledged: _tmux_wake returns None so the sink
385
+ DEFERS and the cursor stays back — otherwise the wake is silently lost
386
+ when the human never sends their line."""
385
387
  calls, state = tmux
386
388
  state["captures"] = ["> check mesh half-typed human line"]
387
389
  assert mesh._wake_still_pending("pane") is False
388
- assert mesh._tmux_wake("pane") is True # adopted — not owed
390
+ assert mesh._tmux_wake("pane") is None # adopted — DEFER, not delivered
389
391
  assert sum(1 for c in calls if c[-1] == "Enter") == 1 # first Enter only
390
392
 
391
393
 
394
+ def test_merged_mid_settle_defers_and_holds_the_cursor(tmux):
395
+ """Deliver-level round 5: the gate reads clear, the inject lands, and
396
+ the human merges into the wake during the settle. deliver() must DEFER
397
+ (None): last_delivered_id does NOT advance, no failure is counted, and
398
+ wake_outstanding is NOT set (nothing of ours is driving)."""
399
+ calls, capstate = tmux
400
+ capstate["captures"] = [
401
+ "> ", # gate: observed clean
402
+ "> check mesh half-typed human", # verify: adopted mid-settle
403
+ ]
404
+ state = _State()
405
+ sink = mesh.TmuxSink("pane")
406
+ assert sink.deliver(state, [], 7) is None
407
+ led = state.ledger("tmux:pane")
408
+ assert led.get("last_delivered_id", 0) == 0 # cursor held
409
+ assert led.get("consecutive_failures", 0) == 0
410
+ assert led.get("wake_outstanding") is not True
411
+
412
+
392
413
  def test_busy_composer_defers_the_inject(gate):
393
414
  """THE commander's case: mid-write, a wake arrives. No text lands, the
394
415
  wake stays owed, and NOTHING is counted as failed."""
@@ -489,3 +510,28 @@ def test_engine_counts_deferral_as_neither_success_nor_failure(tmp_path, capsys)
489
510
  out = capsys.readouterr()
490
511
  assert "DEFERRED" in out.out
491
512
  assert "DELIVERY FAILED" not in out.err
513
+
514
+
515
+ def test_engine_defers_on_adopted_mid_settle_with_real_tmux_sink(tmp_path, tmux, capsys):
516
+ """gpt-ops, #312 round 6: the deliver-level merged test's cursor
517
+ assertions pass TRIVIALLY — deliver() never writes last_delivered_id,
518
+ the ENGINE does. This pins the real path end-to-end: a REAL TmuxSink,
519
+ scripted clear→merged captures, through _monitor_deliver. The DM stays
520
+ owed (cursor held at 0), no failure counted, no delivery recorded, no
521
+ ledger written."""
522
+ calls, capstate = tmux
523
+ capstate["captures"] = [
524
+ "> ", # gate: observed clean
525
+ "> check mesh half-typed human", # verify: adopted mid-settle
526
+ ]
527
+ state = _EngineState(tmp_path)
528
+ state.sinks = [mesh.TmuxSink("pane")]
529
+ mesh._monitor_deliver(state)
530
+ led = state.ledgers["tmux:pane"]
531
+ assert led["last_delivered_id"] == 0 # id 5 still owed
532
+ assert led["consecutive_failures"] == 0
533
+ assert state.deliveries == {}
534
+ assert not state.ledgers_path.exists()
535
+ out = capsys.readouterr()
536
+ assert "DEFERRED" in out.out
537
+ assert "DELIVERY FAILED" not in out.err
File without changes
File without changes
File without changes