agentwire-dev 1.43.0__tar.gz → 1.44.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.43.0 → agentwire_dev-1.44.0}/PKG-INFO +2 -1
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/__init__.py +1 -1
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/__main__.py +325 -70
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/cli_safety.py +225 -55
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/config.py +51 -5
- agentwire_dev-1.44.0/agentwire/devices.py +395 -0
- agentwire_dev-1.44.0/agentwire/hooks/damage-control/mcp-tool-damage-control.py +972 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/hooks/damage-control/rules/aws.yaml +18 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/hooks/damage-control/rules/cloud-hosting.yaml +46 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/hooks/damage-control/rules/containers.yaml +17 -0
- agentwire_dev-1.44.0/agentwire/hooks/damage-control/rules/databases.yaml +147 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/hooks/damage-control/rules/gcp.yaml +15 -0
- agentwire_dev-1.44.0/agentwire/hooks/damage-control/rules/infrastructure.yaml +51 -0
- agentwire_dev-1.44.0/agentwire/hooks/damage-control/rules/outbound.yaml +65 -0
- agentwire_dev-1.44.0/agentwire/hooks/damage-control/rules/publish.yaml +40 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/limits_cli.py +18 -5
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/scheduler.py +180 -20
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/security.py +161 -19
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/server.py +130 -36
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/services.py +6 -2
- agentwire_dev-1.44.0/agentwire/session_context.py +420 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/css/desktop.css +72 -93
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/safety-shared.js +3 -67
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/safety-window.js +10 -27
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/sidebar/safety-section.js +8 -27
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/sidebar/sessions-section.js +75 -1
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/token-modal.js +1 -1
- agentwire_dev-1.44.0/agentwire/templates/pair.html +86 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/INDEX.md +1 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/deployment/remote-access.md +11 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/internals/damage-control.md +115 -8
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/scheduling/scheduled-workloads.md +7 -0
- agentwire_dev-1.44.0/docs/wiki/security/remote-access-hardening.md +273 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/pyproject.toml +4 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/conftest.py +16 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/integration/test_scheduler_board.py +172 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_damage_control_hooks.py +236 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_damage_control_sync.py +1 -0
- agentwire_dev-1.44.0/tests/unit/test_devices.py +208 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_portal_api.py +149 -0
- agentwire_dev-1.44.0/tests/unit/test_rebuild_guard.py +134 -0
- agentwire_dev-1.44.0/tests/unit/test_safety_heal.py +158 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_security.py +120 -0
- agentwire_dev-1.44.0/tests/unit/test_session_context.py +307 -0
- agentwire_dev-1.43.0/agentwire/hooks/damage-control/rules/databases.yaml +0 -52
- agentwire_dev-1.43.0/agentwire/hooks/damage-control/rules/infrastructure.yaml +0 -21
- agentwire_dev-1.43.0/agentwire/session_context.py +0 -196
- agentwire_dev-1.43.0/tests/unit/test_session_context.py +0 -96
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/.agents/skills/agentwire-cli/SKILL.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/.agents/skills/agentwire-config/SKILL.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/.agents/skills/agentwire-desktop-ui/SKILL.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/.agents/skills/agentwire-mcp-tools/SKILL.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/.agents/skills/agentwire-pi/SKILL.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/.agents/skills/agentwire-project-config/SKILL.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/.agents/skills/agentwire-scheduler/SKILL.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/.agents/skills/wiki/SKILL.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/.github/FUNDING.yml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/.github/workflows/pytest.yml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/.github/workflows/tts-smoke.yml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/.gitignore +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/AGENTS.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/CLA.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/CODE_OF_CONDUCT.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/CONTRIBUTING.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/Dockerfile.local +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/Dockerfile.runpod +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/LICENSE +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/README.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/RELEASING.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/SECURITY.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/SPONSORS.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/agents/__init__.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/agents/base.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/agents/tmux.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/cached_status.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/channels/__init__.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/channels/base.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/channels/email.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/channels/quo.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/completion.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/council/__init__.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/council/cli.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/council/inbox.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/council/state.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/council/view.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/doctor_voice.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/fetch.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/handoff/__init__.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/handoff/git_state.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/handoff/instructions.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/handoff/parser.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/handoff/renderer.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/handoff/schema.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/history.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/hooks/__init__.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/hooks/agentwire-permission.sh +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/hooks/damage-control/__init__.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/hooks/damage-control/audit_logger.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/hooks/damage-control/bash-tool-damage-control.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/hooks/damage-control/edit-tool-damage-control.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/hooks/damage-control/rules/agentwire.yaml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/hooks/damage-control/rules/core.yaml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/hooks/damage-control/rules/firebase.yaml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/hooks/damage-control/rules/git.yaml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/hooks/damage-control/rules/gws.yaml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/hooks/damage-control/rules/remote.yaml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/hooks/damage-control/write-tool-damage-control.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/hooks/idle-handler.sh +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/hooks/queue-processor.sh +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/inbox.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/listen.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/locking.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/mcp_server.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/msg_cli.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/network.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/onboarding.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/pane_manager.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/project_config.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/projects.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/prompt_router.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/prompts/__init__.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/prompts/init.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/prompts_cli.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/research.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/__init__.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/agentwire.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/anchor.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/chatbot.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/correspondent.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/council-brain.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/council-conscience.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/council-critic.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/council-devils-advocate.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/council-gut.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/council-historian.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/council-member.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/council-orchestrator.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/init.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/notifications.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/orchestrator.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/soul.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/task-runner.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/voice.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/worker.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/roles/worktree-session.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/safety/__init__.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/safety/_core.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/scratchpad.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/session_ready.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/ssh.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/agentwire-Echo--black.png +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/agentwire-Echo--transparent.png +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/agentwire-Echo.png +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/agentwire-email-banner.png +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/agentwire-splash-logo-layers--agentwire-text.png +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/agentwire-splash-logo-layers--echo-claw-fg.png +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/agentwire-splash-logo-layers--echo.png +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/agentwire-splash-logo-layers--full--transparent-top.png +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/agentwire-splash-logo-layers--full-black.png +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/agentwire-splash-logo-layers--telephone-fg.png +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/agentwire-splash-logo-layers--telephone.png +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/agentwire-splash-logo-layers--transparent-top.png +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/agentwire-splash-logo-layers--transparent.png +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/agentwire-splash-logo-layers--tree.png +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/agentwire-splash-logo-layers.png +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/announcements.json +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/css/mobile.css +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/favicon.png +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/machines/android.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/machines/automaton.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/machines/bot.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/machines/cyborg.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/machines/droid.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/machines/drone.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/machines/guardian.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/machines/mech.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/machines/probe.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/machines/robot.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/machines/sentinel.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/machines/unit.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/projects/blob.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/projects/cloud.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/projects/crystal.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/projects/cyclops.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/projects/flame.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/projects/fuzzy.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/projects/horned.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/projects/moon.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/projects/slime.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/projects/star.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/projects/tentacle.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/projects/winged.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/sessions/bear.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/sessions/cat.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/sessions/crown.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/sessions/custom/agentwire-portal.png +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/sessions/custom/agentwire-tts.png +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/sessions/custom/agentwire.png +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/sessions/deer.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/sessions/drone.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/sessions/eagle.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/sessions/fox.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/sessions/hawk.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/sessions/horse.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/sessions/lion.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/sessions/rabbit.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/sessions/robot.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/sessions/tiger.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/icons/sessions/wolf.jpeg +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/.gitkeep +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/announcement-modal.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/api.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/artifact-window.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/collage.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/command-palette.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/components/icon-picker.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/components/list-card.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/components/type-tag.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/council-window.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/dead-key-suppressor.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/desktop-manager.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/desktop.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/icon-manager.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/mobile.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/notification-prefs.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/notifications-panel.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/scratchpad.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/service-classification.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/session-id.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/session-window.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/sidebar/artifacts-section.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/sidebar/config-section.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/sidebar/council-section.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/sidebar/machines-section.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/sidebar/projects-section.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/sidebar/scheduler-section.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/sidebar/services-section.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/sidebar.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/terminal-font-prefs.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/tile-manager.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/toast.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/utils/ansi.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/utils/auto-refresh.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/utils/swipe.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/voice/autosend-prefs.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/voice/browser-stt.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/voice/browser-tts.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/voice/jargon.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/voice/prompt.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/static/js/winbox.bundle.min.js +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/stt/__init__.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/stt/base.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/stt/cloud.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/stt/engine.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/stt/local.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/stt/server_backend.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/stt/stt_server.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tasks.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/templates/__init__.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/templates/base.html +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/templates/desktop.html +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/templates/email_notification.html +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/templates/handoff/show-the-story.html.j2 +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/templates/handoff/theme.css.j2 +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/templates/mobile.html +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/templates/tmux.conf +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/templating.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tooldefs/aws.yaml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tooldefs/docker.yaml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tooldefs/gcp.yaml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tooldefs/gh.yaml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tooldefs/git.yaml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tooldefs/gws.yaml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tooldefs/kubectl.yaml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tooldefs/npm.yaml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tooldefs/terraform.yaml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tooldefs/uv.yaml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tts/__init__.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tts/audio.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tts/base.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tts/engines/__init__.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tts/engines/chatterbox.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tts/engines/kokoro.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tts/engines/qwen_base.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tts/engines/qwen_custom.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tts/engines/qwen_design.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tts/engines/zonos.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tts/kokoro_server.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tts/local.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tts/registry.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tts_server.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/tunnels.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/usage_limit.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/utils/__init__.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/utils/chunker.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/utils/file_io.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/utils/paths.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/utils/speech.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/utils/subprocess.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/validation.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/voice_status.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/voiceclone.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/voices/darren.wav +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/voices/default.wav +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/voices/jessica.wav +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/voices/lisa.wav +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/voices/may.wav +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/wiki_audit.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/worktree.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/agentwire/worktree_registry.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/decisions/obsidian-second-brain.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/logo.png +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/architecture.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/briefing-mode.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/communication/channels.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/communication/hammerspoon.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/communication/handoff.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/concepts.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/council.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/deployment/remote-machines.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/glossary.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/integrations/gws-google-workspace-cli.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/internals/portal.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/internals/shell-escaping.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/internals/troubleshooting.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/internals/window-collage.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/quickstart.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/research/briefing-mode-feasibility.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/research/orchestration-transport-alternatives.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/security/secrets.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/services.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/sessions/claude-code-auto-mode.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/sessions/messaging.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/sessions/pi.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/sessions/prompt-routing.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/sessions/window-sizing.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/sessions/worktree-sessions.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/usage-limit-recovery.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/voice/shim-contract.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/voice/stt-cloud.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/voice/stt-self-hosted.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/docs/wiki/voice/tts-self-hosted.md +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/requirements-tts.txt +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/e2e/test_portal_ui.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/fixtures/sample_agentwire.yml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/fixtures/sample_config.yaml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/fixtures/sample_scheduler.yaml +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/integration/test_council_portal.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/integration/test_server_websockets.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/integration/test_worktree_cmd.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_announcements.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_build_agent_command.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_channels.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_cli_commands.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_cli_output.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_cli_safety.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_config.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_council_cli.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_council_inbox.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_council_state.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_council_view.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_doctor_voice.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_file_io.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_handoff_git_state.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_handoff_instructions.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_handoff_parser.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_handoff_renderer.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_history.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_hooks_install.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_idle_handler.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_inbox.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_locking.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_mcp_server.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_mcp_tools_args.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_msg_cli.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_project_config.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_prompt_router.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_roles.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_safety_disabled_rules.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_safety_escape_hatch.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_safety_kill_switch.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_scheduler.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_scheduler_parsing.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_scratchpad.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_server_async.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_server_pure.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_services.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_session_ready.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_speech_tags.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_ssh.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_stt_backend.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_stt_cloud.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_stt_engine.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_task_cli.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_tasks.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_templating.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_terminal_resize.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_tmux_template.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_tts_engine_resolution.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_tts_local.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_usage_limit.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_validation.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_voice_status.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_wiki_audit.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_worktree.py +0 -0
- {agentwire_dev-1.43.0 → agentwire_dev-1.44.0}/tests/unit/test_worktree_registry.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agentwire-dev
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.44.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
|
|
@@ -694,6 +694,7 @@ Requires-Dist: mcp>=1.2.0
|
|
|
694
694
|
Requires-Dist: pydantic>=2.0.0
|
|
695
695
|
Requires-Dist: python-dotenv>=1.0.0
|
|
696
696
|
Requires-Dist: pyyaml>=6.0
|
|
697
|
+
Requires-Dist: qrcode>=7.4
|
|
697
698
|
Requires-Dist: requests>=2.28.0
|
|
698
699
|
Requires-Dist: resend>=2.0.0
|
|
699
700
|
Requires-Dist: useful-moonshine-onnx>=20250101; python_version < '3.14'
|
|
@@ -820,9 +820,6 @@ def _start_portal_local(args, attach: bool = True) -> int:
|
|
|
820
820
|
When attach is False (used by `agentwire up`), the portal is started
|
|
821
821
|
detached and we return without attaching.
|
|
822
822
|
"""
|
|
823
|
-
from .network import NetworkContext
|
|
824
|
-
from .tunnels import TunnelManager
|
|
825
|
-
|
|
826
823
|
session_name = get_portal_session_name()
|
|
827
824
|
|
|
828
825
|
if tmux_session_exists(session_name):
|
|
@@ -832,31 +829,10 @@ def _start_portal_local(args, attach: bool = True) -> int:
|
|
|
832
829
|
subprocess.run(["tmux", "attach-session", "-t", session_name])
|
|
833
830
|
return 0
|
|
834
831
|
|
|
835
|
-
#
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
if required_tunnels:
|
|
840
|
-
print("Ensuring tunnels to remote services...")
|
|
841
|
-
tm = TunnelManager()
|
|
842
|
-
|
|
843
|
-
for spec in required_tunnels:
|
|
844
|
-
status = tm.check_tunnel(spec)
|
|
845
|
-
|
|
846
|
-
if status.status == "up":
|
|
847
|
-
print(f" [ok] {spec.remote_machine}:{spec.remote_port} (already up)")
|
|
848
|
-
else:
|
|
849
|
-
print(f" [..] Creating tunnel to {spec.remote_machine}:{spec.remote_port}...", end=" ", flush=True)
|
|
850
|
-
result = tm.create_tunnel(spec, ctx)
|
|
851
|
-
|
|
852
|
-
if result.status == "up":
|
|
853
|
-
print("[ok]")
|
|
854
|
-
else:
|
|
855
|
-
print("[!!]")
|
|
856
|
-
print(f" Warning: Could not create tunnel: {result.error}")
|
|
857
|
-
print(f" The portal may not be able to reach {spec.remote_machine}.")
|
|
858
|
-
|
|
859
|
-
print()
|
|
832
|
+
# No tunnel auto-spawn (#420): agentwire owns only the local portal
|
|
833
|
+
# boundary. Reaching the portal from elsewhere is bring-your-own
|
|
834
|
+
# (cloudflared/tailscale/ssh -L), and `agentwire tunnels *` remains as an
|
|
835
|
+
# opt-in manual helper for the vestigial remote-service-split case.
|
|
860
836
|
|
|
861
837
|
# Build the server command
|
|
862
838
|
# --dev runs from source with uv run (picks up code changes immediately)
|
|
@@ -1224,6 +1200,80 @@ def cmd_portal_token(args) -> int:
|
|
|
1224
1200
|
return 0
|
|
1225
1201
|
|
|
1226
1202
|
|
|
1203
|
+
def cmd_portal_pair(args) -> int:
|
|
1204
|
+
"""Create a short-lived pairing code (+ QR) for a new device."""
|
|
1205
|
+
from .devices import PAIRING_TTL_SECONDS, create_pairing
|
|
1206
|
+
|
|
1207
|
+
pairing = create_pairing(name=getattr(args, "name", None) or "device")
|
|
1208
|
+
|
|
1209
|
+
portal_url = _default_portal_url()
|
|
1210
|
+
pair_url = f"{portal_url}/pair?code={pairing.code}"
|
|
1211
|
+
ttl_min = PAIRING_TTL_SECONDS // 60
|
|
1212
|
+
|
|
1213
|
+
print(f"Pairing code: {pairing.code}")
|
|
1214
|
+
print(f" Name: {pairing.name}")
|
|
1215
|
+
print(f" Expires in {ttl_min} minutes.")
|
|
1216
|
+
print()
|
|
1217
|
+
print("On the device, open:")
|
|
1218
|
+
print(f" {pair_url}")
|
|
1219
|
+
print("or visit", f"{portal_url}/pair", "and enter the code.")
|
|
1220
|
+
print()
|
|
1221
|
+
|
|
1222
|
+
try:
|
|
1223
|
+
import qrcode # type: ignore
|
|
1224
|
+
|
|
1225
|
+
qr = qrcode.QRCode(border=1)
|
|
1226
|
+
qr.add_data(pair_url)
|
|
1227
|
+
qr.make()
|
|
1228
|
+
qr.print_ascii(invert=True)
|
|
1229
|
+
except Exception:
|
|
1230
|
+
print("(install `qrcode` to render a scannable QR here)")
|
|
1231
|
+
|
|
1232
|
+
return 0
|
|
1233
|
+
|
|
1234
|
+
|
|
1235
|
+
def cmd_portal_devices(args) -> int:
|
|
1236
|
+
"""List paired portal devices."""
|
|
1237
|
+
from .devices import DeviceRegistry
|
|
1238
|
+
|
|
1239
|
+
registry = DeviceRegistry.load()
|
|
1240
|
+
json_mode = getattr(args, "json", False)
|
|
1241
|
+
|
|
1242
|
+
if json_mode:
|
|
1243
|
+
_output_json({"success": True, "devices": [d.public() for d in registry.devices]})
|
|
1244
|
+
return 0
|
|
1245
|
+
|
|
1246
|
+
if not registry.devices:
|
|
1247
|
+
print("No paired devices. The host bootstrap token (agentwire portal token)")
|
|
1248
|
+
print("is the only credential. Add one with: agentwire portal pair")
|
|
1249
|
+
return 0
|
|
1250
|
+
|
|
1251
|
+
print(f"{'ID':<14}{'NAME':<24}{'LAST SEEN':<22}STATUS")
|
|
1252
|
+
for d in registry.devices:
|
|
1253
|
+
status = "revoked" if d.revoked else "active"
|
|
1254
|
+
print(
|
|
1255
|
+
f"{d.id:<14}{(d.name or '')[:23]:<24}"
|
|
1256
|
+
f"{(d.last_seen or 'never'):<22}{status}"
|
|
1257
|
+
)
|
|
1258
|
+
return 0
|
|
1259
|
+
|
|
1260
|
+
|
|
1261
|
+
def cmd_portal_revoke(args) -> int:
|
|
1262
|
+
"""Revoke one paired device without affecting the others."""
|
|
1263
|
+
from .devices import DeviceRegistry
|
|
1264
|
+
|
|
1265
|
+
registry = DeviceRegistry.load()
|
|
1266
|
+
if registry.revoke(args.device_id):
|
|
1267
|
+
print(f"Revoked device '{args.device_id}'. It now gets 401 on every route.")
|
|
1268
|
+
return 0
|
|
1269
|
+
print(
|
|
1270
|
+
f"No active device with id '{args.device_id}'. "
|
|
1271
|
+
"List them with: agentwire portal devices",
|
|
1272
|
+
file=sys.stderr,
|
|
1273
|
+
)
|
|
1274
|
+
return 1
|
|
1275
|
+
|
|
1276
|
+
|
|
1227
1277
|
def cmd_portal_restart(args) -> int:
|
|
1228
1278
|
"""Restart the AgentWire portal (stop + start)."""
|
|
1229
1279
|
import time
|
|
@@ -3005,6 +3055,30 @@ def _record_session_creator(session_name: str, created_by: str | None, via: str)
|
|
|
3005
3055
|
store_session_metadata(session_name, metadata)
|
|
3006
3056
|
|
|
3007
3057
|
|
|
3058
|
+
def _display_parent(session_name: str, path: str = "") -> "str | None":
|
|
3059
|
+
"""The session that should visually own this one in the sidebar.
|
|
3060
|
+
|
|
3061
|
+
Display-only relationship (powers sidebar nesting, issue #448) — NOT a
|
|
3062
|
+
lifecycle coupling. Mirrors prompt_router.resolve_parent's precedence for
|
|
3063
|
+
pane-0 sessions, minus the liveness check (the sidebar decides whether to
|
|
3064
|
+
nest based on whether the parent is actually in the list):
|
|
3065
|
+
1. Creator recorded at `agentwire new` time (session metadata).
|
|
3066
|
+
2. `.agentwire.yml` `parent:` field (from the session's path).
|
|
3067
|
+
Returns None for top-level sessions (no recorded parent).
|
|
3068
|
+
"""
|
|
3069
|
+
bare = session_name.split("@")[0]
|
|
3070
|
+
creator = load_session_metadata(bare).get("created_by")
|
|
3071
|
+
if isinstance(creator, str) and creator and creator != bare:
|
|
3072
|
+
return creator
|
|
3073
|
+
try:
|
|
3074
|
+
parent = get_parent_from_config(Path(path) if path else None)
|
|
3075
|
+
except Exception:
|
|
3076
|
+
parent = None
|
|
3077
|
+
if parent and parent != bare:
|
|
3078
|
+
return parent
|
|
3079
|
+
return None
|
|
3080
|
+
|
|
3081
|
+
|
|
3008
3082
|
def cmd_notify(args) -> int:
|
|
3009
3083
|
"""Send a notification to the portal about session/pane state changes.
|
|
3010
3084
|
|
|
@@ -3347,6 +3421,7 @@ def cmd_list(args) -> int:
|
|
|
3347
3421
|
"machine": None,
|
|
3348
3422
|
"type": cfg.get("type"),
|
|
3349
3423
|
"roles": cfg.get("roles", []),
|
|
3424
|
+
"parent": _display_parent(parts[0], path),
|
|
3350
3425
|
}
|
|
3351
3426
|
if usage_limit_parked(parts[0]):
|
|
3352
3427
|
session_info["usage_limit"] = True
|
|
@@ -6248,8 +6323,11 @@ def cmd_machine_add(args) -> int:
|
|
|
6248
6323
|
print()
|
|
6249
6324
|
print("Next steps:")
|
|
6250
6325
|
print(" 1. Ensure SSH access: ssh", f"{user}@{host}" if user else host)
|
|
6251
|
-
print(" 2.
|
|
6252
|
-
print(
|
|
6326
|
+
print(" 2. Restart portal: agentwire portal stop && agentwire portal start")
|
|
6327
|
+
print()
|
|
6328
|
+
print("Remote session management uses plain SSH — no tunnel needed. To reach")
|
|
6329
|
+
print("the portal from another network, bring your own tunnel (cloudflared/")
|
|
6330
|
+
print("tailscale); see docs/wiki/deployment/remote-access.md.")
|
|
6253
6331
|
print()
|
|
6254
6332
|
print("For full setup guide, run: /machine-setup in a Claude session")
|
|
6255
6333
|
|
|
@@ -6287,28 +6365,6 @@ def cmd_machine_remove(args) -> int:
|
|
|
6287
6365
|
print(f"Removing machine '{machine_id}' (host: {host})...")
|
|
6288
6366
|
print()
|
|
6289
6367
|
|
|
6290
|
-
# Step 2: Kill autossh tunnel
|
|
6291
|
-
print("Stopping tunnel...")
|
|
6292
|
-
result = subprocess.run(
|
|
6293
|
-
["pkill", "-f", f"autossh.*{machine_id}"],
|
|
6294
|
-
capture_output=True,
|
|
6295
|
-
)
|
|
6296
|
-
if result.returncode == 0:
|
|
6297
|
-
print(f" ✓ Killed autossh tunnel for {machine_id}")
|
|
6298
|
-
else:
|
|
6299
|
-
# Also try by host if different from id
|
|
6300
|
-
if host != machine_id:
|
|
6301
|
-
result = subprocess.run(
|
|
6302
|
-
["pkill", "-f", f"autossh.*{host}"],
|
|
6303
|
-
capture_output=True,
|
|
6304
|
-
)
|
|
6305
|
-
if result.returncode == 0:
|
|
6306
|
-
print(f" ✓ Killed autossh tunnel for {host}")
|
|
6307
|
-
else:
|
|
6308
|
-
print(" - No tunnel running (or already stopped)")
|
|
6309
|
-
else:
|
|
6310
|
-
print(" - No tunnel running (or already stopped)")
|
|
6311
|
-
|
|
6312
6368
|
# Step 3: Remove from machines.json
|
|
6313
6369
|
print("Updating machines.json...")
|
|
6314
6370
|
machines_data["machines"] = [m for m in machines if m.get("id") != machine_id]
|
|
@@ -6326,21 +6382,17 @@ def cmd_machine_remove(args) -> int:
|
|
|
6326
6382
|
print("1. Remove SSH config entry:")
|
|
6327
6383
|
print(f" Edit ~/.ssh/config and remove the 'Host {machine_id}' block")
|
|
6328
6384
|
print()
|
|
6329
|
-
print("2.
|
|
6330
|
-
print(" Edit ~/.local/bin/agentwire-tunnels")
|
|
6331
|
-
print(f" Remove '{machine_id}' from the MACHINES list")
|
|
6332
|
-
print()
|
|
6333
|
-
print("3. Delete GitHub deploy keys:")
|
|
6385
|
+
print("2. Delete GitHub deploy keys:")
|
|
6334
6386
|
print(" gh repo deploy-key list --repo <user>/<repo>")
|
|
6335
6387
|
print(f" # Find keys titled '{machine_id}' and delete them:")
|
|
6336
6388
|
print(" gh repo deploy-key delete <key-id> --repo <user>/<repo>")
|
|
6337
6389
|
print()
|
|
6338
|
-
print("
|
|
6390
|
+
print("3. Destroy remote machine:")
|
|
6339
6391
|
print(" Option A: Delete user only")
|
|
6340
6392
|
print(" ssh root@<ip> 'pkill -u agentwire; userdel -r agentwire'")
|
|
6341
6393
|
print(" Option B: Destroy the VM entirely via provider console")
|
|
6342
6394
|
print()
|
|
6343
|
-
print("
|
|
6395
|
+
print("4. Restart portal to pick up changes:")
|
|
6344
6396
|
print(" agentwire portal stop && agentwire portal start")
|
|
6345
6397
|
print()
|
|
6346
6398
|
|
|
@@ -7062,7 +7114,7 @@ def cmd_safety_logs(args) -> int:
|
|
|
7062
7114
|
|
|
7063
7115
|
def cmd_safety_install(args) -> int:
|
|
7064
7116
|
"""CLI command: agentwire safety install"""
|
|
7065
|
-
return cli_safety.safety_install_cmd()
|
|
7117
|
+
return cli_safety.safety_install_cmd(assume_yes=getattr(args, "yes", False))
|
|
7066
7118
|
|
|
7067
7119
|
|
|
7068
7120
|
def cmd_safety_tooldefs_list(args) -> int:
|
|
@@ -7075,6 +7127,79 @@ def cmd_safety_tooldefs_show(args) -> int:
|
|
|
7075
7127
|
return cli_safety.safety_tooldefs_show_cmd(args.tool)
|
|
7076
7128
|
|
|
7077
7129
|
|
|
7130
|
+
def _render_damage_control_section() -> int:
|
|
7131
|
+
"""Print the damage-control health block. Returns the count of issues found.
|
|
7132
|
+
|
|
7133
|
+
Covers the four #462 blind spots plus DC hook staleness: the global kill
|
|
7134
|
+
switch (``safety.enabled: false``), installed-rules drift vs the bundled
|
|
7135
|
+
rules, PreToolUse matcher registration, and DC hook-script staleness.
|
|
7136
|
+
"""
|
|
7137
|
+
issues = 0
|
|
7138
|
+
|
|
7139
|
+
# Kill switch — config.safety.enabled gates ALL damage control. A silent
|
|
7140
|
+
# `false` is the loudest possible failure, so flag it first and hard.
|
|
7141
|
+
try:
|
|
7142
|
+
from .config import load_config as _load_config_typed
|
|
7143
|
+
safety_enabled = _load_config_typed().safety.enabled
|
|
7144
|
+
except Exception as e:
|
|
7145
|
+
print(f" [..] Could not read safety config: {e}")
|
|
7146
|
+
safety_enabled = True
|
|
7147
|
+
if not safety_enabled:
|
|
7148
|
+
print(" [!!] Damage control is DISABLED (safety.enabled: false)")
|
|
7149
|
+
print(" ALL command/path/outbound gating is off.")
|
|
7150
|
+
print(" Fix: set safety.enabled: true in ~/.agentwire/config.yaml")
|
|
7151
|
+
issues += 1
|
|
7152
|
+
else:
|
|
7153
|
+
print(" [ok] Damage control enabled (safety.enabled: true)")
|
|
7154
|
+
|
|
7155
|
+
try:
|
|
7156
|
+
from . import cli_safety
|
|
7157
|
+
except Exception as e:
|
|
7158
|
+
print(f" [..] Could not load safety module: {e}")
|
|
7159
|
+
return issues
|
|
7160
|
+
|
|
7161
|
+
# DC hook-script staleness (bash/edit/write/mcp-tool + audit_logger).
|
|
7162
|
+
hook_drift = cli_safety.damage_control_hook_drift()
|
|
7163
|
+
stale_hooks = [f for f, s in hook_drift.items() if s == "stale"]
|
|
7164
|
+
missing_hooks = [f for f, s in hook_drift.items() if s == "missing"]
|
|
7165
|
+
if stale_hooks or missing_hooks:
|
|
7166
|
+
if missing_hooks:
|
|
7167
|
+
print(f" [!!] DC hook scripts missing: {', '.join(sorted(missing_hooks))}")
|
|
7168
|
+
if stale_hooks:
|
|
7169
|
+
print(f" [!!] DC hook scripts STALE: {', '.join(sorted(stale_hooks))}")
|
|
7170
|
+
print(" Fix: agentwire safety install --yes")
|
|
7171
|
+
issues += 1
|
|
7172
|
+
else:
|
|
7173
|
+
print(" [ok] DC hook scripts current")
|
|
7174
|
+
|
|
7175
|
+
# Installed-rules drift vs bundled rules (the incident's missing files).
|
|
7176
|
+
rule_drift = cli_safety.rules_drift()
|
|
7177
|
+
missing_rules = [f for f, s in rule_drift.items() if s == "missing"]
|
|
7178
|
+
stale_rules = [f for f, s in rule_drift.items() if s == "stale"]
|
|
7179
|
+
if missing_rules:
|
|
7180
|
+
print(f" [!!] Damage-control rules NOT installed: {', '.join(sorted(missing_rules))}")
|
|
7181
|
+
print(" Fix: agentwire safety install --yes")
|
|
7182
|
+
issues += 1
|
|
7183
|
+
elif stale_rules:
|
|
7184
|
+
# Stale = installed copy differs from bundled. Could be an intentional
|
|
7185
|
+
# customization, so warn (not error) and don't auto-overwrite.
|
|
7186
|
+
print(f" [..] Damage-control rules differ from bundled: {', '.join(sorted(stale_rules))}")
|
|
7187
|
+
print(" (customized? `agentwire safety install --yes` leaves these untouched)")
|
|
7188
|
+
else:
|
|
7189
|
+
print(" [ok] Damage-control rules installed and match bundled")
|
|
7190
|
+
|
|
7191
|
+
# Matcher presence in ~/.claude/settings.json.
|
|
7192
|
+
missing_matchers = cli_safety.missing_damage_control_matchers()
|
|
7193
|
+
if missing_matchers:
|
|
7194
|
+
print(f" [!!] PreToolUse matchers not registered: {', '.join(missing_matchers)}")
|
|
7195
|
+
print(" Fix: agentwire safety install --yes")
|
|
7196
|
+
issues += 1
|
|
7197
|
+
else:
|
|
7198
|
+
print(" [ok] PreToolUse damage-control matchers registered")
|
|
7199
|
+
|
|
7200
|
+
return issues
|
|
7201
|
+
|
|
7202
|
+
|
|
7078
7203
|
def _render_voice_loop_section(config, ctx) -> int:
|
|
7079
7204
|
"""Print the voice-loop (push-to-talk) preflight. Returns failures found.
|
|
7080
7205
|
|
|
@@ -7256,6 +7381,36 @@ def cmd_doctor(args) -> int:
|
|
|
7256
7381
|
print(f" [..] {label}: not found ({why})")
|
|
7257
7382
|
print(" Run: agentwire hooks install")
|
|
7258
7383
|
|
|
7384
|
+
# 4b. Damage control (safety) — the kill switch, install drift, and the
|
|
7385
|
+
# PreToolUse matcher registration. The #462 incident: a global disable and
|
|
7386
|
+
# missing rule files were both invisible to every diagnostic.
|
|
7387
|
+
print("\nChecking damage control (safety)...")
|
|
7388
|
+
issues_found += _render_damage_control_section()
|
|
7389
|
+
|
|
7390
|
+
# 4c. Local checkout vs origin/main — rebuild reinstalls whatever is checked
|
|
7391
|
+
# out, so a never-pulled main silently ships stale code. Today only worktree
|
|
7392
|
+
# creation fetches; surface the drift here too.
|
|
7393
|
+
print("\nChecking source checkout...")
|
|
7394
|
+
src_root = Path(__file__).parent.parent
|
|
7395
|
+
if not (src_root / "pyproject.toml").exists():
|
|
7396
|
+
try:
|
|
7397
|
+
src_root = get_source_dir()
|
|
7398
|
+
except Exception:
|
|
7399
|
+
src_root = None
|
|
7400
|
+
if src_root is None:
|
|
7401
|
+
print(" [..] Could not locate source checkout — skipping git-drift check")
|
|
7402
|
+
else:
|
|
7403
|
+
behind, err = _git_behind_origin(src_root)
|
|
7404
|
+
if err:
|
|
7405
|
+
print(f" [..] Source checkout: skipped git-drift check ({err})")
|
|
7406
|
+
elif behind and behind > 0:
|
|
7407
|
+
print(f" [!!] Local main is {behind} commit(s) behind origin/main")
|
|
7408
|
+
print(f" {src_root}")
|
|
7409
|
+
print(" Fix: git pull --ff-only (then agentwire rebuild)")
|
|
7410
|
+
issues_found += 1
|
|
7411
|
+
else:
|
|
7412
|
+
print(" [ok] Local main up to date with origin/main")
|
|
7413
|
+
|
|
7259
7414
|
# Check custom services (registry-driven: built-in notifications bridge
|
|
7260
7415
|
# + user-defined services from services.custom)
|
|
7261
7416
|
print("\nChecking custom services...")
|
|
@@ -7653,15 +7808,70 @@ def cmd_voiceclone_delete(args) -> int:
|
|
|
7653
7808
|
UV_CACHE_DIR = Path.home() / ".cache" / "uv"
|
|
7654
7809
|
|
|
7655
7810
|
|
|
7811
|
+
def _git_behind_origin(repo: Path, base: str = "main", do_fetch: bool = True):
|
|
7812
|
+
"""How many commits ``origin/<base>`` is ahead of the checkout's HEAD.
|
|
7813
|
+
|
|
7814
|
+
Returns ``(behind, error)``: ``behind`` is the commit count (0 = up to date),
|
|
7815
|
+
or ``None`` with a human-readable ``error`` string when the comparison can't
|
|
7816
|
+
be made (not a git repo, no remote, offline fetch failure, etc.).
|
|
7817
|
+
"""
|
|
7818
|
+
if not (repo / ".git").exists():
|
|
7819
|
+
return None, "not a git checkout"
|
|
7820
|
+
if do_fetch:
|
|
7821
|
+
fetch = subprocess.run(
|
|
7822
|
+
["git", "fetch", "origin", base],
|
|
7823
|
+
cwd=repo, capture_output=True, text=True,
|
|
7824
|
+
)
|
|
7825
|
+
if fetch.returncode != 0:
|
|
7826
|
+
return None, (fetch.stderr or fetch.stdout or "git fetch failed").strip()
|
|
7827
|
+
count = subprocess.run(
|
|
7828
|
+
["git", "rev-list", "--count", f"HEAD..origin/{base}"],
|
|
7829
|
+
cwd=repo, capture_output=True, text=True,
|
|
7830
|
+
)
|
|
7831
|
+
if count.returncode != 0:
|
|
7832
|
+
return None, (count.stderr or count.stdout or "git rev-list failed").strip()
|
|
7833
|
+
try:
|
|
7834
|
+
return int(count.stdout.strip()), None
|
|
7835
|
+
except ValueError:
|
|
7836
|
+
return None, f"unexpected rev-list output: {count.stdout.strip()!r}"
|
|
7837
|
+
|
|
7838
|
+
|
|
7656
7839
|
def cmd_rebuild(args) -> int:
|
|
7657
7840
|
"""Rebuild: clear uv cache, uninstall, reinstall from source.
|
|
7658
7841
|
|
|
7659
7842
|
This is the correct way to pick up source changes when developing.
|
|
7660
7843
|
`uv tool install . --force` does NOT work - it uses cached wheels.
|
|
7661
7844
|
"""
|
|
7845
|
+
force = getattr(args, "force", False)
|
|
7846
|
+
|
|
7662
7847
|
print("Rebuilding agentwire-dev...")
|
|
7663
7848
|
print()
|
|
7664
7849
|
|
|
7850
|
+
# Resolve the source checkout up front so the git-drift guard and the
|
|
7851
|
+
# install step agree on which tree they're operating over.
|
|
7852
|
+
project_root = Path(__file__).parent.parent
|
|
7853
|
+
if not (project_root / "pyproject.toml").exists():
|
|
7854
|
+
project_root = get_source_dir()
|
|
7855
|
+
|
|
7856
|
+
# Git-drift guard: rebuild is otherwise git-blind and will happily reinstall
|
|
7857
|
+
# stale code when local main was never pulled after a remote merge. Refuse
|
|
7858
|
+
# (unless --force) so the fix happens before the reinstall, not after.
|
|
7859
|
+
behind, err = _git_behind_origin(project_root)
|
|
7860
|
+
if err:
|
|
7861
|
+
print(f" - Skipping git-drift check ({err})")
|
|
7862
|
+
elif behind and behind > 0:
|
|
7863
|
+
print(f" [!!] Local checkout is {behind} commit(s) behind origin/main.")
|
|
7864
|
+
print(f" {project_root}")
|
|
7865
|
+
print(" Rebuild would reinstall stale code. Run first:")
|
|
7866
|
+
print(" git pull --ff-only")
|
|
7867
|
+
if not force:
|
|
7868
|
+
print(" (or re-run with --force to rebuild anyway)")
|
|
7869
|
+
return 1
|
|
7870
|
+
print(" --force given: rebuilding from the behind checkout anyway.")
|
|
7871
|
+
else:
|
|
7872
|
+
print(" ✓ Checkout up to date with origin/main")
|
|
7873
|
+
print()
|
|
7874
|
+
|
|
7665
7875
|
# Step 1: Clear uv cache
|
|
7666
7876
|
if UV_CACHE_DIR.exists():
|
|
7667
7877
|
print(f"Clearing uv cache ({UV_CACHE_DIR})...")
|
|
@@ -7683,13 +7893,7 @@ def cmd_rebuild(args) -> int:
|
|
|
7683
7893
|
# Might not be installed, that's fine
|
|
7684
7894
|
print(" - Not installed (continuing)")
|
|
7685
7895
|
|
|
7686
|
-
# Step 3: Reinstall from
|
|
7687
|
-
# Find the project root (where pyproject.toml is)
|
|
7688
|
-
project_root = Path(__file__).parent.parent
|
|
7689
|
-
if not (project_root / "pyproject.toml").exists():
|
|
7690
|
-
# Fallback to configured source directory
|
|
7691
|
-
project_root = get_source_dir()
|
|
7692
|
-
|
|
7896
|
+
# Step 3: Reinstall from the source checkout resolved above.
|
|
7693
7897
|
print(f"Installing from {project_root}...")
|
|
7694
7898
|
result = subprocess.run(
|
|
7695
7899
|
["uv", "tool", "install", "."],
|
|
@@ -8527,6 +8731,17 @@ def install_hooks(force: bool = False, copy: bool = False) -> dict[str, str]:
|
|
|
8527
8731
|
if event:
|
|
8528
8732
|
register_hook_in_settings(event, hook_name)
|
|
8529
8733
|
|
|
8734
|
+
# Heal the full damage-control surface (hook scripts + rules + tooldefs +
|
|
8735
|
+
# PreToolUse matchers), not just the settings.json matchers. This closes the
|
|
8736
|
+
# documented post-rebuild gap: CLAUDE.md tells users to re-run `hooks install`
|
|
8737
|
+
# after a rebuild, so it must actually sync the DC files/rules — drift-aware,
|
|
8738
|
+
# never clobbering a customized rule.
|
|
8739
|
+
try:
|
|
8740
|
+
from agentwire.cli_safety import heal_damage_control
|
|
8741
|
+
heal_damage_control(quiet=True)
|
|
8742
|
+
except Exception:
|
|
8743
|
+
pass
|
|
8744
|
+
|
|
8530
8745
|
return results
|
|
8531
8746
|
|
|
8532
8747
|
|
|
@@ -10258,8 +10473,18 @@ def _set_task_enabled(name: str, enabled: bool) -> int:
|
|
|
10258
10473
|
|
|
10259
10474
|
tasks[name]["enabled"] = enabled
|
|
10260
10475
|
|
|
10261
|
-
|
|
10262
|
-
|
|
10476
|
+
# Atomic + validated write — never leave scheduler.yaml half-written (#449).
|
|
10477
|
+
from .scheduler import _atomic_write
|
|
10478
|
+
|
|
10479
|
+
text = yaml.dump(raw, default_flow_style=False, sort_keys=False)
|
|
10480
|
+
|
|
10481
|
+
def _validate(tmp_path: str) -> None:
|
|
10482
|
+
with open(tmp_path) as f:
|
|
10483
|
+
reparsed = yaml.safe_load(f)
|
|
10484
|
+
if not isinstance(reparsed, dict) or "tasks" not in reparsed:
|
|
10485
|
+
raise ValueError("scheduler board failed re-parse validation")
|
|
10486
|
+
|
|
10487
|
+
_atomic_write(board_path, text, validate=_validate)
|
|
10263
10488
|
|
|
10264
10489
|
action = "Enabled" if enabled else "Disabled"
|
|
10265
10490
|
print(f"{action}: {name}")
|
|
@@ -10929,6 +11154,27 @@ def main() -> int:
|
|
|
10929
11154
|
)
|
|
10930
11155
|
portal_token.set_defaults(func=cmd_portal_token)
|
|
10931
11156
|
|
|
11157
|
+
# portal pair — mint a pairing code (+QR) for a new device
|
|
11158
|
+
portal_pair = portal_subparsers.add_parser(
|
|
11159
|
+
"pair", help="Pair a new device (prints a short-lived code + QR)"
|
|
11160
|
+
)
|
|
11161
|
+
portal_pair.add_argument("--name", help="Friendly device name (e.g. 'phone')")
|
|
11162
|
+
portal_pair.set_defaults(func=cmd_portal_pair)
|
|
11163
|
+
|
|
11164
|
+
# portal devices — list paired devices
|
|
11165
|
+
portal_devices = portal_subparsers.add_parser(
|
|
11166
|
+
"devices", help="List paired portal devices"
|
|
11167
|
+
)
|
|
11168
|
+
portal_devices.add_argument("--json", action="store_true", help="Output JSON")
|
|
11169
|
+
portal_devices.set_defaults(func=cmd_portal_devices)
|
|
11170
|
+
|
|
11171
|
+
# portal revoke — revoke one device
|
|
11172
|
+
portal_revoke = portal_subparsers.add_parser(
|
|
11173
|
+
"revoke", help="Revoke one paired device by id"
|
|
11174
|
+
)
|
|
11175
|
+
portal_revoke.add_argument("device_id", help="Device id (see `portal devices`)")
|
|
11176
|
+
portal_revoke.set_defaults(func=cmd_portal_revoke)
|
|
11177
|
+
|
|
10932
11178
|
# === tts command group ===
|
|
10933
11179
|
tts_parser = subparsers.add_parser("tts", help="Manage TTS server")
|
|
10934
11180
|
tts_subparsers = tts_parser.add_subparsers(dest="tts_command")
|
|
@@ -11690,7 +11936,12 @@ def main() -> int:
|
|
|
11690
11936
|
|
|
11691
11937
|
# safety install
|
|
11692
11938
|
safety_install = safety_subparsers.add_parser(
|
|
11693
|
-
"install", help="Install damage control hooks
|
|
11939
|
+
"install", help="Install/heal damage control hooks, rules, and matchers"
|
|
11940
|
+
)
|
|
11941
|
+
safety_install.add_argument(
|
|
11942
|
+
"-y", "--yes", action="store_true",
|
|
11943
|
+
help="Non-interactive, drift-aware heal (install missing + update stale "
|
|
11944
|
+
"owned hooks; never clobbers existing rules)",
|
|
11694
11945
|
)
|
|
11695
11946
|
safety_install.set_defaults(func=cmd_safety_install)
|
|
11696
11947
|
|
|
@@ -11735,6 +11986,10 @@ def main() -> int:
|
|
|
11735
11986
|
rebuild_parser = subparsers.add_parser(
|
|
11736
11987
|
"rebuild", help="Clear uv cache and reinstall from source (for development)"
|
|
11737
11988
|
)
|
|
11989
|
+
rebuild_parser.add_argument(
|
|
11990
|
+
"--force", action="store_true",
|
|
11991
|
+
help="Rebuild even when the local checkout is behind origin/main",
|
|
11992
|
+
)
|
|
11738
11993
|
rebuild_parser.set_defaults(func=cmd_rebuild)
|
|
11739
11994
|
|
|
11740
11995
|
# === uninstall command ===
|