swarph-cli 0.72.41__tar.gz → 0.72.42__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.
- {swarph_cli-0.72.41/src/swarph_cli.egg-info → swarph_cli-0.72.42}/PKG-INFO +1 -1
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/pyproject.toml +1 -1
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/__init__.py +1 -1
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/mesh.py +391 -31
- {swarph_cli-0.72.41 → swarph_cli-0.72.42/src/swarph_cli.egg-info}/PKG-INFO +1 -1
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli.egg-info/SOURCES.txt +4 -0
- swarph_cli-0.72.42/tests/test_1452_rework1_engine.py +300 -0
- swarph_cli-0.72.42/tests/test_1452_rework2_engine.py +283 -0
- swarph_cli-0.72.42/tests/test_1452_rework3_engine.py +264 -0
- swarph_cli-0.72.42/tests/test_1452_standing_wake_expiry.py +145 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_484_codex_queue_sink.py +1 -1
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_mesh_sidecar_muse_sink.py +3 -2
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_tmux_wake_runstate_defer.py +4 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/LICENSE +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/README.md +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/setup.cfg +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/__main__.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/bench/__init__.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/bench/backends.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/bench/claude_cli.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/bench/codex_cli.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/bench/pack.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/bench/prices.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/bench/providers.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/bench/quality.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/bench/refresh_prices.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/bench/rules.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/bench/runner.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/bench/signal_score.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/bench/validate.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/caller.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/capture/__init__.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/capture/harden.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/capture/lineage.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/capture/liveness.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/capture/manifest.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/capture/paths.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/capture/verify.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/cell.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/chain_token.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/channel.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/__init__.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/_content.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/_display.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/_gateway_client.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/add.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/bench.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/board.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/board_cost.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/board_merge_check.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/board_usage.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/brain.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/brain_ask.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/cell.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/cell_probe.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/cell_selfcheck.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/channel.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/chat.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/codegraph.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/codegraph_hook.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/codex_hook_output.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/codex_waker.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/commander.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/committee.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/compress.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/daemon.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/dev_extract.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/dreaming.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/event.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/gateway.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/gh_route.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/group.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/guide.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/highlight.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/hook_interpreter.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/hook_output.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/hooks.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/import_session.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/init.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/install_codex_hooks.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/install_hook.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/install_multiplexer.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/install_opencode_plugin.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/install_postcompact_hook.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/install_wake_hook.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/lane.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/mcp_server.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/memory.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/memory_emit_hook.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/memory_sync.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/monitor.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/okf_links.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/onboard.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/peer_reply_drain.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/postcompact_hook_output.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/protocol_handler.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/ratify.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/roster.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/rowclear_hook.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/schedule.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/security.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/service.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/skunkworks.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/spawn.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/sweep.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/timeline.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/triage.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/version.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/wake_hook_output.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commands/watchdog.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/commit_trailers.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/compress/__init__.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/compress/levers.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/compress/marker.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/compress/verify.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/console_safe.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/delivery_queue.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/dm_frame.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/dreaming/__init__.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/dreaming/candidates.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/dreaming/clone.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/dreaming/enrich.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/dreaming/index_check.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/dreaming/notify.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/dreaming/organize.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/dreaming/probes.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/dreaming/report.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/dreaming/run.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/dreaming/slm.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/dreaming/transcripts.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/dreaming/verify.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/duplicate_session.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/gateway/__init__.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/gateway/feature_registry.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/gateway/lanes_control.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/gateway/schema.sql +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/gateway/server.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/gateway/services_control.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/gateway_default.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/gh_identity.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/guide/GUIDE.md +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/identity.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/launchd/swarph-codex-outbox.plist +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/launchd/swarph-codex-outbox.timer.plist +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/launchd/swarph-monitor.plist +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/launchd/swarph-watchdog.plist +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/launchd/swarph-watchdog.timer.plist +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/launchd_render.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/main.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/multiplexer.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/operator/__init__.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/operator/__main__.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/operator/api.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/operator/cli.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/operator/config.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/operator/fmt.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/orphan_daemons.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/pane_probe.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/parsers/__init__.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/parsers/claude.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/payloads/opencode/plugin.js +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/payloads/postcompact/_shim.cmd +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/payloads/postcompact/postcompact-recall-grok.sh +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/payloads/postcompact/postcompact-recall.sh +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/payloads/postcompact/posttooluse-emit-antigravity.sh +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/payloads/postcompact/posttooluse-emit-claude.sh +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/payloads/postcompact/posttooluse-emit-grok.sh +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/payloads/postcompact/posttooluse-emit.sh +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/payloads/postcompact/posttooluse-recall.sh +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/payloads/postcompact/precompact-flag.sh +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/payloads/postcompact/preinvocation-recall-antigravity.sh +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/payloads/postcompact/sessionstart-recall.sh +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/peer_executor.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/peer_executor_windows.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/peer_reconciliation.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/peer_reply_outbox.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/peer_service_host.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/peer_service_payload.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/peer_service_reply.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/peer_staging.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/query_filters.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/quota_sync.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/redact.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/rowclear.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/scripts/__init__.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/scripts/dm_notify_filter.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/scripts/ensure_monitor.sh +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/scripts/install_codex_waker_windows.ps1 +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/scripts/install_monitor_task_windows.ps1 +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/scripts/wake_watchdog.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/scrub.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/service/__init__.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/service/app.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/service/providers.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/session_bridge.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/skills/i-have-adhd/LICENSE +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/skills/i-have-adhd/SKILL.md +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/source_text.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/stall_alert.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/systemd/codex-waker.default +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/systemd/peer-reply-drain.default +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/systemd/swarph-codex-outbox@.service +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/systemd/swarph-codex-outbox@.timer +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/systemd/swarph-codex-waker@.service +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/systemd/swarph-codex-waker@.timer +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/systemd/swarph-monitor-reexec.path +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/systemd/swarph-monitor-reexec.service +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/systemd/swarph-monitor@.service +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/systemd/swarph-peer-reply-drain@.service +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/systemd/swarph-peer-reply-drain@.timer +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/systemd/swarph-stuck-sweep.service +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/systemd/swarph-stuck-sweep.timer +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/systemd/swarph-triage.service +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/systemd/swarph-triage.timer +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/systemd/swarph-watchdog.default +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/systemd/swarph-watchdog.service +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/systemd/swarph-watchdog.timer +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/the_ten.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/timeline_paths.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/tokens.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/triage/__init__.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/triage/backend.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/triage/job.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/triage/owners.json +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/triage/router.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/triage/rows.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli/triage/sensor.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli.egg-info/dependency_links.txt +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli.egg-info/entry_points.txt +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli.egg-info/requires.txt +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/src/swarph_cli.egg-info/top_level.txt +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1006_board_publisher.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1006_session_board.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1010_strand_only.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1013_spawn_channel.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1017_muse_tui.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1034_copy_mode.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1050_surrogate_wake.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1052_opencode_deaf.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1059_watchdog_unread_env.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1061_roster_cli.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1064_stuck_sweep.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1065_release.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1066_quiet_wakes.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1068_structured_accept_cli.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1071_quota_sync.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1073_triage.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1073_triage_board.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1073_wheel_install.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1075_task_cli.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1083_openai_decisions.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1144_cell_yaml_github.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1197_commander_taps.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1203_swarph_me_refusal.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1206_offer_question.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1214_egress.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1219_egress_probe.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1221_quota_windows.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1222_maybe_start_cap.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1228_quota_reach.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1243_the_ten.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1248_ship_price_table.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_124_register_merge.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1250_price_cache.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1256_commander_wake.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1261_mcp_install.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1262_wake_followups.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1265_wake_note.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1269_triage_label.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_126_pending_from_complete.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1277_close_usage.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1278_dreaming_reach.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1286_dm_unread_cursor.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1297_commander.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1300_authorization_check.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1301_restart_skew.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1320_commit_trailers.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1321_layered_redaction.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_132_ensure_monitor_state_dir.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1340_router_rollout.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1346_shell_string_gh.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1347_shell_depth_cap.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1353_obligation_release_cli.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1385_duplicate_session_argv.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_138_memory_navigate.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1396_dev_extract.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_139_tool_probe.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1405_skunkworks_basic.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1405_skunkworks_cli.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_1427_membrane_workflow.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_183_card_anchor.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_184_notify_honesty.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_201_win32_bash_refusal.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_243_onboard_per_peer_token.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_307_task4_ask_reply.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_312_codegraph_fuzzy_verb.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_3130_sender.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_3150_identity_router_install.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_319_refusal_exit_codes.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_323_mistral_backend.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_332_report_organize_findings.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_356_query_filters.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_397_gh_identity_router.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_397_router_preflight.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_402_one_identity_resolver.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_432_rowclear.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_467b_onboard_operator_credential.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_472_register_caller_binding.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_513_duplicate_session.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_523_guide.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_524_conftest_hermeticity.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_532_accept_flag.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_535_version_capability.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_538_signal_bench.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_546_default_gateway.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_547_verbs_from_registry.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_548_gateway_remainder.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_552_codegraph_gateway.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_555_relay_row_shape.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_556_relay_freshness.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_559_edges_truncated.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_564_bootstrap_first_peer.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_578_no_machine_specific_host_defaults.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_579_register_bootstrap_message.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_591_cli_step_graph.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_644_monitor_supervision.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_648_install_unit.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_654_reexec.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_656_owned_slm.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_684_dreaming_verb.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_689_pkg_version_order.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_715_grok_wake.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_716_timeline_one_path.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_723_grok_0251.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_724_ps1_ascii_or_bom.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_725_stdio_reconfigure.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_726_grok_limit_screen.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_729_arm_check_delivery_gap.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_729_dm_once.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_729_wake_watchdog.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_734_dreaming_enrich_degrade.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_735_dm_mcp_tools.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_739_wake_writer.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_740_edit_project.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_762_cards_edit_priority.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_764_enrich_collapse.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_801_confirm_flow_cli.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_802_stage_history.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_825_codegraph_hook_noise.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_825_install_posttooluse_only.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_825_remaining_cap_shred_bind.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_829_counterfactual_column.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_830_hook_binding_version.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_84_cli_labels.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_866_doctrine_guide.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_872_identity_refuses_not_warns.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_874_source_text.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_888_opencode_data_dir_can_fail.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_931_board_search.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_935_deadline_clock.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_937_dreaming_notify.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_938_organize_line_limit.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_941_bench_backends.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_941_harness_342.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_945_same_line_pairing.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_955_prompt_audit.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_957_auth_http.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_959_venv_interpreter.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_960_channel.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_960_ensure_monitor_heartbeat.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_961_cursor_grok_footer.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_961_loud_stop.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_963_plugin_manifest.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_964_channel_cell.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_965_mesh_wait.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_975_channel_hop.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_add_security_gate.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_artifact_add.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_artifact_hash.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_artifact_lib.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_artifact_mcp.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_artifact_skill.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_artifact_tool.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_artifact_uri.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_bench_backends.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_bench_claude_cli.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_bench_codex_cli.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_bench_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_bench_pack.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_bench_prices.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_bench_quality.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_bench_runner.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_bench_validate.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_board_card_thread.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_board_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_board_merge_check.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_board_obligation_close.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_brain_ask_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_brain_ask_env_diagnosis.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_brain_ask_identity_explicitness.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_brain_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_caller_meta_guard.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_capture_lineage.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_capture_liveness.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_capture_manifest.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_capture_paths.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_capture_security.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_cell_command_dispatch.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_cell_harden.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_cell_loader.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_cell_selfcheck.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_cell_verify.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_chain_token.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_channel_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_channel_poll_never_breaks_dms.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_channel_post.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_channel_wake_policy_filter.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_chat_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_claude_parser.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_claude_tmux_template.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_codegraph_caller_scope.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_codegraph_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_codegraph_hook.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_codegraph_mcp.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_codex_waker.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_committee_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_compress_caller_convention.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_compress_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_compress_levers.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_compress_marker.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_compress_verify.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_console_encoding_e2e.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_content_composition.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_copilot_membrane.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_copilot_pane_reader.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_cursor_membrane.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_daemon_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_daemon_console_encoding.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_daemon_delivery.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_delivery_queue.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_display_sanitize.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_ensure_monitor_no_peer_default.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_event_emit.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_feature_to_uri.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_gateway_brain.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_gateway_client.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_gateway_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_gateway_message_idempotency.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_gh_route_doctor_mesh_name.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_group_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_guide_commands_parse.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_guide_selfcheck.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_heartbeat_check.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_highlight_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_hook_output.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_hooks_activity_marker.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_hooks_add.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_hooks_bundle.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_hooks_init.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_hooks_legacy_generation_removal.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_hooks_lifecycle.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_hooks_merge.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_hooks_verify.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_hooks_win32_bash_wrapper.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_hooks_win32_command_path.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_import_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_inbox_identity_provenance.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_init_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_init_provider_menu.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_install_codex_hooks.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_install_hook.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_install_multiplexer_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_install_postcompact_hook.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_install_wake_hook.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_lane_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_launchd_units.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_main.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_main_unknown_verb_guard.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_mcp_missing_hint.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_mcp_server.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_memory_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_memory_emit_snippet.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_memory_gateway.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_memory_sync.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_memory_sync_membrane.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_mesh_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_mesh_inbox_mark_read.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_mesh_inbox_sanitize.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_mesh_originate_thread_623.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_mesh_send_unknown_peer.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_mesh_sidecar.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_mesh_sidecar_cursor_decoupled.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_mesh_sidecar_wake_survives_read.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_meta_edge_identity.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_monitor_channel_poll.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_monitor_cli.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_monitor_daemon_collision.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_monitor_self_name_verification.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_monitor_state_split.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_multiplexer.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_muse_membrane.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_muse_own_cli.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_obligation_close_is_surfaced.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_okf_links.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_onboard_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_opencode_membrane.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_opencode_plugin.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_operator_me.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_orphan_daemons.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_packaged_artifacts_exist.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_packaged_skills.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_peer_executor.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_peer_executor_windows.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_peer_reply_drain_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_peer_reply_drain_supervisor.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_peer_reply_outbox.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_peer_reply_transport.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_peer_service_e2e.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_peer_service_host.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_peer_service_payload.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_peer_service_reply.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_postcompact_recall.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_process_liveness.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_protocol_handler.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_providers_isolation.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_ratify_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_readme_claims_no_gateway_default.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_repl_caller_convention.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_schedule_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_schedule_create_contract.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_scrub.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_security.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_service_app.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_service_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_service_providers.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_session_bridge_inject.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_session_bridge_probe.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_session_bridge_resolve.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_session_path_role_gate.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_shipped_units_match_the_cli.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_smoke_chat.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_smoke_one_shot.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_smoke_phase_5_5.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_spawn_base_hoist.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_spawn_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_spawn_identity_stamp.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_spawn_live_pin.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_spawn_mitosis_lineage.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_spawn_tmux_session.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_spawn_windows_relaunch.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_stall_alert.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_subprocess_decode_encoding.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_timeline_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_tmux_wake_session_reanchor.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_tmux_wake_stale.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_tmux_wake_submit_verify.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_token_file_one_parser.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_token_precedence_explicit_first.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_unified_token_resolver.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_version_command.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_version_consistency.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_vibe_membrane.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_watchdog.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_watchdog_dm_wake.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_watchdog_dm_wake_cooldown.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_watchdog_dm_wake_wiring.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_watchdog_emit_health.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_watchdog_install_flags.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_watchdog_model_rung.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/tests/test_watchdog_stale_peers.py +0 -0
- {swarph_cli-0.72.41 → swarph_cli-0.72.42}/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.
|
|
3
|
+
Version: 0.72.42
|
|
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.
|
|
7
|
+
version = "0.72.42"
|
|
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" }
|
|
@@ -1370,6 +1370,12 @@ class Sink:
|
|
|
1370
1370
|
|
|
1371
1371
|
def __init__(self, name: str):
|
|
1372
1372
|
self.name = name
|
|
1373
|
+
# Card #1452 rework 1 (item 6): True when the send a deliver() call
|
|
1374
|
+
# just made was a standing-wake expiry REFRESH, not a first delivery
|
|
1375
|
+
# of newly owed DMs. The engine reads it after a True outcome: a
|
|
1376
|
+
# refresh must not reset the deferred-tick stall count or clear a
|
|
1377
|
+
# stall alert — no send may hide a cell that never drains.
|
|
1378
|
+
self.refresh_send = False
|
|
1373
1379
|
|
|
1374
1380
|
def deliver(self, state: "MonitorState", dms: list, up_to_id: int) -> Optional[bool]:
|
|
1375
1381
|
"""Push `dms` (may be a bounded/empty replay). Three outcomes:
|
|
@@ -1473,6 +1479,98 @@ def _stamp_wake(led: dict) -> None:
|
|
|
1473
1479
|
led["last_wake_injected_at"] = now
|
|
1474
1480
|
|
|
1475
1481
|
|
|
1482
|
+
# Card #1452: standing-wake expiry — ONE implementation shared by every sink
|
|
1483
|
+
# that holds a standing wake (TmuxSink, MuseSink, CodexSink). A standing
|
|
1484
|
+
# wake is trusted for at most STANDING_WAKE_EXPIRY_S without DRAIN PROGRESS
|
|
1485
|
+
# (unread decreasing); past that it is expired and the sink owes one fresh
|
|
1486
|
+
# wake. A poll that sends nothing reports the DM owed (None), never
|
|
1487
|
+
# delivered. The clock restarts only on a real send or on observed drain
|
|
1488
|
+
# progress — never on a bare poll, so a stuck cell still expires.
|
|
1489
|
+
STANDING_WAKE_EXPIRY_S = 600.0
|
|
1490
|
+
# Card #1452 rework 1 (note 89766 item 4): the trust limit BACKS OFF per
|
|
1491
|
+
# consecutive expiry refresh — STANDING_WAKE_EXPIRY_S x 2^k, capped at
|
|
1492
|
+
# STANDING_WAKE_EXPIRY_CAP_S. k (`wake_backoff_k` in the ledger) resets on
|
|
1493
|
+
# drain progress or on a drain to 0, so a cell that is actually reading
|
|
1494
|
+
# never pays the backed-off limit.
|
|
1495
|
+
STANDING_WAKE_EXPIRY_CAP_S = 3600.0
|
|
1496
|
+
# Card #1452 rework 1 (note 89766 item 3): with NOTHING newly owed (the
|
|
1497
|
+
# delivery ledger already covers the observed cursor — the lost-wake case),
|
|
1498
|
+
# a standing wake earns at most this many refreshes for the same delivered
|
|
1499
|
+
# id; then refreshes stop and the stall alert is raised once. A new DM
|
|
1500
|
+
# resets the count.
|
|
1501
|
+
STANDING_WAKE_MAX_CAUGHTUP_REFRESHES = 3
|
|
1502
|
+
|
|
1503
|
+
|
|
1504
|
+
def _standing_wake_limit(led: dict) -> float:
|
|
1505
|
+
"""Current trust limit for a standing wake: 600s x 2^k, cap 3600s."""
|
|
1506
|
+
k = int(led.get("wake_backoff_k", 0) or 0)
|
|
1507
|
+
if k < 0:
|
|
1508
|
+
k = 0
|
|
1509
|
+
return min(STANDING_WAKE_EXPIRY_S * float(2 ** min(k, 16)),
|
|
1510
|
+
STANDING_WAKE_EXPIRY_CAP_S)
|
|
1511
|
+
|
|
1512
|
+
|
|
1513
|
+
def _standing_wake_verdict(led: dict, unread, *, now=None) -> str:
|
|
1514
|
+
"""Classify a standing wake: drained/unreadable/progress/hold/expired.
|
|
1515
|
+
|
|
1516
|
+
Mutates only the progress bookkeeping (`wake_last_unread`,
|
|
1517
|
+
`wake_progress_at`, `wake_backoff_k`). `hold` mutates neither clock
|
|
1518
|
+
field. The expiry anchor is the LATER of `wake_progress_at` and
|
|
1519
|
+
`last_wake_injected_at` (rework 1 item 1: preferring an old progress
|
|
1520
|
+
stamp over a newer injection read a fresh wake as instantly expired).
|
|
1521
|
+
"""
|
|
1522
|
+
if unread is None:
|
|
1523
|
+
return "unreadable"
|
|
1524
|
+
if unread == 0:
|
|
1525
|
+
led["wake_backoff_k"] = 0 # a drain to 0 resets the backoff
|
|
1526
|
+
return "drained"
|
|
1527
|
+
if now is None:
|
|
1528
|
+
now = time.time()
|
|
1529
|
+
prev = led.get("wake_last_unread")
|
|
1530
|
+
led["wake_last_unread"] = int(unread)
|
|
1531
|
+
if prev is not None and int(unread) < int(prev):
|
|
1532
|
+
led["wake_progress_at"] = now
|
|
1533
|
+
led["wake_backoff_k"] = 0 # drain progress resets the backoff
|
|
1534
|
+
return "progress"
|
|
1535
|
+
anchor = max(float(led.get("wake_progress_at") or 0.0),
|
|
1536
|
+
float(led.get("last_wake_injected_at") or 0.0))
|
|
1537
|
+
if anchor <= 0 or now - anchor >= _standing_wake_limit(led):
|
|
1538
|
+
return "expired"
|
|
1539
|
+
return "hold"
|
|
1540
|
+
|
|
1541
|
+
|
|
1542
|
+
def _note_fresh_wake(led: dict, unread=None, *, expired=False) -> None:
|
|
1543
|
+
"""Restart the standing-wake clock after a real send.
|
|
1544
|
+
|
|
1545
|
+
An expiry refresh (`expired=True`) raises the backoff step k for the
|
|
1546
|
+
NEXT interval; a first/fresh send leaves k where the last progress or
|
|
1547
|
+
drain reset put it. A failed caught-up refresh counts like a sent one
|
|
1548
|
+
(rework 2, note 89818 item 3): the engine calls this with
|
|
1549
|
+
`expired=True` because the sink only reaches it on success.
|
|
1550
|
+
"""
|
|
1551
|
+
if expired:
|
|
1552
|
+
led["wake_backoff_k"] = int(led.get("wake_backoff_k", 0) or 0) + 1
|
|
1553
|
+
led["wake_progress_at"] = time.time()
|
|
1554
|
+
if unread is None:
|
|
1555
|
+
led.pop("wake_last_unread", None)
|
|
1556
|
+
else:
|
|
1557
|
+
led["wake_last_unread"] = int(unread)
|
|
1558
|
+
|
|
1559
|
+
|
|
1560
|
+
def _standing_refresh_prompt(unread, up_to_id: int) -> str:
|
|
1561
|
+
"""Wake text for a caught-up standing-wake refresh (item 5).
|
|
1562
|
+
|
|
1563
|
+
The original DM body is no longer owed (the ledger already covers it),
|
|
1564
|
+
so the text names what is unread instead of replaying a body.
|
|
1565
|
+
"""
|
|
1566
|
+
return (
|
|
1567
|
+
f"You have {unread} unread mesh DM(s). "
|
|
1568
|
+
f"(Standing-wake refresh: the last delivered DM id is {up_to_id}, "
|
|
1569
|
+
"and the inbox still shows unread mail.) "
|
|
1570
|
+
"Read each and act per your standing instructions."
|
|
1571
|
+
)
|
|
1572
|
+
|
|
1573
|
+
|
|
1476
1574
|
class TmuxSink(Sink):
|
|
1477
1575
|
"""Poke a tmux pane — the behaviour `mesh sidecar` has always had.
|
|
1478
1576
|
|
|
@@ -1504,6 +1602,7 @@ class TmuxSink(Sink):
|
|
|
1504
1602
|
def deliver(self, state: "MonitorState", dms: list, up_to_id: int) -> Optional[bool]:
|
|
1505
1603
|
led = state.ledger(self.name)
|
|
1506
1604
|
self.failure_reason = None
|
|
1605
|
+
self.refresh_send = False
|
|
1507
1606
|
# #1010: the deferral cause, named for the monitor's DEFERRED log —
|
|
1508
1607
|
# a hardcoded cause is a lie on every path that defers for another
|
|
1509
1608
|
# reason (the standing-wake hold defers with a CLEAR composer).
|
|
@@ -1580,7 +1679,27 @@ class TmuxSink(Sink):
|
|
|
1580
1679
|
from swarph_cli.commands.watchdog import _gateway_unread_count
|
|
1581
1680
|
unread = _gateway_unread_count(state.gateway, state.self_name,
|
|
1582
1681
|
state.token)
|
|
1583
|
-
|
|
1682
|
+
# Card #1452: shared standing-wake verdict (see
|
|
1683
|
+
# _standing_wake_verdict). Unreadable and drain-progress polls
|
|
1684
|
+
# send nothing and hold the DM owed; expiry is honoured by the
|
|
1685
|
+
# stale bound in the clear-composer arm below.
|
|
1686
|
+
swake = _standing_wake_verdict(led, unread)
|
|
1687
|
+
if swake == "unreadable":
|
|
1688
|
+
print(f"[monitor] {self.name}: standing wake, unread "
|
|
1689
|
+
f"unreadable (None) — DM held owed, no send this poll",
|
|
1690
|
+
flush=True)
|
|
1691
|
+
self.deferred_reason = (
|
|
1692
|
+
"standing wake, unread unreadable — DM held owed, "
|
|
1693
|
+
"no send")
|
|
1694
|
+
return None
|
|
1695
|
+
if swake == "progress":
|
|
1696
|
+
print(f"[monitor] {self.name}: standing wake, drain "
|
|
1697
|
+
f"progress (unread now {unread}) — DM held owed, "
|
|
1698
|
+
f"no send this poll", flush=True)
|
|
1699
|
+
self.deferred_reason = (
|
|
1700
|
+
"standing wake, drain progress — DM held owed, no send")
|
|
1701
|
+
return None
|
|
1702
|
+
if swake == "drained":
|
|
1584
1703
|
led["wake_outstanding"] = False # drained since — re-arm
|
|
1585
1704
|
else:
|
|
1586
1705
|
composer = _composer_state(self.target)
|
|
@@ -1592,6 +1711,8 @@ class TmuxSink(Sink):
|
|
|
1592
1711
|
if _agent_running(self.target):
|
|
1593
1712
|
return None
|
|
1594
1713
|
_tmux_enter(self.target) # one verified nudge, no new text
|
|
1714
|
+
_note_fresh_wake(led, unread, expired=(swake == "expired"))
|
|
1715
|
+
self.refresh_send = (swake == "expired")
|
|
1595
1716
|
return True
|
|
1596
1717
|
if composer == "clear":
|
|
1597
1718
|
# A finished opencode turn leaves a ▣ header with a
|
|
@@ -1602,6 +1723,8 @@ class TmuxSink(Sink):
|
|
|
1602
1723
|
ok = _tmux_wake(self.target)
|
|
1603
1724
|
if ok:
|
|
1604
1725
|
_stamp_wake(led)
|
|
1726
|
+
_note_fresh_wake(led, unread, expired=(swake == "expired"))
|
|
1727
|
+
self.refresh_send = (swake == "expired")
|
|
1605
1728
|
return True
|
|
1606
1729
|
if ok is None:
|
|
1607
1730
|
return None
|
|
@@ -1627,6 +1750,8 @@ class TmuxSink(Sink):
|
|
|
1627
1750
|
ok = _tmux_wake(self.target)
|
|
1628
1751
|
if ok:
|
|
1629
1752
|
_stamp_wake(led)
|
|
1753
|
+
_note_fresh_wake(led, unread, expired=(swake == "expired"))
|
|
1754
|
+
self.refresh_send = (swake == "expired")
|
|
1630
1755
|
return True
|
|
1631
1756
|
if ok is None:
|
|
1632
1757
|
return None # human adopted mid-settle: defer
|
|
@@ -1647,7 +1772,7 @@ class TmuxSink(Sink):
|
|
|
1647
1772
|
# (lab-ovh's rebase ruling): a line that says "no
|
|
1648
1773
|
# keystroke this poll" immediately followed by a keystroke
|
|
1649
1774
|
# is the lie both PRs exist to stop.
|
|
1650
|
-
if
|
|
1775
|
+
if swake == "expired":
|
|
1651
1776
|
# #619: a stale re-inject into a RUNNING TUI lands in
|
|
1652
1777
|
# the input-gated queue — lost again, just later.
|
|
1653
1778
|
# Defer; the first idle poll re-injects for real.
|
|
@@ -1656,6 +1781,8 @@ class TmuxSink(Sink):
|
|
|
1656
1781
|
ok = _tmux_wake(self.target)
|
|
1657
1782
|
if ok:
|
|
1658
1783
|
_stamp_wake(led)
|
|
1784
|
+
_note_fresh_wake(led, unread, expired=True)
|
|
1785
|
+
self.refresh_send = True
|
|
1659
1786
|
return True
|
|
1660
1787
|
if ok is None:
|
|
1661
1788
|
return None # human adopted mid-settle: defer
|
|
@@ -1753,6 +1880,12 @@ class TmuxSink(Sink):
|
|
|
1753
1880
|
if ok:
|
|
1754
1881
|
led["wake_outstanding"] = True
|
|
1755
1882
|
_stamp_wake(led)
|
|
1883
|
+
# Card #1452 rework 1 (item 1): a fresh Tmux wake resets the
|
|
1884
|
+
# progress clock, as Codex and Muse already do — otherwise a
|
|
1885
|
+
# progress stamp from a drained episode hours ago reads the
|
|
1886
|
+
# fresh wake as instantly expired and a DM a minute later
|
|
1887
|
+
# double-wakes inside the trust limit.
|
|
1888
|
+
_note_fresh_wake(led)
|
|
1756
1889
|
return True
|
|
1757
1890
|
# False splits by what the pane actually holds: text observably STUCK
|
|
1758
1891
|
# in the composer -> mark outstanding so the next poll nudges instead
|
|
@@ -1940,9 +2073,11 @@ def _muse_send(session: str, text: str, *,
|
|
|
1940
2073
|
class MuseSink(Sink):
|
|
1941
2074
|
"""Wake a live muse session with `session-message send` instead of typing.
|
|
1942
2075
|
|
|
1943
|
-
Edge-triggered on the drain like TmuxSink
|
|
1944
|
-
stands
|
|
1945
|
-
|
|
2076
|
+
Edge-triggered on the drain like TmuxSink, with the card #1452 expiry:
|
|
2077
|
+
while `wake_outstanding` stands and drain progress continues, further
|
|
2078
|
+
deliveries hold the DM owed (None) with NO new send; after
|
|
2079
|
+
STANDING_WAKE_EXPIRY_S without progress exactly one fresh wake is sent;
|
|
2080
|
+
the next delivery after the drain sends again. There is no
|
|
1946
2081
|
composer to read — a muse session has no TUI pane — so there is no
|
|
1947
2082
|
politeness gate, only the outstanding flag plus the gateway drain check.
|
|
1948
2083
|
A refused or failed send returns False with a NAMED reason printed loud;
|
|
@@ -1974,17 +2109,57 @@ class MuseSink(Sink):
|
|
|
1974
2109
|
|
|
1975
2110
|
def deliver(self, state: "MonitorState", dms: list, up_to_id: int) -> Optional[bool]:
|
|
1976
2111
|
led = state.ledger(self.name)
|
|
2112
|
+
self.deferred_reason = None
|
|
2113
|
+
self.refresh_send = False
|
|
2114
|
+
unread = None
|
|
1977
2115
|
if led.get("wake_outstanding"):
|
|
1978
2116
|
# Lazy: watchdog imports mesh module-level, so the reverse must
|
|
1979
|
-
# not.
|
|
1980
|
-
#
|
|
2117
|
+
# not. Card #1452: shared standing-wake verdict — a poll that
|
|
2118
|
+
# sends nothing holds the DM owed (None), never delivered.
|
|
1981
2119
|
from swarph_cli.commands.watchdog import _gateway_unread_count
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
2120
|
+
unread = _gateway_unread_count(state.gateway, state.self_name,
|
|
2121
|
+
state.token)
|
|
2122
|
+
swake = _standing_wake_verdict(led, unread)
|
|
2123
|
+
if swake == "drained":
|
|
2124
|
+
led["wake_outstanding"] = False # drained since — re-arm
|
|
2125
|
+
if not dms and up_to_id <= int(led.get("last_delivered_id", 0)):
|
|
2126
|
+
# Caught-up evaluation (item 2): the engine has already
|
|
2127
|
+
# advanced the ledger on this drain (item 5) — no send.
|
|
2128
|
+
return None
|
|
2129
|
+
elif swake == "expired":
|
|
2130
|
+
if not dms and up_to_id > int(led.get("last_delivered_id", 0)):
|
|
2131
|
+
print(f"[monitor] {self.name}: {up_to_id} observed but no body "
|
|
2132
|
+
f"recoverable from inbox.log for the owed range", flush=True)
|
|
2133
|
+
return False
|
|
2134
|
+
# Item 5: with nothing newly owed the original body is gone
|
|
2135
|
+
# from the owed range; the refresh names what is unread.
|
|
2136
|
+
text = (self._prompt(dms) if dms
|
|
2137
|
+
else _standing_refresh_prompt(unread, up_to_id))
|
|
2138
|
+
ok, reason = _muse_send(self.session, text)
|
|
2139
|
+
if ok:
|
|
2140
|
+
limit = _standing_wake_limit(led)
|
|
2141
|
+
led["wake_outstanding"] = True
|
|
2142
|
+
led["last_wake_injected_at"] = time.time()
|
|
2143
|
+
_note_fresh_wake(led, unread, expired=True)
|
|
2144
|
+
self.refresh_send = True
|
|
2145
|
+
print(f"[monitor] {self.name}: standing wake expired after "
|
|
2146
|
+
f"{limit:.0f}s without drain progress "
|
|
2147
|
+
f"— sent one fresh wake", flush=True)
|
|
2148
|
+
return True
|
|
2149
|
+
print(f"[monitor] {self.name}: muse send FAILED: {reason}", flush=True)
|
|
2150
|
+
return False
|
|
2151
|
+
elif swake == "unreadable":
|
|
2152
|
+
print(f"[monitor] {self.name}: standing wake, unread unreadable "
|
|
2153
|
+
f"(None) — DM held owed, no send this poll", flush=True)
|
|
2154
|
+
self.deferred_reason = (
|
|
2155
|
+
"standing wake, unread unreadable — DM held owed, no send")
|
|
2156
|
+
return None
|
|
2157
|
+
else:
|
|
2158
|
+
print(f"[monitor] {self.name}: standing wake ({swake}) — DM held "
|
|
2159
|
+
f"owed, no send this poll", flush=True)
|
|
2160
|
+
self.deferred_reason = (
|
|
2161
|
+
f"standing wake ({swake}) — DM held owed, no send")
|
|
2162
|
+
return None
|
|
1988
2163
|
if not dms:
|
|
1989
2164
|
# Nothing recoverable to hand over (log rotated) — do NOT claim
|
|
1990
2165
|
# a delivery; the ledger stays and the gap stays visible.
|
|
@@ -1997,6 +2172,7 @@ class MuseSink(Sink):
|
|
|
1997
2172
|
if ok:
|
|
1998
2173
|
led["wake_outstanding"] = True
|
|
1999
2174
|
led["last_wake_injected_at"] = time.time()
|
|
2175
|
+
_note_fresh_wake(led, unread)
|
|
2000
2176
|
return True
|
|
2001
2177
|
print(f"[monitor] {self.name}: muse send FAILED: {reason}", flush=True)
|
|
2002
2178
|
return False
|
|
@@ -2051,9 +2227,11 @@ def _codex_send(thread: str, text: str, *,
|
|
|
2051
2227
|
class CodexSink(Sink):
|
|
2052
2228
|
"""Wake the live gpt-ops session with `codex queue` instead of typing.
|
|
2053
2229
|
|
|
2054
|
-
Edge-triggered on the drain like MuseSink
|
|
2055
|
-
stands
|
|
2056
|
-
|
|
2230
|
+
Edge-triggered on the drain like MuseSink, with the card #1452 expiry:
|
|
2231
|
+
while `wake_outstanding` stands and drain progress continues, further
|
|
2232
|
+
deliveries hold the DM owed (None) with NO new send; after
|
|
2233
|
+
STANDING_WAKE_EXPIRY_S without progress exactly one fresh wake is sent;
|
|
2234
|
+
the next delivery after the drain sends again. There is no
|
|
2057
2235
|
composer to read — codex queues into the session, it does not type —
|
|
2058
2236
|
so there is no politeness gate, only the outstanding flag plus the
|
|
2059
2237
|
gateway drain check. A refused or failed send returns False with a NAMED
|
|
@@ -2085,17 +2263,57 @@ class CodexSink(Sink):
|
|
|
2085
2263
|
|
|
2086
2264
|
def deliver(self, state: "MonitorState", dms: list, up_to_id: int) -> Optional[bool]:
|
|
2087
2265
|
led = state.ledger(self.name)
|
|
2266
|
+
self.deferred_reason = None
|
|
2267
|
+
self.refresh_send = False
|
|
2268
|
+
unread = None
|
|
2088
2269
|
if led.get("wake_outstanding"):
|
|
2089
2270
|
# Lazy: watchdog imports mesh module-level, so the reverse must
|
|
2090
|
-
# not.
|
|
2091
|
-
#
|
|
2271
|
+
# not. Card #1452: shared standing-wake verdict — a poll that
|
|
2272
|
+
# sends nothing holds the DM owed (None), never delivered.
|
|
2092
2273
|
from swarph_cli.commands.watchdog import _gateway_unread_count
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2274
|
+
unread = _gateway_unread_count(state.gateway, state.self_name,
|
|
2275
|
+
state.token)
|
|
2276
|
+
swake = _standing_wake_verdict(led, unread)
|
|
2277
|
+
if swake == "drained":
|
|
2278
|
+
led["wake_outstanding"] = False # drained since — re-arm
|
|
2279
|
+
if not dms and up_to_id <= int(led.get("last_delivered_id", 0)):
|
|
2280
|
+
# Caught-up evaluation (item 2): the engine has already
|
|
2281
|
+
# advanced the ledger on this drain (item 5) — no send.
|
|
2282
|
+
return None
|
|
2283
|
+
elif swake == "expired":
|
|
2284
|
+
if not dms and up_to_id > int(led.get("last_delivered_id", 0)):
|
|
2285
|
+
print(f"[monitor] {self.name}: {up_to_id} observed but no body "
|
|
2286
|
+
f"recoverable from inbox.log for the owed range", flush=True)
|
|
2287
|
+
return False
|
|
2288
|
+
# Item 5: with nothing newly owed the original body is gone
|
|
2289
|
+
# from the owed range; the refresh names what is unread.
|
|
2290
|
+
text = (self._prompt(dms) if dms
|
|
2291
|
+
else _standing_refresh_prompt(unread, up_to_id))
|
|
2292
|
+
ok, reason = _codex_send(self.thread, text)
|
|
2293
|
+
if ok:
|
|
2294
|
+
limit = _standing_wake_limit(led)
|
|
2295
|
+
led["wake_outstanding"] = True
|
|
2296
|
+
led["last_wake_injected_at"] = time.time()
|
|
2297
|
+
_note_fresh_wake(led, unread, expired=True)
|
|
2298
|
+
self.refresh_send = True
|
|
2299
|
+
print(f"[monitor] {self.name}: standing wake expired after "
|
|
2300
|
+
f"{limit:.0f}s without drain progress "
|
|
2301
|
+
f"— sent one fresh wake", flush=True)
|
|
2302
|
+
return True
|
|
2303
|
+
print(f"[monitor] {self.name}: codex send FAILED: {reason}", flush=True)
|
|
2304
|
+
return False
|
|
2305
|
+
elif swake == "unreadable":
|
|
2306
|
+
print(f"[monitor] {self.name}: standing wake, unread unreadable "
|
|
2307
|
+
f"(None) — DM held owed, no send this poll", flush=True)
|
|
2308
|
+
self.deferred_reason = (
|
|
2309
|
+
"standing wake, unread unreadable — DM held owed, no send")
|
|
2310
|
+
return None
|
|
2311
|
+
else:
|
|
2312
|
+
print(f"[monitor] {self.name}: standing wake ({swake}) — DM held "
|
|
2313
|
+
f"owed, no send this poll", flush=True)
|
|
2314
|
+
self.deferred_reason = (
|
|
2315
|
+
f"standing wake ({swake}) — DM held owed, no send")
|
|
2316
|
+
return None
|
|
2099
2317
|
if not dms:
|
|
2100
2318
|
# Nothing recoverable to hand over (log rotated) — do NOT claim
|
|
2101
2319
|
# a delivery; the ledger stays and the gap stays visible.
|
|
@@ -2108,6 +2326,7 @@ class CodexSink(Sink):
|
|
|
2108
2326
|
if ok:
|
|
2109
2327
|
led["wake_outstanding"] = True
|
|
2110
2328
|
led["last_wake_injected_at"] = time.time()
|
|
2329
|
+
_note_fresh_wake(led, unread)
|
|
2111
2330
|
return True
|
|
2112
2331
|
print(f"[monitor] {self.name}: codex send FAILED: {reason}", flush=True)
|
|
2113
2332
|
return False
|
|
@@ -2403,7 +2622,7 @@ _WAKE_SUBMIT_ATTEMPTS = 4
|
|
|
2403
2622
|
# enough that a legitimately queued follow-up survives a marathon agent turn;
|
|
2404
2623
|
# short enough that a lost wake costs minutes of silence, not hours. The
|
|
2405
2624
|
# retry self-rate-limits: a successful re-injection re-anchors the clock.
|
|
2406
|
-
_WAKE_STALE_S =
|
|
2625
|
+
_WAKE_STALE_S = STANDING_WAKE_EXPIRY_S
|
|
2407
2626
|
|
|
2408
2627
|
|
|
2409
2628
|
def _capture_pane_lines(target: str) -> Optional[list[str]]:
|
|
@@ -3583,15 +3802,151 @@ def _monitor_deliver(state: MonitorState) -> None:
|
|
|
3583
3802
|
# Per-poll, the drain is caught within one interval and the next
|
|
3584
3803
|
# DM earns a wake of its own. unread == None (gateway error)
|
|
3585
3804
|
# reads as NOT-drained — never re-arm on an unreadable signal.
|
|
3586
|
-
|
|
3805
|
+
# Card #1452 rework 3 (note 89855 route B): this branch used to
|
|
3806
|
+
# read the count only while wake_outstanding stood. A running
|
|
3807
|
+
# plain-tmux turn clears that flag (#620), so a drain inside the
|
|
3808
|
+
# turn was invisible and the stall row stayed open until the
|
|
3809
|
+
# turn ended — and the turn's end then woke on mail already
|
|
3810
|
+
# read. Read while a wake stands OR while an alert stands
|
|
3811
|
+
# (caught-up marker set, or deferred ticks at or above
|
|
3812
|
+
# _STALL_FIRST). No read otherwise.
|
|
3813
|
+
unread = None
|
|
3814
|
+
from swarph_cli import stall_alert
|
|
3815
|
+
ticks = int(led.get("deferred_ticks", 0) or 0)
|
|
3816
|
+
alert_stands = (
|
|
3817
|
+
int(led.get("standing_refresh_alerted_id", 0) or 0) != 0
|
|
3818
|
+
or ticks >= stall_alert._STALL_FIRST)
|
|
3819
|
+
if led.get("wake_outstanding") or alert_stands:
|
|
3587
3820
|
from swarph_cli.commands.watchdog import _gateway_unread_count
|
|
3588
|
-
|
|
3589
|
-
|
|
3821
|
+
unread = _gateway_unread_count(state.gateway, state.self_name,
|
|
3822
|
+
state.token)
|
|
3823
|
+
if unread == 0:
|
|
3590
3824
|
led["wake_outstanding"] = False
|
|
3825
|
+
# Card #1452 rework 1 (item 5): an observed drain to 0
|
|
3826
|
+
# ADVANCES the ledger to the observed cursor with NO
|
|
3827
|
+
# send — a healthy drain costs no spurious wake. Only a
|
|
3828
|
+
# real send moves delivery evidence otherwise. The
|
|
3829
|
+
# backoff and the caught-up refresh count reset here.
|
|
3830
|
+
if int(led["last_delivered_id"]) != observed:
|
|
3831
|
+
led["last_delivered_id"] = observed
|
|
3832
|
+
# Card #1452 rework 2 (note 89818 item 2): a drain closes
|
|
3833
|
+
# the stall row. The bound alert leaves deferred_ticks at
|
|
3834
|
+
# 0, and the tick alert leaves them high, so neither the
|
|
3835
|
+
# next delivery nor this branch used to close it. When
|
|
3836
|
+
# either alert stands, zero the ticks and close the row.
|
|
3837
|
+
led["wake_backoff_k"] = 0
|
|
3838
|
+
led["standing_refresh_count"] = 0
|
|
3839
|
+
led["standing_refresh_alerted_id"] = 0
|
|
3840
|
+
if alert_stands:
|
|
3841
|
+
led["deferred_ticks"] = 0
|
|
3842
|
+
stall_alert.clear_stall_alert(
|
|
3843
|
+
state.gateway, state.token, state.self_name)
|
|
3591
3844
|
changed = True
|
|
3592
3845
|
delivered = int(led["last_delivered_id"])
|
|
3593
3846
|
if delivered >= observed:
|
|
3594
|
-
|
|
3847
|
+
# Card #1452 rework 1 (item 2): a standing wake is evaluated
|
|
3848
|
+
# on EVERY poll, also when nothing is newly owed — the
|
|
3849
|
+
# lost-wake case (one unread DM, no later DM) otherwise
|
|
3850
|
+
# never refreshed, and its drain progress was discarded.
|
|
3851
|
+
# The engine runs the shared verdict itself (recording any
|
|
3852
|
+
# nonzero drain progress in the ledger) and calls deliver()
|
|
3853
|
+
# only when a refresh send is actually due, so a hold poll
|
|
3854
|
+
# costs no sink read (e.g. no tmux pane capture).
|
|
3855
|
+
if not led.get("wake_outstanding"):
|
|
3856
|
+
continue # this sink owes nothing, no wake stands
|
|
3857
|
+
if unread is None:
|
|
3858
|
+
continue # unreadable: the flag stands, no send
|
|
3859
|
+
verdict = _standing_wake_verdict(led, unread)
|
|
3860
|
+
if verdict == "progress":
|
|
3861
|
+
changed = True # persist the re-anchored progress clock
|
|
3862
|
+
continue
|
|
3863
|
+
if verdict != "expired":
|
|
3864
|
+
continue # hold: nothing material changed
|
|
3865
|
+
refresh_for = int(led.get("standing_refresh_for_id", -1))
|
|
3866
|
+
refresh_count = (int(led.get("standing_refresh_count", 0))
|
|
3867
|
+
if refresh_for == delivered else 0)
|
|
3868
|
+
if refresh_count >= STANDING_WAKE_MAX_CAUGHTUP_REFRESHES:
|
|
3869
|
+
# Item 3: at most STANDING_WAKE_MAX_CAUGHTUP_REFRESHES
|
|
3870
|
+
# refreshes for the same delivered id, then stop and
|
|
3871
|
+
# raise the existing stall alert ONCE. A new DM (the
|
|
3872
|
+
# owed path below) resets the count.
|
|
3873
|
+
if int(led.get("standing_refresh_alerted_id", 0)) != delivered:
|
|
3874
|
+
led["standing_refresh_alerted_id"] = delivered
|
|
3875
|
+
from swarph_cli import stall_alert
|
|
3876
|
+
stall_alert.send_stall_alert(
|
|
3877
|
+
state.gateway, state.token, state.self_name,
|
|
3878
|
+
refresh_count,
|
|
3879
|
+
unread if isinstance(unread, int) and unread > 0 else 1)
|
|
3880
|
+
print(f"{state.log_prefix} standing wake for {sink.name} "
|
|
3881
|
+
f"hit the caught-up refresh bound "
|
|
3882
|
+
f"({STANDING_WAKE_MAX_CAUGHTUP_REFRESHES} for id "
|
|
3883
|
+
f"{delivered}) — no further refresh; stall alert raised",
|
|
3884
|
+
flush=True)
|
|
3885
|
+
changed = True
|
|
3886
|
+
continue
|
|
3887
|
+
outcome = sink.deliver(state, [], observed)
|
|
3888
|
+
if outcome is None:
|
|
3889
|
+
# Card #1452 rework 2 (note 89818 item 1): plain tmux
|
|
3890
|
+
# clears wake_outstanding when a turn is running (#620)
|
|
3891
|
+
# and returns None. Nothing is newly owed, so a cleared
|
|
3892
|
+
# flag would never re-enter this sink and the lost wake
|
|
3893
|
+
# would stay lost. Keep the flag while unread remains.
|
|
3894
|
+
# A deferral is not a refresh: the clock and the count
|
|
3895
|
+
# stay, so the refresh still happens once the turn ends.
|
|
3896
|
+
if isinstance(unread, int) and unread > 0:
|
|
3897
|
+
led["wake_outstanding"] = True
|
|
3898
|
+
changed = True
|
|
3899
|
+
continue
|
|
3900
|
+
# True and False both consume one caught-up refresh (note
|
|
3901
|
+
# 89818 item 3). A refused send used to leave the clock and
|
|
3902
|
+
# the count unmoved, so a dead sink retried every poll and
|
|
3903
|
+
# never reached the stall alert. Count it like a sent one.
|
|
3904
|
+
# The sink restarts the clock only on success; do it here on
|
|
3905
|
+
# failure. The owed path below is unchanged: a failed send
|
|
3906
|
+
# there raises no new alert (carded separately).
|
|
3907
|
+
if not outcome:
|
|
3908
|
+
_note_fresh_wake(
|
|
3909
|
+
led, unread if isinstance(unread, int) else None,
|
|
3910
|
+
expired=True)
|
|
3911
|
+
# Note 89855 item 3: plain tmux clears the flag on the
|
|
3912
|
+
# running read (#620) and the idle read can then refuse
|
|
3913
|
+
# the send, so the flag is down unless this puts it
|
|
3914
|
+
# back. Without it the refused refresh is the last
|
|
3915
|
+
# attempt and the stall alert never comes.
|
|
3916
|
+
if isinstance(unread, int) and unread > 0:
|
|
3917
|
+
led["wake_outstanding"] = True
|
|
3918
|
+
led["standing_refresh_count"] = refresh_count + 1
|
|
3919
|
+
led["standing_refresh_for_id"] = delivered
|
|
3920
|
+
if outcome:
|
|
3921
|
+
led["last_delivery_at"] = now
|
|
3922
|
+
led["consecutive_failures"] = 0
|
|
3923
|
+
state.deliveries[sink.name] = state.deliveries.get(sink.name, 0) + 1
|
|
3924
|
+
print(f"{state.log_prefix} standing wake refreshed for "
|
|
3925
|
+
f"{sink.name} (refresh "
|
|
3926
|
+
f"{refresh_count + 1}/{STANDING_WAKE_MAX_CAUGHTUP_REFRESHES} "
|
|
3927
|
+
f"for id {delivered}; nothing newly owed)",
|
|
3928
|
+
flush=True)
|
|
3929
|
+
else:
|
|
3930
|
+
led["consecutive_failures"] = int(led["consecutive_failures"]) + 1
|
|
3931
|
+
detail = getattr(sink, "failure_reason", None) or (
|
|
3932
|
+
"the sink is probably gone (session restart / renamed target)"
|
|
3933
|
+
)
|
|
3934
|
+
print(f"{state.log_prefix} DELIVERY FAILED to {sink.name} "
|
|
3935
|
+
f"({led['consecutive_failures']} consecutive) -- DMs up to "
|
|
3936
|
+
f"id {observed} were still observed and archived; {detail}",
|
|
3937
|
+
file=sys.stderr, flush=True)
|
|
3938
|
+
changed = True
|
|
3939
|
+
continue
|
|
3940
|
+
# Something is newly owed: a new DM resets the caught-up
|
|
3941
|
+
# refresh count (item 3) so the new id can refresh. Card #1452
|
|
3942
|
+
# rework 3 (note 89855 route A): do NOT zero
|
|
3943
|
+
# standing_refresh_alerted_id here. Zeroing it dropped the
|
|
3944
|
+
# stall row's identity, the drain then found nothing to close,
|
|
3945
|
+
# and that open row absorbed the next stall. The drain branch
|
|
3946
|
+
# still zeroes the marker when it closes the row.
|
|
3947
|
+
if int(led.get("standing_refresh_count", 0) or 0):
|
|
3948
|
+
led["standing_refresh_count"] = 0
|
|
3949
|
+
changed = True
|
|
3595
3950
|
if now - float(led["last_delivery_at"]) < state.min_interval_s:
|
|
3596
3951
|
print(f"{state.log_prefix} wake suppressed by idle guard for "
|
|
3597
3952
|
f"{sink.name} (cursor advanced; delivery still pending)",
|
|
@@ -3634,7 +3989,12 @@ def _monitor_deliver(state: MonitorState) -> None:
|
|
|
3634
3989
|
flush=True)
|
|
3635
3990
|
continue
|
|
3636
3991
|
was_stalled = bool(led.get("deferred_ticks"))
|
|
3637
|
-
|
|
3992
|
+
# Card #1452 rework 1 (item 6): a standing-wake REFRESH send must
|
|
3993
|
+
# not hide a cell that never drains — it neither resets the
|
|
3994
|
+
# deferred-tick count nor clears the stall alert. Only a
|
|
3995
|
+
# non-refresh delivery (or a drain) resolves a stall.
|
|
3996
|
+
is_refresh = bool(getattr(sink, "refresh_send", False))
|
|
3997
|
+
if was_stalled and not is_refresh:
|
|
3638
3998
|
led["deferred_ticks"] = 0
|
|
3639
3999
|
if outcome:
|
|
3640
4000
|
led["last_delivered_id"] = observed
|
|
@@ -3643,7 +4003,7 @@ def _monitor_deliver(state: MonitorState) -> None:
|
|
|
3643
4003
|
state.deliveries[sink.name] = state.deliveries.get(sink.name, 0) + 1
|
|
3644
4004
|
print(f"{state.log_prefix} delivered to {sink.name} up to id {observed}",
|
|
3645
4005
|
flush=True)
|
|
3646
|
-
if was_stalled:
|
|
4006
|
+
if was_stalled and not is_refresh:
|
|
3647
4007
|
from swarph_cli import stall_alert
|
|
3648
4008
|
stall_alert.clear_stall_alert(
|
|
3649
4009
|
state.gateway, state.token, state.self_name)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: swarph-cli
|
|
3
|
-
Version: 0.72.
|
|
3
|
+
Version: 0.72.42
|
|
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
|
|
@@ -279,6 +279,10 @@ tests/test_139_tool_probe.py
|
|
|
279
279
|
tests/test_1405_skunkworks_basic.py
|
|
280
280
|
tests/test_1405_skunkworks_cli.py
|
|
281
281
|
tests/test_1427_membrane_workflow.py
|
|
282
|
+
tests/test_1452_rework1_engine.py
|
|
283
|
+
tests/test_1452_rework2_engine.py
|
|
284
|
+
tests/test_1452_rework3_engine.py
|
|
285
|
+
tests/test_1452_standing_wake_expiry.py
|
|
282
286
|
tests/test_183_card_anchor.py
|
|
283
287
|
tests/test_184_notify_honesty.py
|
|
284
288
|
tests/test_201_win32_bash_refusal.py
|