swarph-cli 0.72.4__tar.gz → 0.72.5__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 (476) hide show
  1. {swarph_cli-0.72.4/src/swarph_cli.egg-info → swarph_cli-0.72.5}/PKG-INFO +1 -1
  2. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/pyproject.toml +1 -1
  3. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/__init__.py +1 -1
  4. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/mesh.py +32 -0
  5. swarph_cli-0.72.5/src/swarph_cli/commands/rowclear_hook.py +42 -0
  6. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/guide/GUIDE.md +1 -0
  7. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/main.py +8 -2
  8. swarph_cli-0.72.5/src/swarph_cli/rowclear.py +239 -0
  9. {swarph_cli-0.72.4 → swarph_cli-0.72.5/src/swarph_cli.egg-info}/PKG-INFO +1 -1
  10. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli.egg-info/SOURCES.txt +3 -0
  11. swarph_cli-0.72.5/tests/test_432_rowclear.py +278 -0
  12. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/LICENSE +0 -0
  13. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/README.md +0 -0
  14. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/setup.cfg +0 -0
  15. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/__main__.py +0 -0
  16. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/__init__.py +0 -0
  17. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/backends.py +0 -0
  18. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/claude_cli.py +0 -0
  19. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/codex_cli.py +0 -0
  20. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/pack.py +0 -0
  21. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/prices.py +0 -0
  22. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/providers.py +0 -0
  23. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/quality.py +0 -0
  24. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/refresh_prices.py +0 -0
  25. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/rules.py +0 -0
  26. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/runner.py +0 -0
  27. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/signal_score.py +0 -0
  28. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/validate.py +0 -0
  29. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/caller.py +0 -0
  30. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/capture/__init__.py +0 -0
  31. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/capture/harden.py +0 -0
  32. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/capture/lineage.py +0 -0
  33. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/capture/liveness.py +0 -0
  34. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/capture/manifest.py +0 -0
  35. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/capture/paths.py +0 -0
  36. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/capture/verify.py +0 -0
  37. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/cell.py +0 -0
  38. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/chain_token.py +0 -0
  39. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/channel.py +0 -0
  40. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/__init__.py +0 -0
  41. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/_content.py +0 -0
  42. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/_display.py +0 -0
  43. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/_gateway_client.py +0 -0
  44. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/add.py +0 -0
  45. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/bench.py +0 -0
  46. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/board.py +0 -0
  47. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/board_merge_check.py +0 -0
  48. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/brain.py +0 -0
  49. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/brain_ask.py +0 -0
  50. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/cell.py +0 -0
  51. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/cell_probe.py +0 -0
  52. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/cell_selfcheck.py +0 -0
  53. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/channel.py +0 -0
  54. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/chat.py +0 -0
  55. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/codegraph.py +0 -0
  56. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/codegraph_hook.py +0 -0
  57. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/codex_hook_output.py +0 -0
  58. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/codex_waker.py +0 -0
  59. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/compress.py +0 -0
  60. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/daemon.py +0 -0
  61. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/dreaming.py +0 -0
  62. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/event.py +0 -0
  63. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/gateway.py +0 -0
  64. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/gh_route.py +0 -0
  65. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/group.py +0 -0
  66. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/guide.py +0 -0
  67. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/highlight.py +0 -0
  68. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/hook_interpreter.py +0 -0
  69. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/hook_output.py +0 -0
  70. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/hooks.py +0 -0
  71. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/import_session.py +0 -0
  72. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/init.py +0 -0
  73. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/install_codex_hooks.py +0 -0
  74. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/install_hook.py +0 -0
  75. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/install_multiplexer.py +0 -0
  76. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/install_opencode_plugin.py +0 -0
  77. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/install_postcompact_hook.py +0 -0
  78. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/install_wake_hook.py +0 -0
  79. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/lane.py +0 -0
  80. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/mcp_server.py +0 -0
  81. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/memory.py +0 -0
  82. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/memory_emit_hook.py +0 -0
  83. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/memory_sync.py +0 -0
  84. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/monitor.py +0 -0
  85. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/okf_links.py +0 -0
  86. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/onboard.py +0 -0
  87. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/peer_reply_drain.py +0 -0
  88. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/postcompact_hook_output.py +0 -0
  89. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/protocol_handler.py +0 -0
  90. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/ratify.py +0 -0
  91. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/schedule.py +0 -0
  92. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/security.py +0 -0
  93. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/service.py +0 -0
  94. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/spawn.py +0 -0
  95. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/timeline.py +0 -0
  96. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/version.py +0 -0
  97. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/wake_hook_output.py +0 -0
  98. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/watchdog.py +0 -0
  99. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/compress/__init__.py +0 -0
  100. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/compress/levers.py +0 -0
  101. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/compress/marker.py +0 -0
  102. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/compress/verify.py +0 -0
  103. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/console_safe.py +0 -0
  104. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/delivery_queue.py +0 -0
  105. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dm_frame.py +0 -0
  106. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/__init__.py +0 -0
  107. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/candidates.py +0 -0
  108. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/clone.py +0 -0
  109. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/enrich.py +0 -0
  110. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/index_check.py +0 -0
  111. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/notify.py +0 -0
  112. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/organize.py +0 -0
  113. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/probes.py +0 -0
  114. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/report.py +0 -0
  115. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/run.py +0 -0
  116. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/slm.py +0 -0
  117. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/transcripts.py +0 -0
  118. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/verify.py +0 -0
  119. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/gateway/__init__.py +0 -0
  120. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/gateway/feature_registry.py +0 -0
  121. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/gateway/lanes_control.py +0 -0
  122. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/gateway/schema.sql +0 -0
  123. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/gateway/server.py +0 -0
  124. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/gateway/services_control.py +0 -0
  125. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/gateway_default.py +0 -0
  126. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/gh_identity.py +0 -0
  127. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/identity.py +0 -0
  128. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/multiplexer.py +0 -0
  129. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/operator/__init__.py +0 -0
  130. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/operator/__main__.py +0 -0
  131. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/operator/api.py +0 -0
  132. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/operator/cli.py +0 -0
  133. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/operator/config.py +0 -0
  134. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/operator/fmt.py +0 -0
  135. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/orphan_daemons.py +0 -0
  136. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/pane_probe.py +0 -0
  137. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/parsers/__init__.py +0 -0
  138. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/parsers/claude.py +0 -0
  139. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/opencode/plugin.js +0 -0
  140. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/_shim.cmd +0 -0
  141. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/postcompact-recall-grok.sh +0 -0
  142. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/postcompact-recall.sh +0 -0
  143. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/posttooluse-emit-antigravity.sh +0 -0
  144. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/posttooluse-emit-claude.sh +0 -0
  145. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/posttooluse-emit-grok.sh +0 -0
  146. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/posttooluse-emit.sh +0 -0
  147. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/posttooluse-recall.sh +0 -0
  148. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/precompact-flag.sh +0 -0
  149. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/preinvocation-recall-antigravity.sh +0 -0
  150. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/sessionstart-recall.sh +0 -0
  151. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/peer_executor.py +0 -0
  152. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/peer_executor_windows.py +0 -0
  153. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/peer_reconciliation.py +0 -0
  154. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/peer_reply_outbox.py +0 -0
  155. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/peer_service_host.py +0 -0
  156. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/peer_service_payload.py +0 -0
  157. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/peer_service_reply.py +0 -0
  158. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/peer_staging.py +0 -0
  159. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/query_filters.py +0 -0
  160. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/scripts/__init__.py +0 -0
  161. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/scripts/dm_notify_filter.py +0 -0
  162. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/scripts/ensure_monitor.sh +0 -0
  163. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/scripts/install_codex_waker_windows.ps1 +0 -0
  164. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/scripts/install_monitor_task_windows.ps1 +0 -0
  165. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/scripts/wake_watchdog.py +0 -0
  166. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/service/__init__.py +0 -0
  167. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/service/app.py +0 -0
  168. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/service/providers.py +0 -0
  169. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/session_bridge.py +0 -0
  170. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/skills/i-have-adhd/LICENSE +0 -0
  171. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/skills/i-have-adhd/SKILL.md +0 -0
  172. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/source_text.py +0 -0
  173. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/stall_alert.py +0 -0
  174. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/codex-waker.default +0 -0
  175. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/peer-reply-drain.default +0 -0
  176. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-codex-outbox@.service +0 -0
  177. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-codex-outbox@.timer +0 -0
  178. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-codex-waker@.service +0 -0
  179. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-codex-waker@.timer +0 -0
  180. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-monitor-reexec.path +0 -0
  181. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-monitor-reexec.service +0 -0
  182. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-monitor@.service +0 -0
  183. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-peer-reply-drain@.service +0 -0
  184. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-peer-reply-drain@.timer +0 -0
  185. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-watchdog.default +0 -0
  186. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-watchdog.service +0 -0
  187. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-watchdog.timer +0 -0
  188. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/timeline_paths.py +0 -0
  189. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/tokens.py +0 -0
  190. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli.egg-info/dependency_links.txt +0 -0
  191. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli.egg-info/entry_points.txt +0 -0
  192. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli.egg-info/requires.txt +0 -0
  193. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli.egg-info/top_level.txt +0 -0
  194. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_1006_board_publisher.py +0 -0
  195. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_1006_session_board.py +0 -0
  196. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_1010_strand_only.py +0 -0
  197. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_1013_spawn_channel.py +0 -0
  198. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_1017_muse_tui.py +0 -0
  199. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_124_register_merge.py +0 -0
  200. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_126_pending_from_complete.py +0 -0
  201. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_132_ensure_monitor_state_dir.py +0 -0
  202. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_138_memory_navigate.py +0 -0
  203. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_139_tool_probe.py +0 -0
  204. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_183_card_anchor.py +0 -0
  205. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_184_notify_honesty.py +0 -0
  206. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_201_win32_bash_refusal.py +0 -0
  207. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_243_onboard_per_peer_token.py +0 -0
  208. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_307_task4_ask_reply.py +0 -0
  209. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_312_codegraph_fuzzy_verb.py +0 -0
  210. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_319_refusal_exit_codes.py +0 -0
  211. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_323_mistral_backend.py +0 -0
  212. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_332_report_organize_findings.py +0 -0
  213. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_356_query_filters.py +0 -0
  214. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_397_gh_identity_router.py +0 -0
  215. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_397_router_preflight.py +0 -0
  216. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_402_one_identity_resolver.py +0 -0
  217. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_467b_onboard_operator_credential.py +0 -0
  218. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_472_register_caller_binding.py +0 -0
  219. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_484_codex_queue_sink.py +0 -0
  220. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_523_guide.py +0 -0
  221. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_524_conftest_hermeticity.py +0 -0
  222. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_532_accept_flag.py +0 -0
  223. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_535_version_capability.py +0 -0
  224. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_538_signal_bench.py +0 -0
  225. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_546_default_gateway.py +0 -0
  226. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_547_verbs_from_registry.py +0 -0
  227. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_548_gateway_remainder.py +0 -0
  228. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_552_codegraph_gateway.py +0 -0
  229. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_555_relay_row_shape.py +0 -0
  230. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_556_relay_freshness.py +0 -0
  231. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_559_edges_truncated.py +0 -0
  232. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_564_bootstrap_first_peer.py +0 -0
  233. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_578_no_machine_specific_host_defaults.py +0 -0
  234. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_579_register_bootstrap_message.py +0 -0
  235. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_591_cli_step_graph.py +0 -0
  236. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_644_monitor_supervision.py +0 -0
  237. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_648_install_unit.py +0 -0
  238. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_654_reexec.py +0 -0
  239. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_656_owned_slm.py +0 -0
  240. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_684_dreaming_verb.py +0 -0
  241. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_689_pkg_version_order.py +0 -0
  242. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_715_grok_wake.py +0 -0
  243. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_716_timeline_one_path.py +0 -0
  244. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_723_grok_0251.py +0 -0
  245. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_724_ps1_ascii_or_bom.py +0 -0
  246. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_725_stdio_reconfigure.py +0 -0
  247. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_726_grok_limit_screen.py +0 -0
  248. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_729_arm_check_delivery_gap.py +0 -0
  249. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_729_dm_once.py +0 -0
  250. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_729_wake_watchdog.py +0 -0
  251. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_734_dreaming_enrich_degrade.py +0 -0
  252. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_735_dm_mcp_tools.py +0 -0
  253. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_739_wake_writer.py +0 -0
  254. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_740_edit_project.py +0 -0
  255. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_762_cards_edit_priority.py +0 -0
  256. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_764_enrich_collapse.py +0 -0
  257. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_801_confirm_flow_cli.py +0 -0
  258. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_802_stage_history.py +0 -0
  259. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_825_codegraph_hook_noise.py +0 -0
  260. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_825_install_posttooluse_only.py +0 -0
  261. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_825_remaining_cap_shred_bind.py +0 -0
  262. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_829_counterfactual_column.py +0 -0
  263. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_830_hook_binding_version.py +0 -0
  264. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_84_cli_labels.py +0 -0
  265. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_866_doctrine_guide.py +0 -0
  266. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_872_identity_refuses_not_warns.py +0 -0
  267. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_874_source_text.py +0 -0
  268. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_888_opencode_data_dir_can_fail.py +0 -0
  269. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_937_dreaming_notify.py +0 -0
  270. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_938_organize_line_limit.py +0 -0
  271. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_941_bench_backends.py +0 -0
  272. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_941_harness_342.py +0 -0
  273. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_945_same_line_pairing.py +0 -0
  274. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_955_prompt_audit.py +0 -0
  275. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_957_auth_http.py +0 -0
  276. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_959_venv_interpreter.py +0 -0
  277. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_960_channel.py +0 -0
  278. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_960_ensure_monitor_heartbeat.py +0 -0
  279. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_961_cursor_grok_footer.py +0 -0
  280. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_961_loud_stop.py +0 -0
  281. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_963_plugin_manifest.py +0 -0
  282. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_964_channel_cell.py +0 -0
  283. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_965_mesh_wait.py +0 -0
  284. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_975_channel_hop.py +0 -0
  285. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_add_security_gate.py +0 -0
  286. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_artifact_add.py +0 -0
  287. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_artifact_hash.py +0 -0
  288. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_artifact_lib.py +0 -0
  289. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_artifact_mcp.py +0 -0
  290. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_artifact_skill.py +0 -0
  291. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_artifact_tool.py +0 -0
  292. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_artifact_uri.py +0 -0
  293. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_bench_backends.py +0 -0
  294. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_bench_claude_cli.py +0 -0
  295. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_bench_codex_cli.py +0 -0
  296. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_bench_command.py +0 -0
  297. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_bench_pack.py +0 -0
  298. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_bench_prices.py +0 -0
  299. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_bench_quality.py +0 -0
  300. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_bench_runner.py +0 -0
  301. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_bench_validate.py +0 -0
  302. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_board_card_thread.py +0 -0
  303. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_board_command.py +0 -0
  304. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_board_merge_check.py +0 -0
  305. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_board_obligation_close.py +0 -0
  306. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_brain_ask_command.py +0 -0
  307. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_brain_ask_env_diagnosis.py +0 -0
  308. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_brain_ask_identity_explicitness.py +0 -0
  309. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_brain_command.py +0 -0
  310. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_caller_meta_guard.py +0 -0
  311. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_capture_lineage.py +0 -0
  312. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_capture_liveness.py +0 -0
  313. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_capture_manifest.py +0 -0
  314. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_capture_paths.py +0 -0
  315. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_capture_security.py +0 -0
  316. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_cell_command_dispatch.py +0 -0
  317. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_cell_harden.py +0 -0
  318. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_cell_loader.py +0 -0
  319. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_cell_selfcheck.py +0 -0
  320. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_cell_verify.py +0 -0
  321. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_chain_token.py +0 -0
  322. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_channel_command.py +0 -0
  323. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_channel_poll_never_breaks_dms.py +0 -0
  324. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_channel_post.py +0 -0
  325. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_channel_wake_policy_filter.py +0 -0
  326. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_chat_command.py +0 -0
  327. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_claude_parser.py +0 -0
  328. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_claude_tmux_template.py +0 -0
  329. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_codegraph_caller_scope.py +0 -0
  330. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_codegraph_command.py +0 -0
  331. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_codegraph_hook.py +0 -0
  332. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_codegraph_mcp.py +0 -0
  333. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_codex_waker.py +0 -0
  334. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_compress_caller_convention.py +0 -0
  335. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_compress_command.py +0 -0
  336. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_compress_levers.py +0 -0
  337. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_compress_marker.py +0 -0
  338. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_compress_verify.py +0 -0
  339. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_console_encoding_e2e.py +0 -0
  340. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_content_composition.py +0 -0
  341. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_cursor_membrane.py +0 -0
  342. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_daemon_command.py +0 -0
  343. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_daemon_console_encoding.py +0 -0
  344. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_daemon_delivery.py +0 -0
  345. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_delivery_queue.py +0 -0
  346. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_display_sanitize.py +0 -0
  347. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_ensure_monitor_no_peer_default.py +0 -0
  348. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_event_emit.py +0 -0
  349. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_feature_to_uri.py +0 -0
  350. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_gateway_brain.py +0 -0
  351. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_gateway_client.py +0 -0
  352. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_gateway_command.py +0 -0
  353. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_gateway_message_idempotency.py +0 -0
  354. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_gh_route_doctor_mesh_name.py +0 -0
  355. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_group_command.py +0 -0
  356. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_guide_commands_parse.py +0 -0
  357. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_guide_selfcheck.py +0 -0
  358. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_heartbeat_check.py +0 -0
  359. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_highlight_command.py +0 -0
  360. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hook_output.py +0 -0
  361. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hooks_activity_marker.py +0 -0
  362. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hooks_add.py +0 -0
  363. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hooks_bundle.py +0 -0
  364. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hooks_init.py +0 -0
  365. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hooks_legacy_generation_removal.py +0 -0
  366. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hooks_lifecycle.py +0 -0
  367. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hooks_merge.py +0 -0
  368. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hooks_verify.py +0 -0
  369. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hooks_win32_bash_wrapper.py +0 -0
  370. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hooks_win32_command_path.py +0 -0
  371. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_import_command.py +0 -0
  372. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_inbox_identity_provenance.py +0 -0
  373. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_init_command.py +0 -0
  374. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_init_provider_menu.py +0 -0
  375. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_install_codex_hooks.py +0 -0
  376. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_install_hook.py +0 -0
  377. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_install_multiplexer_command.py +0 -0
  378. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_install_postcompact_hook.py +0 -0
  379. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_install_wake_hook.py +0 -0
  380. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_lane_command.py +0 -0
  381. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_main.py +0 -0
  382. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_main_unknown_verb_guard.py +0 -0
  383. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mcp_missing_hint.py +0 -0
  384. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mcp_server.py +0 -0
  385. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_memory_command.py +0 -0
  386. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_memory_emit_snippet.py +0 -0
  387. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_memory_gateway.py +0 -0
  388. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_memory_sync.py +0 -0
  389. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_memory_sync_membrane.py +0 -0
  390. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mesh_command.py +0 -0
  391. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mesh_inbox_mark_read.py +0 -0
  392. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mesh_inbox_sanitize.py +0 -0
  393. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mesh_originate_thread_623.py +0 -0
  394. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mesh_send_unknown_peer.py +0 -0
  395. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mesh_sidecar.py +0 -0
  396. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mesh_sidecar_cursor_decoupled.py +0 -0
  397. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mesh_sidecar_muse_sink.py +0 -0
  398. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mesh_sidecar_wake_survives_read.py +0 -0
  399. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_meta_edge_identity.py +0 -0
  400. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_monitor_channel_poll.py +0 -0
  401. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_monitor_cli.py +0 -0
  402. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_monitor_daemon_collision.py +0 -0
  403. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_monitor_self_name_verification.py +0 -0
  404. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_monitor_state_split.py +0 -0
  405. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_multiplexer.py +0 -0
  406. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_muse_membrane.py +0 -0
  407. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_muse_own_cli.py +0 -0
  408. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_obligation_close_is_surfaced.py +0 -0
  409. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_okf_links.py +0 -0
  410. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_onboard_command.py +0 -0
  411. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_opencode_membrane.py +0 -0
  412. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_opencode_plugin.py +0 -0
  413. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_operator_me.py +0 -0
  414. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_orphan_daemons.py +0 -0
  415. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_packaged_artifacts_exist.py +0 -0
  416. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_packaged_skills.py +0 -0
  417. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_peer_executor.py +0 -0
  418. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_peer_executor_windows.py +0 -0
  419. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_peer_reply_drain_command.py +0 -0
  420. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_peer_reply_drain_supervisor.py +0 -0
  421. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_peer_reply_outbox.py +0 -0
  422. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_peer_reply_transport.py +0 -0
  423. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_peer_service_e2e.py +0 -0
  424. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_peer_service_host.py +0 -0
  425. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_peer_service_payload.py +0 -0
  426. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_peer_service_reply.py +0 -0
  427. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_postcompact_recall.py +0 -0
  428. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_process_liveness.py +0 -0
  429. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_protocol_handler.py +0 -0
  430. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_providers_isolation.py +0 -0
  431. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_ratify_command.py +0 -0
  432. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_readme_claims_no_gateway_default.py +0 -0
  433. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_repl_caller_convention.py +0 -0
  434. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_schedule_command.py +0 -0
  435. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_schedule_create_contract.py +0 -0
  436. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_security.py +0 -0
  437. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_service_app.py +0 -0
  438. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_service_command.py +0 -0
  439. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_service_providers.py +0 -0
  440. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_session_bridge_inject.py +0 -0
  441. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_session_bridge_probe.py +0 -0
  442. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_session_bridge_resolve.py +0 -0
  443. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_session_path_role_gate.py +0 -0
  444. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_shipped_units_match_the_cli.py +0 -0
  445. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_smoke_chat.py +0 -0
  446. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_smoke_one_shot.py +0 -0
  447. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_smoke_phase_5_5.py +0 -0
  448. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_spawn_base_hoist.py +0 -0
  449. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_spawn_command.py +0 -0
  450. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_spawn_identity_stamp.py +0 -0
  451. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_spawn_live_pin.py +0 -0
  452. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_spawn_mitosis_lineage.py +0 -0
  453. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_spawn_tmux_session.py +0 -0
  454. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_spawn_windows_relaunch.py +0 -0
  455. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_stall_alert.py +0 -0
  456. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_subprocess_decode_encoding.py +0 -0
  457. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_timeline_command.py +0 -0
  458. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_tmux_wake_runstate_defer.py +0 -0
  459. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_tmux_wake_session_reanchor.py +0 -0
  460. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_tmux_wake_stale.py +0 -0
  461. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_tmux_wake_submit_verify.py +0 -0
  462. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_token_file_one_parser.py +0 -0
  463. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_token_precedence_explicit_first.py +0 -0
  464. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_unified_token_resolver.py +0 -0
  465. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_version_command.py +0 -0
  466. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_version_consistency.py +0 -0
  467. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_vibe_membrane.py +0 -0
  468. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_watchdog.py +0 -0
  469. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_watchdog_dm_wake.py +0 -0
  470. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_watchdog_dm_wake_cooldown.py +0 -0
  471. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_watchdog_dm_wake_wiring.py +0 -0
  472. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_watchdog_emit_health.py +0 -0
  473. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_watchdog_install_flags.py +0 -0
  474. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_watchdog_model_rung.py +0 -0
  475. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_watchdog_stale_peers.py +0 -0
  476. {swarph_cli-0.72.4 → swarph_cli-0.72.5}/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.72.4
