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.
- {swarph_cli-0.72.4/src/swarph_cli.egg-info → swarph_cli-0.72.5}/PKG-INFO +1 -1
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/pyproject.toml +1 -1
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/__init__.py +1 -1
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/mesh.py +32 -0
- swarph_cli-0.72.5/src/swarph_cli/commands/rowclear_hook.py +42 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/guide/GUIDE.md +1 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/main.py +8 -2
- swarph_cli-0.72.5/src/swarph_cli/rowclear.py +239 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5/src/swarph_cli.egg-info}/PKG-INFO +1 -1
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli.egg-info/SOURCES.txt +3 -0
- swarph_cli-0.72.5/tests/test_432_rowclear.py +278 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/LICENSE +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/README.md +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/setup.cfg +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/__main__.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/__init__.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/backends.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/claude_cli.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/codex_cli.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/pack.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/prices.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/providers.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/quality.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/refresh_prices.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/rules.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/runner.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/signal_score.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/bench/validate.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/caller.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/capture/__init__.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/capture/harden.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/capture/lineage.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/capture/liveness.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/capture/manifest.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/capture/paths.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/capture/verify.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/cell.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/chain_token.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/channel.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/__init__.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/_content.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/_display.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/_gateway_client.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/add.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/bench.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/board.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/board_merge_check.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/brain.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/brain_ask.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/cell.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/cell_probe.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/cell_selfcheck.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/channel.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/chat.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/codegraph.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/codegraph_hook.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/codex_hook_output.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/codex_waker.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/compress.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/daemon.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/dreaming.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/event.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/gateway.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/gh_route.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/group.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/guide.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/highlight.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/hook_interpreter.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/hook_output.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/hooks.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/import_session.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/init.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/install_codex_hooks.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/install_hook.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/install_multiplexer.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/install_opencode_plugin.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/install_postcompact_hook.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/install_wake_hook.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/lane.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/mcp_server.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/memory.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/memory_emit_hook.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/memory_sync.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/monitor.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/okf_links.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/onboard.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/peer_reply_drain.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/postcompact_hook_output.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/protocol_handler.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/ratify.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/schedule.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/security.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/service.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/spawn.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/timeline.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/version.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/wake_hook_output.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/commands/watchdog.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/compress/__init__.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/compress/levers.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/compress/marker.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/compress/verify.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/console_safe.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/delivery_queue.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dm_frame.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/__init__.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/candidates.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/clone.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/enrich.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/index_check.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/notify.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/organize.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/probes.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/report.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/run.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/slm.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/transcripts.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/dreaming/verify.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/gateway/__init__.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/gateway/feature_registry.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/gateway/lanes_control.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/gateway/schema.sql +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/gateway/server.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/gateway/services_control.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/gateway_default.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/gh_identity.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/identity.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/multiplexer.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/operator/__init__.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/operator/__main__.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/operator/api.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/operator/cli.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/operator/config.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/operator/fmt.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/orphan_daemons.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/pane_probe.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/parsers/__init__.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/parsers/claude.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/opencode/plugin.js +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/_shim.cmd +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/postcompact-recall-grok.sh +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/postcompact-recall.sh +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/posttooluse-emit-antigravity.sh +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/posttooluse-emit-claude.sh +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/posttooluse-emit-grok.sh +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/posttooluse-emit.sh +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/posttooluse-recall.sh +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/precompact-flag.sh +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/preinvocation-recall-antigravity.sh +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/payloads/postcompact/sessionstart-recall.sh +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/peer_executor.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/peer_executor_windows.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/peer_reconciliation.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/peer_reply_outbox.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/peer_service_host.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/peer_service_payload.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/peer_service_reply.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/peer_staging.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/query_filters.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/scripts/__init__.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/scripts/dm_notify_filter.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/scripts/ensure_monitor.sh +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/scripts/install_codex_waker_windows.ps1 +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/scripts/install_monitor_task_windows.ps1 +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/scripts/wake_watchdog.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/service/__init__.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/service/app.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/service/providers.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/session_bridge.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/skills/i-have-adhd/LICENSE +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/skills/i-have-adhd/SKILL.md +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/source_text.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/stall_alert.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/codex-waker.default +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/peer-reply-drain.default +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-codex-outbox@.service +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-codex-outbox@.timer +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-codex-waker@.service +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-codex-waker@.timer +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-monitor-reexec.path +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-monitor-reexec.service +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-monitor@.service +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-peer-reply-drain@.service +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-peer-reply-drain@.timer +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-watchdog.default +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-watchdog.service +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/systemd/swarph-watchdog.timer +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/timeline_paths.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli/tokens.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli.egg-info/dependency_links.txt +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli.egg-info/entry_points.txt +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli.egg-info/requires.txt +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/src/swarph_cli.egg-info/top_level.txt +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_1006_board_publisher.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_1006_session_board.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_1010_strand_only.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_1013_spawn_channel.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_1017_muse_tui.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_124_register_merge.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_126_pending_from_complete.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_132_ensure_monitor_state_dir.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_138_memory_navigate.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_139_tool_probe.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_183_card_anchor.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_184_notify_honesty.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_201_win32_bash_refusal.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_243_onboard_per_peer_token.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_307_task4_ask_reply.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_312_codegraph_fuzzy_verb.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_319_refusal_exit_codes.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_323_mistral_backend.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_332_report_organize_findings.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_356_query_filters.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_397_gh_identity_router.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_397_router_preflight.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_402_one_identity_resolver.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_467b_onboard_operator_credential.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_472_register_caller_binding.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_484_codex_queue_sink.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_523_guide.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_524_conftest_hermeticity.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_532_accept_flag.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_535_version_capability.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_538_signal_bench.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_546_default_gateway.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_547_verbs_from_registry.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_548_gateway_remainder.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_552_codegraph_gateway.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_555_relay_row_shape.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_556_relay_freshness.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_559_edges_truncated.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_564_bootstrap_first_peer.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_578_no_machine_specific_host_defaults.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_579_register_bootstrap_message.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_591_cli_step_graph.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_644_monitor_supervision.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_648_install_unit.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_654_reexec.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_656_owned_slm.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_684_dreaming_verb.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_689_pkg_version_order.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_715_grok_wake.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_716_timeline_one_path.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_723_grok_0251.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_724_ps1_ascii_or_bom.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_725_stdio_reconfigure.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_726_grok_limit_screen.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_729_arm_check_delivery_gap.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_729_dm_once.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_729_wake_watchdog.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_734_dreaming_enrich_degrade.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_735_dm_mcp_tools.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_739_wake_writer.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_740_edit_project.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_762_cards_edit_priority.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_764_enrich_collapse.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_801_confirm_flow_cli.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_802_stage_history.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_825_codegraph_hook_noise.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_825_install_posttooluse_only.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_825_remaining_cap_shred_bind.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_829_counterfactual_column.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_830_hook_binding_version.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_84_cli_labels.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_866_doctrine_guide.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_872_identity_refuses_not_warns.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_874_source_text.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_888_opencode_data_dir_can_fail.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_937_dreaming_notify.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_938_organize_line_limit.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_941_bench_backends.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_941_harness_342.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_945_same_line_pairing.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_955_prompt_audit.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_957_auth_http.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_959_venv_interpreter.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_960_channel.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_960_ensure_monitor_heartbeat.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_961_cursor_grok_footer.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_961_loud_stop.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_963_plugin_manifest.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_964_channel_cell.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_965_mesh_wait.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_975_channel_hop.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_add_security_gate.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_artifact_add.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_artifact_hash.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_artifact_lib.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_artifact_mcp.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_artifact_skill.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_artifact_tool.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_artifact_uri.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_bench_backends.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_bench_claude_cli.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_bench_codex_cli.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_bench_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_bench_pack.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_bench_prices.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_bench_quality.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_bench_runner.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_bench_validate.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_board_card_thread.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_board_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_board_merge_check.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_board_obligation_close.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_brain_ask_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_brain_ask_env_diagnosis.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_brain_ask_identity_explicitness.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_brain_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_caller_meta_guard.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_capture_lineage.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_capture_liveness.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_capture_manifest.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_capture_paths.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_capture_security.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_cell_command_dispatch.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_cell_harden.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_cell_loader.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_cell_selfcheck.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_cell_verify.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_chain_token.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_channel_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_channel_poll_never_breaks_dms.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_channel_post.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_channel_wake_policy_filter.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_chat_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_claude_parser.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_claude_tmux_template.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_codegraph_caller_scope.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_codegraph_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_codegraph_hook.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_codegraph_mcp.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_codex_waker.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_compress_caller_convention.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_compress_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_compress_levers.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_compress_marker.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_compress_verify.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_console_encoding_e2e.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_content_composition.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_cursor_membrane.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_daemon_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_daemon_console_encoding.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_daemon_delivery.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_delivery_queue.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_display_sanitize.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_ensure_monitor_no_peer_default.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_event_emit.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_feature_to_uri.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_gateway_brain.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_gateway_client.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_gateway_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_gateway_message_idempotency.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_gh_route_doctor_mesh_name.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_group_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_guide_commands_parse.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_guide_selfcheck.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_heartbeat_check.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_highlight_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hook_output.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hooks_activity_marker.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hooks_add.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hooks_bundle.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hooks_init.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hooks_legacy_generation_removal.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hooks_lifecycle.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hooks_merge.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hooks_verify.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hooks_win32_bash_wrapper.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_hooks_win32_command_path.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_import_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_inbox_identity_provenance.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_init_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_init_provider_menu.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_install_codex_hooks.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_install_hook.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_install_multiplexer_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_install_postcompact_hook.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_install_wake_hook.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_lane_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_main.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_main_unknown_verb_guard.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mcp_missing_hint.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mcp_server.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_memory_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_memory_emit_snippet.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_memory_gateway.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_memory_sync.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_memory_sync_membrane.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mesh_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mesh_inbox_mark_read.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mesh_inbox_sanitize.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mesh_originate_thread_623.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mesh_send_unknown_peer.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mesh_sidecar.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mesh_sidecar_cursor_decoupled.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mesh_sidecar_muse_sink.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_mesh_sidecar_wake_survives_read.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_meta_edge_identity.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_monitor_channel_poll.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_monitor_cli.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_monitor_daemon_collision.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_monitor_self_name_verification.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_monitor_state_split.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_multiplexer.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_muse_membrane.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_muse_own_cli.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_obligation_close_is_surfaced.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_okf_links.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_onboard_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_opencode_membrane.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_opencode_plugin.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_operator_me.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_orphan_daemons.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_packaged_artifacts_exist.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_packaged_skills.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_peer_executor.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_peer_executor_windows.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_peer_reply_drain_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_peer_reply_drain_supervisor.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_peer_reply_outbox.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_peer_reply_transport.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_peer_service_e2e.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_peer_service_host.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_peer_service_payload.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_peer_service_reply.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_postcompact_recall.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_process_liveness.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_protocol_handler.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_providers_isolation.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_ratify_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_readme_claims_no_gateway_default.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_repl_caller_convention.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_schedule_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_schedule_create_contract.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_security.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_service_app.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_service_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_service_providers.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_session_bridge_inject.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_session_bridge_probe.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_session_bridge_resolve.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_session_path_role_gate.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_shipped_units_match_the_cli.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_smoke_chat.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_smoke_one_shot.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_smoke_phase_5_5.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_spawn_base_hoist.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_spawn_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_spawn_identity_stamp.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_spawn_live_pin.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_spawn_mitosis_lineage.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_spawn_tmux_session.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_spawn_windows_relaunch.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_stall_alert.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_subprocess_decode_encoding.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_timeline_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_tmux_wake_runstate_defer.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_tmux_wake_session_reanchor.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_tmux_wake_stale.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_tmux_wake_submit_verify.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_token_file_one_parser.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_token_precedence_explicit_first.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_unified_token_resolver.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_version_command.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_version_consistency.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_vibe_membrane.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_watchdog.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_watchdog_dm_wake.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_watchdog_dm_wake_cooldown.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_watchdog_dm_wake_wiring.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_watchdog_emit_health.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_watchdog_install_flags.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_watchdog_model_rung.py +0 -0
- {swarph_cli-0.72.4 → swarph_cli-0.72.5}/tests/test_watchdog_stale_peers.py +0 -0
- {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.
|
|
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.
|
|
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" }
|
|
@@ -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
|
-
|
|
151
|
-
|
|
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.
|
|
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
|