swarph-cli 0.68.2__tar.gz → 0.69.1__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.68.2/src/swarph_cli.egg-info → swarph_cli-0.69.1}/PKG-INFO +1 -1
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/pyproject.toml +1 -1
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/__init__.py +1 -1
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/channel.py +4 -3
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/brain_ask.py +33 -22
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/codegraph.py +7 -8
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/codegraph_hook.py +2 -1
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/daemon.py +5 -8
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/gh_route.py +3 -2
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/highlight.py +14 -7
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/hooks.py +2 -5
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/install_postcompact_hook.py +2 -2
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/mcp_server.py +6 -3
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/memory.py +5 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/memory_emit_hook.py +12 -3
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/mesh.py +187 -21
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/monitor.py +2 -1
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/onboard.py +4 -3
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/wake_hook_output.py +2 -1
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/watchdog.py +8 -5
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/gateway/server.py +11 -0
- swarph_cli-0.69.1/src/swarph_cli/identity.py +85 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1/src/swarph_cli.egg-info}/PKG-INFO +1 -1
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli.egg-info/SOURCES.txt +3 -0
- swarph_cli-0.69.1/tests/test_402_one_identity_resolver.py +229 -0
- swarph_cli-0.69.1/tests/test_472_register_caller_binding.py +101 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_brain_ask_env_diagnosis.py +12 -9
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_brain_ask_identity_explicitness.py +12 -12
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_mesh_sidecar.py +1 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_postcompact_recall.py +3 -3
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_tmux_wake_runstate_defer.py +2 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_tmux_wake_submit_verify.py +197 -4
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_watchdog.py +8 -6
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/LICENSE +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/README.md +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/setup.cfg +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/__main__.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/bench/__init__.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/bench/backends.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/bench/pack.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/bench/prices.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/bench/providers.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/bench/quality.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/bench/refresh_prices.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/bench/rules.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/bench/runner.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/bench/validate.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/caller.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/capture/__init__.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/capture/harden.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/capture/lineage.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/capture/liveness.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/capture/manifest.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/capture/paths.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/capture/verify.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/cell.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/chain_token.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/__init__.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/_content.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/_display.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/_gateway_client.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/add.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/bench.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/board.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/board_merge_check.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/brain.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/cell.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/cell_probe.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/cell_selfcheck.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/channel.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/chat.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/codex_hook_output.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/codex_waker.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/compress.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/dreaming.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/event.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/gateway.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/group.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/guide.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/hook_interpreter.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/hook_output.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/import_session.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/init.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/install_codex_hooks.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/install_hook.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/install_multiplexer.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/install_opencode_plugin.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/install_wake_hook.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/lane.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/memory_sync.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/okf_links.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/peer_reply_drain.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/postcompact_hook_output.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/protocol_handler.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/ratify.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/schedule.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/security.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/service.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/spawn.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/timeline.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/commands/version.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/compress/__init__.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/compress/levers.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/compress/marker.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/compress/verify.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/console_safe.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/delivery_queue.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/dm_frame.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/dreaming/__init__.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/dreaming/candidates.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/dreaming/clone.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/dreaming/enrich.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/dreaming/index_check.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/dreaming/notify.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/dreaming/organize.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/dreaming/probes.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/dreaming/report.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/dreaming/run.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/dreaming/slm.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/dreaming/transcripts.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/dreaming/verify.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/gateway/__init__.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/gateway/feature_registry.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/gateway/lanes_control.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/gateway/schema.sql +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/gateway/services_control.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/gateway_default.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/gh_identity.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/guide/GUIDE.md +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/main.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/multiplexer.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/orphan_daemons.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/pane_probe.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/parsers/__init__.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/parsers/claude.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/payloads/opencode/plugin.js +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/payloads/postcompact/_shim.cmd +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/payloads/postcompact/postcompact-recall-grok.sh +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/payloads/postcompact/postcompact-recall.sh +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/payloads/postcompact/posttooluse-emit-antigravity.sh +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/payloads/postcompact/posttooluse-emit-claude.sh +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/payloads/postcompact/posttooluse-emit-grok.sh +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/payloads/postcompact/posttooluse-emit.sh +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/payloads/postcompact/posttooluse-recall.sh +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/payloads/postcompact/precompact-flag.sh +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/payloads/postcompact/preinvocation-recall-antigravity.sh +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/payloads/postcompact/sessionstart-recall.sh +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/peer_executor.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/peer_executor_windows.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/peer_reconciliation.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/peer_reply_outbox.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/peer_service_host.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/peer_service_payload.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/peer_service_reply.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/peer_staging.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/query_filters.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/scripts/__init__.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/scripts/dm_notify_filter.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/scripts/ensure_monitor.sh +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/scripts/install_codex_waker_windows.ps1 +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/scripts/install_monitor_task_windows.ps1 +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/scripts/wake_watchdog.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/service/__init__.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/service/app.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/service/providers.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/session_bridge.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/skills/i-have-adhd/LICENSE +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/skills/i-have-adhd/SKILL.md +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/source_text.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/stall_alert.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/systemd/codex-waker.default +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/systemd/peer-reply-drain.default +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/systemd/swarph-codex-outbox@.service +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/systemd/swarph-codex-outbox@.timer +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/systemd/swarph-codex-waker@.service +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/systemd/swarph-codex-waker@.timer +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/systemd/swarph-monitor-reexec.path +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/systemd/swarph-monitor-reexec.service +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/systemd/swarph-monitor@.service +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/systemd/swarph-peer-reply-drain@.service +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/systemd/swarph-peer-reply-drain@.timer +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/systemd/swarph-watchdog.default +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/systemd/swarph-watchdog.service +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/systemd/swarph-watchdog.timer +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/timeline_paths.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli/tokens.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli.egg-info/dependency_links.txt +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli.egg-info/entry_points.txt +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli.egg-info/requires.txt +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/src/swarph_cli.egg-info/top_level.txt +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_124_register_merge.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_126_pending_from_complete.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_132_ensure_monitor_state_dir.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_138_memory_navigate.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_139_tool_probe.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_183_card_anchor.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_184_notify_honesty.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_201_win32_bash_refusal.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_243_onboard_per_peer_token.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_307_task4_ask_reply.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_312_codegraph_fuzzy_verb.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_319_refusal_exit_codes.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_323_mistral_backend.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_332_report_organize_findings.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_356_query_filters.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_397_gh_identity_router.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_397_router_preflight.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_467b_onboard_operator_credential.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_523_guide.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_524_conftest_hermeticity.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_532_accept_flag.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_535_version_capability.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_546_default_gateway.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_547_verbs_from_registry.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_548_gateway_remainder.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_552_codegraph_gateway.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_555_relay_row_shape.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_556_relay_freshness.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_559_edges_truncated.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_564_bootstrap_first_peer.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_578_no_machine_specific_host_defaults.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_579_register_bootstrap_message.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_591_cli_step_graph.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_644_monitor_supervision.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_648_install_unit.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_654_reexec.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_656_owned_slm.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_684_dreaming_verb.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_689_pkg_version_order.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_716_timeline_one_path.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_724_ps1_ascii_or_bom.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_725_stdio_reconfigure.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_729_dm_once.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_729_wake_watchdog.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_734_dreaming_enrich_degrade.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_735_dm_mcp_tools.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_740_edit_project.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_762_cards_edit_priority.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_764_enrich_collapse.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_801_confirm_flow_cli.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_802_stage_history.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_825_codegraph_hook_noise.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_825_install_posttooluse_only.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_825_remaining_cap_shred_bind.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_829_counterfactual_column.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_830_hook_binding_version.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_84_cli_labels.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_866_doctrine_guide.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_872_identity_refuses_not_warns.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_874_source_text.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_888_opencode_data_dir_can_fail.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_937_dreaming_notify.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_938_organize_line_limit.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_941_bench_backends.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_941_harness_342.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_945_same_line_pairing.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_955_prompt_audit.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_957_auth_http.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_959_venv_interpreter.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_960_channel.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_963_plugin_manifest.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_964_channel_cell.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_965_mesh_wait.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_975_channel_hop.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_add_security_gate.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_artifact_add.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_artifact_hash.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_artifact_lib.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_artifact_mcp.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_artifact_skill.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_artifact_tool.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_artifact_uri.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_bench_backends.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_bench_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_bench_pack.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_bench_prices.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_bench_quality.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_bench_runner.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_bench_validate.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_board_card_thread.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_board_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_board_merge_check.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_board_obligation_close.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_brain_ask_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_brain_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_caller_meta_guard.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_capture_lineage.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_capture_liveness.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_capture_manifest.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_capture_paths.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_capture_security.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_cell_command_dispatch.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_cell_harden.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_cell_loader.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_cell_selfcheck.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_cell_verify.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_chain_token.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_channel_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_channel_poll_never_breaks_dms.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_channel_post.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_channel_wake_policy_filter.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_chat_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_claude_parser.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_claude_tmux_template.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_codegraph_caller_scope.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_codegraph_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_codegraph_hook.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_codegraph_mcp.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_codex_waker.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_compress_caller_convention.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_compress_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_compress_levers.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_compress_marker.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_compress_verify.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_console_encoding_e2e.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_content_composition.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_cursor_membrane.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_daemon_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_daemon_console_encoding.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_daemon_delivery.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_delivery_queue.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_display_sanitize.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_ensure_monitor_no_peer_default.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_event_emit.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_feature_to_uri.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_gateway_brain.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_gateway_client.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_gateway_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_gateway_message_idempotency.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_gh_route_doctor_mesh_name.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_group_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_guide_commands_parse.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_guide_selfcheck.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_heartbeat_check.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_highlight_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_hook_output.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_hooks_activity_marker.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_hooks_add.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_hooks_bundle.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_hooks_init.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_hooks_legacy_generation_removal.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_hooks_lifecycle.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_hooks_merge.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_hooks_verify.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_hooks_win32_bash_wrapper.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_hooks_win32_command_path.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_import_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_inbox_identity_provenance.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_init_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_init_provider_menu.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_install_codex_hooks.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_install_hook.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_install_multiplexer_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_install_postcompact_hook.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_install_wake_hook.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_lane_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_main.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_main_unknown_verb_guard.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_mcp_missing_hint.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_mcp_server.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_memory_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_memory_emit_snippet.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_memory_gateway.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_memory_sync.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_memory_sync_membrane.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_mesh_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_mesh_inbox_mark_read.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_mesh_inbox_sanitize.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_mesh_originate_thread_623.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_mesh_send_unknown_peer.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_mesh_sidecar_cursor_decoupled.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_mesh_sidecar_wake_survives_read.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_meta_edge_identity.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_monitor_channel_poll.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_monitor_cli.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_monitor_daemon_collision.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_monitor_self_name_verification.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_monitor_state_split.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_multiplexer.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_muse_membrane.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_muse_own_cli.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_obligation_close_is_surfaced.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_okf_links.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_onboard_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_opencode_membrane.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_opencode_plugin.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_orphan_daemons.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_packaged_artifacts_exist.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_packaged_skills.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_peer_executor.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_peer_executor_windows.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_peer_reply_drain_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_peer_reply_drain_supervisor.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_peer_reply_outbox.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_peer_reply_transport.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_peer_service_e2e.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_peer_service_host.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_peer_service_payload.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_peer_service_reply.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_process_liveness.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_protocol_handler.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_providers_isolation.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_ratify_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_readme_claims_no_gateway_default.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_repl_caller_convention.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_schedule_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_schedule_create_contract.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_security.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_service_app.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_service_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_service_providers.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_session_bridge_inject.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_session_bridge_probe.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_session_bridge_resolve.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_session_path_role_gate.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_shipped_units_match_the_cli.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_smoke_chat.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_smoke_one_shot.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_smoke_phase_5_5.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_spawn_base_hoist.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_spawn_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_spawn_identity_stamp.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_spawn_live_pin.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_spawn_mitosis_lineage.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_spawn_tmux_session.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_spawn_windows_relaunch.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_stall_alert.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_subprocess_decode_encoding.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_timeline_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_tmux_wake_session_reanchor.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_tmux_wake_stale.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_token_file_one_parser.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_token_precedence_explicit_first.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_unified_token_resolver.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_version_command.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_version_consistency.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_vibe_membrane.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_watchdog_dm_wake.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_watchdog_dm_wake_cooldown.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_watchdog_dm_wake_wiring.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_watchdog_emit_health.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_watchdog_install_flags.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_watchdog_model_rung.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/tests/test_watchdog_stale_peers.py +0 -0
- {swarph_cli-0.68.2 → swarph_cli-0.69.1}/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.
|
|
3
|
+
Version: 0.69.1
|
|
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.
|
|
7
|
+
version = "0.69.1"
|
|
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" }
|
|
@@ -13,6 +13,7 @@ import threading
|
|
|
13
13
|
import time
|
|
14
14
|
from pathlib import Path
|
|
15
15
|
|
|
16
|
+
from swarph_cli import identity
|
|
16
17
|
from swarph_cli.dm_frame import FIRST_START_GRACE_S, created_within, frame_text, rows
|
|
17
18
|
from swarph_cli.scripts.dm_notify_filter import is_real_dm
|
|
18
19
|
|
|
@@ -35,8 +36,8 @@ def channel_opted_in() -> bool:
|
|
|
35
36
|
|
|
36
37
|
def channel_serves() -> bool:
|
|
37
38
|
"""Only the cell spawn named in SWARPH_CHANNEL_CELL may poll."""
|
|
38
|
-
self_name =
|
|
39
|
-
named = os.environ.get("SWARPH_CHANNEL_CELL") or ""
|
|
39
|
+
self_name = identity.declared(env=identity.SELF_ONLY)[0] or ""
|
|
40
|
+
named = (os.environ.get("SWARPH_CHANNEL_CELL") or "").strip()
|
|
40
41
|
return channel_opted_in() and bool(named) and named == self_name
|
|
41
42
|
|
|
42
43
|
|
|
@@ -290,7 +291,7 @@ def serve(chan: Channel) -> None:
|
|
|
290
291
|
|
|
291
292
|
|
|
292
293
|
def main(argv: list[str] | None = None) -> int:
|
|
293
|
-
cell =
|
|
294
|
+
cell = identity.declared(env=identity.SELF_ONLY)[0] or ""
|
|
294
295
|
if not cell:
|
|
295
296
|
print("swarph channel: SWARPH_SELF is unset; refusing to start", file=sys.stderr)
|
|
296
297
|
return 2
|
|
@@ -31,6 +31,7 @@ import os
|
|
|
31
31
|
import sys
|
|
32
32
|
import urllib.request
|
|
33
33
|
|
|
34
|
+
from swarph_cli import identity
|
|
34
35
|
from swarph_cli import tokens
|
|
35
36
|
from pathlib import Path
|
|
36
37
|
from typing import Optional
|
|
@@ -108,22 +109,27 @@ def _peer_token_path(self_name: str) -> Path:
|
|
|
108
109
|
return Path.home() / ".config" / "swarph" / f"{self_name}.peer_token"
|
|
109
110
|
|
|
110
111
|
|
|
111
|
-
#
|
|
112
|
-
#
|
|
113
|
-
#
|
|
114
|
-
#
|
|
115
|
-
#
|
|
116
|
-
#
|
|
117
|
-
|
|
112
|
+
# card #402: there is NO default identity. The old fallback was ANOTHER CELL'S NAME
|
|
113
|
+
# ("lab-ovh"): harmless on lab-ovh, silently wrong everywhere else, and it made the
|
|
114
|
+
# cold-env failure report a TOKEN fault (with SWARPH_SELF unset the cell hunted
|
|
115
|
+
# lab-ovh.peer_token, found nothing and blamed the credential; measured 2026-07-29 on
|
|
116
|
+
# 6 of 6 cells). An undeclared cell now does no peer-token lookup at all: brain reads
|
|
117
|
+
# still work from GBRAIN_TOKEN / SWARPH_BRAIN_TOKEN / --token-file, and the gateway
|
|
118
|
+
# path, which needs the cell's own peer token, refuses with the missing variable named.
|
|
119
|
+
# The identity picks a CREDENTIAL file here, so this verb reads SWARPH_SELF (and its
|
|
120
|
+
# legacy SWARPH_NODE alias) only, like the mesh verbs: an ambient SWARPH_CELL, which
|
|
121
|
+
# psmux leaks from the spawning environment (#538), must not select another cell's
|
|
122
|
+
# peer token.
|
|
123
|
+
_IDENTITY_ENV = identity.SELF_ONLY + identity.NODE_ALIAS
|
|
118
124
|
|
|
119
125
|
|
|
120
|
-
def _self_name() -> str:
|
|
121
|
-
return
|
|
126
|
+
def _self_name() -> Optional[str]:
|
|
127
|
+
return identity.declared(env=_IDENTITY_ENV)[0]
|
|
122
128
|
|
|
123
129
|
|
|
124
|
-
def
|
|
125
|
-
"""True when no env
|
|
126
|
-
return
|
|
130
|
+
def _self_name_is_undeclared() -> bool:
|
|
131
|
+
"""True when no flag or env names this cell. There is no fallback name."""
|
|
132
|
+
return _self_name() is None
|
|
127
133
|
|
|
128
134
|
|
|
129
135
|
def env_diagnosis() -> str:
|
|
@@ -135,10 +141,9 @@ def env_diagnosis() -> str:
|
|
|
135
141
|
a sourced profile, a bashrc or a settings.json `env` block never applies.
|
|
136
142
|
"""
|
|
137
143
|
bits = []
|
|
138
|
-
if
|
|
139
|
-
bits.append(
|
|
140
|
-
|
|
141
|
-
f"wrong file)")
|
|
144
|
+
if _self_name_is_undeclared():
|
|
145
|
+
bits.append("SWARPH_SELF unset — no cell identity is declared, so no peer-token "
|
|
146
|
+
"lookup is attempted (there is no default identity; card #402)")
|
|
142
147
|
if not os.environ.get("SWARPH_BRAIN_GATEWAY"):
|
|
143
148
|
bits.append("SWARPH_BRAIN_GATEWAY unset — falling back to a direct brain "
|
|
144
149
|
"connection, which only works where the brain service is reachable "
|
|
@@ -167,8 +172,8 @@ def _resolve_token(token_file: Optional[str], self_name: str) -> Optional[str]:
|
|
|
167
172
|
reviewing #190, and it is the sharpest kind of catch: I had noticed the
|
|
168
173
|
hazard, written a comment about it, and not handled it.
|
|
169
174
|
|
|
170
|
-
`_self_name()` NEVER
|
|
171
|
-
("lab-ovh"). So `bool(self_name)`
|
|
175
|
+
`_self_name()` used to NEVER return empty — it fell back to a default peer
|
|
176
|
+
name ("lab-ovh"; removed by card #402). So `bool(self_name)` was always true, and passing that as
|
|
172
177
|
identity_is_explicit would promote `lab-ovh.peer_token` — ANOTHER CELL'S
|
|
173
178
|
CREDENTIAL — above GBRAIN_TOKEN on every invocation where nothing named the
|
|
174
179
|
cell. The comment above already says why that fallback is dangerous
|
|
@@ -183,15 +188,15 @@ def _resolve_token(token_file: Optional[str], self_name: str) -> Optional[str]:
|
|
|
183
188
|
rather than the resolver, because a unit test at the resolver cannot see
|
|
184
189
|
what the caller makes reachable.
|
|
185
190
|
|
|
186
|
-
Explicitness therefore comes from
|
|
187
|
-
truthiness
|
|
188
|
-
|
|
191
|
+
Explicitness therefore comes from whether a name was DECLARED, not from
|
|
192
|
+
truthiness. Since card #402 nothing is ever guessed, so a declared name is
|
|
193
|
+
the only kind there is, and an undeclared cell gets the env-first order.
|
|
189
194
|
"""
|
|
190
195
|
res = tokens.resolve_token(
|
|
191
196
|
self_name or None,
|
|
192
197
|
token_file,
|
|
193
198
|
env_keys=("GBRAIN_TOKEN", "SWARPH_BRAIN_TOKEN"),
|
|
194
|
-
identity_is_explicit=
|
|
199
|
+
identity_is_explicit=self_name is not None,
|
|
195
200
|
)
|
|
196
201
|
return res.token if res is not None else None
|
|
197
202
|
|
|
@@ -262,6 +267,12 @@ def run_brain_ask(argv: list) -> int:
|
|
|
262
267
|
gw = os.environ.get("SWARPH_BRAIN_GATEWAY")
|
|
263
268
|
if gw:
|
|
264
269
|
self_name = _self_name()
|
|
270
|
+
if self_name is None:
|
|
271
|
+
sys.stderr.write(env_diagnosis())
|
|
272
|
+
sys.stderr.write(
|
|
273
|
+
"swarph brain-ask: SWARPH_BRAIN_GATEWAY set but no cell identity is "
|
|
274
|
+
"declared, so there is no peer token to present (set SWARPH_SELF)\n")
|
|
275
|
+
return 2
|
|
265
276
|
try:
|
|
266
277
|
peer_token = _peer_token_path(self_name).read_text(encoding="utf-8").strip()
|
|
267
278
|
except OSError:
|
|
@@ -34,6 +34,7 @@ import re
|
|
|
34
34
|
import sqlite3
|
|
35
35
|
import sys
|
|
36
36
|
|
|
37
|
+
from swarph_cli import identity
|
|
37
38
|
from swarph_cli.commands.codegraph_hook import _match_quality
|
|
38
39
|
|
|
39
40
|
DEFAULT_INDEX = os.path.expanduser("~/.swarph/codegraph/index.db")
|
|
@@ -68,8 +69,8 @@ DEFAULT_INDEX = os.path.expanduser("~/.swarph/codegraph/index.db")
|
|
|
68
69
|
IDENTITY_UNSET = object() # sentinel: argparse default when --caller-cell is omitted
|
|
69
70
|
|
|
70
71
|
|
|
71
|
-
class
|
|
72
|
-
|
|
72
|
+
# card #402: one exception class for "nobody declared this cell", shared by every verb.
|
|
73
|
+
IdentityNotDeclared = identity.IdentityNotDeclared
|
|
73
74
|
|
|
74
75
|
|
|
75
76
|
def require_caller_cell(explicit=None, *, verb: str) -> str:
|
|
@@ -80,12 +81,10 @@ def require_caller_cell(explicit=None, *, verb: str) -> str:
|
|
|
80
81
|
The refusal names the verb and every way to satisfy it, because an error that
|
|
81
82
|
says only "identity unset" moves the work to the reader.
|
|
82
83
|
"""
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if v:
|
|
88
|
-
return v
|
|
84
|
+
# card #402: the order lives in swarph_cli.identity, once, for every verb.
|
|
85
|
+
name, _ = identity.declared(None if explicit is IDENTITY_UNSET else explicit)
|
|
86
|
+
if name is not None:
|
|
87
|
+
return name
|
|
89
88
|
raise IdentityNotDeclared(
|
|
90
89
|
f"swarph {verb}: NO CALLER IDENTITY DECLARED, and there is no default.\n"
|
|
91
90
|
f" This used to fall back to 'lab-ovh', which meant an undeclared caller\n"
|
|
@@ -33,6 +33,7 @@ import urllib.request
|
|
|
33
33
|
from datetime import datetime, timezone
|
|
34
34
|
from pathlib import Path
|
|
35
35
|
from typing import Optional
|
|
36
|
+
from swarph_cli import identity
|
|
36
37
|
from swarph_cli.gateway_default import env_gateway
|
|
37
38
|
|
|
38
39
|
TIMEOUT_S = 6
|
|
@@ -477,7 +478,7 @@ def supported_hook_events() -> frozenset:
|
|
|
477
478
|
def run_codegraph_hook(argv: Optional[list] = None) -> int:
|
|
478
479
|
"""ALWAYS exits 0 — must never fail a turn."""
|
|
479
480
|
argv = list(argv or [])
|
|
480
|
-
self_name =
|
|
481
|
+
self_name = identity.declared(env=identity.SELF_ONLY)[0] or ""
|
|
481
482
|
gateway = env_gateway()
|
|
482
483
|
for i, a in enumerate(argv):
|
|
483
484
|
if a == "--as" and i + 1 < len(argv):
|
|
@@ -49,6 +49,7 @@ from contextlib import suppress
|
|
|
49
49
|
from pathlib import Path
|
|
50
50
|
from typing import Optional
|
|
51
51
|
|
|
52
|
+
from swarph_cli import identity
|
|
52
53
|
from swarph_cli import session_bridge, stall_alert
|
|
53
54
|
from swarph_cli.console_safe import print_safe
|
|
54
55
|
from swarph_cli.delivery_queue import DeliveryQueue
|
|
@@ -115,18 +116,14 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
115
116
|
|
|
116
117
|
|
|
117
118
|
def _resolve_self_name(arg: Optional[str], state_dir: Path) -> str:
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
env = os.environ.get("SWARPH_SELF")
|
|
121
|
-
if env:
|
|
122
|
-
return env
|
|
123
|
-
return state_dir.name
|
|
119
|
+
name, _ = identity.declared(arg, env=identity.SELF_ONLY)
|
|
120
|
+
return name if name is not None else state_dir.name
|
|
124
121
|
|
|
125
122
|
|
|
126
123
|
def _resolve_state_dir(arg: Optional[str], self_name_arg: Optional[str]) -> Path:
|
|
127
124
|
if arg:
|
|
128
125
|
return Path(arg).expanduser()
|
|
129
|
-
self_name = self_name_arg
|
|
126
|
+
self_name = identity.declared(self_name_arg, env=identity.SELF_ONLY)[0]
|
|
130
127
|
if self_name:
|
|
131
128
|
return Path.home() / "swarph_state" / self_name
|
|
132
129
|
# Last resort — a self_name is needed to disambiguate; surface error.
|
|
@@ -550,7 +547,7 @@ def run_daemon(argv: list[str]) -> int:
|
|
|
550
547
|
args = _build_parser().parse_args(argv)
|
|
551
548
|
|
|
552
549
|
# Resolve identity + state path
|
|
553
|
-
self_name = args.self_name
|
|
550
|
+
self_name = identity.declared(args.self_name, env=identity.SELF_ONLY)[0]
|
|
554
551
|
if args.state_dir:
|
|
555
552
|
state_dir = Path(args.state_dir).expanduser()
|
|
556
553
|
if not self_name:
|
|
@@ -24,6 +24,7 @@ import os
|
|
|
24
24
|
import sys
|
|
25
25
|
from typing import Optional
|
|
26
26
|
|
|
27
|
+
from swarph_cli import identity
|
|
27
28
|
from swarph_cli import gh_identity as ghid
|
|
28
29
|
from swarph_cli.cell import cells_dir
|
|
29
30
|
from swarph_cli.console_safe import print_safe
|
|
@@ -69,7 +70,7 @@ def run_hook(stdin_text: Optional[str] = None) -> int:
|
|
|
69
70
|
# The caller named a credential. #332: an explicit argument is a decision.
|
|
70
71
|
return _allow_unchanged()
|
|
71
72
|
|
|
72
|
-
peer =
|
|
73
|
+
peer = identity.declared(env=identity.SELF_ONLY)[0] or ""
|
|
73
74
|
try:
|
|
74
75
|
res = ghid.resolve(peer or None)
|
|
75
76
|
except ghid.RouterRefusal as exc:
|
|
@@ -93,7 +94,7 @@ def run_hook(stdin_text: Optional[str] = None) -> int:
|
|
|
93
94
|
|
|
94
95
|
|
|
95
96
|
def run_show() -> int:
|
|
96
|
-
peer =
|
|
97
|
+
peer = identity.declared(env=identity.SELF_ONLY)[0] or ""
|
|
97
98
|
try:
|
|
98
99
|
res = ghid.resolve(peer or None)
|
|
99
100
|
except ghid.RouterRefusal as exc:
|
|
@@ -31,6 +31,7 @@ import sys
|
|
|
31
31
|
from datetime import datetime, timezone
|
|
32
32
|
from pathlib import Path
|
|
33
33
|
|
|
34
|
+
from swarph_cli import identity
|
|
34
35
|
from swarph_cli.commands.mesh import _post_json, _resolve_token
|
|
35
36
|
from swarph_cli.timeline_paths import timeline_dir
|
|
36
37
|
|
|
@@ -177,7 +178,12 @@ def _log_via_gateway(gateway: str, cell: str, highlight: str,
|
|
|
177
178
|
if memory:
|
|
178
179
|
body["memory"] = memory
|
|
179
180
|
try:
|
|
180
|
-
token
|
|
181
|
+
# card #402: only a DECLARED identity may select its own peer token over the
|
|
182
|
+
# ambient one. A name guessed from git user.name or the hostname is
|
|
183
|
+
# attribution only: on a shared box it can be ANOTHER cell's name, and its
|
|
184
|
+
# peer token must not be presented as this caller's.
|
|
185
|
+
token = _resolve_token(cell, token_file,
|
|
186
|
+
identity_is_explicit=cell_source in _DECLARED_SOURCES)
|
|
181
187
|
except RuntimeError as exc:
|
|
182
188
|
print(_credential_error(cell, cell_source, exc), file=sys.stderr)
|
|
183
189
|
return 1
|
|
@@ -247,6 +253,10 @@ def _is_git_repo(repo: Path) -> bool:
|
|
|
247
253
|
return r.returncode == 0 and r.stdout.strip() == "true"
|
|
248
254
|
|
|
249
255
|
|
|
256
|
+
# Sources that DECLARE an identity (as opposed to guessing one), card #402.
|
|
257
|
+
_DECLARED_SOURCES = ("--cell", "$SWARPH_SELF", "$SWARPH_CELL")
|
|
258
|
+
|
|
259
|
+
|
|
250
260
|
def _resolve_cell(arg, repo: Path) -> tuple[str, str]:
|
|
251
261
|
"""Return ``(cell, source)``.
|
|
252
262
|
|
|
@@ -257,12 +267,9 @@ def _resolve_cell(arg, repo: Path) -> tuple[str, str]:
|
|
|
257
267
|
"""
|
|
258
268
|
if arg:
|
|
259
269
|
return _collapse(arg), "--cell"
|
|
260
|
-
|
|
261
|
-
if
|
|
262
|
-
return _collapse(
|
|
263
|
-
cell_env = os.environ.get("SWARPH_CELL")
|
|
264
|
-
if cell_env:
|
|
265
|
-
return _collapse(cell_env), "$SWARPH_CELL"
|
|
270
|
+
name, source = identity.declared()
|
|
271
|
+
if name is not None:
|
|
272
|
+
return _collapse(name), source
|
|
266
273
|
if _is_git_repo(repo):
|
|
267
274
|
r = _git(repo, "config", "user.name")
|
|
268
275
|
if r.returncode == 0 and r.stdout.strip():
|
|
@@ -47,6 +47,7 @@ import tempfile
|
|
|
47
47
|
from dataclasses import dataclass
|
|
48
48
|
from pathlib import Path
|
|
49
49
|
|
|
50
|
+
from swarph_cli import identity
|
|
50
51
|
from swarph_cli import __version__ as _SWARPH_CLI_VERSION
|
|
51
52
|
|
|
52
53
|
# Placeholder substituted at install time into generated scripts (#830).
|
|
@@ -309,11 +310,7 @@ def touch_activity(argv: list[str] | None = None) -> int:
|
|
|
309
310
|
from swarph_cli.cell import discover_cell_in_cwd, load_cell
|
|
310
311
|
from swarph_cli.commands.watchdog import _resolve_activity_marker_path
|
|
311
312
|
|
|
312
|
-
role = (
|
|
313
|
-
os.environ.get("SWARPH_SELF")
|
|
314
|
-
or os.environ.get("SWARPH_CELL")
|
|
315
|
-
or "unidentified-cell"
|
|
316
|
-
)
|
|
313
|
+
role = identity.or_sentinel()
|
|
317
314
|
cell_marker = None
|
|
318
315
|
cell_path = discover_cell_in_cwd()
|
|
319
316
|
if cell_path is not None:
|
|
@@ -59,6 +59,7 @@ from importlib import resources
|
|
|
59
59
|
from pathlib import Path
|
|
60
60
|
from typing import Any, Optional
|
|
61
61
|
|
|
62
|
+
from swarph_cli import identity
|
|
62
63
|
from swarph_cli.cell import _atomic_write_text
|
|
63
64
|
from swarph_cli.commands.hook_interpreter import hook_interpreter, refuse_unless_importable
|
|
64
65
|
from swarph_cli.commands.install_wake_hook import _detect_harness
|
|
@@ -392,8 +393,7 @@ def run_install_postcompact_hook(argv: Optional[list[str]] = None) -> int:
|
|
|
392
393
|
)
|
|
393
394
|
return 2
|
|
394
395
|
|
|
395
|
-
cell = args.cell
|
|
396
|
-
or os.environ.get("SWARPH_CELL") or None
|
|
396
|
+
cell = identity.declared(args.cell)[0]
|
|
397
397
|
memory_dir: Optional[Path] = None
|
|
398
398
|
if args.memory_dir:
|
|
399
399
|
memory_dir = Path(os.path.expanduser(args.memory_dir))
|
|
@@ -39,6 +39,7 @@ import os
|
|
|
39
39
|
import urllib.error
|
|
40
40
|
import urllib.request
|
|
41
41
|
|
|
42
|
+
from swarph_cli import identity
|
|
42
43
|
from swarph_cli.commands import add
|
|
43
44
|
from swarph_cli.commands import codegraph
|
|
44
45
|
from swarph_cli.commands import brain_ask, memory, timeline
|
|
@@ -152,7 +153,7 @@ def _codegraph_query(query: str, *, limit: int = 8) -> list[dict]:
|
|
|
152
153
|
"""Structural code search over the local codegraph index (Task 1).
|
|
153
154
|
|
|
154
155
|
Delegates to :func:`codegraph.structural_query` against the module-level
|
|
155
|
-
``_CODEGRAPH_INDEX`` path, using ``SWARPH_CELL
|
|
156
|
+
``_CODEGRAPH_INDEX`` path, using the house identity order (``SWARPH_SELF``, then ``SWARPH_CELL``; else
|
|
156
157
|
``codegraph.require_caller_cell``, which REFUSES rather than defaulting) as
|
|
157
158
|
the A8 caller identity and the
|
|
158
159
|
default operate-what-you-own allowlist (``allowlist=None``).
|
|
@@ -170,8 +171,10 @@ def _codegraph_query(query: str, *, limit: int = 8) -> list[dict]:
|
|
|
170
171
|
# authority. require_caller_cell raises IdentityNotDeclared, which the
|
|
171
172
|
# NEVER-RAISES contract below turns into an empty result — FAIL-CLOSED: the
|
|
172
173
|
# MCP host gets nothing rather than somebody else's answer.
|
|
173
|
-
|
|
174
|
-
|
|
174
|
+
# card #402: SWARPH_CELL used to be passed as the EXPLICIT identity here,
|
|
175
|
+
# so it outranked SWARPH_SELF, the CELL-first order #538 measured posting
|
|
176
|
+
# under another cell's name. The house order now decides.
|
|
177
|
+
caller_cell = codegraph.require_caller_cell(None, verb="mcp codegraph_query")
|
|
175
178
|
rows = codegraph.structural_query(
|
|
176
179
|
query,
|
|
177
180
|
index_path=_CODEGRAPH_INDEX,
|
|
@@ -85,6 +85,11 @@ def _via_gateway(op: str, arguments: dict):
|
|
|
85
85
|
if not gw:
|
|
86
86
|
return False, None
|
|
87
87
|
self_name = brain_ask._self_name()
|
|
88
|
+
if self_name is None:
|
|
89
|
+
# card #402: no default identity, so no peer token to present. OSError keeps
|
|
90
|
+
# run_memory's CLI fail-safe; the text names the variable to set.
|
|
91
|
+
raise OSError("SWARPH_BRAIN_GATEWAY is set but no cell identity is declared, "
|
|
92
|
+
"so there is no peer token to present (set SWARPH_SELF)")
|
|
88
93
|
peer_token = brain_ask._peer_token_path(self_name).read_text(encoding="utf-8").strip()
|
|
89
94
|
return True, _gateway_call(gw, peer_token, op, arguments)
|
|
90
95
|
|
|
@@ -36,6 +36,7 @@ import tempfile
|
|
|
36
36
|
from pathlib import Path
|
|
37
37
|
from typing import Optional
|
|
38
38
|
|
|
39
|
+
from swarph_cli import identity
|
|
39
40
|
from swarph_cli.commands.highlight import _log_via_gateway, _resolve_gateway
|
|
40
41
|
|
|
41
42
|
_SUPPRESS_WINDOW = dt.timedelta(minutes=30)
|
|
@@ -137,8 +138,14 @@ def _cell() -> str:
|
|
|
137
138
|
# leaks SWARPH_CELL from the spawning environment, so a CELL-first order
|
|
138
139
|
# posts this cell's highlight under ANOTHER cell's name and token
|
|
139
140
|
# (measured by cursor-win on the Windows membrane, 2026-08-22).
|
|
140
|
-
return (
|
|
141
|
-
|
|
141
|
+
return _cell_with_source()[0]
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def _cell_with_source() -> tuple:
|
|
145
|
+
name, source = identity.declared()
|
|
146
|
+
if name is not None:
|
|
147
|
+
return name, source
|
|
148
|
+
return socket.gethostname(), "hostname"
|
|
142
149
|
|
|
143
150
|
|
|
144
151
|
def run_memory_emit_hook(argv: list[str] | None = None) -> int:
|
|
@@ -167,7 +174,9 @@ def run_memory_emit_hook(argv: list[str] | None = None) -> int:
|
|
|
167
174
|
gateway = _resolve_gateway(None)
|
|
168
175
|
if not gateway:
|
|
169
176
|
return 0 # no gateway configured -> nowhere to emit; silent by design
|
|
170
|
-
|
|
177
|
+
cell, cell_source = _cell_with_source()
|
|
178
|
+
rc = _log_via_gateway(gateway, cell, text, f"[[{slug}]]", None, None,
|
|
179
|
+
cell_source=cell_source)
|
|
171
180
|
if rc == 0:
|
|
172
181
|
_mark_emitted(slug)
|
|
173
182
|
except Exception:
|