3
+ Version: 0.72.5
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.72.4"
7
+ version = "0.72.5"
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.72.4"
19
+ __version__ = "0.72.5"
20
20
 
21
21
  __all__ = ["__version__"]
@@ -3392,6 +3392,35 @@ def _monitor_deliver(state: MonitorState) -> None:
3392
3392
  _write_ledgers_atomic(state.ledgers_path, state.ledgers)
3393
3393
 
3394
3394
 
3395
+ def _type_slash_clear(target: str) -> bool:
3396
+ """Type ``/clear`` and submit it. One command, not a wake."""
3397
+ for argv in (
3398
+ ["tmux", "send-keys", "-t", target, "-l", "/clear"],
3399
+ ["tmux", "send-keys", "-t", target, "Enter"],
3400
+ ):
3401
+ try:
3402
+ r = subprocess.run(
3403
+ argv, capture_output=True, timeout=5,
3404
+ text=True, encoding="utf-8", errors="replace",
3405
+ )
3406
+ except (OSError, subprocess.TimeoutExpired):
3407
+ return False
3408
+ if r.returncode != 0:
3409
+ return False
3410
+ return True
3411
+
3412
+
3413
+ def _maybe_rowclear(state: MonitorState) -> str:
3414
+ """Card #432. Off and non-opted-in cells return before any pane read."""
3415
+ from swarph_cli.rowclear import maybe_rowclear
3416
+ return maybe_rowclear(
3417
+ state,
3418
+ agent_running=_agent_running,
3419
+ http_get=_http_get_json,
3420
+ type_clear=_type_slash_clear,
3421
+ )
3422
+
3423
+
3395
3424
  def _monitor_iteration(state: MonitorState, *, poll_channels: bool = True) -> None:
