swarph-cli 0.69.5__tar.gz → 0.69.7__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.69.5/src/swarph_cli.egg-info → swarph_cli-0.69.7}/PKG-INFO +1 -1
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/pyproject.toml +1 -1
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/__init__.py +1 -1
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/mesh.py +144 -5
- {swarph_cli-0.69.5 → swarph_cli-0.69.7/src/swarph_cli.egg-info}/PKG-INFO +1 -1
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli.egg-info/SOURCES.txt +3 -0
- swarph_cli-0.69.7/tests/test_715_grok_wake.py +88 -0
- swarph_cli-0.69.7/tests/test_723_grok_0251.py +104 -0
- swarph_cli-0.69.7/tests/test_726_grok_limit_screen.py +60 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/LICENSE +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/README.md +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/setup.cfg +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/__main__.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/bench/__init__.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/bench/backends.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/bench/claude_cli.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/bench/pack.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/bench/prices.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/bench/providers.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/bench/quality.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/bench/refresh_prices.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/bench/rules.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/bench/runner.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/bench/validate.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/caller.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/capture/__init__.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/capture/harden.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/capture/lineage.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/capture/liveness.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/capture/manifest.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/capture/paths.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/capture/verify.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/cell.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/chain_token.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/channel.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/__init__.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/_content.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/_display.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/_gateway_client.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/add.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/bench.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/board.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/board_merge_check.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/brain.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/brain_ask.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/cell.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/cell_probe.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/cell_selfcheck.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/channel.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/chat.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/codegraph.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/codegraph_hook.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/codex_hook_output.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/codex_waker.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/compress.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/daemon.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/dreaming.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/event.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/gateway.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/gh_route.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/group.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/guide.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/highlight.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/hook_interpreter.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/hook_output.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/hooks.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/import_session.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/init.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/install_codex_hooks.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/install_hook.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/install_multiplexer.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/install_opencode_plugin.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/install_postcompact_hook.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/install_wake_hook.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/lane.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/mcp_server.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/memory.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/memory_emit_hook.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/memory_sync.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/monitor.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/okf_links.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/onboard.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/peer_reply_drain.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/postcompact_hook_output.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/protocol_handler.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/ratify.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/schedule.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/security.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/service.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/spawn.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/timeline.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/version.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/wake_hook_output.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/commands/watchdog.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/compress/__init__.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/compress/levers.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/compress/marker.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/compress/verify.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/console_safe.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/delivery_queue.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/dm_frame.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/dreaming/__init__.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/dreaming/candidates.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/dreaming/clone.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/dreaming/enrich.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/dreaming/index_check.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/dreaming/notify.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/dreaming/organize.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/dreaming/probes.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/dreaming/report.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/dreaming/run.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/dreaming/slm.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/dreaming/transcripts.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/dreaming/verify.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/gateway/__init__.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/gateway/feature_registry.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/gateway/lanes_control.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/gateway/schema.sql +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/gateway/server.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/gateway/services_control.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/gateway_default.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/gh_identity.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/guide/GUIDE.md +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/identity.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/main.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/multiplexer.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/orphan_daemons.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/pane_probe.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/parsers/__init__.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/parsers/claude.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/payloads/opencode/plugin.js +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/payloads/postcompact/_shim.cmd +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/payloads/postcompact/postcompact-recall-grok.sh +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/payloads/postcompact/postcompact-recall.sh +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/payloads/postcompact/posttooluse-emit-antigravity.sh +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/payloads/postcompact/posttooluse-emit-claude.sh +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/payloads/postcompact/posttooluse-emit-grok.sh +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/payloads/postcompact/posttooluse-emit.sh +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/payloads/postcompact/posttooluse-recall.sh +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/payloads/postcompact/precompact-flag.sh +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/payloads/postcompact/preinvocation-recall-antigravity.sh +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/payloads/postcompact/sessionstart-recall.sh +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/peer_executor.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/peer_executor_windows.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/peer_reconciliation.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/peer_reply_outbox.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/peer_service_host.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/peer_service_payload.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/peer_service_reply.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/peer_staging.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/query_filters.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/scripts/__init__.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/scripts/dm_notify_filter.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/scripts/ensure_monitor.sh +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/scripts/install_codex_waker_windows.ps1 +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/scripts/install_monitor_task_windows.ps1 +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/scripts/wake_watchdog.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/service/__init__.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/service/app.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/service/providers.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/session_bridge.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/skills/i-have-adhd/LICENSE +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/skills/i-have-adhd/SKILL.md +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/source_text.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/stall_alert.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/systemd/codex-waker.default +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/systemd/peer-reply-drain.default +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/systemd/swarph-codex-outbox@.service +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/systemd/swarph-codex-outbox@.timer +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/systemd/swarph-codex-waker@.service +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/systemd/swarph-codex-waker@.timer +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/systemd/swarph-monitor-reexec.path +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/systemd/swarph-monitor-reexec.service +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/systemd/swarph-monitor@.service +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/systemd/swarph-peer-reply-drain@.service +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/systemd/swarph-peer-reply-drain@.timer +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/systemd/swarph-watchdog.default +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/systemd/swarph-watchdog.service +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/systemd/swarph-watchdog.timer +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/timeline_paths.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli/tokens.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli.egg-info/dependency_links.txt +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli.egg-info/entry_points.txt +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli.egg-info/requires.txt +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/src/swarph_cli.egg-info/top_level.txt +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_124_register_merge.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_126_pending_from_complete.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_132_ensure_monitor_state_dir.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_138_memory_navigate.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_139_tool_probe.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_183_card_anchor.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_184_notify_honesty.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_201_win32_bash_refusal.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_243_onboard_per_peer_token.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_307_task4_ask_reply.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_312_codegraph_fuzzy_verb.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_319_refusal_exit_codes.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_323_mistral_backend.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_332_report_organize_findings.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_356_query_filters.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_397_gh_identity_router.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_397_router_preflight.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_402_one_identity_resolver.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_467b_onboard_operator_credential.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_472_register_caller_binding.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_523_guide.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_524_conftest_hermeticity.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_532_accept_flag.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_535_version_capability.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_546_default_gateway.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_547_verbs_from_registry.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_548_gateway_remainder.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_552_codegraph_gateway.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_555_relay_row_shape.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_556_relay_freshness.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_559_edges_truncated.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_564_bootstrap_first_peer.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_578_no_machine_specific_host_defaults.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_579_register_bootstrap_message.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_591_cli_step_graph.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_644_monitor_supervision.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_648_install_unit.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_654_reexec.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_656_owned_slm.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_684_dreaming_verb.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_689_pkg_version_order.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_716_timeline_one_path.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_724_ps1_ascii_or_bom.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_725_stdio_reconfigure.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_729_dm_once.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_729_wake_watchdog.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_734_dreaming_enrich_degrade.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_735_dm_mcp_tools.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_740_edit_project.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_762_cards_edit_priority.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_764_enrich_collapse.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_801_confirm_flow_cli.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_802_stage_history.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_825_codegraph_hook_noise.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_825_install_posttooluse_only.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_825_remaining_cap_shred_bind.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_829_counterfactual_column.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_830_hook_binding_version.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_84_cli_labels.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_866_doctrine_guide.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_872_identity_refuses_not_warns.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_874_source_text.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_888_opencode_data_dir_can_fail.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_937_dreaming_notify.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_938_organize_line_limit.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_941_bench_backends.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_941_harness_342.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_945_same_line_pairing.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_955_prompt_audit.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_957_auth_http.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_959_venv_interpreter.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_960_channel.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_960_ensure_monitor_heartbeat.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_963_plugin_manifest.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_964_channel_cell.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_965_mesh_wait.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_975_channel_hop.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_add_security_gate.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_artifact_add.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_artifact_hash.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_artifact_lib.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_artifact_mcp.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_artifact_skill.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_artifact_tool.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_artifact_uri.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_bench_backends.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_bench_claude_cli.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_bench_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_bench_pack.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_bench_prices.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_bench_quality.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_bench_runner.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_bench_validate.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_board_card_thread.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_board_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_board_merge_check.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_board_obligation_close.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_brain_ask_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_brain_ask_env_diagnosis.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_brain_ask_identity_explicitness.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_brain_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_caller_meta_guard.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_capture_lineage.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_capture_liveness.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_capture_manifest.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_capture_paths.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_capture_security.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_cell_command_dispatch.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_cell_harden.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_cell_loader.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_cell_selfcheck.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_cell_verify.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_chain_token.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_channel_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_channel_poll_never_breaks_dms.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_channel_post.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_channel_wake_policy_filter.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_chat_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_claude_parser.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_claude_tmux_template.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_codegraph_caller_scope.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_codegraph_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_codegraph_hook.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_codegraph_mcp.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_codex_waker.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_compress_caller_convention.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_compress_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_compress_levers.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_compress_marker.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_compress_verify.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_console_encoding_e2e.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_content_composition.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_cursor_membrane.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_daemon_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_daemon_console_encoding.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_daemon_delivery.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_delivery_queue.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_display_sanitize.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_ensure_monitor_no_peer_default.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_event_emit.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_feature_to_uri.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_gateway_brain.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_gateway_client.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_gateway_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_gateway_message_idempotency.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_gh_route_doctor_mesh_name.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_group_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_guide_commands_parse.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_guide_selfcheck.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_heartbeat_check.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_highlight_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_hook_output.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_hooks_activity_marker.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_hooks_add.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_hooks_bundle.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_hooks_init.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_hooks_legacy_generation_removal.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_hooks_lifecycle.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_hooks_merge.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_hooks_verify.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_hooks_win32_bash_wrapper.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_hooks_win32_command_path.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_import_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_inbox_identity_provenance.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_init_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_init_provider_menu.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_install_codex_hooks.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_install_hook.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_install_multiplexer_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_install_postcompact_hook.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_install_wake_hook.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_lane_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_main.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_main_unknown_verb_guard.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_mcp_missing_hint.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_mcp_server.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_memory_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_memory_emit_snippet.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_memory_gateway.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_memory_sync.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_memory_sync_membrane.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_mesh_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_mesh_inbox_mark_read.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_mesh_inbox_sanitize.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_mesh_originate_thread_623.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_mesh_send_unknown_peer.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_mesh_sidecar.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_mesh_sidecar_cursor_decoupled.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_mesh_sidecar_wake_survives_read.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_meta_edge_identity.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_monitor_channel_poll.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_monitor_cli.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_monitor_daemon_collision.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_monitor_self_name_verification.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_monitor_state_split.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_multiplexer.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_muse_membrane.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_muse_own_cli.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_obligation_close_is_surfaced.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_okf_links.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_onboard_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_opencode_membrane.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_opencode_plugin.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_orphan_daemons.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_packaged_artifacts_exist.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_packaged_skills.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_peer_executor.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_peer_executor_windows.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_peer_reply_drain_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_peer_reply_drain_supervisor.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_peer_reply_outbox.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_peer_reply_transport.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_peer_service_e2e.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_peer_service_host.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_peer_service_payload.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_peer_service_reply.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_postcompact_recall.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_process_liveness.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_protocol_handler.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_providers_isolation.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_ratify_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_readme_claims_no_gateway_default.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_repl_caller_convention.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_schedule_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_schedule_create_contract.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_security.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_service_app.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_service_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_service_providers.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_session_bridge_inject.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_session_bridge_probe.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_session_bridge_resolve.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_session_path_role_gate.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_shipped_units_match_the_cli.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_smoke_chat.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_smoke_one_shot.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_smoke_phase_5_5.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_spawn_base_hoist.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_spawn_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_spawn_identity_stamp.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_spawn_live_pin.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_spawn_mitosis_lineage.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_spawn_tmux_session.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_spawn_windows_relaunch.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_stall_alert.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_subprocess_decode_encoding.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_timeline_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_tmux_wake_runstate_defer.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_tmux_wake_session_reanchor.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_tmux_wake_stale.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_tmux_wake_submit_verify.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_token_file_one_parser.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_token_precedence_explicit_first.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_unified_token_resolver.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_version_command.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_version_consistency.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_vibe_membrane.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_watchdog.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_watchdog_dm_wake.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_watchdog_dm_wake_cooldown.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_watchdog_dm_wake_wiring.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_watchdog_emit_health.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_watchdog_install_flags.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_watchdog_model_rung.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/tests/test_watchdog_stale_peers.py +0 -0
- {swarph_cli-0.69.5 → swarph_cli-0.69.7}/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.69.
|
|
3
|
+
Version: 0.69.7
|
|
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.69.
|
|
7
|
+
version = "0.69.7"
|
|
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" }
|
|
@@ -1481,6 +1481,18 @@ class TmuxSink(Sink):
|
|
|
1481
1481
|
|
|
1482
1482
|
def deliver(self, state: "MonitorState", dms: list, up_to_id: int) -> Optional[bool]:
|
|
1483
1483
|
led = state.ledger(self.name)
|
|
1484
|
+
# #723: a rate-limit or usage-limit screen is not deliverable. An
|
|
1485
|
+
# empty composer beside "Retry failed: rate limit" used to inject
|
|
1486
|
+
# again, and the 1.0.44 upgrade modal (no Grok footer) used to
|
|
1487
|
+
# return False and log DELIVERY FAILED. Defer with a named reason
|
|
1488
|
+
# and send nothing.
|
|
1489
|
+
pane = _capture_pane_lines(self.target)
|
|
1490
|
+
if pane:
|
|
1491
|
+
reason = _grok_block_reason(pane)
|
|
1492
|
+
if reason:
|
|
1493
|
+
print(f"[monitor] {self.name}: {reason} — deferring, zero keys",
|
|
1494
|
+
flush=True)
|
|
1495
|
+
return None
|
|
1484
1496
|
# #620: a wake's job is done the moment a TURN is observed running —
|
|
1485
1497
|
# the cell is awake, whoever woke it (our injected wake fired, or
|
|
1486
1498
|
# the human typed). Both older clearing paths miss the zombie
|
|
@@ -1497,7 +1509,7 @@ class TmuxSink(Sink):
|
|
|
1497
1509
|
# Opencode keeps the finished ▣ header on screen, so a deferral
|
|
1498
1510
|
# during the turn must not clear the flag: the next idle poll
|
|
1499
1511
|
# still owes a wake. Cursor's #620 clear stays.
|
|
1500
|
-
if _opencode_in_progress(self.target):
|
|
1512
|
+
if _opencode_in_progress(self.target) or _grok_in_progress(self.target):
|
|
1501
1513
|
return None
|
|
1502
1514
|
led["wake_outstanding"] = False
|
|
1503
1515
|
if led.get("wake_outstanding"):
|
|
@@ -1524,7 +1536,8 @@ class TmuxSink(Sink):
|
|
|
1524
1536
|
# A finished opencode turn leaves a ▣ header with a
|
|
1525
1537
|
# trailing duration and a clear box. The standing-wake
|
|
1526
1538
|
# claim would swallow every later DM. Inject again.
|
|
1527
|
-
if _opencode_turn_finished_target(self.target)
|
|
1539
|
+
if (_opencode_turn_finished_target(self.target)
|
|
1540
|
+
or _grok_turn_finished_target(self.target)):
|
|
1528
1541
|
ok = _tmux_wake(self.target)
|
|
1529
1542
|
if ok:
|
|
1530
1543
|
_stamp_wake(led)
|
|
@@ -2020,6 +2033,9 @@ _WAKE_PROMPT = "check mesh"
|
|
|
2020
2033
|
# not shown. Longer than _WAKE_PROMPT, so wake-text detection strips this
|
|
2021
2034
|
# one first.
|
|
2022
2035
|
_OPENCODE_WAKE_PROMPT = "check mesh: swarph_dm_unread"
|
|
2036
|
+
# Grok's TUI has the same shape (#715, grok 1.0.41): no push channel, so
|
|
2037
|
+
# the wake is one line naming the pull tool and no DM body.
|
|
2038
|
+
_GROK_WAKE_PROMPT = "check mesh: swarph_dm_unread"
|
|
2023
2039
|
# A finished turn keeps its ▣ header and adds a duration.
|
|
2024
2040
|
# Short turns read `· 3.3s` (drop-on-meta-edge, 1.18.33, card #961 post
|
|
2025
2041
|
# 54557). A longer idle turn reads `· 3m 4s` (opencode pane, 2026-09-29
|
|
@@ -2130,7 +2146,7 @@ def _only_wake_text(content: str) -> bool:
|
|
|
2130
2146
|
human's line.
|
|
2131
2147
|
"""
|
|
2132
2148
|
rest = content
|
|
2133
|
-
for prompt in (_OPENCODE_WAKE_PROMPT, _WAKE_PROMPT):
|
|
2149
|
+
for prompt in (_GROK_WAKE_PROMPT, _OPENCODE_WAKE_PROMPT, _WAKE_PROMPT):
|
|
2134
2150
|
rest = rest.replace(prompt, "")
|
|
2135
2151
|
return rest.strip() == ""
|
|
2136
2152
|
|
|
@@ -2265,6 +2281,126 @@ def _opencode_composer_state(lines: list[str]) -> Optional[str]:
|
|
|
2265
2281
|
return "busy"
|
|
2266
2282
|
|
|
2267
2283
|
|
|
2284
|
+
def _is_grok_pane(lines: list[str]) -> bool:
|
|
2285
|
+
"""Grok Build composer, measured on sacrificial 1.0.41 and 0.2.51 TUIs.
|
|
2286
|
+
|
|
2287
|
+
The footer names ``Grok 4.`` inside the box, or the splash prints
|
|
2288
|
+
``Grok Build``. History also draws a ``❯`` for the submitted prompt;
|
|
2289
|
+
that row has no box bar, so it is not the composer. A usage-limit
|
|
2290
|
+
modal drops both of those and is recognized by ``_grok_block_reason``.
|
|
2291
|
+
"""
|
|
2292
|
+
return any("Grok 4." in ln or ln.strip().startswith("Grok Build") for ln in lines)
|
|
2293
|
+
|
|
2294
|
+
|
|
2295
|
+
def _grok_input(lines: list[str]) -> Optional[str]:
|
|
2296
|
+
"""Text in the live ``│ ❯`` box, '' when empty, None if no box."""
|
|
2297
|
+
row = None
|
|
2298
|
+
for ln in lines:
|
|
2299
|
+
if "❯" in ln and "│" in ln:
|
|
2300
|
+
row = ln
|
|
2301
|
+
if row is None:
|
|
2302
|
+
return None
|
|
2303
|
+
after = row.split("❯", 1)[1]
|
|
2304
|
+
if "│" in after:
|
|
2305
|
+
after = after.split("│", 1)[0]
|
|
2306
|
+
return after.strip()
|
|
2307
|
+
|
|
2308
|
+
|
|
2309
|
+
# One grok screen, measured on the live 0.2.51 pane (52 rows). Lines above
|
|
2310
|
+
# this window are scrollback. A transcript that merely quotes the limit
|
|
2311
|
+
# strings is not the limit screen.
|
|
2312
|
+
_GROK_SCREEN_ROWS = 52
|
|
2313
|
+
|
|
2314
|
+
|
|
2315
|
+
def _grok_block_reason(lines: list[str]) -> Optional[str]:
|
|
2316
|
+
"""A rate or usage limit screen is not an idle composer and not a dead pane.
|
|
2317
|
+
|
|
2318
|
+
Match the screen by where it is drawn, not by a quote anywhere in the
|
|
2319
|
+
capture. 1.0.44 draws a ``┃`` modal ``You hit your free usage limit``
|
|
2320
|
+
(no Grok footer). 0.2.51 draws a status line that starts ``Retry failed:``
|
|
2321
|
+
on the current screen, under the composer. A cursor transcript that
|
|
2322
|
+
quotes those sentences, and a grok scrollback that still contains them
|
|
2323
|
+
above an idle screen, are not that screen.
|
|
2324
|
+
"""
|
|
2325
|
+
screen = lines[-_GROK_SCREEN_ROWS:]
|
|
2326
|
+
# Opencode draws its transcript in ┃ rows, so a quoted sentence there is
|
|
2327
|
+
# not the grok modal. The modal identifies itself (Upgrade to SuperGrok)
|
|
2328
|
+
# or the pane is already grok.
|
|
2329
|
+
modal = "\n".join(ln for ln in screen if "┃" in ln).lower()
|
|
2330
|
+
if ("you hit your free usage limit" in modal
|
|
2331
|
+
and (_is_grok_pane(screen) or "upgrade to supergrok" in modal)):
|
|
2332
|
+
return "grok-usage-limit"
|
|
2333
|
+
if not _is_grok_pane(screen):
|
|
2334
|
+
return None
|
|
2335
|
+
for ln in screen:
|
|
2336
|
+
stripped = ln.strip()
|
|
2337
|
+
low = stripped.lower()
|
|
2338
|
+
if not stripped.startswith("Retry failed:"):
|
|
2339
|
+
continue
|
|
2340
|
+
if "rate limit" in low:
|
|
2341
|
+
return "grok-rate-limit"
|
|
2342
|
+
return "grok-retry-failed"
|
|
2343
|
+
return None
|
|
2344
|
+
|
|
2345
|
+
|
|
2346
|
+
def _grok_running(lines: list[str]) -> bool:
|
|
2347
|
+
"""True only while the turn is in progress.
|
|
2348
|
+
|
|
2349
|
+
1.0.41/1.0.44: ``Waiting for response``. 0.2.51: ``Waiting…`` at the
|
|
2350
|
+
start of the turn, then a tool row whose footer is ``Ctrl+c:cancel``
|
|
2351
|
+
for as long as the turn lasts. ``Worked for`` / ``Thought for`` stay
|
|
2352
|
+
on screen after the turn and must not count as running.
|
|
2353
|
+
"""
|
|
2354
|
+
for ln in lines:
|
|
2355
|
+
if "Waiting for response" in ln or "Waiting…" in ln or "Waiting..." in ln:
|
|
2356
|
+
return True
|
|
2357
|
+
if "Ctrl+c:cancel" in ln:
|
|
2358
|
+
return True
|
|
2359
|
+
return False
|
|
2360
|
+
|
|
2361
|
+
|
|
2362
|
+
def _grok_turn_finished(lines: list[str]) -> bool:
|
|
2363
|
+
if _grok_running(lines) or _grok_block_reason(lines):
|
|
2364
|
+
return False
|
|
2365
|
+
return any(
|
|
2366
|
+
"Worked for" in ln or "Thought for" in ln or "Turn cancelled" in ln
|
|
2367
|
+
for ln in lines
|
|
2368
|
+
)
|
|
2369
|
+
|
|
2370
|
+
|
|
2371
|
+
def _grok_in_progress(target: str) -> bool:
|
|
2372
|
+
lines = _capture_pane_lines(target)
|
|
2373
|
+
if not lines or not _is_grok_pane(lines):
|
|
2374
|
+
return False
|
|
2375
|
+
return _grok_running(lines)
|
|
2376
|
+
|
|
2377
|
+
|
|
2378
|
+
def _grok_turn_finished_target(target: str) -> bool:
|
|
2379
|
+
lines = _capture_pane_lines(target)
|
|
2380
|
+
if not lines or not _is_grok_pane(lines):
|
|
2381
|
+
return False
|
|
2382
|
+
return _grok_turn_finished(lines)
|
|
2383
|
+
|
|
2384
|
+
|
|
2385
|
+
def _grok_composer_state(lines: list[str]) -> Optional[str]:
|
|
2386
|
+
text = _grok_input(lines)
|
|
2387
|
+
if text is None:
|
|
2388
|
+
return None
|
|
2389
|
+
if not text:
|
|
2390
|
+
return "clear"
|
|
2391
|
+
if _only_wake_text(text):
|
|
2392
|
+
return "wake"
|
|
2393
|
+
return "busy"
|
|
2394
|
+
|
|
2395
|
+
|
|
2396
|
+
def _wake_prompt_for(lines: Optional[list[str]]) -> str:
|
|
2397
|
+
if lines and _is_grok_pane(lines):
|
|
2398
|
+
return _GROK_WAKE_PROMPT
|
|
2399
|
+
if lines and _is_opencode_pane(lines):
|
|
2400
|
+
return _OPENCODE_WAKE_PROMPT
|
|
2401
|
+
return _WAKE_PROMPT
|
|
2402
|
+
|
|
2403
|
+
|
|
2268
2404
|
def _agent_running(target: str) -> Optional[bool]:
|
|
2269
2405
|
"""True while a keystroke would miss the idle composer.
|
|
2270
2406
|
|
|
@@ -2283,6 +2419,8 @@ def _agent_running(target: str) -> Optional[bool]:
|
|
|
2283
2419
|
return None
|
|
2284
2420
|
if _is_opencode_pane(lines):
|
|
2285
2421
|
return _opencode_running(lines)
|
|
2422
|
+
if _is_grok_pane(lines):
|
|
2423
|
+
return _grok_running(lines)
|
|
2286
2424
|
composer = _composer_line(lines)
|
|
2287
2425
|
if composer is None:
|
|
2288
2426
|
return None
|
|
@@ -2311,6 +2449,8 @@ def _composer_state(target: str) -> Optional[str]:
|
|
|
2311
2449
|
return None
|
|
2312
2450
|
if _is_opencode_pane(lines):
|
|
2313
2451
|
return _opencode_composer_state(lines)
|
|
2452
|
+
if _is_grok_pane(lines):
|
|
2453
|
+
return _grok_composer_state(lines)
|
|
2314
2454
|
composer = _composer_line(lines)
|
|
2315
2455
|
if composer is None:
|
|
2316
2456
|
return None
|
|
@@ -2399,8 +2539,7 @@ def _tmux_wake(target: str) -> Optional[bool]:
|
|
|
2399
2539
|
"""
|
|
2400
2540
|
try:
|
|
2401
2541
|
seen = _capture_pane_lines(target)
|
|
2402
|
-
prompt = (
|
|
2403
|
-
if seen and _is_opencode_pane(seen) else _WAKE_PROMPT)
|
|
2542
|
+
prompt = _wake_prompt_for(seen)
|
|
2404
2543
|
subprocess.run(
|
|
2405
2544
|
["tmux", "send-keys", "-t", target, "-l", prompt],
|
|
2406
2545
|
check=True,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: swarph-cli
|
|
3
|
-
Version: 0.69.
|
|
3
|
+
Version: 0.69.7
|
|
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
|
|
@@ -219,9 +219,12 @@ tests/test_654_reexec.py
|
|
|
219
219
|
tests/test_656_owned_slm.py
|
|
220
220
|
tests/test_684_dreaming_verb.py
|
|
221
221
|
tests/test_689_pkg_version_order.py
|
|
222
|
+
tests/test_715_grok_wake.py
|
|
222
223
|
tests/test_716_timeline_one_path.py
|
|
224
|
+
tests/test_723_grok_0251.py
|
|
223
225
|
tests/test_724_ps1_ascii_or_bom.py
|
|
224
226
|
tests/test_725_stdio_reconfigure.py
|
|
227
|
+
tests/test_726_grok_limit_screen.py
|
|
225
228
|
tests/test_729_dm_once.py
|
|
226
229
|
tests/test_729_wake_watchdog.py
|
|
227
230
|
tests/test_734_dreaming_enrich_degrade.py
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"""card #961 — grok 1.0.41 pane fixtures. These assertions fail on main:
|
|
2
|
+
main has no grok reader, so an idle ``│ ❯`` box is not a clear composer and
|
|
3
|
+
``Waiting for response`` is not a running turn.
|
|
4
|
+
"""
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from swarph_cli.commands import mesh
|
|
8
|
+
|
|
9
|
+
FIX = Path(__file__).resolve().parents[1] / "tests" / "fixtures" / "grok-715"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def lines(name):
|
|
13
|
+
return (FIX / name).read_text(encoding="utf-8").splitlines()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def test_idle_box_is_clear_and_not_running():
|
|
17
|
+
pane = lines("idle.txt")
|
|
18
|
+
assert mesh._is_grok_pane(pane)
|
|
19
|
+
assert mesh._grok_composer_state(pane) == "clear"
|
|
20
|
+
assert mesh._grok_running(pane) is False
|
|
21
|
+
assert mesh._wake_prompt_for(pane) == "check mesh: swarph_dm_unread"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def test_typed_text_defers():
|
|
25
|
+
pane = lines("typed.txt")
|
|
26
|
+
assert mesh._grok_input(pane) == "draft-not-submitted"
|
|
27
|
+
assert mesh._grok_composer_state(pane) == "busy"
|
|
28
|
+
assert mesh._grok_running(pane) is False
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def test_running_turn_is_not_idle():
|
|
32
|
+
pane = lines("running.txt")
|
|
33
|
+
assert mesh._grok_running(pane) is True
|
|
34
|
+
assert mesh._grok_turn_finished(pane) is False
|
|
35
|
+
# the box is empty while the turn runs; empty must not read as "inject"
|
|
36
|
+
assert mesh._grok_input(pane) == ""
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_finished_turn_reads_idle_so_the_next_dm_can_wake():
|
|
40
|
+
pane = lines("finished.txt")
|
|
41
|
+
assert "Worked for" in "\n".join(pane)
|
|
42
|
+
assert mesh._grok_running(pane) is False
|
|
43
|
+
assert mesh._grok_turn_finished(pane) is True
|
|
44
|
+
# the submitted prompt stays in history with a bare ❯; the live box is empty
|
|
45
|
+
assert mesh._grok_input(pane) == ""
|
|
46
|
+
assert mesh._grok_composer_state(pane) == "clear"
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def test_history_prompt_is_not_composer_text():
|
|
50
|
+
pane = lines("finished.txt")
|
|
51
|
+
assert any(ln.strip().startswith("❯ Reply") for ln in pane)
|
|
52
|
+
assert mesh._grok_composer_state(pane) == "clear"
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class _State:
|
|
56
|
+
def __init__(self, led):
|
|
57
|
+
self.led = led
|
|
58
|
+
self.gateway = "http://stub.invalid"
|
|
59
|
+
self.self_name = "grok-researcher"
|
|
60
|
+
self.token = "tok"
|
|
61
|
+
|
|
62
|
+
def ledger(self, _name):
|
|
63
|
+
return self.led
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_a_running_delivery_sends_zero_keys(monkeypatch):
|
|
67
|
+
pane = lines("running.txt")
|
|
68
|
+
keys = []
|
|
69
|
+
monkeypatch.setattr(mesh, "_capture_pane_lines", lambda _t: pane)
|
|
70
|
+
monkeypatch.setattr(mesh, "_tmux_wake", lambda _t: keys.append("wake") or True)
|
|
71
|
+
monkeypatch.setattr(mesh, "_tmux_enter", lambda _t: keys.append("enter") or True)
|
|
72
|
+
led = {"wake_outstanding": True}
|
|
73
|
+
assert mesh.TmuxSink("grok-715-sac").deliver(_State(led), [], 1) is None
|
|
74
|
+
assert keys == []
|
|
75
|
+
assert led["wake_outstanding"] is True
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def test_a_finished_clear_box_injects_again(monkeypatch):
|
|
79
|
+
pane = lines("finished.txt")
|
|
80
|
+
keys = []
|
|
81
|
+
monkeypatch.setattr(mesh, "_capture_pane_lines", lambda _t: pane)
|
|
82
|
+
monkeypatch.setattr(mesh, "_tmux_wake", lambda _t: keys.append("wake") or True)
|
|
83
|
+
monkeypatch.setattr(mesh, "_tmux_enter", lambda _t: keys.append("enter") or True)
|
|
84
|
+
monkeypatch.setattr(
|
|
85
|
+
"swarph_cli.commands.watchdog._gateway_unread_count", lambda *_a: 1)
|
|
86
|
+
led = {"wake_outstanding": True, "last_wake_injected_at": 1.0}
|
|
87
|
+
assert mesh.TmuxSink("grok-715-sac").deliver(_State(led), [], 2) is True
|
|
88
|
+
assert keys == ["wake"]
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"""card #961 — grok 0.2.51 pane fixtures. These assertions fail on 87c8fba:
|
|
2
|
+
that head only treats ``Waiting for response`` as running and ``Worked for``
|
|
3
|
+
as finished, and an empty box beside a rate-limit line is a clear composer.
|
|
4
|
+
"""
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from swarph_cli.commands import mesh
|
|
8
|
+
|
|
9
|
+
FIX = Path(__file__).resolve().parents[1] / "tests" / "fixtures" / "grok-723"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def lines(name):
|
|
13
|
+
return (FIX / name).read_text(encoding="utf-8").splitlines()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class _State:
|
|
17
|
+
def __init__(self, led):
|
|
18
|
+
self.led = led
|
|
19
|
+
self.gateway = "http://stub.invalid"
|
|
20
|
+
self.self_name = "grok-researcher"
|
|
21
|
+
self.token = "tok"
|
|
22
|
+
|
|
23
|
+
def ledger(self, _name):
|
|
24
|
+
return self.led
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _deliver(monkeypatch, pane, led):
|
|
28
|
+
keys = []
|
|
29
|
+
monkeypatch.setattr(mesh, "_capture_pane_lines", lambda _t: pane)
|
|
30
|
+
monkeypatch.setattr(mesh, "_tmux_wake", lambda _t: keys.append("wake") or True)
|
|
31
|
+
monkeypatch.setattr(mesh, "_tmux_enter", lambda _t: keys.append("enter") or True)
|
|
32
|
+
outcome = mesh.TmuxSink("grok-723-sac").deliver(_State(led), [], 1)
|
|
33
|
+
return outcome, keys
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_idle_0251_box_is_clear():
|
|
37
|
+
pane = lines("idle.txt")
|
|
38
|
+
assert "Grok Build 0.2.51" in "\n".join(pane)
|
|
39
|
+
assert mesh._is_grok_pane(pane)
|
|
40
|
+
assert mesh._grok_block_reason(pane) is None
|
|
41
|
+
assert mesh._grok_composer_state(pane) == "clear"
|
|
42
|
+
assert mesh._grok_running(pane) is False
|
|
43
|
+
assert mesh._wake_prompt_for(pane) == "check mesh: swarph_dm_unread"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_typed_0251_defers():
|
|
47
|
+
pane = lines("typed.txt")
|
|
48
|
+
assert mesh._grok_block_reason(pane) is None
|
|
49
|
+
assert mesh._grok_input(pane) == "draft-not-submitted"
|
|
50
|
+
assert mesh._grok_composer_state(pane) == "busy"
|
|
51
|
+
assert mesh._grok_running(pane) is False
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def test_running_0251_is_not_idle(monkeypatch):
|
|
55
|
+
pane = lines("running.txt")
|
|
56
|
+
assert "Waiting…" in "\n".join(pane)
|
|
57
|
+
assert "Waiting for response" not in "\n".join(pane)
|
|
58
|
+
assert mesh._grok_running(pane) is True
|
|
59
|
+
assert mesh._grok_turn_finished(pane) is False
|
|
60
|
+
assert mesh._grok_input(pane) == ""
|
|
61
|
+
outcome, keys = _deliver(
|
|
62
|
+
monkeypatch, pane, {"wake_outstanding": True, "last_wake_injected_at": 1.0})
|
|
63
|
+
assert outcome is None
|
|
64
|
+
assert keys == []
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def test_finished_0251_thought_for_can_wake_again():
|
|
68
|
+
pane = lines("finished.txt")
|
|
69
|
+
text = "\n".join(pane)
|
|
70
|
+
assert "Thought for" in text
|
|
71
|
+
assert "Worked for" not in text
|
|
72
|
+
assert "Ctrl+c:cancel" not in text
|
|
73
|
+
assert mesh._grok_running(pane) is False
|
|
74
|
+
assert mesh._grok_turn_finished(pane) is True
|
|
75
|
+
assert mesh._grok_input(pane) == ""
|
|
76
|
+
assert mesh._grok_composer_state(pane) == "clear"
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def test_rate_limit_defers_with_named_reason_and_zero_keys(monkeypatch, capsys):
|
|
80
|
+
pane = lines("rate-limit.txt")
|
|
81
|
+
assert "rate limit" in "\n".join(pane).lower()
|
|
82
|
+
assert mesh._grok_block_reason(pane) == "grok-rate-limit"
|
|
83
|
+
assert mesh._grok_running(pane) is False
|
|
84
|
+
assert mesh._grok_turn_finished(pane) is False
|
|
85
|
+
# a previous turn's "Thought for" must not win over the limit screen
|
|
86
|
+
poisoned = pane + [" ◆ Thought for 2s"]
|
|
87
|
+
assert mesh._grok_turn_finished(poisoned) is False
|
|
88
|
+
outcome, keys = _deliver(monkeypatch, pane, {})
|
|
89
|
+
assert outcome is None
|
|
90
|
+
assert keys == []
|
|
91
|
+
assert "grok-rate-limit" in capsys.readouterr().out
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def test_usage_limit_modal_defers_instead_of_failing(monkeypatch, capsys):
|
|
95
|
+
pane = lines("usage-limit.txt")
|
|
96
|
+
assert "You hit your free usage limit" in "\n".join(pane)
|
|
97
|
+
assert mesh._is_grok_pane(pane) is False
|
|
98
|
+
assert mesh._grok_block_reason(pane) == "grok-usage-limit"
|
|
99
|
+
outcome, keys = _deliver(monkeypatch, pane, {})
|
|
100
|
+
assert outcome is None
|
|
101
|
+
assert keys == []
|
|
102
|
+
err = capsys.readouterr().out
|
|
103
|
+
assert "grok-usage-limit" in err
|
|
104
|
+
assert "DELIVERY FAILED" not in err
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""card #961 — the limit check must be the limit screen, not a quote.
|
|
2
|
+
|
|
3
|
+
These assertions fail on 1d55233: that head treats any line containing the
|
|
4
|
+
limit sentences as a grok block, including a cursor transcript and grok
|
|
5
|
+
scrollback above an idle screen.
|
|
6
|
+
"""
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from swarph_cli.commands import mesh
|
|
10
|
+
|
|
11
|
+
FIX723 = Path(__file__).resolve().parents[1] / "tests" / "fixtures" / "grok-723"
|
|
12
|
+
FIX726 = Path(__file__).resolve().parents[1] / "tests" / "fixtures" / "grok-726"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def lines(root, name):
|
|
16
|
+
return (root / name).read_text(encoding="utf-8").splitlines()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def test_cursor_transcript_quoting_both_limits_is_not_blocked():
|
|
20
|
+
pane = lines(FIX726, "cursor-transcript.txt")
|
|
21
|
+
text = "\n".join(pane)
|
|
22
|
+
assert "rate limit" in text
|
|
23
|
+
assert "You hit your free usage limit" in text
|
|
24
|
+
assert "Models matching" in text
|
|
25
|
+
assert mesh._is_grok_pane(pane) is False
|
|
26
|
+
assert mesh._grok_block_reason(pane) is None
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_opencode_transcript_quoting_the_usage_limit_is_not_blocked():
|
|
30
|
+
src = Path(__file__).resolve().parents[1] / "tests" / "fixtures" / "opencode-pane-idle-footer-0710.txt"
|
|
31
|
+
pane = src.read_text(encoding="utf-8").splitlines()
|
|
32
|
+
# Inside the current screen, on a ┃ transcript row, not a grok modal.
|
|
33
|
+
pane.insert(len(pane) - 8, " ┃ You hit your free usage limit")
|
|
34
|
+
assert mesh._is_opencode_pane(pane) is True
|
|
35
|
+
assert mesh._is_grok_pane(pane) is False
|
|
36
|
+
assert mesh._grok_block_reason(pane) is None
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def test_grok_rate_limit_and_usage_modal_still_defer():
|
|
40
|
+
rate = lines(FIX723, "rate-limit.txt")
|
|
41
|
+
usage = lines(FIX723, "usage-limit.txt")
|
|
42
|
+
assert mesh._grok_block_reason(rate) == "grok-rate-limit"
|
|
43
|
+
assert mesh._grok_turn_finished(rate) is False
|
|
44
|
+
assert mesh._is_grok_pane(usage) is False
|
|
45
|
+
assert mesh._grok_block_reason(usage) == "grok-usage-limit"
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def test_old_scrollback_limit_on_an_idle_grok_screen_reads_idle():
|
|
49
|
+
idle = lines(FIX723, "idle.txt")
|
|
50
|
+
scroll = [
|
|
51
|
+
" ❯ an earlier turn",
|
|
52
|
+
" Retry failed: You’ve hit the rate limit for your plan.",
|
|
53
|
+
" You hit your free usage limit",
|
|
54
|
+
]
|
|
55
|
+
# Push the quote above one screen. The idle composer stays.
|
|
56
|
+
pane = (scroll * 20) + idle
|
|
57
|
+
assert mesh._is_grok_pane(pane)
|
|
58
|
+
assert mesh._grok_block_reason(pane) is None
|
|
59
|
+
assert mesh._grok_composer_state(pane) == "clear"
|
|
60
|
+
assert mesh._grok_running(pane) is False
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|