agentwire-dev 1.79.0__tar.gz → 1.80.0__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.
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/.github/workflows/pytest.yml +24 -1
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/PKG-INFO +2 -2
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/RELEASING.md +7 -2
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/__init__.py +1 -1
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/__main__.py +2 -1
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/cohort.py +33 -7
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/config.py +31 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/core.py +13 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/doctor_cli.py +61 -7
- agentwire_dev-1.80.0/agentwire/fleet.py +189 -0
- agentwire_dev-1.80.0/agentwire/fleet_cli.py +89 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/hooks/agentwire-permission.sh +17 -2
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/hooks_cli.py +54 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/prompt_router.py +13 -1
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/restart_cli.py +1 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/orchestrator.md +4 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/reviewer-worktree.md +4 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/reviewer.md +4 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/worker-worktree.md +4 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/worker.md +4 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/routes/sessions.py +20 -0
- agentwire_dev-1.80.0/agentwire/sandbox.py +115 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/session_cli.py +33 -13
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/css/desktop.css +16 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/desktop.js +2 -0
- agentwire_dev-1.80.0/agentwire/static/js/sidebar/fleet-section.js +68 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/INDEX.md +3 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/architecture.md +11 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/auth-expired.md +6 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/briefing-mode.md +6 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/council.md +6 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/internals/damage-control.md +28 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/internals/troubleshooting.md +6 -0
- agentwire_dev-1.80.0/docs/wiki/internals/upgrade-test.md +26 -0
- agentwire_dev-1.80.0/docs/wiki/security/sandbox-spike.md +109 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/sessions/conversation-identity.md +8 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/sessions/fan-out-cohorts.md +8 -0
- agentwire_dev-1.80.0/docs/wiki/sessions/fleet.md +49 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/sessions/messaging.md +6 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/sessions/prompt-routing.md +16 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/sessions/worktree-sessions.md +19 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/pyproject.toml +4 -1
- agentwire_dev-1.80.0/tests/fixtures/upgrade/gws.yaml +33 -0
- agentwire_dev-1.80.0/tests/integration/test_upgrade_from_release.py +227 -0
- agentwire_dev-1.80.0/tests/unit/test_escape_ask_routing.py +129 -0
- agentwire_dev-1.80.0/tests/unit/test_fleet.py +183 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_routes_snapshot.py +2 -0
- agentwire_dev-1.80.0/tests/unit/test_sandbox.py +60 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/.agentwire.yml.example +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/.claude/commands/handoff.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/.claude/skills/wiki/SKILL.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/.github/FUNDING.yml +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/.github/workflows/ruff.yml +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/.github/workflows/security.yml +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/.github/workflows/tts-smoke.yml +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/.gitignore +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/AGENTS.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/CODE_OF_CONDUCT.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/CONTRIBUTING.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/Dockerfile.local +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/LICENSE +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/README.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/SECURITY.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/SPONSORS.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/agents/__init__.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/agents/base.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/agents/tmux.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/auth_expired.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/background_tasks.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/beta.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/cached_status.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/channels/__init__.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/channels/base.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/channels/email.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/channels/push.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/channels/quo.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/channels_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/chrome_tabs.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/claude_settings.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/completion.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/config_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/council/__init__.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/council/cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/council/inbox.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/council/minutes.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/council/state.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/council/view.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/devices.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/diff_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/doctor_voice.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/ensure_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/env_loader.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/fetch.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/handoff/__init__.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/handoff/git_state.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/handoff/instructions.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/handoff/parser.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/handoff/renderer.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/handoff/schema.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/handoff_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/history.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/history_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/history_migrate.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/hooks/__init__.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/hooks/idle-handler.sh +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/hooks/outcome_logger.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/hooks/queue-processor.sh +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/hooks/session-start-handler.sh +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/inbox.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/limits_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/listen.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/locking.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/machine_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_channels.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_chrome.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_core.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_council.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_desktop.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_handoff.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_history.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_listen.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_lock.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_machine.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_msg.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_notify.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_pane.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_projects.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_scheduler.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_scratchpad.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_server.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_services.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_session.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_status.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_task.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_tunnels.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_voice.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_wiki.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/mcp_worktree.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/msg_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/network.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/notify_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/onboarding.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/palette_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/pane_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/pane_manager.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/playback_lane.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/portal_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/project_config.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/projects.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/prompts_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/push_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/push_store.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/repo_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/research.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/role_prompts.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/__init__.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/agentwire.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/anchor.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/chatbot.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/contributor.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/correspondent.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/council-brain.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/council-conscience.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/council-critic.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/council-devils-advocate.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/council-gut.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/council-historian.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/council-member.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/council-orchestrator.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/init.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/notifications.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/shared-checkout.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/soul.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/task-runner.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles/voice.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/roles_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/routes/__init__.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/routes/artifacts.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/routes/config.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/routes/council.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/routes/desktop.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/routes/history.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/routes/machines.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/routes/notify.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/routes/palette.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/routes/permission.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/routes/projects.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/routes/push.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/routes/safety.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/routes/scheduler.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/routes/scratchpad.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/routes/sessions_admin.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/routes/voice.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety/__init__.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety/audit.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety/lint.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety/provenance.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety/residuals.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety/rule_baselines.json +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety/rules/agentwire-control-plane.json +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety/rules/agentwire-control-plane.yaml +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety/rules/agentwire-core.json +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety/rules/agentwire-core.yaml +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety/rules/agentwire-mcp-tools.json +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety/rules/agentwire-mcp-tools.yaml +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety/rules/agentwire-outbound.json +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety/rules/agentwire-outbound.yaml +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety/rules/agentwire.json +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety/rules/agentwire.yaml +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety/suggest.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety_commands.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety_ext.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety_migrate.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety_notify.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/safety_packs_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/scheduler/__init__.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/scheduler/dispatch.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/scheduler/gates.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/scheduler/loop.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/scheduler/models.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/scheduler/report.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/scheduler/schedule.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/scheduler/state.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/scheduler/zombie.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/scheduler_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/scratchpad.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/security.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/send_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/sent_ledger.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/server.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/services.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/session_context.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/session_ready.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/session_state.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/ssh.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/agentwire-splash-logo-layers--agentwire-text.png +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/agentwire-splash-logo-layers--echo-claw-fg.png +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/agentwire-splash-logo-layers--echo.png +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/agentwire-splash-logo-layers--telephone.png +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/agentwire-splash-logo-layers--tree.png +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/announcements.json +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/apple-touch-icon.png +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/css/mobile.css +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/favicon-32.png +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/favicon-64.png +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/icons/sessions/bear.webp +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/icons/sessions/cat.webp +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/icons/sessions/crown.webp +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/icons/sessions/custom/agentwire-portal.webp +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/icons/sessions/custom/agentwire-tts.webp +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/icons/sessions/custom/agentwire.webp +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/icons/sessions/deer.webp +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/icons/sessions/drone.webp +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/icons/sessions/eagle.webp +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/icons/sessions/fox.webp +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/icons/sessions/hawk.webp +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/icons/sessions/horse.webp +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/icons/sessions/lion.webp +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/icons/sessions/rabbit.webp +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/icons/sessions/robot.webp +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/icons/sessions/tiger.webp +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/icons/sessions/wolf.webp +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/img/icon-192.png +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/img/icon-512.png +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/.gitkeep +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/announcement-modal.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/api.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/artifact-window.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/card-terminal.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/collage.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/command-palette.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/council-window.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/dead-key-residue.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/desktop-manager.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/help-modal.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/hotkeys.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/icon-manager.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/lineage.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/mobile.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/notification-prefs.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/notifications-panel.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/ptt.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/push-client.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/review-window.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/safety-shared.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/safety-window.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/scratchpad.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/service-classification.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/session-hud-controller.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/session-hud-notices.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/session-hud-spawn.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/session-hud.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/session-id.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/session-window.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/shortcuts.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/sidebar/artifacts-section.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/sidebar/config-section.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/sidebar/council-section.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/sidebar/machines-section.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/sidebar/projects-section.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/sidebar/safety-section.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/sidebar/scheduler-section.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/sidebar/services-section.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/sidebar/sessions-section.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/sidebar.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/spawn-ghost.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/taskbar-persist.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/terminal-font-prefs.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/terminal-pane.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/tile-manager.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/toast.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/token-modal.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/topology-render.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/utils/ansi.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/utils/rich-text.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/utils/swipe.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/voice/audio-unlock.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/voice/autosend-prefs.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/voice/browser-stt.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/voice/browser-tts.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/voice/jargon.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/voice/prompt.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/winbox.bundle.min.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/js/workspace-window.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/manifest.webmanifest +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/service-worker.js +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/static/topology-harness.html +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/stt/__init__.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/stt/base.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/stt/cloud.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/stt/engine.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/stt/local.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/stt/server_backend.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/stt/stt_server.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/system_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/tabs_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/tasks.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/tasks_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/templates/__init__.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/templates/base.html +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/templates/council/minutes.html.j2 +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/templates/desktop.html +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/templates/email_notification.html +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/templates/handoff/show-the-story.html.j2 +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/templates/handoff/theme.css.j2 +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/templates/mobile.html +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/templates/pair.html +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/templates/statusline.sh +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/templates/tmux.conf +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/templating.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/tts/__init__.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/tts/audio.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/tts/base.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/tts/engines/__init__.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/tts/engines/chatterbox.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/tts/engines/kokoro.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/tts/engines/zonos.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/tts/kokoro_server.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/tts/local.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/tts/registry.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/tts_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/tts_server.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/tunnels.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/tunnels_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/usage_limit.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/utils/__init__.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/utils/chunker.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/utils/event_log.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/utils/file_io.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/utils/paths.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/utils/speech.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/utils/subprocess.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/validation.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/voice_status.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/wait_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/wiki.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/wiki_audit.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/wiki_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/worktree.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/worktree_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/agentwire/worktree_registry.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/corpus/cases/bypass.yaml +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/corpus/cases/control_plane.yaml +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/corpus/cases/path_spelling.yaml +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/corpus/cases/relative_paths.yaml +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/corpus/golden/effective_rules.json +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/corpus/golden/harvested.json +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/corpus/golden/rule_ids.json +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/corpus/golden/snapshot.json +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/corpus/schema.json +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/decisions/obsidian-second-brain.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/design/session-card-fields.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/design/session-card-recommendation.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/logo.png +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/communication/channels.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/communication/hammerspoon.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/communication/handoff.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/concepts.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/deployment/remote-access.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/deployment/remote-machines.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/glossary.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/integrations/gws-google-workspace-cli.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/internals/parallel-refactor.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/internals/portal.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/internals/session-topology.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/internals/shell-escaping.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/internals/window-collage.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/quickstart.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/research/briefing-mode-feasibility.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/research/orchestration-transport-alternatives.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/scheduling/scheduled-workloads.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/security/damage-control-hardening.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/security/pip-audit.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/security/remote-access-hardening.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/security/secrets.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/services.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/sessions/claude-code-auto-mode.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/sessions/heal-line-count-cliff.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/sessions/helper-sessions.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/sessions/window-sizing.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/usage-limit-recovery.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/voice/shim-contract.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/voice/stt-cloud.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/voice/stt-self-hosted.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/docs/wiki/voice/tts-self-hosted.md +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/conftest.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/corpus_runner.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/e2e/test_portal_ui.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/audio_unlock_harness.mjs +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/background_tasks/pane_30_shell.txt +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/background_tasks/pane_80_agent.txt +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/background_tasks/pane_80_done.txt +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/background_tasks/pane_80_interrupted.txt +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/background_tasks/pane_80_monitor.txt +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/background_tasks/pane_80_quoted_footer.txt +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/background_tasks/pane_80_second_notice.txt +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/background_tasks/pane_80_shell.txt +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/background_tasks/pane_80_shell_and_monitor.txt +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/background_tasks/transcript_bash_done.jsonl +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/background_tasks/transcript_bash_pending.jsonl +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/background_tasks/transcript_monitor_done.jsonl +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/background_tasks/transcript_monitor_events.jsonl +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/dc_msg_body_quoting_carriers.txt +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/hotkeys_harness.mjs +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/sample_agentwire.yml +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/sample_config.yaml +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/sample_scheduler.yaml +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/session_hud_detent_harness.mjs +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/taskbar_persist_harness.mjs +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/fixtures/topology_expand_harness.mjs +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/home_guard.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/integration/test_council_portal.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/integration/test_scheduler_board.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/integration/test_send_verified_tmux.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/integration/test_server_websockets.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/integration/test_tmux_name_rewrite.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/integration/test_worktree_cmd.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_agentwire_rules_layer.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_announcements.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_audio_unlock_js.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_audit_attribution.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_audit_outcomes.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_auth_expired.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_auth_expired_dispatch.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_background_tasks.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_background_tasks_review.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_beta_flag.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_block_rows_carry_an_id.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_brace_expansion_zero_access.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_breakglass.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_buddy_removal_keeps.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_build_agent_command.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_channels.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_chrome_tabs.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_claude_settings.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_cli_commands.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_cli_output.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_cli_smoke.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_cli_stderr_clean.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_cohort.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_config.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_config_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_control_plane_protection.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_conversation_change.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_corpus.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_council_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_council_inbox.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_council_minutes.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_council_state.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_council_view.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_damage_control_bypass.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_damage_control_delete_recursive.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_damage_control_hooks.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_damage_control_pin.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_dangling_worktrees.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_dc_install.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_dc_policy_packs.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_dc_profile_isolation.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_devices.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_diff_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_doctor_orphaned_history.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_doctor_scheduler_staleness.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_doctor_secrets_perms.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_doctor_task_migration.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_doctor_voice.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_ensure_shared_dir.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_ensure_verified_prompt.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_env_loader.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_event_log.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_extension_points.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_golden_snapshot.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_guarded_launch_command.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_handoff_git_state.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_handoff_instructions.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_handoff_parser.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_handoff_renderer.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_helper_session.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_heredoc_marker_liveness.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_history.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_history_migrate.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_history_migrate_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_history_resume_name.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_hook_fail_closed.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_hook_fail_closed_matrix.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_hook_link_guard.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_hook_python_floor.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_hook_subprocess.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_hooks_install.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_hotkeys_js.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_idle_handler.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_idle_nag.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_inbox.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_init_command.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_install_parity.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_launch_line_reentry.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_launch_via_env.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_limits_tick_isolation.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_live_target_1261.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_locking.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_mcp_nonblocking.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_mcp_server.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_mcp_tool_policy.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_mcp_tools_args.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_msg_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_notify_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_onboarding_reinit.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_owner_only_writes.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_palette_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_path_case_folding.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_path_spelling.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_payload_position.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_pending_message_visibility.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_playback_lane.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_policy_ladder.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_portal_api.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_portal_pair_url.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_posture_default.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_powershell_matcher.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_project_config.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_projects_registry.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_prompt_router.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_prompt_router_dedup.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_prompt_router_resume.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_prose_operands.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_push.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_rebuild_guard.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_rebuild_uv_lock.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_relative_path_operands.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_remote_session_record.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_repo_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_report_back_path_1259.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_restart_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_rich_text_js.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_rm_recoverable.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_role_prompt_retention.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_role_prompt_sweep_wiring.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_roles.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_rule_files_load.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_rule_ids_pinned.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_rules_json_in_sync.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_safe_cwd.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_safety_deployment.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_safety_ext.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_safety_groups.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_safety_install.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_safety_migrate.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_safety_notify.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_safety_packs.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_say_lane.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_scan_budget.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_scheduler.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_scheduler_liveness.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_scheduler_zombie.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_scratchpad.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_security.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_sed_script_is_data.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_sent_ledger.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_server_async.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_services.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_services_command.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_session_context.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_session_created_by_env.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_session_hud_detent_js.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_session_metadata_ssot.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_session_metadata_write.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_session_ready.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_session_state.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_shared_dir_guard.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_shim_selfheal.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_skill_install.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_speech_tags.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_ssh.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_stt_backend.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_stt_cloud.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_stt_engine.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_task_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_task_max_duration.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_taskbar_persist_js.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_tasks.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_tasks_cli.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_templating.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_terminal_resize.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_tmux_session_cwd.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_topology_expand_js.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_tts_engine_resolution.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_tts_local.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_tunnels_probe.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_unattended_allow.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_unattended_env_isolation.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_unattended_scoped_allow.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_usage_limit.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_voice_assistant_removed.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_voice_off_and_shim_bind.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_voice_status.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_watchdog_stages.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_wiki.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_wiki_audit.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_worktree.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_worktree_branch_cleanup.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_worktree_dot_project.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_worktree_git_truth.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_worktree_layout.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_worktree_registry.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tests/unit/test_zero_access_member_access.py +0 -0
- {agentwire_dev-1.79.0 → agentwire_dev-1.80.0}/tools/nonce_stt_probe.py +0 -0
|
@@ -48,7 +48,7 @@ jobs:
|
|
|
48
48
|
- name: Run test suite (full) + coverage
|
|
49
49
|
if: github.event_name != 'pull_request'
|
|
50
50
|
run: >
|
|
51
|
-
uv run --no-sync pytest -q -m "not requires_tmux"
|
|
51
|
+
uv run --no-sync pytest -q -m "not requires_tmux and not upgrade"
|
|
52
52
|
--cov=agentwire --cov-report=term-missing --cov-report=xml
|
|
53
53
|
|
|
54
54
|
- name: Publish coverage summary (report-only)
|
|
@@ -70,6 +70,29 @@ jobs:
|
|
|
70
70
|
path: coverage.xml
|
|
71
71
|
if-no-files-found: ignore
|
|
72
72
|
|
|
73
|
+
# Upgrade test (#1276): the previous release from PyPI, upgraded in place to this checkout, in a
|
|
74
|
+
# fresh HOME. Needs the network and builds two venvs, so it is NOT in the PR gate: it runs on
|
|
75
|
+
# pushes to main and on PRs into a release branch. Budget: ~10 min timeout, ~1 min typical.
|
|
76
|
+
# PyPI index lag is the one flake to rerun, not a reason to skip it.
|
|
77
|
+
upgrade:
|
|
78
|
+
name: upgrade from previous release
|
|
79
|
+
if: github.event_name == 'push' || startsWith(github.base_ref, 'release')
|
|
80
|
+
runs-on: ubuntu-latest
|
|
81
|
+
timeout-minutes: 10
|
|
82
|
+
steps:
|
|
83
|
+
- uses: actions/checkout@v4
|
|
84
|
+
|
|
85
|
+
- name: Install uv
|
|
86
|
+
uses: astral-sh/setup-uv@v5
|
|
87
|
+
with:
|
|
88
|
+
python-version: "3.12"
|
|
89
|
+
|
|
90
|
+
- name: Sync dependencies
|
|
91
|
+
run: uv sync --extra dev
|
|
92
|
+
|
|
93
|
+
- name: Upgrade test
|
|
94
|
+
run: uv run --no-sync pytest -q -m upgrade tests/integration/test_upgrade_from_release.py
|
|
95
|
+
|
|
73
96
|
# The hook is `python -I -m damage_control.hook` and runs under whatever `python3` the user
|
|
74
97
|
# has; the package's declared floor is 3.9 (#1223: a 3.10-only construct made the hooks crash
|
|
75
98
|
# non-blocking, i.e. fail OPEN). The main job runs 3.12 and cannot see that. agentwire itself
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: agentwire-dev
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.80.0
|
|
4
4
|
Summary: Multi-session voice web interface for AI coding agents
|
|
5
5
|
Project-URL: Homepage, https://agentwire.dev
|
|
6
6
|
Project-URL: Repository, https://github.com/dotdevdotdev/agentwire-dev
|
|
@@ -228,7 +228,7 @@ Requires-Dist: aiohttp-jinja2>=1.6
|
|
|
228
228
|
Requires-Dist: aiohttp>=3.13.4
|
|
229
229
|
Requires-Dist: av>=12.0.0
|
|
230
230
|
Requires-Dist: certifi>=2026.10.23
|
|
231
|
-
Requires-Dist: damage-control-dev<0.
|
|
231
|
+
Requires-Dist: damage-control-dev<0.4,>=0.3.0
|
|
232
232
|
Requires-Dist: fastapi>=0.104.0
|
|
233
233
|
Requires-Dist: jinja2>=3.1.0
|
|
234
234
|
Requires-Dist: kokoro-onnx>=0.4.9; python_version < '3.14'
|
|
@@ -6,17 +6,22 @@ Every release does **both** a PyPI publish and a GitHub release. The **GitHub re
|
|
|
6
6
|
|
|
7
7
|
## The engine is a separate project (single source)
|
|
8
8
|
|
|
9
|
-
The damage-control engine has exactly one source: the `damage-control-dev` repo (<https://github.com/dotdevdotdev/damage-control-dev>), published on PyPI. `agentwire-dev` only *consumes* it through the range in `pyproject.toml` (currently `damage-control-dev>=0.
|
|
9
|
+
The damage-control engine has exactly one source: the `damage-control-dev` repo (<https://github.com/dotdevdotdev/damage-control-dev>), published on PyPI. `agentwire-dev` only *consumes* it through the range in `pyproject.toml` (currently `damage-control-dev>=0.3.0,<0.4`); a checkout and a PyPI install both resolve it from PyPI. There is no copy of the engine in this repo and nothing to release from here. `tests/unit/test_damage_control_pin.py` checks that the declared floor/ceiling parse and that the installed engine satisfies them.
|
|
10
10
|
|
|
11
11
|
To ship an engine change:
|
|
12
12
|
|
|
13
13
|
1. **Land it in the damage-control-dev repo**, tag and release it there (its own release flow). Do not tag or release from this repo.
|
|
14
|
-
2. **Raise the floor here** in a normal agentwire PR: bump the `>=` in `pyproject.toml` (and the `<` ceiling too if the engine crossed it, e.g. `>=0.
|
|
14
|
+
2. **Raise the floor here** in a normal agentwire PR: bump the `>=` in `pyproject.toml` (and the `<` ceiling too if the engine crossed it, e.g. `>=0.3.0,<0.4`), run `uv lock`, and re-run `scripts/golden_snapshot.py check` and `scripts/effective_rules.py --check` — re-record the golden only if the behavior change is intended, in that same PR.
|
|
15
15
|
3. **Verify against the published wheel** before releasing agentwire: in a scratch venv, install the agentwire wheel (it pulls the engine from PyPI), then run the fast suite, `agentwire doctor` and a hook subprocess smoke under a temp `HOME`.
|
|
16
16
|
4. **Then** bump and publish `agentwire-dev` (steps below), then the GitHub release.
|
|
17
17
|
|
|
18
18
|
An `agentwire-dev` whose floor names an engine version PyPI doesn't have yet is uninstallable, so step 1 always completes (published) before step 2 merges.
|
|
19
19
|
|
|
20
|
+
## Pre-release checklist
|
|
21
|
+
|
|
22
|
+
- The **`upgrade from previous release`** job in `.github/workflows/pytest.yml` is green on the commit you are about to tag (it runs on pushes to main and on PRs into a `release*` branch, not on ordinary PRs). It installs the previous release from PyPI, upgrades it to this checkout in a fresh `HOME`, then asserts `safety migrate` and `doctor` behave. Details: [`docs/wiki/internals/upgrade-test.md`](docs/wiki/internals/upgrade-test.md). Rerun it if the only failure is PyPI index lag.
|
|
23
|
+
- Engine bumps: also follow step 3 of the engine section above.
|
|
24
|
+
|
|
20
25
|
## Steps
|
|
21
26
|
|
|
22
27
|
### 1. Bump version
|
|
@@ -189,7 +189,7 @@ Command Categories:
|
|
|
189
189
|
from . import doctor_cli, history_cli, machine_cli, safety_cli
|
|
190
190
|
from . import handoff_cli, hooks_cli, mcp_cli, roles_cli, tunnels_cli
|
|
191
191
|
from . import notify_cli, palette_cli, push_cli, repo_cli, system_cli, wiki_cli
|
|
192
|
-
from . import restart_cli, tabs_cli, wait_cli, worktree_cli
|
|
192
|
+
from . import fleet_cli, restart_cli, tabs_cli, wait_cli, worktree_cli
|
|
193
193
|
from .council import cli as council_cli
|
|
194
194
|
|
|
195
195
|
_REGISTRARS = [ # noqa: N806 # registry constant; Phase 1 of #495 appends here
|
|
@@ -226,6 +226,7 @@ Command Categories:
|
|
|
226
226
|
palette_cli.register_palette_parser,
|
|
227
227
|
tabs_cli.register_tabs_parser,
|
|
228
228
|
wait_cli.register_wait_parser,
|
|
229
|
+
fleet_cli.register_fleet_parser,
|
|
229
230
|
worktree_cli.register_helper_parser,
|
|
230
231
|
]
|
|
231
232
|
for _reg in _REGISTRARS:
|
|
@@ -132,19 +132,43 @@ def ledger_path(parent: str) -> Path:
|
|
|
132
132
|
return path
|
|
133
133
|
|
|
134
134
|
|
|
135
|
+
def read(parent: str) -> tuple[dict | None, str | None]:
|
|
136
|
+
"""``(ledger, problem)`` — exactly one is None.
|
|
137
|
+
|
|
138
|
+
``problem`` is ``"missing"`` (no file) or ``"corrupt: <why>"``. The
|
|
139
|
+
distinction is for read-only reporters (``agentwire fleet``); the guard
|
|
140
|
+
paths use :func:`load`, which deliberately collapses both to "no cohort".
|
|
141
|
+
"""
|
|
142
|
+
try:
|
|
143
|
+
text = ledger_path(parent).read_text()
|
|
144
|
+
except FileNotFoundError:
|
|
145
|
+
return None, "missing"
|
|
146
|
+
except (OSError, ValueError) as e: # ValueError: invalid session name / undecodable bytes
|
|
147
|
+
return None, f"corrupt: {e}"
|
|
148
|
+
try:
|
|
149
|
+
data = json.loads(text)
|
|
150
|
+
except ValueError as e:
|
|
151
|
+
return None, f"corrupt: {e}"
|
|
152
|
+
if not isinstance(data, dict) or not isinstance(data.get("children"), list):
|
|
153
|
+
return None, "corrupt: not a cohort ledger (no children list)"
|
|
154
|
+
return data, None
|
|
155
|
+
|
|
156
|
+
|
|
135
157
|
def load(parent: str) -> dict | None:
|
|
136
158
|
"""The parent's ledger, or None when absent/unreadable/malformed.
|
|
137
159
|
|
|
138
160
|
Fails open on purpose: a corrupt ledger reads as "no cohort", so the guard
|
|
139
161
|
stops suppressing and the parent resumes normal idle handling.
|
|
140
162
|
"""
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
163
|
+
return read(parent)[0]
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def ledger_parents() -> list[str]:
|
|
167
|
+
"""Every parent session that has a ledger file, sorted (worktree names nest)."""
|
|
168
|
+
if not COHORT_ROOT.exists():
|
|
169
|
+
return []
|
|
170
|
+
return sorted(str(p.relative_to(COHORT_ROOT))[: -len(".json")]
|
|
171
|
+
for p in COHORT_ROOT.rglob("*.json"))
|
|
148
172
|
|
|
149
173
|
|
|
150
174
|
def _save(parent: str, data: dict) -> None:
|
|
@@ -301,6 +325,7 @@ def _mark(data: dict, child: str, state: str, report: str | None = None) -> None
|
|
|
301
325
|
for entry in data["children"]:
|
|
302
326
|
if entry.get("session") == child:
|
|
303
327
|
entry["state"] = state
|
|
328
|
+
entry["resolved_at"] = _now()
|
|
304
329
|
if report is not None:
|
|
305
330
|
entry["report"] = report
|
|
306
331
|
|
|
@@ -344,6 +369,7 @@ def record_delivery(parent: str, messages: list) -> None:
|
|
|
344
369
|
else:
|
|
345
370
|
continue
|
|
346
371
|
entry["delivered"] = True
|
|
372
|
+
entry["resolved_at"] = _now()
|
|
347
373
|
changed = True
|
|
348
374
|
log_event("delivered_by_drain", parent=parent, child=entry["session"],
|
|
349
375
|
state=entry["state"])
|
|
@@ -295,6 +295,27 @@ class AgentConfig:
|
|
|
295
295
|
command: str = field(default_factory=_get_default_agent_command)
|
|
296
296
|
|
|
297
297
|
|
|
298
|
+
@dataclass
|
|
299
|
+
class SandboxConfig:
|
|
300
|
+
"""Allowances for ``agentwire new --sandbox`` (#1279). Opt-in; nothing here
|
|
301
|
+
applies to a session launched without the flag. Writes are otherwise
|
|
302
|
+
limited to the session's working directory; ``~/.agentwire`` stays
|
|
303
|
+
read-only except the message-passing paths below, so a sandboxed agent
|
|
304
|
+
cannot edit ``damagecontrol.yml`` or ``.env``."""
|
|
305
|
+
|
|
306
|
+
allow_write: list[str] = field(default_factory=lambda: [
|
|
307
|
+
"~/.cache/uv", # uv run / uv sync
|
|
308
|
+
"~/.agentwire/inbox", "~/.agentwire/inbox-events.jsonl", # msg send / notify-parent --queued
|
|
309
|
+
"~/.agentwire/sent-ledger",
|
|
310
|
+
])
|
|
311
|
+
allowed_domains: list[str] = field(default_factory=lambda: [
|
|
312
|
+
"github.com", "api.github.com", "pypi.org", "files.pythonhosted.org",
|
|
313
|
+
])
|
|
314
|
+
allow_unix_sockets: list[str] = field(default_factory=list) # tmux socket is always added
|
|
315
|
+
excluded_commands: list[str] = field(default_factory=lambda: ["gh *"]) # Go TLS fails under the proxy on macOS
|
|
316
|
+
allow_local_binding: bool = True # macOS: needed to reach the local portal API
|
|
317
|
+
|
|
318
|
+
|
|
298
319
|
@dataclass
|
|
299
320
|
class MachinesConfig:
|
|
300
321
|
"""Remote machines registry configuration."""
|
|
@@ -618,6 +639,7 @@ class Config:
|
|
|
618
639
|
tts: TTSConfig = field(default_factory=TTSConfig)
|
|
619
640
|
stt: STTConfig = field(default_factory=STTConfig)
|
|
620
641
|
agent: AgentConfig = field(default_factory=AgentConfig)
|
|
642
|
+
sandbox: SandboxConfig = field(default_factory=SandboxConfig)
|
|
621
643
|
machines: MachinesConfig = field(default_factory=MachinesConfig)
|
|
622
644
|
uploads: UploadsConfig = field(default_factory=UploadsConfig)
|
|
623
645
|
artifacts: ArtifactsConfig = field(default_factory=ArtifactsConfig)
|
|
@@ -775,6 +797,14 @@ def _dict_to_config(data: dict) -> Config:
|
|
|
775
797
|
command=agent_data.get("command", _get_default_agent_command()),
|
|
776
798
|
)
|
|
777
799
|
|
|
800
|
+
# Sandbox allowances (#1279) — a key that is absent keeps its default.
|
|
801
|
+
sandbox_data = data.get("sandbox") or {}
|
|
802
|
+
sandbox_defaults = SandboxConfig()
|
|
803
|
+
sandbox = SandboxConfig(**{
|
|
804
|
+
key: sandbox_data.get(key, getattr(sandbox_defaults, key))
|
|
805
|
+
for key in SandboxConfig.__dataclass_fields__
|
|
806
|
+
})
|
|
807
|
+
|
|
778
808
|
# Machines
|
|
779
809
|
machines_data = data.get("machines", {})
|
|
780
810
|
machines = MachinesConfig(
|
|
@@ -1017,6 +1047,7 @@ def _dict_to_config(data: dict) -> Config:
|
|
|
1017
1047
|
tts=tts,
|
|
1018
1048
|
stt=stt,
|
|
1019
1049
|
agent=agent,
|
|
1050
|
+
sandbox=sandbox,
|
|
1020
1051
|
machines=machines,
|
|
1021
1052
|
uploads=uploads,
|
|
1022
1053
|
artifacts=artifacts,
|
|
@@ -254,6 +254,7 @@ class AgentCommand:
|
|
|
254
254
|
roles: list[str] = field(default_factory=list) # Role NAMES, in merge order
|
|
255
255
|
model: str | None = None # --model override, if the launch chose one
|
|
256
256
|
effort: str | None = None # --effort override, if the launch chose one
|
|
257
|
+
sandbox: bool = False # launched under Claude Code's sandbox (--sandbox, #1279)
|
|
257
258
|
|
|
258
259
|
|
|
259
260
|
_UNATTENDED_ENV_KEYS = ("AGENTWIRE_UNATTENDED", "AGENTWIRE_UNATTENDED_ALLOW")
|
|
@@ -626,9 +627,13 @@ def build_agent_command(
|
|
|
626
627
|
model: str | None = None,
|
|
627
628
|
resume_session_id: str | None = None,
|
|
628
629
|
effort: str | None = None,
|
|
630
|
+
sandbox: bool = False,
|
|
629
631
|
) -> AgentCommand:
|
|
630
632
|
"""Build the shell command + injected env for the given posture.
|
|
631
633
|
|
|
634
|
+
``sandbox`` adds ``--settings`` enabling Claude Code's native sandbox with
|
|
635
|
+
the allowances from ``config.yaml`` (#1279; see :mod:`agentwire.sandbox`).
|
|
636
|
+
|
|
632
637
|
The ONE flag-builder (#729): fresh sessions AND history resume both route
|
|
633
638
|
through here, so a posture always launches with the same flags — no
|
|
634
639
|
create-vs-resume drift. Posture switches the permission-mode flags; ``bare``
|
|
@@ -687,6 +692,12 @@ def build_agent_command(
|
|
|
687
692
|
if effort:
|
|
688
693
|
parts.append(f"--effort {effort}")
|
|
689
694
|
|
|
695
|
+
if sandbox:
|
|
696
|
+
from . import sandbox as sandbox_mod
|
|
697
|
+
from .config import load_config as load_typed_config
|
|
698
|
+
|
|
699
|
+
parts.append(sandbox_mod.settings_flag(sandbox_mod.settings_for(load_typed_config())))
|
|
700
|
+
|
|
690
701
|
# Role-based flags (merged roles always apply — no tool-locking posture left)
|
|
691
702
|
role_prompt_path = None
|
|
692
703
|
if merged:
|
|
@@ -712,6 +723,7 @@ def build_agent_command(
|
|
|
712
723
|
roles=role_names,
|
|
713
724
|
model=model,
|
|
714
725
|
effort=effort,
|
|
726
|
+
sandbox=sandbox,
|
|
715
727
|
)
|
|
716
728
|
|
|
717
729
|
|
|
@@ -1523,6 +1535,7 @@ def record_session_launch(
|
|
|
1523
1535
|
# conversation back on a different model/effort than it was running on.
|
|
1524
1536
|
"model": agent.model,
|
|
1525
1537
|
"effort": agent.effort,
|
|
1538
|
+
"sandbox": agent.sandbox,
|
|
1526
1539
|
"role_prompt_path": agent.role_prompt_path,
|
|
1527
1540
|
"launched_at": now,
|
|
1528
1541
|
**({"repo": None, "branch": None, "worktree_path": None}
|
|
@@ -1128,13 +1128,11 @@ def _render_cohort_section() -> int:
|
|
|
1128
1128
|
from . import cohort
|
|
1129
1129
|
|
|
1130
1130
|
suspects = []
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
if reason:
|
|
1137
|
-
suspects.append((parent, reason))
|
|
1131
|
+
for parent in cohort.ledger_parents():
|
|
1132
|
+
data = cohort.load(parent)
|
|
1133
|
+
reason = cohort.suspect_reason(parent, data) if data else None
|
|
1134
|
+
if reason:
|
|
1135
|
+
suspects.append((parent, reason))
|
|
1138
1136
|
if not suspects:
|
|
1139
1137
|
print(" [ok] No suspect cohort ledgers")
|
|
1140
1138
|
return 0
|
|
@@ -1146,6 +1144,28 @@ def _render_cohort_section() -> int:
|
|
|
1146
1144
|
return 1
|
|
1147
1145
|
|
|
1148
1146
|
|
|
1147
|
+
def _render_fleet_section() -> int:
|
|
1148
|
+
"""Doctor section: delegation problems from ``agentwire fleet`` (#1277).
|
|
1149
|
+
|
|
1150
|
+
Renders :func:`fleet.build_fleet` and nothing else — the flags are decided
|
|
1151
|
+
there, so doctor, the CLI and the portal cannot disagree.
|
|
1152
|
+
"""
|
|
1153
|
+
from . import fleet
|
|
1154
|
+
|
|
1155
|
+
data = fleet.build_fleet(None)
|
|
1156
|
+
problems = len(data["flagged"]) + len(data["broken_ledgers"])
|
|
1157
|
+
if not problems:
|
|
1158
|
+
print(" [ok] No stuck or silent children in any fan-out")
|
|
1159
|
+
return 0
|
|
1160
|
+
print(f" [!!] {problems} fleet problem(s):")
|
|
1161
|
+
for b in data["broken_ledgers"]:
|
|
1162
|
+
print(f" - {b['parent']}: cohort ledger {b['ledger']}")
|
|
1163
|
+
for f in data["flagged"]:
|
|
1164
|
+
print(f" - {f['session']} (child of {f['parent']}): {f['flag']}")
|
|
1165
|
+
print(" Details: agentwire fleet --all")
|
|
1166
|
+
return 1
|
|
1167
|
+
|
|
1168
|
+
|
|
1149
1169
|
def _render_auth_expired_section() -> int:
|
|
1150
1170
|
"""Doctor section: an active expired-login outage (#906).
|
|
1151
1171
|
|
|
@@ -1426,6 +1446,28 @@ def _render_role_prompt_store_section(
|
|
|
1426
1446
|
return 1, 1
|
|
1427
1447
|
|
|
1428
1448
|
|
|
1449
|
+
def _render_sandbox_section() -> int:
|
|
1450
|
+
"""Which recorded sessions run under the Claude Code sandbox (#1279).
|
|
1451
|
+
|
|
1452
|
+
Reads the launch record — the flag is recorded, not guessed from a pane —
|
|
1453
|
+
and flags a machine where a sandboxed session could not (re)start, since
|
|
1454
|
+
``failIfUnavailable`` makes that a hard refusal, not a silent downgrade.
|
|
1455
|
+
"""
|
|
1456
|
+
from . import sandbox
|
|
1457
|
+
|
|
1458
|
+
names = sandbox.sandboxed_sessions()
|
|
1459
|
+
problem = sandbox.platform_problem()
|
|
1460
|
+
if not names:
|
|
1461
|
+
print(" [ok] No session was launched with --sandbox")
|
|
1462
|
+
return 0
|
|
1463
|
+
for name in names:
|
|
1464
|
+
print(f" [ok] {name}: sandboxed (launch record)")
|
|
1465
|
+
if problem:
|
|
1466
|
+
print(f" [!!] sandbox cannot start on this machine: {problem}")
|
|
1467
|
+
return 1
|
|
1468
|
+
return 0
|
|
1469
|
+
|
|
1470
|
+
|
|
1429
1471
|
def _render_blocked_prompt_section() -> int:
|
|
1430
1472
|
"""Doctor section: agent alive, but the pane sits on an unanswered menu (#905).
|
|
1431
1473
|
|
|
@@ -2165,6 +2207,12 @@ def cmd_doctor(args) -> int:
|
|
|
2165
2207
|
print("\nChecking for suspect cohort ledgers...")
|
|
2166
2208
|
issues_found += _render_cohort_section()
|
|
2167
2209
|
|
|
2210
|
+
print("\nChecking the fleet (stuck or silent children)...")
|
|
2211
|
+
try:
|
|
2212
|
+
issues_found += _render_fleet_section()
|
|
2213
|
+
except Exception as e:
|
|
2214
|
+
print(f" [..] Could not check the fleet: {e}")
|
|
2215
|
+
|
|
2168
2216
|
# 10c. Expired Claude login (#906) — the state that made #867 cost two
|
|
2169
2217
|
# hours. Nothing else on this list would surface it: the pane is alive and
|
|
2170
2218
|
# the agent process is running, so every liveness check passes.
|
|
@@ -2251,6 +2299,12 @@ def cmd_doctor(args) -> int:
|
|
|
2251
2299
|
except Exception as e:
|
|
2252
2300
|
print(f" [..] Could not check the role-prompt store: {e}")
|
|
2253
2301
|
|
|
2302
|
+
print("\nChecking sandboxed sessions (#1279)...")
|
|
2303
|
+
try:
|
|
2304
|
+
issues_found += _render_sandbox_section()
|
|
2305
|
+
except Exception as e:
|
|
2306
|
+
print(f" [..] Could not check sandboxed sessions: {e}")
|
|
2307
|
+
|
|
2254
2308
|
# 12c. Sessions blocked on an unanswered dialog (#905). The one state every
|
|
2255
2309
|
# other check calls healthy: the agent process is running, so liveness
|
|
2256
2310
|
# passes, while the pane sits on a menu and does nothing.
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"""Fleet view — one read-only picture of every session an orchestrator spawned (#1277).
|
|
2
|
+
|
|
3
|
+
Delegation failed silently in three different ways (no parent, wrong parent
|
|
4
|
+
name, dead-lettered reports) and each was found hours later by the owner. The
|
|
5
|
+
data to see all three already exists in four places; this module is the ONE
|
|
6
|
+
reader that joins them:
|
|
7
|
+
|
|
8
|
+
* the cohort ledger (:mod:`agentwire.cohort`) — who spawned whom, and what each
|
|
9
|
+
child's report-back resolved to;
|
|
10
|
+
* the worktree registry — a child's branch;
|
|
11
|
+
* the inbox (:mod:`agentwire.inbox`) — reports waiting for, or dead-lettered
|
|
12
|
+
away from, the parent, plus messages waiting for the child itself;
|
|
13
|
+
* session records and tmux liveness.
|
|
14
|
+
|
|
15
|
+
``agentwire fleet --json`` is :func:`build_fleet`'s output verbatim; ``doctor``
|
|
16
|
+
and the portal call the CLI and render it — neither re-derives anything.
|
|
17
|
+
|
|
18
|
+
**Reads only.** No ledger is rewritten, no message touched, nothing killed.
|
|
19
|
+
|
|
20
|
+
**Absence is reported, never raised.** A corrupt ledger is a parent row whose
|
|
21
|
+
``ledger`` field says so; a child with no session record is a row with
|
|
22
|
+
``session_record: false``. A reader that crashes on the broken thing it exists
|
|
23
|
+
to expose is useless exactly when it matters.
|
|
24
|
+
|
|
25
|
+
Flags (``flags`` on a child, aggregated in ``flagged``):
|
|
26
|
+
|
|
27
|
+
``idle_no_report``
|
|
28
|
+
The child went idle and the only thing it left was the idle handler's
|
|
29
|
+
placeholder — its work may not have happened.
|
|
30
|
+
``report_queued_to_dead_session``
|
|
31
|
+
A report from the child sits in the inbox of a parent that is not live;
|
|
32
|
+
nothing will ever drain it.
|
|
33
|
+
``report_dead_lettered``
|
|
34
|
+
A load-bearing message from the child was dead-lettered on the way to the
|
|
35
|
+
parent.
|
|
36
|
+
``gone_with_open_pr``
|
|
37
|
+
The child's session is gone but its branch still has an OPEN PR — nobody
|
|
38
|
+
is positioned to act on it. PR state comes from
|
|
39
|
+
:func:`agentwire.session_cli.pr_for_branch`, the same probe the dangling-PR
|
|
40
|
+
scan uses.
|
|
41
|
+
``no_session_record``
|
|
42
|
+
A live child with no launch record — its role and parent are unknowable.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
from __future__ import annotations
|
|
46
|
+
|
|
47
|
+
import time
|
|
48
|
+
|
|
49
|
+
from . import cohort, inbox, worktree_registry
|
|
50
|
+
|
|
51
|
+
IDLE_NO_REPORT = "idle_no_report"
|
|
52
|
+
REPORT_QUEUED_TO_DEAD = "report_queued_to_dead_session"
|
|
53
|
+
REPORT_DEAD_LETTERED = "report_dead_lettered"
|
|
54
|
+
GONE_WITH_OPEN_PR = "gone_with_open_pr"
|
|
55
|
+
NO_SESSION_RECORD = "no_session_record"
|
|
56
|
+
|
|
57
|
+
STATE_RUNNING = "running"
|
|
58
|
+
STATE_IDLE = "idle"
|
|
59
|
+
STATE_GONE = "gone"
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _oldest_age_s(messages: list, now_ms: int) -> int | None:
|
|
63
|
+
stamps = [m.ts for m in messages if m.ts]
|
|
64
|
+
return max(0, (now_ms - min(stamps)) // 1000) if stamps else None
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _safe(fn, *args) -> list:
|
|
68
|
+
"""An inbox read that degrades to "nothing" — an unreadable inbox must not
|
|
69
|
+
take the whole fleet view down with it."""
|
|
70
|
+
try:
|
|
71
|
+
return fn(*args)
|
|
72
|
+
except (OSError, ValueError):
|
|
73
|
+
return []
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _branches_by_session() -> dict[str, dict]:
|
|
77
|
+
"""Registry entry per worktree-topology session (pane entries name their
|
|
78
|
+
OWNER, not a child, so they are not a branch of any session here)."""
|
|
79
|
+
try:
|
|
80
|
+
rows = worktree_registry.all_entries()
|
|
81
|
+
except Exception:
|
|
82
|
+
return {}
|
|
83
|
+
return {r["session"]: r for r in rows
|
|
84
|
+
if r.get("session") and r.get("topology", "worktree") == "worktree"}
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _child_row(parent: str, parent_live: bool, entry: dict, *, registry: dict[str, dict],
|
|
88
|
+
parent_pending: list, parent_dead: list, now_ms: int,
|
|
89
|
+
with_pr: bool) -> dict:
|
|
90
|
+
from .core import load_session_metadata
|
|
91
|
+
from .session_cli import pr_for_branch
|
|
92
|
+
|
|
93
|
+
name = str(entry.get("session") or "")
|
|
94
|
+
ledger_state = entry.get("state")
|
|
95
|
+
live = bool(name) and cohort.session_exists(name)
|
|
96
|
+
if not live:
|
|
97
|
+
state = STATE_GONE
|
|
98
|
+
elif ledger_state == cohort.IDLE:
|
|
99
|
+
state = STATE_IDLE
|
|
100
|
+
else:
|
|
101
|
+
state = STATE_RUNNING
|
|
102
|
+
|
|
103
|
+
record = load_session_metadata(name) if name else {}
|
|
104
|
+
reg = registry.get(name) or {}
|
|
105
|
+
branch = reg.get("branch")
|
|
106
|
+
pr = pr_for_branch(branch, reg.get("project")) if (with_pr and branch) else None
|
|
107
|
+
|
|
108
|
+
queued = [m for m in parent_pending if m.sender == name and m.kind in cohort.REPORT_KINDS]
|
|
109
|
+
dead = inbox.load_bearing([m for m in parent_dead if m.sender == name])
|
|
110
|
+
resolved_at = entry.get("resolved_at")
|
|
111
|
+
|
|
112
|
+
row = {
|
|
113
|
+
"session": name,
|
|
114
|
+
"parent": parent,
|
|
115
|
+
"role": record.get("role"),
|
|
116
|
+
"roles": record.get("roles") or [],
|
|
117
|
+
"topology": entry.get("topology"),
|
|
118
|
+
"state": state,
|
|
119
|
+
"ledger_state": ledger_state,
|
|
120
|
+
"session_record": bool(record),
|
|
121
|
+
"branch": branch,
|
|
122
|
+
"pr": {"state": str(pr.get("state", "")).upper(), "url": pr.get("url")} if pr else None,
|
|
123
|
+
"last_report_at": resolved_at if ledger_state == cohort.REPORTED else None,
|
|
124
|
+
"inbox_waiting_age_s": _oldest_age_s(_safe(inbox.list_messages, name), now_ms) if name else None,
|
|
125
|
+
"dead_letter_age_s": _oldest_age_s(_safe(inbox.list_dead, name), now_ms) if name else None,
|
|
126
|
+
"report_queued_age_s": _oldest_age_s(queued, now_ms),
|
|
127
|
+
"report_dead_letter_age_s": _oldest_age_s(dead, now_ms),
|
|
128
|
+
"flags": [],
|
|
129
|
+
}
|
|
130
|
+
flags = row["flags"]
|
|
131
|
+
if ledger_state == cohort.IDLE:
|
|
132
|
+
flags.append(IDLE_NO_REPORT)
|
|
133
|
+
if queued and not parent_live:
|
|
134
|
+
flags.append(REPORT_QUEUED_TO_DEAD)
|
|
135
|
+
if dead:
|
|
136
|
+
flags.append(REPORT_DEAD_LETTERED)
|
|
137
|
+
if state == STATE_GONE and row["pr"] and row["pr"]["state"] == "OPEN":
|
|
138
|
+
flags.append(GONE_WITH_OPEN_PR)
|
|
139
|
+
if live and not record:
|
|
140
|
+
flags.append(NO_SESSION_RECORD)
|
|
141
|
+
return row
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def _parent_row(parent: str, *, registry: dict[str, dict], now_ms: int, with_pr: bool) -> dict:
|
|
145
|
+
data, problem = cohort.read(parent)
|
|
146
|
+
row = {
|
|
147
|
+
"parent": parent,
|
|
148
|
+
"live": cohort.session_exists(parent),
|
|
149
|
+
"ledger": problem or "ok",
|
|
150
|
+
"task": (data or {}).get("task"),
|
|
151
|
+
"children": [],
|
|
152
|
+
}
|
|
153
|
+
if data is None:
|
|
154
|
+
return row
|
|
155
|
+
parent_pending = _safe(inbox.list_messages, parent)
|
|
156
|
+
parent_dead = _safe(inbox.list_dead, parent)
|
|
157
|
+
for entry in data["children"]:
|
|
158
|
+
if not isinstance(entry, dict):
|
|
159
|
+
continue
|
|
160
|
+
row["children"].append(_child_row(
|
|
161
|
+
parent, row["live"], entry, registry=registry, parent_pending=parent_pending,
|
|
162
|
+
parent_dead=parent_dead, now_ms=now_ms, with_pr=with_pr))
|
|
163
|
+
return row
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def build_fleet(parent: str | None = None, *, with_pr: bool = True) -> dict:
|
|
167
|
+
"""The fleet view: one row per parent, one row per child under it.
|
|
168
|
+
|
|
169
|
+
*parent* ``None`` means every ledger on the machine; otherwise just that
|
|
170
|
+
parent (a parent with no ledger yields a row saying ``missing``, so a typo
|
|
171
|
+
is visible rather than an empty success). Zero ledgers is a valid, empty
|
|
172
|
+
fleet.
|
|
173
|
+
"""
|
|
174
|
+
now_ms = int(time.time() * 1000)
|
|
175
|
+
registry = _branches_by_session()
|
|
176
|
+
parents = [parent] if parent else cohort.ledger_parents()
|
|
177
|
+
rows = [_parent_row(p, registry=registry, now_ms=now_ms, with_pr=with_pr) for p in parents]
|
|
178
|
+
flagged = [
|
|
179
|
+
{"session": c["session"], "parent": r["parent"], "flag": f}
|
|
180
|
+
for r in rows for c in r["children"] for f in c["flags"]
|
|
181
|
+
]
|
|
182
|
+
broken = [{"parent": r["parent"], "ledger": r["ledger"]}
|
|
183
|
+
for r in rows if r["ledger"] not in ("ok", "missing")]
|
|
184
|
+
return {
|
|
185
|
+
"success": True,
|
|
186
|
+
"parents": rows,
|
|
187
|
+
"flagged": flagged,
|
|
188
|
+
"broken_ledgers": broken,
|
|
189
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""``agentwire fleet`` — the report-back ledger and fleet view (#1277).
|
|
2
|
+
|
|
3
|
+
The CLI is the single source of truth: ``--json`` is :func:`fleet.build_fleet`
|
|
4
|
+
verbatim, and ``doctor`` and the portal both call it. See :mod:`agentwire.fleet`.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
import time
|
|
9
|
+
|
|
10
|
+
from . import fleet
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _age(seconds) -> str:
|
|
14
|
+
if seconds is None:
|
|
15
|
+
return "-"
|
|
16
|
+
for unit, size in (("d", 86400), ("h", 3600), ("m", 60)):
|
|
17
|
+
if seconds >= size:
|
|
18
|
+
return f"{seconds // size}{unit}"
|
|
19
|
+
return f"{seconds}s"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def render_fleet_text(data: dict) -> str:
|
|
23
|
+
"""Human rendering of a :func:`fleet.build_fleet` result."""
|
|
24
|
+
lines: list[str] = []
|
|
25
|
+
for p in data["parents"]:
|
|
26
|
+
live = "live" if p["live"] else "NOT LIVE"
|
|
27
|
+
lines.append(f"{p['parent']} ({live})" + (f" — ledger {p['ledger']}" if p["ledger"] != "ok" else ""))
|
|
28
|
+
for c in p["children"]:
|
|
29
|
+
bits = [c["state"], c.get("topology") or "?"]
|
|
30
|
+
if c.get("role"):
|
|
31
|
+
bits.append(c["role"])
|
|
32
|
+
if c.get("branch"):
|
|
33
|
+
bits.append(f"branch={c['branch']}")
|
|
34
|
+
if c.get("pr"):
|
|
35
|
+
bits.append(f"PR {c['pr']['state']} {c['pr'].get('url') or ''}".strip())
|
|
36
|
+
if c.get("last_report_at"):
|
|
37
|
+
bits.append(f"reported {_age(int(time.time()) - int(c['last_report_at']))} ago")
|
|
38
|
+
for label, key in (("inbox", "inbox_waiting_age_s"), ("dead", "dead_letter_age_s"),
|
|
39
|
+
("report queued", "report_queued_age_s"),
|
|
40
|
+
("report dead-lettered", "report_dead_letter_age_s")):
|
|
41
|
+
if c.get(key) is not None:
|
|
42
|
+
bits.append(f"{label} {_age(c[key])}")
|
|
43
|
+
flags = "".join(f" [!! {f}]" for f in c["flags"])
|
|
44
|
+
lines.append(f" {c['session']}: {', '.join(bits)}{flags}")
|
|
45
|
+
if not p["children"] and p["ledger"] == "ok":
|
|
46
|
+
lines.append(" (no children)")
|
|
47
|
+
if not data["parents"]:
|
|
48
|
+
lines.append("No cohort ledgers — nothing has been spawned with a report-back.")
|
|
49
|
+
if data["flagged"]:
|
|
50
|
+
lines.append(f"\n{len(data['flagged'])} problem(s) flagged.")
|
|
51
|
+
return "\n".join(lines)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def cmd_fleet(args) -> int:
|
|
55
|
+
"""Print the fleet. Read-only; exit 0 even when flags are raised."""
|
|
56
|
+
from . import pane_manager
|
|
57
|
+
|
|
58
|
+
parent = None
|
|
59
|
+
if not getattr(args, "all", False):
|
|
60
|
+
parent = getattr(args, "session", None) or pane_manager.get_current_session()
|
|
61
|
+
data = fleet.build_fleet(parent, with_pr=not getattr(args, "no_pr", False))
|
|
62
|
+
if getattr(args, "json", False):
|
|
63
|
+
print(json.dumps(data, indent=2))
|
|
64
|
+
else:
|
|
65
|
+
print(render_fleet_text(data))
|
|
66
|
+
return 0
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def register_fleet_parser(subparsers) -> None:
|
|
70
|
+
parser = subparsers.add_parser(
|
|
71
|
+
"fleet",
|
|
72
|
+
help="Every session an orchestrator spawned: state, PR, report-back, stuck messages",
|
|
73
|
+
description=(
|
|
74
|
+
"Read-only view of a session's fan-out: per child its role/topology, "
|
|
75
|
+
"state (running/idle/gone), branch and open PR, last report time, and "
|
|
76
|
+
"the age of any message waiting in or dead-lettered from its inbox. "
|
|
77
|
+
"Flags a child that went idle without reporting, a report queued for "
|
|
78
|
+
"a session that is not live, a dead-lettered report, and a gone "
|
|
79
|
+
"child still holding an open PR."
|
|
80
|
+
),
|
|
81
|
+
)
|
|
82
|
+
parser.add_argument("-s", "--session",
|
|
83
|
+
help="Orchestrator to show (default: the current tmux session)")
|
|
84
|
+
parser.add_argument("--all", action="store_true",
|
|
85
|
+
help="Every orchestrator with a cohort ledger on this machine")
|
|
86
|
+
parser.add_argument("--no-pr", action="store_true",
|
|
87
|
+
help="Skip the GitHub PR lookup (faster; offline)")
|
|
88
|
+
parser.add_argument("--json", action="store_true", help="Output JSON")
|
|
89
|
+
parser.set_defaults(func=cmd_fleet)
|