3396
3425
  state.iterations += 1
3397
3426
  last_id = int(state.observed.get("last_msg_id", 0))
@@ -3456,6 +3485,9 @@ def _monitor_iteration(state: MonitorState, *, poll_channels: bool = True) -> No
3456
3485
  # A delivery deferred by the idle guard (or failed against a dead sink) must
3457
3486
  # still land even though no NEW mail arrived, so this runs on every poll.
3458
3487
  _monitor_deliver(state)
3488
+ # Card #432: after delivery, so an owed DM (cursor still behind) blocks
3489
+ # the clear. off / not-opted-in return before any pane or board read.
3490
+ _maybe_rowclear(state)
3459
3491
  # The observation cursor is written BEFORE delivery, while last_wake_at is
3460
3492
  # still unknown. A wake that landed this poll has to be written again or
3461
3493
  # cursor.json keeps the 0.0 default after a real keystroke (#405).
@@ -0,0 +1,42 @@
1
+ """``swarph rowclear-hook`` — SessionStart hook for card #432.
2
+
3
+ Claude Code runs this on SessionStart. When the payload's ``source`` is
4
+ ``clear``, the new ``session_id`` is written into the role's
5
+ ``<role>.session-id`` pin (the role is ``SWARPH_SELF``). Spawn then
6
+ resumes that id instead of the pre-clear session.
7
+
8
+ Exit 0 on every path. A hook that fails closed refuses the session.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import json
14
+ import sys
15
+
16
+ from swarph_cli import identity
17
+ from swarph_cli.rowclear import apply_sessionstart_clear
18
+
19
+
20
+ def _read_stdin() -> dict:
21
+ try:
22
+ if not sys.stdin.isatty():
23
+ raw = sys.stdin.read()
24
+ if raw.strip():
25
+ return json.loads(raw.lstrip("\ufeff"))
26
+ except Exception:
27
+ return {}
28
+ return {}
29
+
30
+
31
+ def run_rowclear_hook(argv: list[str] | None = None) -> int:
32
+ del argv
33
+ role = identity.declared(env=identity.SELF_ONLY)[0] or ""
34
+ if not role:
35
+ print("rowclear-hook: SWARPH_SELF unset — pin not rewritten",
36
+ file=sys.stderr)
37
+ return 0
38
+ try:
39
+ apply_sessionstart_clear(_read_stdin(), role)
40
+ except Exception as exc:
41
+ print(f"rowclear-hook: {exc}", file=sys.stderr)
42
+ return 0
@@ -543,6 +543,7 @@ answers `--help`; hook-plumbing verbs are the callbacks hooks invoke, not comman
543
543
  - `swarph protocol-handler` -- register `swarph://` as an OS URL-scheme handler.
544
544
  - `swarph ratify` -- witness flip that admits an onboarded peer; takes the peer name and `--reason`.
545
545
  - `swarph rights` -- RBAC rights over the gateway (companion of `swarph group`).
546
+ - `swarph rowclear-hook` -- SessionStart hook (card #432): when `source` is `clear`, write the new session id into the role's `<role>.session-id` pin so the next spawn resumes the cleared session.
546
547
  - `swarph scan` -- statically scan an artifact for dangerous patterns before publish.
547
548
  - `swarph schedule` -- the gateway's scheduled events: create, list, get, enable, disable, delete, fire-now.
548
549
  - `swarph service` -- stand up a $0 subscription-LLM HTTP lane.
@@ -92,6 +92,7 @@ _VERB_HANDLERS: dict[str, str] = {
92
92
  "install-wake-hook": "swarph_cli.commands.install_wake_hook.run_install_wake_hook",
93
93
  "wake-hook-output": "swarph_cli.commands.wake_hook_output.run_wake_hook_output",
94
94
  "postcompact-hook-output": "swarph_cli.commands.postcompact_hook_output.run_postcompact_hook_output",
95
+ "rowclear-hook": "swarph_cli.commands.rowclear_hook.run_rowclear_hook",
95
96
  "install-postcompact-hook": "swarph_cli.commands.install_postcompact_hook.run_install_postcompact_hook",
96
97
  "install-opencode-plugin": "swarph_cli.commands.install_opencode_plugin.run_install_opencode_plugin",
97
98
  "memory-emit-hook": "swarph_cli.commands.memory_emit_hook.run_memory_emit_hook",
@@ -147,8 +148,13 @@ def _verbs_block(width: int = 78) -> str:
147
148
  import textwrap
148
149
  verbs = registered_verbs()
149
150
  head = f"Verbs ({len(verbs)}) -- each has --help and a guide entry (swarph guide <verb>):"
150
- return head + "\n" + textwrap.fill(", ".join(verbs), width=width,
151
- initial_indent=" ", subsequent_indent=" ") + "\n"
151
+ # break_on_hyphens would split a verb at a wrap (wake-hook-output
152
+ # became "wake-hook-" / "output" once the list grew past the width).
153
+ return head + "\n" + textwrap.fill(
154
+ ", ".join(verbs), width=width,
155
+ initial_indent=" ", subsequent_indent=" ",
156
+ break_on_hyphens=False, break_long_words=False,
157
+ ) + "\n"
152
158
 
153
159
 
154
160
  def _build_parser() -> argparse.ArgumentParser:
@@ -0,0 +1,239 @@
1
+ """Card #432: type ``/clear`` at a row boundary, and follow the new session.
2
+
3
+ The monitor types ``/clear`` into an opted-in role cell's tmux pane only
4
+ when the cell holds no live row, the pane reads idle, and no DM is owed.
5
+ ``SWARPH_ROWCLEAR`` is ``off`` (default), ``shadow`` (log a would-clear,
6
+ type nothing), or ``live``. v1 opt-in is drop-on-meta-edge only: a cell
7
+ that owns a project keeps its context (design_1007 / optin_owners).
8
+
9
+ A ``/clear`` mints a new Claude session id. The SessionStart hook with
10
+ ``source=clear`` writes that id into the role's ``<role>.session-id``
11
+ pin, so the next spawn resumes the cleared session instead of the long
12
+ one the pin still named.
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import json
18
+ import os
19
+ import sys
20
+ from datetime import datetime, timezone
21
+ from typing import Any, Callable, Optional
22
+
23
+ from swarph_cli.cell import (
24
+ CellError,
25
+ _read_session_sidecar,
26
+ _write_session_sidecar,
27
+ session_state_path,
28
+ validate_uuid_str,
29
+ )
30
+
31
+ # v1. Further cells join only by their own or the commander's opt-in.
32
+ OPT_IN = frozenset({"drop-on-meta-edge"})
33
+
34
+ # Gateway statuses are open, closed, and fallback_fired. ``open`` is a
35
+ # live row (taken or offered). ``closed`` and ``fallback_fired`` are
36
+ # finished and do not block: drop-on-meta-edge holds a fallback_fired
37
+ # row that would otherwise make the only opted-in cell never clear.
38
+ # Any other status fails closed — a status this code does not know must
39
+ # not look like an empty cell.
40
+ _LIVE = "open"
41
+ _FINISHED = frozenset({"closed", "fallback_fired"})
42
+
43
+ _MODES = frozenset({"off", "shadow", "live"})
44
+
45
+
46
+ def mode_from_env() -> str:
47
+ raw = os.environ.get("SWARPH_ROWCLEAR", "off").strip().lower()
48
+ return raw if raw in _MODES else "off"
49
+
50
+
51
+ def _latch_path(state) -> "os.PathLike[str]":
52
+ return state.state_dir / "rowclear.json"
53
+
54
+
55
+ def _log_path(state) -> "os.PathLike[str]":
56
+ return state.state_dir / "rowclear.log"
57
+
58
+
59
+ def _read_latch(state) -> Optional[str]:
60
+ path = _latch_path(state)
61
+ try:
62
+ data = json.loads(path.read_text(encoding="utf-8"))
63
+ except (OSError, ValueError):
64
+ return None
65
+ mode = data.get("latched_mode") if isinstance(data, dict) else None
66
+ return mode if isinstance(mode, str) else None
67
+
68
+
69
+ def _write_latch(state, mode: Optional[str]) -> None:
70
+ path = _latch_path(state)
71
+ path.parent.mkdir(parents=True, exist_ok=True)
72
+ path.write_text(
73
+ json.dumps({"latched_mode": mode}) + "\n", encoding="utf-8")
74
+
75
+
76
+ def _tmux_target(state) -> Optional[str]:
77
+ for sink in state.sinks:
78
+ if type(sink).__name__ == "TmuxSink":
79
+ target = getattr(sink, "target", None)
80
+ if target:
81
+ return target
82
+ return None
83
+
84
+
85
+ def _dm_owed(state) -> bool:
86
+ observed = int(state.observed.get("last_msg_id", 0))
87
+ for sink in state.sinks:
88
+ if not getattr(sink, "keeps_ledger", False):
89
+ continue
90
+ led = state.ledger(sink.name)
91
+ if int(led.get("last_delivered_id", 0)) < observed:
92
+ return True
93
+ if led.get("wake_outstanding"):
94
+ return True
95
+ return False
96
+
97
+
98
+ def _live_row_count(state, http_get: Callable) -> Optional[int]:
99
+ """How many unfinished rows this cell holds, or None if unread.
100
+
101
+ None fails closed: an unreadable board must not look like an empty
102
+ one, or a live row we failed to see gets a ``/clear``.
103
+ """
104
+ url = f"{state.gateway}/board/obligations?holder={state.self_name}"
105
+ try:
106
+ status, body = http_get(url, state.token)
107
+ except Exception:
108
+ return None
109
+ if status != 200 or not isinstance(body, dict):
110
+ return None
111
+ rows = body.get("obligations")
112
+ if not isinstance(rows, list):
113
+ return None
114
+ live = 0
115
+ for row in rows:
116
+ if not isinstance(row, dict):
117
+ return None
118
+ status = str(row.get("status") or "")
119
+ if status == _LIVE:
120
+ live += 1
121
+ elif status not in _FINISHED:
122
+ return None
123
+ return live
124
+
125
+
126
+ def _append_would_clear(state, *, open_rows: int, pane_state: str) -> None:
127
+ path = _log_path(state)
128
+ path.parent.mkdir(parents=True, exist_ok=True)
129
+ record = {
130
+ "cell": state.self_name,
131
+ "time": datetime.now(timezone.utc).isoformat(),
132
+ "open_rows": open_rows,
133
+ "pane_state": pane_state,
134
+ "action": "would-clear",
135
+ }
136
+ with path.open("a", encoding="utf-8") as fp:
137
+ fp.write(json.dumps(record) + "\n")
138
+
139
+
140
+ def maybe_rowclear(
141
+ state,
142
+ *,
143
+ agent_running: Callable[[str], Optional[bool]],
144
+ http_get: Callable,
145
+ type_clear: Callable[[str], bool],
146
+ ) -> str:
147
+ """One poll. Returns the decision, so a test can name why no key went.
148
+
149
+ ``off`` and a cell not on the opt-in list return before any read or
150
+ write: they are unchanged. A live row, a busy pane, or an owed DM
151
+ unlatches the idle boundary and types nothing. Unknown rows or an
152
+ unknown pane type nothing and leave the latch alone.
153
+ """
154
+ mode = mode_from_env()
155
+ if mode == "off":
156
+ return "off"
157
+ if state.self_name not in OPT_IN:
158
+ return "not-opted-in"
159
+
160
+ live = _live_row_count(state, http_get)
161
+ if live is None:
162
+ return "blocked-rows-unknown"
163
+ if live > 0:
164
+ _write_latch(state, None)
165
+ return "blocked-live-row"
166
+
167
+ target = _tmux_target(state)
168
+ if target is None:
169
+ return "blocked-no-pane"
170
+ pane = agent_running(target)
171
+ if pane is True:
172
+ _write_latch(state, None)
173
+ return "blocked-busy"
174
+ if pane is None:
175
+ return "blocked-unknown-pane"
176
+ if _dm_owed(state):
177
+ _write_latch(state, None)
178
+ return "blocked-owed-dm"
179
+
180
+ if _read_latch(state) == mode:
181
+ return "latched"
182
+
183
+ if mode == "shadow":
184
+ _append_would_clear(state, open_rows=live, pane_state="idle")
185
+ _write_latch(state, mode)
186
+ print(
187
+ f"[rowclear] {state.self_name}: would-clear "
188
+ f"(open_rows={live}, pane=idle) — shadow, zero keys",
189
+ flush=True,
190
+ )
191
+ return "shadow"
192
+
193
+ if not type_clear(target):
194
+ print(
195
+ f"[rowclear] {state.self_name}: /clear send failed — "
196
+ "not latched, retried next poll",
197
+ flush=True,
198
+ )
199
+ return "type-failed"
200
+ _write_latch(state, mode)
201
+ print(
202
+ f"[rowclear] {state.self_name}: typed /clear "
203
+ f"(open_rows={live}, pane=idle, no DM owed)",
204
+ flush=True,
205
+ )
206
+ return "live"
207
+
208
+
209
+ def apply_sessionstart_clear(payload: dict[str, Any], role: str) -> bool:
210
+ """Write ``session_id`` into the role pin when SessionStart source is clear.
211
+
212
+ Any other source leaves the pin alone: a resume must not clobber the
213
+ id the spawn will attach to. Returns True only when the pin was rewritten.
214
+ """
215
+ if not isinstance(payload, dict) or payload.get("source") != "clear":
216
+ return False
217
+ raw = payload.get("session_id") or payload.get("sessionId") or ""
218
+ try:
219
+ session_id = validate_uuid_str(str(raw))
220
+ except (CellError, TypeError, ValueError):
221
+ return False
222
+ path = session_state_path(role)
223
+ _uuid, recorded_cwd = _read_session_sidecar(path)
224
+ payload_cwd = payload.get("cwd") or ""
225
+ # ruling_1236: a clear from a different project must not rewrite
226
+ # another role's pin (shared HOME, card #964). Refuse only when
227
+ # both sides name a cwd and they differ. A missing side keeps the
228
+ # old fallback.
229
+ if recorded_cwd and str(payload_cwd).strip():
230
+ if os.path.normpath(recorded_cwd) != os.path.normpath(str(payload_cwd)):
231
+ print(
232
+ f"rowclear: payload cwd {payload_cwd} differs from the "
233
+ f"pin's recorded cwd {recorded_cwd} — pin not rewritten",
234
+ file=sys.stderr,
235
+ )
236
+ return False
237
+ cwd = payload_cwd or recorded_cwd or ""
238
+ _write_session_sidecar(path, session_id, cwd)
239
+ return True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: swarph-cli
3
- Version: 0.72.4
3
+ Version: 0.72.5
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
@@ -26,6 +26,7 @@ src/swarph_cli/peer_service_payload.py
26
26
  src/swarph_cli/peer_service_reply.py
