swarph-cli 0.72.24__tar.gz → 0.72.26__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.24/src/swarph_cli.egg-info → swarph_cli-0.72.26}/PKG-INFO +1 -1
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/pyproject.toml +1 -1
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/__init__.py +1 -1
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/mesh.py +11 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/operator/cli.py +16 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/quota_sync.py +133 -13
- {swarph_cli-0.72.24 → swarph_cli-0.72.26/src/swarph_cli.egg-info}/PKG-INFO +1 -1
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli.egg-info/SOURCES.txt +4 -0
- swarph_cli-0.72.26/tests/test_1203_swarph_me_refusal.py +49 -0
- swarph_cli-0.72.26/tests/test_1214_egress.py +336 -0
- swarph_cli-0.72.26/tests/test_1219_egress_probe.py +261 -0
- swarph_cli-0.72.26/tests/test_1221_quota_windows.py +114 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_402_one_identity_resolver.py +4 -1
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_mesh_command.py +40 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_operator_me.py +8 -5
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/LICENSE +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/README.md +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/setup.cfg +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/__main__.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/bench/__init__.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/bench/backends.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/bench/claude_cli.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/bench/codex_cli.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/bench/pack.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/bench/prices.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/bench/providers.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/bench/quality.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/bench/refresh_prices.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/bench/rules.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/bench/runner.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/bench/signal_score.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/bench/validate.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/caller.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/capture/__init__.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/capture/harden.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/capture/lineage.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/capture/liveness.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/capture/manifest.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/capture/paths.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/capture/verify.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/cell.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/chain_token.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/channel.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/__init__.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/_content.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/_display.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/_gateway_client.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/add.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/bench.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/board.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/board_merge_check.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/brain.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/brain_ask.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/cell.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/cell_probe.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/cell_selfcheck.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/channel.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/chat.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/codegraph.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/codegraph_hook.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/codex_hook_output.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/codex_waker.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/compress.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/daemon.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/dreaming.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/event.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/gateway.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/gh_route.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/group.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/guide.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/highlight.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/hook_interpreter.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/hook_output.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/hooks.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/import_session.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/init.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/install_codex_hooks.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/install_hook.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/install_multiplexer.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/install_opencode_plugin.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/install_postcompact_hook.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/install_wake_hook.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/lane.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/mcp_server.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/memory.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/memory_emit_hook.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/memory_sync.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/monitor.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/okf_links.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/onboard.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/peer_reply_drain.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/postcompact_hook_output.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/protocol_handler.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/ratify.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/roster.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/rowclear_hook.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/schedule.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/security.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/service.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/spawn.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/sweep.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/timeline.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/triage.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/version.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/wake_hook_output.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/commands/watchdog.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/compress/__init__.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/compress/levers.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/compress/marker.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/compress/verify.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/console_safe.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/delivery_queue.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/dm_frame.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/dreaming/__init__.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/dreaming/candidates.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/dreaming/clone.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/dreaming/enrich.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/dreaming/index_check.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/dreaming/notify.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/dreaming/organize.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/dreaming/probes.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/dreaming/report.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/dreaming/run.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/dreaming/slm.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/dreaming/transcripts.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/dreaming/verify.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/gateway/__init__.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/gateway/feature_registry.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/gateway/lanes_control.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/gateway/schema.sql +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/gateway/server.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/gateway/services_control.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/gateway_default.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/gh_identity.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/guide/GUIDE.md +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/identity.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/launchd/swarph-codex-outbox.plist +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/launchd/swarph-codex-outbox.timer.plist +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/launchd/swarph-monitor.plist +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/launchd/swarph-watchdog.plist +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/launchd/swarph-watchdog.timer.plist +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/launchd_render.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/main.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/multiplexer.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/operator/__init__.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/operator/__main__.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/operator/api.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/operator/config.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/operator/fmt.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/orphan_daemons.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/pane_probe.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/parsers/__init__.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/parsers/claude.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/payloads/opencode/plugin.js +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/payloads/postcompact/_shim.cmd +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/payloads/postcompact/postcompact-recall-grok.sh +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/payloads/postcompact/postcompact-recall.sh +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/payloads/postcompact/posttooluse-emit-antigravity.sh +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/payloads/postcompact/posttooluse-emit-claude.sh +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/payloads/postcompact/posttooluse-emit-grok.sh +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/payloads/postcompact/posttooluse-emit.sh +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/payloads/postcompact/posttooluse-recall.sh +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/payloads/postcompact/precompact-flag.sh +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/payloads/postcompact/preinvocation-recall-antigravity.sh +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/payloads/postcompact/sessionstart-recall.sh +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/peer_executor.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/peer_executor_windows.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/peer_reconciliation.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/peer_reply_outbox.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/peer_service_host.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/peer_service_payload.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/peer_service_reply.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/peer_staging.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/query_filters.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/rowclear.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/scripts/__init__.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/scripts/dm_notify_filter.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/scripts/ensure_monitor.sh +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/scripts/install_codex_waker_windows.ps1 +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/scripts/install_monitor_task_windows.ps1 +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/scripts/wake_watchdog.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/scrub.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/service/__init__.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/service/app.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/service/providers.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/session_bridge.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/skills/i-have-adhd/LICENSE +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/skills/i-have-adhd/SKILL.md +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/source_text.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/stall_alert.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/systemd/codex-waker.default +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/systemd/peer-reply-drain.default +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/systemd/swarph-codex-outbox@.service +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/systemd/swarph-codex-outbox@.timer +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/systemd/swarph-codex-waker@.service +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/systemd/swarph-codex-waker@.timer +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/systemd/swarph-monitor-reexec.path +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/systemd/swarph-monitor-reexec.service +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/systemd/swarph-monitor@.service +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/systemd/swarph-peer-reply-drain@.service +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/systemd/swarph-peer-reply-drain@.timer +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/systemd/swarph-stuck-sweep.service +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/systemd/swarph-stuck-sweep.timer +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/systemd/swarph-triage.service +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/systemd/swarph-triage.timer +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/systemd/swarph-watchdog.default +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/systemd/swarph-watchdog.service +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/systemd/swarph-watchdog.timer +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/timeline_paths.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/tokens.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/triage/__init__.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/triage/backend.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/triage/job.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/triage/owners.json +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/triage/router.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/triage/rows.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli/triage/sensor.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli.egg-info/dependency_links.txt +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli.egg-info/entry_points.txt +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli.egg-info/requires.txt +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/src/swarph_cli.egg-info/top_level.txt +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1006_board_publisher.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1006_session_board.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1010_strand_only.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1013_spawn_channel.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1017_muse_tui.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1050_surrogate_wake.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1052_opencode_deaf.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1059_watchdog_unread_env.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1061_roster_cli.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1064_stuck_sweep.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1065_release.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1066_quiet_wakes.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1068_structured_accept_cli.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1071_quota_sync.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1073_triage.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1073_triage_board.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1073_wheel_install.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1075_task_cli.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1083_openai_decisions.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1144_cell_yaml_github.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1197_commander_taps.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_1206_offer_question.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_124_register_merge.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_126_pending_from_complete.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_132_ensure_monitor_state_dir.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_138_memory_navigate.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_139_tool_probe.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_183_card_anchor.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_184_notify_honesty.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_201_win32_bash_refusal.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_243_onboard_per_peer_token.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_307_task4_ask_reply.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_312_codegraph_fuzzy_verb.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_319_refusal_exit_codes.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_323_mistral_backend.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_332_report_organize_findings.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_356_query_filters.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_397_gh_identity_router.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_397_router_preflight.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_432_rowclear.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_467b_onboard_operator_credential.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_472_register_caller_binding.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_484_codex_queue_sink.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_523_guide.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_524_conftest_hermeticity.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_532_accept_flag.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_535_version_capability.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_538_signal_bench.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_546_default_gateway.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_547_verbs_from_registry.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_548_gateway_remainder.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_552_codegraph_gateway.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_555_relay_row_shape.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_556_relay_freshness.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_559_edges_truncated.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_564_bootstrap_first_peer.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_578_no_machine_specific_host_defaults.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_579_register_bootstrap_message.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_591_cli_step_graph.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_644_monitor_supervision.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_648_install_unit.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_654_reexec.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_656_owned_slm.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_684_dreaming_verb.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_689_pkg_version_order.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_715_grok_wake.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_716_timeline_one_path.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_723_grok_0251.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_724_ps1_ascii_or_bom.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_725_stdio_reconfigure.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_726_grok_limit_screen.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_729_arm_check_delivery_gap.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_729_dm_once.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_729_wake_watchdog.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_734_dreaming_enrich_degrade.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_735_dm_mcp_tools.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_739_wake_writer.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_740_edit_project.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_762_cards_edit_priority.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_764_enrich_collapse.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_801_confirm_flow_cli.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_802_stage_history.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_825_codegraph_hook_noise.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_825_install_posttooluse_only.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_825_remaining_cap_shred_bind.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_829_counterfactual_column.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_830_hook_binding_version.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_84_cli_labels.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_866_doctrine_guide.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_872_identity_refuses_not_warns.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_874_source_text.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_888_opencode_data_dir_can_fail.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_937_dreaming_notify.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_938_organize_line_limit.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_941_bench_backends.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_941_harness_342.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_945_same_line_pairing.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_955_prompt_audit.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_957_auth_http.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_959_venv_interpreter.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_960_channel.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_960_ensure_monitor_heartbeat.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_961_cursor_grok_footer.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_961_loud_stop.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_963_plugin_manifest.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_964_channel_cell.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_965_mesh_wait.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_975_channel_hop.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_add_security_gate.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_artifact_add.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_artifact_hash.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_artifact_lib.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_artifact_mcp.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_artifact_skill.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_artifact_tool.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_artifact_uri.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_bench_backends.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_bench_claude_cli.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_bench_codex_cli.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_bench_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_bench_pack.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_bench_prices.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_bench_quality.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_bench_runner.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_bench_validate.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_board_card_thread.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_board_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_board_merge_check.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_board_obligation_close.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_brain_ask_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_brain_ask_env_diagnosis.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_brain_ask_identity_explicitness.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_brain_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_caller_meta_guard.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_capture_lineage.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_capture_liveness.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_capture_manifest.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_capture_paths.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_capture_security.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_cell_command_dispatch.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_cell_harden.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_cell_loader.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_cell_selfcheck.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_cell_verify.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_chain_token.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_channel_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_channel_poll_never_breaks_dms.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_channel_post.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_channel_wake_policy_filter.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_chat_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_claude_parser.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_claude_tmux_template.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_codegraph_caller_scope.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_codegraph_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_codegraph_hook.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_codegraph_mcp.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_codex_waker.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_compress_caller_convention.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_compress_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_compress_levers.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_compress_marker.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_compress_verify.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_console_encoding_e2e.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_content_composition.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_copilot_membrane.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_copilot_pane_reader.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_cursor_membrane.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_daemon_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_daemon_console_encoding.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_daemon_delivery.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_delivery_queue.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_display_sanitize.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_ensure_monitor_no_peer_default.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_event_emit.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_feature_to_uri.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_gateway_brain.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_gateway_client.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_gateway_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_gateway_message_idempotency.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_gh_route_doctor_mesh_name.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_group_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_guide_commands_parse.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_guide_selfcheck.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_heartbeat_check.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_highlight_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_hook_output.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_hooks_activity_marker.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_hooks_add.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_hooks_bundle.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_hooks_init.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_hooks_legacy_generation_removal.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_hooks_lifecycle.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_hooks_merge.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_hooks_verify.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_hooks_win32_bash_wrapper.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_hooks_win32_command_path.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_import_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_inbox_identity_provenance.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_init_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_init_provider_menu.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_install_codex_hooks.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_install_hook.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_install_multiplexer_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_install_postcompact_hook.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_install_wake_hook.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_lane_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_launchd_units.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_main.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_main_unknown_verb_guard.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_mcp_missing_hint.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_mcp_server.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_memory_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_memory_emit_snippet.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_memory_gateway.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_memory_sync.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_memory_sync_membrane.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_mesh_inbox_mark_read.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_mesh_inbox_sanitize.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_mesh_originate_thread_623.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_mesh_send_unknown_peer.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_mesh_sidecar.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_mesh_sidecar_cursor_decoupled.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_mesh_sidecar_muse_sink.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_mesh_sidecar_wake_survives_read.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_meta_edge_identity.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_monitor_channel_poll.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_monitor_cli.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_monitor_daemon_collision.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_monitor_self_name_verification.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_monitor_state_split.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_multiplexer.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_muse_membrane.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_muse_own_cli.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_obligation_close_is_surfaced.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_okf_links.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_onboard_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_opencode_membrane.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_opencode_plugin.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_orphan_daemons.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_packaged_artifacts_exist.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_packaged_skills.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_peer_executor.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_peer_executor_windows.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_peer_reply_drain_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_peer_reply_drain_supervisor.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_peer_reply_outbox.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_peer_reply_transport.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_peer_service_e2e.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_peer_service_host.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_peer_service_payload.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_peer_service_reply.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_postcompact_recall.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_process_liveness.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_protocol_handler.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_providers_isolation.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_ratify_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_readme_claims_no_gateway_default.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_repl_caller_convention.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_schedule_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_schedule_create_contract.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_scrub.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_security.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_service_app.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_service_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_service_providers.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_session_bridge_inject.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_session_bridge_probe.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_session_bridge_resolve.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_session_path_role_gate.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_shipped_units_match_the_cli.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_smoke_chat.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_smoke_one_shot.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_smoke_phase_5_5.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_spawn_base_hoist.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_spawn_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_spawn_identity_stamp.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_spawn_live_pin.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_spawn_mitosis_lineage.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_spawn_tmux_session.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_spawn_windows_relaunch.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_stall_alert.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_subprocess_decode_encoding.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_timeline_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_tmux_wake_runstate_defer.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_tmux_wake_session_reanchor.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_tmux_wake_stale.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_tmux_wake_submit_verify.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_token_file_one_parser.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_token_precedence_explicit_first.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_unified_token_resolver.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_version_command.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_version_consistency.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_vibe_membrane.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_watchdog.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_watchdog_dm_wake.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_watchdog_dm_wake_cooldown.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_watchdog_dm_wake_wiring.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_watchdog_emit_health.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_watchdog_install_flags.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_watchdog_model_rung.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/tests/test_watchdog_stale_peers.py +0 -0
- {swarph_cli-0.72.24 → swarph_cli-0.72.26}/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.26
|
|
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.26"
|
|
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" }
|
|
@@ -97,6 +97,15 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
97
97
|
default=[],
|
|
98
98
|
help="extra recipient (repeatable). from_node in this list is refused.",
|
|
99
99
|
)
|
|
100
|
+
send.add_argument(
|
|
101
|
+
"--reply-to",
|
|
102
|
+
type=int,
|
|
103
|
+
default=None,
|
|
104
|
+
metavar="ID",
|
|
105
|
+
help="id of the message this one answers, sent as reply_to (card #1224). "
|
|
106
|
+
"The gateway refuses an id that does not exist. It binds nothing "
|
|
107
|
+
"by itself and does NOT set thread_id.",
|
|
108
|
+
)
|
|
100
109
|
add_content_args(send)
|
|
101
110
|
_add_common(send)
|
|
102
111
|
|
|
@@ -680,6 +689,8 @@ def _run_send(args: argparse.Namespace) -> int:
|
|
|
680
689
|
}
|
|
681
690
|
if cc:
|
|
682
691
|
body["cc"] = cc
|
|
692
|
+
if getattr(args, "reply_to", None) is not None:
|
|
693
|
+
body["reply_to"] = args.reply_to
|
|
683
694
|
thread_arg = getattr(args, "thread", None)
|
|
684
695
|
if thread_arg:
|
|
685
696
|
if thread_arg == "new":
|
|
@@ -8,6 +8,7 @@ from __future__ import annotations
|
|
|
8
8
|
|
|
9
9
|
import argparse
|
|
10
10
|
import json
|
|
11
|
+
import os
|
|
11
12
|
import sys
|
|
12
13
|
from pathlib import Path
|
|
13
14
|
from typing import Sequence
|
|
@@ -482,6 +483,18 @@ def main(argv: Sequence[str] | None = None) -> int:
|
|
|
482
483
|
print(HELP)
|
|
483
484
|
return 0
|
|
484
485
|
|
|
486
|
+
# card #1203: inside a cell (SWARPH_SELF set), refuse BEFORE any token
|
|
487
|
+
# is read -- a cell must not act as the commander by accident. The
|
|
488
|
+
# explicit --as-operator hatch overrides, loudly (both names on stderr).
|
|
489
|
+
as_operator = "--as-operator" in stripped
|
|
490
|
+
if as_operator:
|
|
491
|
+
stripped = [a for a in stripped if a != "--as-operator"]
|
|
492
|
+
cell_self = (os.environ.get("SWARPH_SELF") or "").strip()
|
|
493
|
+
if cell_self and not as_operator:
|
|
494
|
+
print(f"SWARPH_SELF={cell_self}: this process is inside a cell; "
|
|
495
|
+
"run swarph-me from a human shell", file=sys.stderr)
|
|
496
|
+
return 2
|
|
497
|
+
|
|
485
498
|
try:
|
|
486
499
|
identity, gateway, token = resolve_session(as_name, config_path=config_path)
|
|
487
500
|
except SystemExit as exc:
|
|
@@ -490,6 +503,9 @@ def main(argv: Sequence[str] | None = None) -> int:
|
|
|
490
503
|
except ValueError as exc:
|
|
491
504
|
print(f"swarph-me: {exc}", file=sys.stderr)
|
|
492
505
|
return 2
|
|
506
|
+
if cell_self and as_operator:
|
|
507
|
+
print(f"SWARPH_SELF={cell_self}: --as-operator override; "
|
|
508
|
+
f"acting as operator {identity}", file=sys.stderr)
|
|
493
509
|
|
|
494
510
|
try:
|
|
495
511
|
return run_verb(identity, gateway, token, stripped)
|
|
@@ -12,10 +12,13 @@ or null, and never clears a prior quota or block.
|
|
|
12
12
|
"""
|
|
13
13
|
from __future__ import annotations
|
|
14
14
|
|
|
15
|
+
import logging
|
|
15
16
|
import re
|
|
16
17
|
from datetime import datetime, timedelta, timezone
|
|
17
18
|
from typing import Callable, Optional
|
|
18
19
|
|
|
20
|
+
log = logging.getLogger(__name__)
|
|
21
|
+
|
|
19
22
|
READ_COOLDOWN = timedelta(minutes=5)
|
|
20
23
|
BLOCK_HOLD = timedelta(minutes=5)
|
|
21
24
|
|
|
@@ -31,6 +34,16 @@ _LOG_LIMIT_RE = re.compile(
|
|
|
31
34
|
r"usage limit[^\n]*?try again at\s+(.+?)\s*$",
|
|
32
35
|
re.IGNORECASE | re.MULTILINE)
|
|
33
36
|
_RATE_EXCEEDED_RE = re.compile(r"rate limits? exceeded", re.IGNORECASE)
|
|
37
|
+
# card #1221: Claude Code /usage, the 2026-10-19 22:42Z capture. The two
|
|
38
|
+
# runway windows are "Current session" and "Current week (all models)".
|
|
39
|
+
# "Current week (Fable)" is the same weekly reset for one model, so it is
|
|
40
|
+
# not a second window. The gateway ranks on used_pct, resets_at and as_of.
|
|
41
|
+
_CLAUDE_USAGE_RE = re.compile(
|
|
42
|
+
r"^Current (session|week \(all models\)): "
|
|
43
|
+
r"([0-9]+(?:\.[0-9]+)?)% used \u00b7 resets "
|
|
44
|
+
r"(?:([A-Z][a-z]{2} \d{1,2}), )?(\d{1,2}(?::\d{2})?[ap]m) \(UTC\)\s*$",
|
|
45
|
+
re.MULTILINE,
|
|
46
|
+
)
|
|
34
47
|
|
|
35
48
|
|
|
36
49
|
def _iso(dt: datetime) -> str:
|
|
@@ -39,40 +52,136 @@ def _iso(dt: datetime) -> str:
|
|
|
39
52
|
return dt.isoformat()
|
|
40
53
|
|
|
41
54
|
|
|
55
|
+
def _clock(clock: str) -> Optional[datetime]:
|
|
56
|
+
"""`4:59pm` or the on-the-hour form `5pm`."""
|
|
57
|
+
norm = clock[:-2] + clock[-2:].upper()
|
|
58
|
+
try:
|
|
59
|
+
return datetime.strptime(norm, "%I:%M%p" if ":" in norm else "%I%p")
|
|
60
|
+
except ValueError:
|
|
61
|
+
return None
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _claude_reset_iso(date: Optional[str], clock: str, as_of: str) -> Optional[str]:
|
|
65
|
+
"""A dated reset uses as_of's year. A bare clock is the next time after as_of."""
|
|
66
|
+
try:
|
|
67
|
+
anchor = datetime.fromisoformat(as_of.replace("Z", "+00:00"))
|
|
68
|
+
except ValueError:
|
|
69
|
+
return None
|
|
70
|
+
if anchor.tzinfo is None:
|
|
71
|
+
return None
|
|
72
|
+
anchor = anchor.astimezone(timezone.utc)
|
|
73
|
+
clock_dt = _clock(clock)
|
|
74
|
+
if clock_dt is None:
|
|
75
|
+
return None
|
|
76
|
+
if not date:
|
|
77
|
+
candidate = anchor.replace(
|
|
78
|
+
hour=clock_dt.hour, minute=clock_dt.minute,
|
|
79
|
+
second=0, microsecond=0)
|
|
80
|
+
if candidate <= anchor:
|
|
81
|
+
candidate += timedelta(days=1)
|
|
82
|
+
return candidate.isoformat()
|
|
83
|
+
norm = clock[:-2] + clock[-2:].upper()
|
|
84
|
+
try:
|
|
85
|
+
parsed = datetime.strptime(
|
|
86
|
+
f"{date} {norm} {anchor.year}",
|
|
87
|
+
"%b %d " + ("%I:%M%p" if ":" in norm else "%I%p") + " %Y",
|
|
88
|
+
)
|
|
89
|
+
except ValueError:
|
|
90
|
+
return None
|
|
91
|
+
parsed = parsed.replace(tzinfo=timezone.utc)
|
|
92
|
+
if parsed < anchor - timedelta(days=1):
|
|
93
|
+
parsed = parsed.replace(year=anchor.year + 1)
|
|
94
|
+
return parsed.isoformat()
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _window_rows(text: str, as_of: str) -> list:
|
|
98
|
+
"""Last session line and last weekly-all-models line, or neither.
|
|
99
|
+
|
|
100
|
+
A pane can repeat a name or hold an older /usage display above a newer
|
|
101
|
+
one. Counting rows would send two session windows, or stamp the stale
|
|
102
|
+
display as current, which is the 5h mask card #1217 exists to stop.
|
|
103
|
+
The set is the last line of each name, and it is sent only when both
|
|
104
|
+
names parsed.
|
|
105
|
+
"""
|
|
106
|
+
by_name = {}
|
|
107
|
+
for match in _CLAUDE_USAGE_RE.finditer(text or ""):
|
|
108
|
+
reset = _claude_reset_iso(match.group(3), match.group(4), as_of)
|
|
109
|
+
if reset is None:
|
|
110
|
+
continue
|
|
111
|
+
by_name[match.group(1)] = {"used_pct": float(match.group(2)),
|
|
112
|
+
"resets_at": reset,
|
|
113
|
+
"as_of": as_of}
|
|
114
|
+
session = by_name.get("session")
|
|
115
|
+
weekly = by_name.get("week (all models)")
|
|
116
|
+
if session is not None and weekly is not None:
|
|
117
|
+
return [session, weekly]
|
|
118
|
+
if session is None and weekly is None:
|
|
119
|
+
return []
|
|
120
|
+
found = "session" if session is not None else "week (all models)"
|
|
121
|
+
missing = "weekly" if session is not None else "session"
|
|
122
|
+
log.warning(
|
|
123
|
+
"quota windows dropped: parsed %s only, %s did not parse; "
|
|
124
|
+
"sending no quota_windows",
|
|
125
|
+
found, missing)
|
|
126
|
+
return []
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def _with_windows(record: Optional[dict], windows: list) -> Optional[dict]:
|
|
130
|
+
if record is None:
|
|
131
|
+
return None
|
|
132
|
+
if windows:
|
|
133
|
+
record = dict(record)
|
|
134
|
+
record["windows"] = windows
|
|
135
|
+
return record
|
|
136
|
+
|
|
137
|
+
|
|
42
138
|
def parse_pane_capture(text: str, as_of: str):
|
|
43
139
|
"""One read-only pane capture -> a usage record, or None (unknown).
|
|
44
140
|
|
|
45
141
|
Self-selecting: the codex hit-limit line beats its own heads-up bound;
|
|
46
142
|
a grok modal and a mistral rate error are blocked without figures;
|
|
47
|
-
anything else (Claude
|
|
143
|
+
anything else (a Claude cell transcript, agy labels, empty captures)
|
|
144
|
+
is None. A Claude Code /usage display keeps two windows: the session
|
|
145
|
+
and the weekly all-models line (card #1221). The per-model week line
|
|
146
|
+
is not a second runway window.
|
|
48
147
|
"""
|
|
49
148
|
text = text or ""
|
|
149
|
+
windows = _window_rows(text, as_of)
|
|
50
150
|
low = text.lower()
|
|
51
151
|
# The mistral provider error surfaces in pane output but is classified
|
|
52
152
|
# source 'error' per ruling 2 — it is an API error, not a usage display.
|
|
53
153
|
if _RATE_EXCEEDED_RE.search(text):
|
|
54
|
-
return
|
|
55
|
-
|
|
154
|
+
return _with_windows(
|
|
155
|
+
{"used_pct": None, "credits": None, "reset_at": None,
|
|
156
|
+
"blocked": True, "source": "error", "as_of": as_of}, windows)
|
|
56
157
|
if "buy more credits" in low and "try again" in low:
|
|
57
|
-
return
|
|
58
|
-
|
|
158
|
+
return _with_windows(
|
|
159
|
+
{"used_pct": None, "credits": None, "reset_at": None,
|
|
160
|
+
"blocked": True, "source": "pane", "as_of": as_of}, windows)
|
|
59
161
|
hit = _CODEX_HIT_RE.search(text)
|
|
60
162
|
if hit:
|
|
61
163
|
# A trailing period is sentence punctuation, not timestamp.
|
|
62
164
|
reset = hit.group(1).strip().rstrip(".").strip() or None
|
|
63
|
-
return
|
|
64
|
-
|
|
165
|
+
return _with_windows(
|
|
166
|
+
{"used_pct": 100, "credits": None, "reset_at": reset,
|
|
167
|
+
"blocked": True, "source": "pane", "as_of": as_of}, windows)
|
|
65
168
|
bound = _CODEX_BOUND_RE.search(text)
|
|
66
169
|
if bound:
|
|
67
170
|
# A bound, not a measurement: used_pct stays null (ruling 2).
|
|
68
|
-
return
|
|
69
|
-
|
|
70
|
-
|
|
171
|
+
return _with_windows(
|
|
172
|
+
{"used_pct": None, "credits": None, "reset_at": None,
|
|
173
|
+
"blocked": False, "source": "pane", "as_of": as_of,
|
|
174
|
+
"bound_left_pct": float(bound.group(1))}, windows)
|
|
71
175
|
copilot = _COPILOT_RE.search(text)
|
|
72
176
|
if copilot:
|
|
73
|
-
return
|
|
74
|
-
|
|
75
|
-
|
|
177
|
+
return _with_windows(
|
|
178
|
+
{"used_pct": None, "credits": float(copilot.group(1)),
|
|
179
|
+
"reset_at": None, "blocked": False, "source": "pane",
|
|
180
|
+
"as_of": as_of}, windows)
|
|
181
|
+
if windows:
|
|
182
|
+
return {"used_pct": None, "credits": None, "reset_at": None,
|
|
183
|
+
"blocked": False, "source": "pane", "as_of": as_of,
|
|
184
|
+
"windows": windows}
|
|
76
185
|
return None
|
|
77
186
|
|
|
78
187
|
|
|
@@ -111,6 +220,17 @@ def decide_put(prior: Optional[dict], record: Optional[dict],
|
|
|
111
220
|
used = record.get("used_pct")
|
|
112
221
|
if used is not None and used != prior.get("quota_used_pct"):
|
|
113
222
|
body["quota_used_pct"] = used
|
|
223
|
+
windows = []
|
|
224
|
+
for window in record.get("windows") or []:
|
|
225
|
+
pct = window.get("used_pct")
|
|
226
|
+
reset = window.get("resets_at")
|
|
227
|
+
if pct is None or not reset:
|
|
228
|
+
continue
|
|
229
|
+
windows.append({"used_pct": float(pct),
|
|
230
|
+
"resets_at": str(reset),
|
|
231
|
+
"as_of": window.get("as_of") or as_of})
|
|
232
|
+
if windows and windows != (prior.get("quota_windows") or []):
|
|
233
|
+
body["quota_windows"] = windows
|
|
114
234
|
if record.get("blocked"):
|
|
115
235
|
reset = record.get("reset_at")
|
|
116
236
|
until = reset if reset else _iso(now + BLOCK_HOLD)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: swarph-cli
|
|
3
|
-
Version: 0.72.
|
|
3
|
+
Version: 0.72.26
|
|
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
|
|
@@ -231,7 +231,11 @@ tests/test_1075_task_cli.py
|
|
|
231
231
|
tests/test_1083_openai_decisions.py
|
|
232
232
|
tests/test_1144_cell_yaml_github.py
|
|
233
233
|
tests/test_1197_commander_taps.py
|
|
234
|
+
tests/test_1203_swarph_me_refusal.py
|
|
234
235
|
tests/test_1206_offer_question.py
|
|
236
|
+
tests/test_1214_egress.py
|
|
237
|
+
tests/test_1219_egress_probe.py
|
|
238
|
+
tests/test_1221_quota_windows.py
|
|
235
239
|
tests/test_124_register_merge.py
|
|
236
240
|
tests/test_126_pending_from_complete.py
|
|
237
241
|
tests/test_132_ensure_monitor_state_dir.py
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""card #1203 — swarph-me REFUSES when SWARPH_SELF is set (before any token
|
|
2
|
+
is read), with an explicit, loud --as-operator escape hatch."""
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "src"))
|
|
8
|
+
|
|
9
|
+
from swarph_cli.operator import cli # noqa: E402
|
|
10
|
+
from swarph_cli.operator import config as op_config # noqa: E402
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _cfg(tmp_path):
|
|
14
|
+
token = tmp_path / "commander.peer_token"
|
|
15
|
+
token.write_text("test-token\n", encoding="utf-8")
|
|
16
|
+
cfg = tmp_path / "operator.json"
|
|
17
|
+
op_config.save_config(identity="commander", gateway="http://example.test:8788",
|
|
18
|
+
token_file=str(token), path=cfg)
|
|
19
|
+
return cfg
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_self_set_refuses_and_no_token_opened(tmp_path, monkeypatch, capsys):
|
|
23
|
+
monkeypatch.setenv("SWARPH_SELF", "cursor-win")
|
|
24
|
+
monkeypatch.setattr(cli, "_read_token",
|
|
25
|
+
lambda *a, **k: (_ for _ in ()).throw(
|
|
26
|
+
AssertionError("token was read before refusal")))
|
|
27
|
+
rc = cli.main(["cards", "--config", str(_cfg(tmp_path))])
|
|
28
|
+
assert rc != 0
|
|
29
|
+
err = capsys.readouterr().err
|
|
30
|
+
assert "SWARPH_SELF=cursor-win" in err
|
|
31
|
+
assert "this process is inside a cell" in err
|
|
32
|
+
assert "run swarph-me from a human shell" in err
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def test_as_operator_proceeds_and_stderr_names_both(tmp_path, monkeypatch, capsys):
|
|
36
|
+
monkeypatch.setenv("SWARPH_SELF", "cursor-win")
|
|
37
|
+
monkeypatch.setattr(cli, "run_verb", lambda identity, gateway, token, rest: 0)
|
|
38
|
+
rc = cli.main(["cards", "--as-operator", "--config", str(_cfg(tmp_path))])
|
|
39
|
+
assert rc == 0
|
|
40
|
+
err = capsys.readouterr().err
|
|
41
|
+
assert "cursor-win" in err and "commander" in err
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_self_unset_behaviour_unchanged(tmp_path, monkeypatch, capsys):
|
|
45
|
+
monkeypatch.delenv("SWARPH_SELF", raising=False)
|
|
46
|
+
monkeypatch.setattr(cli, "run_verb", lambda identity, gateway, token, rest: 0)
|
|
47
|
+
rc = cli.main(["cards", "--config", str(_cfg(tmp_path))])
|
|
48
|
+
assert rc == 0
|
|
49
|
+
assert "inside a cell" not in capsys.readouterr().err
|