27
27
  src/swarph_cli/peer_staging.py
28
28
  src/swarph_cli/query_filters.py
29
+ src/swarph_cli/rowclear.py
29
30
  src/swarph_cli/session_bridge.py
30
31
  src/swarph_cli/source_text.py
31
32
  src/swarph_cli/stall_alert.py
@@ -109,6 +110,7 @@ src/swarph_cli/commands/peer_reply_drain.py
109
110
  src/swarph_cli/commands/postcompact_hook_output.py
110
111
  src/swarph_cli/commands/protocol_handler.py
111
112
  src/swarph_cli/commands/ratify.py
113
+ src/swarph_cli/commands/rowclear_hook.py
112
114
  src/swarph_cli/commands/schedule.py
113
115
  src/swarph_cli/commands/security.py
114
116
  src/swarph_cli/commands/service.py
@@ -209,6 +211,7 @@ tests/test_356_query_filters.py
209
211
  tests/test_397_gh_identity_router.py
210
212
  tests/test_397_router_preflight.py
211
213
  tests/test_402_one_identity_resolver.py
214
+ tests/test_432_rowclear.py
212
215
  tests/test_467b_onboard_operator_credential.py
213
216
  tests/test_472_register_caller_binding.py
214
217
  tests/test_484_codex_queue_sink.py