agentwire-dev 1.63.0__tar.gz → 1.64.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.63.0 → agentwire_dev-1.64.0}/PKG-INFO +1 -1
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/__init__.py +1 -1
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/config.py +10 -2
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/doctor_cli.py +78 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/bash-tool-damage-control.py +3 -2
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/edit-tool-damage-control.py +3 -2
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/mcp-tool-damage-control.py +3 -2
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/read-tool-damage-control.py +3 -2
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/write-tool-damage-control.py +3 -2
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/safety/_core.py +3 -2
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/scheduler/gates.py +29 -6
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/scheduler/models.py +1 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/scheduler/report.py +2 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/scheduler/state.py +3 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/scheduler_cli.py +8 -2
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/css/desktop.css +124 -27
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/session-hud-controller.js +122 -10
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/session-hud.js +149 -20
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/sidebar/scheduler-section.js +6 -1
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/topology-render.js +105 -13
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/worktree.py +16 -5
- agentwire_dev-1.64.0/docs/design/session-card-fields.md +99 -0
- agentwire_dev-1.64.0/docs/design/session-card-recommendation.md +177 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/architecture.md +10 -7
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/communication/channels.md +3 -2
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/communication/handoff.md +2 -2
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/concepts.md +3 -1
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/deployment/remote-access.md +5 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/deployment/remote-machines.md +36 -31
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/glossary.md +6 -6
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/integrations/gws-google-workspace-cli.md +1 -1
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/internals/damage-control.md +29 -11
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/internals/portal.md +4 -2
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/internals/session-topology.md +1 -1
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/internals/shell-escaping.md +2 -2
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/internals/troubleshooting.md +2 -12
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/internals/window-collage.md +1 -1
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/research/orchestration-transport-alternatives.md +1 -1
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/scheduling/scheduled-workloads.md +4 -4
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/security/damage-control-hardening.md +7 -4
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/security/remote-access-hardening.md +30 -27
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/security/secrets.md +4 -5
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/sessions/claude-code-auto-mode.md +3 -7
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/sessions/prompt-routing.md +0 -1
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/voice/shim-contract.md +2 -2
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/voice/stt-self-hosted.md +28 -18
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/integration/test_scheduler_board.py +22 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_damage_control_hooks.py +29 -12
- agentwire_dev-1.64.0/tests/unit/test_doctor_scheduler_staleness.py +109 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_scheduler.py +83 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_worktree.py +27 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/.agentwire.yml.example +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/.claude/commands/handoff.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/.claude/skills/wiki/SKILL.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/.github/FUNDING.yml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/.github/workflows/pytest.yml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/.github/workflows/ruff.yml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/.github/workflows/security.yml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/.github/workflows/tts-smoke.yml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/.gitignore +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/AGENTS.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/CODE_OF_CONDUCT.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/CONTRIBUTING.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/Dockerfile.local +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/LICENSE +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/README.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/RELEASING.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/SECURITY.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/SPONSORS.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/__main__.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/agents/__init__.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/agents/base.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/agents/tmux.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/cached_status.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/channels/__init__.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/channels/base.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/channels/email.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/channels/push.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/channels/quo.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/channels_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/chrome_tabs.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/completion.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/config_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/core.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/council/__init__.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/council/cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/council/inbox.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/council/minutes.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/council/state.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/council/view.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/devices.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/diff_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/doctor_voice.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/ensure_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/fetch.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/handoff/__init__.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/handoff/git_state.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/handoff/instructions.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/handoff/parser.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/handoff/renderer.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/handoff/schema.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/handoff_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/history.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/history_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/__init__.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/agentwire-permission.sh +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/__init__.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/audit_logger.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/rules/agentwire.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/rules/aws.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/rules/cloud-hosting.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/rules/containers.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/rules/control-plane.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/rules/core.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/rules/databases.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/rules/firebase.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/rules/gcp.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/rules/git.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/rules/gws.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/rules/infrastructure.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/rules/outbound.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/rules/publish.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/damage-control/rules/remote.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/idle-handler.sh +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks/queue-processor.sh +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/hooks_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/inbox.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/limits_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/listen.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/locking.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/machine_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_channels.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_chrome.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_core.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_council.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_desktop.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_handoff.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_history.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_listen.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_lock.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_machine.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_msg.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_notify.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_pane.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_projects.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_scheduler.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_scratchpad.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_server.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_services.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_session.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_status.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_task.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_tunnels.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_voice.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_wiki.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/mcp_worktree.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/msg_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/network.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/notify_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/onboarding.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/palette_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/pane_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/pane_manager.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/portal_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/project_config.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/projects.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/prompt_router.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/prompts_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/push_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/push_store.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/repo_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/research.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/__init__.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/agentwire.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/anchor.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/chatbot.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/contributor.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/correspondent.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/council-brain.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/council-conscience.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/council-critic.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/council-devils-advocate.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/council-gut.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/council-historian.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/council-member.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/council-orchestrator.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/init.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/notifications.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/orchestrator.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/soul.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/task-runner.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/voice.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/worker-worktree.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles/worker.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/roles_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/routes/__init__.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/routes/artifacts.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/routes/config.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/routes/council.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/routes/desktop.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/routes/history.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/routes/machines.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/routes/notify.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/routes/palette.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/routes/permission.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/routes/projects.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/routes/push.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/routes/safety.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/routes/scheduler.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/routes/scratchpad.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/routes/sessions.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/routes/sessions_admin.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/routes/voice.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/safety/__init__.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/safety_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/safety_commands.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/scheduler/__init__.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/scheduler/dispatch.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/scheduler/loop.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/scheduler/schedule.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/scheduler/zombie.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/scratchpad.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/security.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/send_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/server.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/services.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/session_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/session_context.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/session_ready.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/ssh.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/agentwire-splash-logo-layers--agentwire-text.png +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/agentwire-splash-logo-layers--echo-claw-fg.png +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/agentwire-splash-logo-layers--echo.png +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/agentwire-splash-logo-layers--telephone.png +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/agentwire-splash-logo-layers--tree.png +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/announcements.json +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/apple-touch-icon.png +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/css/mobile.css +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/favicon-32.png +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/favicon-64.png +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/icons/sessions/bear.webp +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/icons/sessions/cat.webp +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/icons/sessions/crown.webp +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/icons/sessions/custom/agentwire-portal.webp +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/icons/sessions/custom/agentwire-tts.webp +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/icons/sessions/custom/agentwire.webp +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/icons/sessions/deer.webp +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/icons/sessions/drone.webp +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/icons/sessions/eagle.webp +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/icons/sessions/fox.webp +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/icons/sessions/hawk.webp +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/icons/sessions/horse.webp +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/icons/sessions/lion.webp +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/icons/sessions/rabbit.webp +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/icons/sessions/robot.webp +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/icons/sessions/tiger.webp +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/icons/sessions/wolf.webp +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/img/icon-192.png +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/img/icon-512.png +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/.gitkeep +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/announcement-modal.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/api.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/artifact-window.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/card-terminal.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/collage.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/command-palette.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/council-window.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/dead-key-suppressor.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/desktop-manager.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/desktop.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/help-modal.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/icon-manager.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/lineage.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/mobile.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/notification-prefs.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/notifications-panel.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/ptt.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/push-client.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/review-window.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/safety-shared.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/safety-window.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/scratchpad.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/service-classification.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/session-hud-spawn.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/session-id.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/session-window.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/shortcuts.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/sidebar/artifacts-section.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/sidebar/config-section.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/sidebar/council-section.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/sidebar/machines-section.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/sidebar/projects-section.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/sidebar/safety-section.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/sidebar/services-section.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/sidebar/sessions-section.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/sidebar.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/spawn-ghost.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/terminal-font-prefs.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/terminal-pane.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/tile-manager.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/toast.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/token-modal.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/utils/ansi.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/utils/swipe.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/voice/autosend-prefs.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/voice/browser-stt.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/voice/browser-tts.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/voice/jargon.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/voice/prompt.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/winbox.bundle.min.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/js/workspace-window.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/manifest.webmanifest +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/service-worker.js +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/static/topology-harness.html +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/stt/__init__.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/stt/base.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/stt/cloud.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/stt/engine.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/stt/local.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/stt/server_backend.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/stt/stt_server.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/system_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tabs_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tasks.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tasks_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/templates/__init__.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/templates/base.html +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/templates/council/minutes.html.j2 +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/templates/desktop.html +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/templates/email_notification.html +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/templates/handoff/show-the-story.html.j2 +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/templates/handoff/theme.css.j2 +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/templates/mobile.html +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/templates/pair.html +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/templates/tmux.conf +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/templating.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tooldefs/aws.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tooldefs/docker.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tooldefs/gcp.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tooldefs/gh.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tooldefs/git.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tooldefs/gws.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tooldefs/kubectl.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tooldefs/npm.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tooldefs/terraform.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tooldefs/uv.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tts/__init__.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tts/audio.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tts/base.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tts/engines/__init__.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tts/engines/chatterbox.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tts/engines/kokoro.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tts/engines/zonos.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tts/kokoro_server.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tts/local.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tts/registry.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tts_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tts_server.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tunnels.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/tunnels_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/usage_limit.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/utils/__init__.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/utils/chunker.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/utils/event_log.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/utils/file_io.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/utils/paths.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/utils/speech.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/utils/subprocess.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/validation.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/voice_status.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/wiki.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/wiki_audit.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/wiki_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/agentwire/worktree_registry.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/decisions/obsidian-second-brain.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/logo.png +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/INDEX.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/briefing-mode.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/communication/hammerspoon.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/council.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/internals/parallel-refactor.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/quickstart.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/research/briefing-mode-feasibility.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/security/pip-audit.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/services.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/sessions/messaging.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/sessions/window-sizing.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/sessions/worktree-sessions.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/usage-limit-recovery.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/voice/stt-cloud.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/docs/wiki/voice/tts-self-hosted.md +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/pyproject.toml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/conftest.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/e2e/test_portal_ui.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/fixtures/sample_agentwire.yml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/fixtures/sample_config.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/fixtures/sample_scheduler.yaml +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/integration/test_council_portal.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/integration/test_send_verified_tmux.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/integration/test_server_websockets.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/integration/test_worktree_cmd.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_announcements.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_build_agent_command.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_channels.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_chrome_tabs.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_cli_commands.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_cli_output.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_cli_smoke.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_config.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_config_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_control_plane_protection.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_core_created_by_rooting.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_council_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_council_inbox.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_council_minutes.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_council_state.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_council_view.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_damage_control_bypass.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_damage_control_sync.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_dangling_worktrees.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_devices.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_diff_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_doctor_task_migration.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_doctor_voice.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_event_log.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_file_io.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_guarded_launch_command.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_handoff_git_state.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_handoff_instructions.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_handoff_parser.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_handoff_renderer.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_history.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_hooks_install.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_idle_handler.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_idle_nag.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_inbox.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_init_command.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_install_parity.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_limits_tick_isolation.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_locking.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_mcp_server.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_mcp_tools_args.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_msg_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_notify_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_onboarding_reinit.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_palette_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_pip_environment.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_portal_api.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_posture_default.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_project_config.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_prompt_router.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_push.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_rebuild_guard.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_repo_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_roles.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_routes_snapshot.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_safety_commands.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_safety_disabled_rules.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_safety_escape_hatch.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_safety_heal.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_safety_kill_switch.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_scheduler_parsing.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_scheduler_zombie.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_scratchpad.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_security.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_server_async.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_server_pure.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_services.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_session_context.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_session_created_by_env.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_session_ready.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_shared_dir_guard.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_shim_selfheal.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_skill_install.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_speech_tags.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_ssh.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_stt_backend.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_stt_cloud.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_stt_engine.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_task_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_tasks.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_tasks_cli.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_templating.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_terminal_resize.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_tmux_template.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_tts_engine_resolution.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_tts_local.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_tunnels_probe.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_unattended_env_isolation.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_usage_limit.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_validation.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_voice_status.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_wiki.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_wiki_audit.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_window_cycling_binding.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_worktree_branch_cleanup.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_worktree_layout.py +0 -0
- {agentwire_dev-1.63.0 → agentwire_dev-1.64.0}/tests/unit/test_worktree_registry.py +0 -0
|
@@ -13,6 +13,14 @@ from typing import Optional
|
|
|
13
13
|
|
|
14
14
|
import yaml
|
|
15
15
|
|
|
16
|
+
# Gitignored files a fresh git worktree needs seeded — a worktree can't load
|
|
17
|
+
# its session/task config without them. Single source of truth: referenced
|
|
18
|
+
# by WorktreesConfig's default below, the config-loading fallback further
|
|
19
|
+
# down, AND worktree.py's mandatory (never-omittable) seed set (#803) — a
|
|
20
|
+
# stale `copy_files:` in a user's config.yaml that predates one of these
|
|
21
|
+
# being added here must not silently drop it from every fresh worktree.
|
|
22
|
+
DEFAULT_WORKTREE_COPY_FILES = [".env", ".agentwire.yml", ".agentwire.tasks.yml"]
|
|
23
|
+
|
|
16
24
|
|
|
17
25
|
def _get_default_agent_command() -> str:
|
|
18
26
|
"""Get the default agent command.
|
|
@@ -105,7 +113,7 @@ class WorktreesConfig:
|
|
|
105
113
|
# tasks can't load their session/task config without them when the project
|
|
106
114
|
# gitignores them (the latter is the protected, host-authored task-exec file —
|
|
107
115
|
# #720).
|
|
108
|
-
copy_files: list = field(default_factory=lambda:
|
|
116
|
+
copy_files: list = field(default_factory=lambda: list(DEFAULT_WORKTREE_COPY_FILES))
|
|
109
117
|
|
|
110
118
|
|
|
111
119
|
@dataclass
|
|
@@ -623,7 +631,7 @@ def _dict_to_config(data: dict) -> Config:
|
|
|
623
631
|
enabled=worktrees_data.get("enabled", True),
|
|
624
632
|
suffix=worktrees_data.get("suffix", "-worktrees"),
|
|
625
633
|
auto_create_branch=worktrees_data.get("auto_create_branch", True),
|
|
626
|
-
copy_files=worktrees_data.get("copy_files",
|
|
634
|
+
copy_files=worktrees_data.get("copy_files", list(DEFAULT_WORKTREE_COPY_FILES)),
|
|
627
635
|
)
|
|
628
636
|
projects = ProjectsConfig(
|
|
629
637
|
dir=projects_data.get("dir", "~/projects"),
|
|
@@ -19,6 +19,7 @@ import shutil
|
|
|
19
19
|
import socket
|
|
20
20
|
import subprocess
|
|
21
21
|
import sys
|
|
22
|
+
import time
|
|
22
23
|
from pathlib import Path
|
|
23
24
|
|
|
24
25
|
from .core import (
|
|
@@ -475,6 +476,75 @@ def _render_shim_liveness_section() -> int:
|
|
|
475
476
|
return len(dead)
|
|
476
477
|
|
|
477
478
|
|
|
479
|
+
def _scheduler_daemon_started_at() -> float | None:
|
|
480
|
+
"""Epoch seconds the scheduler daemon process started, or ``None`` if not running.
|
|
481
|
+
|
|
482
|
+
Reads the daemon's own self-reported ``started_at`` from the live-state
|
|
483
|
+
file it already writes every loop tick (``scheduler/loop.py`` ->
|
|
484
|
+
``_write_live_state`` -> ``read_live_state()``) rather than reimplementing
|
|
485
|
+
process-start-time discovery via ``ps``/``pgrep`` PID matching, which is
|
|
486
|
+
both platform-fragile (``ps`` elapsed-time output format varies) and
|
|
487
|
+
ambiguous if a stray/duplicate daemon process happens to be running.
|
|
488
|
+
``tmux_session_exists`` confirms the daemon is actually alive, so a
|
|
489
|
+
leftover live-state file from a since-stopped daemon doesn't produce a
|
|
490
|
+
false "stale" reading.
|
|
491
|
+
"""
|
|
492
|
+
from .scheduler import SCHEDULER_SESSION, read_live_state
|
|
493
|
+
|
|
494
|
+
if not tmux_session_exists(SCHEDULER_SESSION):
|
|
495
|
+
return None
|
|
496
|
+
state = read_live_state()
|
|
497
|
+
if not state:
|
|
498
|
+
return None
|
|
499
|
+
started_at = state.get("started_at")
|
|
500
|
+
if not started_at:
|
|
501
|
+
return None
|
|
502
|
+
try:
|
|
503
|
+
from datetime import datetime
|
|
504
|
+
return datetime.fromisoformat(started_at).timestamp()
|
|
505
|
+
except (ValueError, TypeError):
|
|
506
|
+
return None
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
def _newest_installed_source_mtime(pkg_dir: Path | None = None) -> float:
|
|
510
|
+
"""Newest mtime among the installed ``agentwire`` package's ``.py`` files."""
|
|
511
|
+
if pkg_dir is None:
|
|
512
|
+
pkg_dir = Path(__file__).resolve().parent
|
|
513
|
+
try:
|
|
514
|
+
return max((f.stat().st_mtime for f in pkg_dir.rglob("*.py")), default=0.0)
|
|
515
|
+
except Exception:
|
|
516
|
+
return 0.0
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
def _render_scheduler_staleness_section() -> int:
|
|
520
|
+
"""Doctor section: flag a scheduler daemon older than the installed code (#803).
|
|
521
|
+
|
|
522
|
+
``agentwire scheduler serve`` is a long-running Python process — like the
|
|
523
|
+
MCP server, it imports its modules once at start and never re-reads them.
|
|
524
|
+
``agentwire rebuild`` updates the on-disk package but can't touch an
|
|
525
|
+
already-running interpreter's loaded bytecode, so a daemon that has been
|
|
526
|
+
up since before the last rebuild is silently executing stale dispatch
|
|
527
|
+
logic: any bug fixed since then stays live in production until the
|
|
528
|
+
daemon is restarted.
|
|
529
|
+
"""
|
|
530
|
+
started_at = _scheduler_daemon_started_at()
|
|
531
|
+
if started_at is None:
|
|
532
|
+
print(" [..] Scheduler daemon not running — skipping staleness check")
|
|
533
|
+
return 0
|
|
534
|
+
|
|
535
|
+
newest_src = _newest_installed_source_mtime()
|
|
536
|
+
if not newest_src or newest_src <= started_at:
|
|
537
|
+
print(" [ok] Scheduler daemon is current with the installed package")
|
|
538
|
+
return 0
|
|
539
|
+
|
|
540
|
+
age_days = (time.time() - started_at) / 86400
|
|
541
|
+
print(f" [!!] Scheduler daemon has been running {age_days:.1f}d — "
|
|
542
|
+
"predates the most recent `agentwire rebuild`")
|
|
543
|
+
print(" Any dispatch bug fixed since then is still live in the running daemon.")
|
|
544
|
+
print(" Fix: agentwire scheduler stop && agentwire scheduler start")
|
|
545
|
+
return 1
|
|
546
|
+
|
|
547
|
+
|
|
478
548
|
def cmd_doctor(args) -> int:
|
|
479
549
|
"""Auto-diagnose and fix common issues."""
|
|
480
550
|
from .hooks_cli import _managed_file_state, _managed_hook_files, get_hooks_source
|
|
@@ -653,6 +723,14 @@ def cmd_doctor(args) -> int:
|
|
|
653
723
|
else:
|
|
654
724
|
print(" [ok] Local main up to date with origin/main")
|
|
655
725
|
|
|
726
|
+
# 4d. Scheduler daemon staleness — the daemon is a long-running process
|
|
727
|
+
# that never re-imports its code, so it can silently run a dispatch bug
|
|
728
|
+
# that's since been fixed on disk (#803). Distinct from the git-drift
|
|
729
|
+
# check above: that flags an out-of-date CHECKOUT, this flags a
|
|
730
|
+
# currently-running PROCESS that predates the last install.
|
|
731
|
+
print("\nChecking scheduler daemon freshness...")
|
|
732
|
+
issues_found += _render_scheduler_staleness_section()
|
|
733
|
+
|
|
656
734
|
# Check custom services (registry-driven: built-in notifications bridge
|
|
657
735
|
# + user-defined services from services.custom)
|
|
658
736
|
print("\nChecking custom services...")
|
|
@@ -613,8 +613,8 @@ def load_config(
|
|
|
613
613
|
# dispatch by the scheduler), the hook resolves ``ask`` by FAILING CLOSED:
|
|
614
614
|
# block + notify the owner, UNLESS the matched rule's stable ID is on the
|
|
615
615
|
# allowlist. The allowlist is the union of:
|
|
616
|
-
# 1. ``DEFAULT_UNATTENDED_ALLOW`` below (
|
|
617
|
-
# irreversible or outward-facing),
|
|
616
|
+
# 1. ``DEFAULT_UNATTENDED_ALLOW`` below (work + open a PR + notify the owner
|
|
617
|
+
# by email — nothing else irreversible or outward-facing),
|
|
618
618
|
# 2. ``safety.unattended_allow`` from global / project config,
|
|
619
619
|
# 3. ``AGENTWIRE_UNATTENDED_ALLOW`` (comma-separated) — the per-task
|
|
620
620
|
# extension the scheduler stamps from a task's ``unattended_allow``.
|
|
@@ -629,6 +629,7 @@ DEFAULT_UNATTENDED_ALLOW = {
|
|
|
629
629
|
"git.commit", # commit
|
|
630
630
|
"git.push", # push (force/delete are SEPARATE hard-block/ask rules)
|
|
631
631
|
"gh.pr-create", # open a PR — the human-reviewed gate
|
|
632
|
+
"outbound.agentwire-email", # blanket allow, any recipient (#804)
|
|
632
633
|
}
|
|
633
634
|
|
|
634
635
|
|
|
@@ -609,8 +609,8 @@ def load_config(
|
|
|
609
609
|
# dispatch by the scheduler), the hook resolves ``ask`` by FAILING CLOSED:
|
|
610
610
|
# block + notify the owner, UNLESS the matched rule's stable ID is on the
|
|
611
611
|
# allowlist. The allowlist is the union of:
|
|
612
|
-
# 1. ``DEFAULT_UNATTENDED_ALLOW`` below (
|
|
613
|
-
# irreversible or outward-facing),
|
|
612
|
+
# 1. ``DEFAULT_UNATTENDED_ALLOW`` below (work + open a PR + notify the owner
|
|
613
|
+
# by email — nothing else irreversible or outward-facing),
|
|
614
614
|
# 2. ``safety.unattended_allow`` from global / project config,
|
|
615
615
|
# 3. ``AGENTWIRE_UNATTENDED_ALLOW`` (comma-separated) — the per-task
|
|
616
616
|
# extension the scheduler stamps from a task's ``unattended_allow``.
|
|
@@ -625,6 +625,7 @@ DEFAULT_UNATTENDED_ALLOW = {
|
|
|
625
625
|
"git.commit", # commit
|
|
626
626
|
"git.push", # push (force/delete are SEPARATE hard-block/ask rules)
|
|
627
627
|
"gh.pr-create", # open a PR — the human-reviewed gate
|
|
628
|
+
"outbound.agentwire-email", # blanket allow, any recipient (#804)
|
|
628
629
|
}
|
|
629
630
|
|
|
630
631
|
|
|
@@ -621,8 +621,8 @@ def load_config(
|
|
|
621
621
|
# dispatch by the scheduler), the hook resolves ``ask`` by FAILING CLOSED:
|
|
622
622
|
# block + notify the owner, UNLESS the matched rule's stable ID is on the
|
|
623
623
|
# allowlist. The allowlist is the union of:
|
|
624
|
-
# 1. ``DEFAULT_UNATTENDED_ALLOW`` below (
|
|
625
|
-
# irreversible or outward-facing),
|
|
624
|
+
# 1. ``DEFAULT_UNATTENDED_ALLOW`` below (work + open a PR + notify the owner
|
|
625
|
+
# by email — nothing else irreversible or outward-facing),
|
|
626
626
|
# 2. ``safety.unattended_allow`` from global / project config,
|
|
627
627
|
# 3. ``AGENTWIRE_UNATTENDED_ALLOW`` (comma-separated) — the per-task
|
|
628
628
|
# extension the scheduler stamps from a task's ``unattended_allow``.
|
|
@@ -637,6 +637,7 @@ DEFAULT_UNATTENDED_ALLOW = {
|
|
|
637
637
|
"git.commit", # commit
|
|
638
638
|
"git.push", # push (force/delete are SEPARATE hard-block/ask rules)
|
|
639
639
|
"gh.pr-create", # open a PR — the human-reviewed gate
|
|
640
|
+
"outbound.agentwire-email", # blanket allow, any recipient (#804)
|
|
640
641
|
}
|
|
641
642
|
|
|
642
643
|
|
|
@@ -615,8 +615,8 @@ def load_config(
|
|
|
615
615
|
# dispatch by the scheduler), the hook resolves ``ask`` by FAILING CLOSED:
|
|
616
616
|
# block + notify the owner, UNLESS the matched rule's stable ID is on the
|
|
617
617
|
# allowlist. The allowlist is the union of:
|
|
618
|
-
# 1. ``DEFAULT_UNATTENDED_ALLOW`` below (
|
|
619
|
-
# irreversible or outward-facing),
|
|
618
|
+
# 1. ``DEFAULT_UNATTENDED_ALLOW`` below (work + open a PR + notify the owner
|
|
619
|
+
# by email — nothing else irreversible or outward-facing),
|
|
620
620
|
# 2. ``safety.unattended_allow`` from global / project config,
|
|
621
621
|
# 3. ``AGENTWIRE_UNATTENDED_ALLOW`` (comma-separated) — the per-task
|
|
622
622
|
# extension the scheduler stamps from a task's ``unattended_allow``.
|
|
@@ -631,6 +631,7 @@ DEFAULT_UNATTENDED_ALLOW = {
|
|
|
631
631
|
"git.commit", # commit
|
|
632
632
|
"git.push", # push (force/delete are SEPARATE hard-block/ask rules)
|
|
633
633
|
"gh.pr-create", # open a PR — the human-reviewed gate
|
|
634
|
+
"outbound.agentwire-email", # blanket allow, any recipient (#804)
|
|
634
635
|
}
|
|
635
636
|
|
|
636
637
|
|
|
@@ -608,8 +608,8 @@ def load_config(
|
|
|
608
608
|
# dispatch by the scheduler), the hook resolves ``ask`` by FAILING CLOSED:
|
|
609
609
|
# block + notify the owner, UNLESS the matched rule's stable ID is on the
|
|
610
610
|
# allowlist. The allowlist is the union of:
|
|
611
|
-
# 1. ``DEFAULT_UNATTENDED_ALLOW`` below (
|
|
612
|
-
# irreversible or outward-facing),
|
|
611
|
+
# 1. ``DEFAULT_UNATTENDED_ALLOW`` below (work + open a PR + notify the owner
|
|
612
|
+
# by email — nothing else irreversible or outward-facing),
|
|
613
613
|
# 2. ``safety.unattended_allow`` from global / project config,
|
|
614
614
|
# 3. ``AGENTWIRE_UNATTENDED_ALLOW`` (comma-separated) — the per-task
|
|
615
615
|
# extension the scheduler stamps from a task's ``unattended_allow``.
|
|
@@ -624,6 +624,7 @@ DEFAULT_UNATTENDED_ALLOW = {
|
|
|
624
624
|
"git.commit", # commit
|
|
625
625
|
"git.push", # push (force/delete are SEPARATE hard-block/ask rules)
|
|
626
626
|
"gh.pr-create", # open a PR — the human-reviewed gate
|
|
627
|
+
"outbound.agentwire-email", # blanket allow, any recipient (#804)
|
|
627
628
|
}
|
|
628
629
|
|
|
629
630
|
|
|
@@ -577,8 +577,8 @@ def load_config(
|
|
|
577
577
|
# dispatch by the scheduler), the hook resolves ``ask`` by FAILING CLOSED:
|
|
578
578
|
# block + notify the owner, UNLESS the matched rule's stable ID is on the
|
|
579
579
|
# allowlist. The allowlist is the union of:
|
|
580
|
-
# 1. ``DEFAULT_UNATTENDED_ALLOW`` below (
|
|
581
|
-
# irreversible or outward-facing),
|
|
580
|
+
# 1. ``DEFAULT_UNATTENDED_ALLOW`` below (work + open a PR + notify the owner
|
|
581
|
+
# by email — nothing else irreversible or outward-facing),
|
|
582
582
|
# 2. ``safety.unattended_allow`` from global / project config,
|
|
583
583
|
# 3. ``AGENTWIRE_UNATTENDED_ALLOW`` (comma-separated) — the per-task
|
|
584
584
|
# extension the scheduler stamps from a task's ``unattended_allow``.
|
|
@@ -593,6 +593,7 @@ DEFAULT_UNATTENDED_ALLOW = {
|
|
|
593
593
|
"git.commit", # commit
|
|
594
594
|
"git.push", # push (force/delete are SEPARATE hard-block/ask rules)
|
|
595
595
|
"gh.pr-create", # open a PR — the human-reviewed gate
|
|
596
|
+
"outbound.agentwire-email", # blanket allow, any recipient (#804)
|
|
596
597
|
}
|
|
597
598
|
|
|
598
599
|
|
|
@@ -46,7 +46,25 @@ def _check_gate(board, task_name: str) -> bool:
|
|
|
46
46
|
project = task.project
|
|
47
47
|
|
|
48
48
|
def _gate_skip(gate_type: str, reason: str, **extra):
|
|
49
|
-
"""Record a gate skip
|
|
49
|
+
"""Record a gate skip. Logs only on first occurrence (spam control),
|
|
50
|
+
but persists ``last_gate_skip`` on every REASON CHANGE.
|
|
51
|
+
|
|
52
|
+
Distinct from ``_gate_error`` below: this is the CLEAN "not ready
|
|
53
|
+
yet" path (e.g. a ``command`` gate legitimately returning nonzero),
|
|
54
|
+
not an exception. Recorded so the board can show "waiting on gate"
|
|
55
|
+
instead of reading as silently-falling-behind overdue (#803).
|
|
56
|
+
Persisting on reason-change (not just first-occurrence, which
|
|
57
|
+
``_gated_tasks`` alone gates) matters for multi-condition gates: if
|
|
58
|
+
task's blocker shifts from ``git_commit`` to ``command`` without the
|
|
59
|
+
gate ever fully passing in between, ``task_name`` never leaves
|
|
60
|
+
``_gated_tasks``, so a first-occurrence-only write would leave the
|
|
61
|
+
board showing the ORIGINAL, now-stale reason.
|
|
62
|
+
"""
|
|
63
|
+
skip_text = f"{gate_type}: {reason}"
|
|
64
|
+
if state.last_gate_skip != skip_text:
|
|
65
|
+
state.last_gate_skip = skip_text
|
|
66
|
+
board.state[task_name] = state
|
|
67
|
+
_sched.save_board(board)
|
|
50
68
|
if task_name not in _gated_tasks:
|
|
51
69
|
_sched._log_event("task_gated", task=task_name, gate_type=gate_type,
|
|
52
70
|
reason=reason, **extra)
|
|
@@ -69,6 +87,7 @@ def _check_gate(board, task_name: str) -> bool:
|
|
|
69
87
|
print(f"[{_ts()}] Gate error on {task_name}: {gate_type} "
|
|
70
88
|
f"({reason}) — failing open")
|
|
71
89
|
state.last_gate_error = f"{gate_type}: {reason}"
|
|
90
|
+
state.last_gate_skip = "" # failing open — no longer "waiting on gate"
|
|
72
91
|
board.state[task_name] = state
|
|
73
92
|
_sched.save_board(board)
|
|
74
93
|
_gated_tasks.discard(task_name)
|
|
@@ -131,16 +150,20 @@ def _check_gate(board, task_name: str) -> bool:
|
|
|
131
150
|
|
|
132
151
|
|
|
133
152
|
def _clear_gate_error(board, task_name: str) -> None:
|
|
134
|
-
"""Clear a previously-recorded gate error once the gate evaluates cleanly.
|
|
153
|
+
"""Clear a previously-recorded gate error/skip once the gate evaluates cleanly.
|
|
135
154
|
|
|
136
|
-
No-op (and no board write) unless this task actually had
|
|
137
|
-
the common clean path stays cheap.
|
|
155
|
+
No-op (and no board write) unless this task actually had something
|
|
156
|
+
recorded, so the common clean path stays cheap. Clears BOTH
|
|
157
|
+
``last_gate_error`` (exception path) and ``last_gate_skip`` (clean
|
|
158
|
+
"not ready yet" path, #803) — both are stale the moment the gate passes.
|
|
138
159
|
"""
|
|
139
160
|
from agentwire import scheduler as _sched
|
|
140
161
|
|
|
141
162
|
state = board.state.get(task_name)
|
|
142
163
|
had_tracked = _gate_errored.pop(task_name, None) is not None
|
|
143
|
-
|
|
144
|
-
|
|
164
|
+
had_state = state is not None and (state.last_gate_error or state.last_gate_skip)
|
|
165
|
+
if had_tracked or had_state:
|
|
166
|
+
if state is not None and (state.last_gate_error or state.last_gate_skip):
|
|
145
167
|
state.last_gate_error = ""
|
|
168
|
+
state.last_gate_skip = ""
|
|
146
169
|
_sched.save_board(board)
|
|
@@ -89,6 +89,7 @@ class TaskState:
|
|
|
89
89
|
run_count: int = 0
|
|
90
90
|
last_summary: str = ""
|
|
91
91
|
last_gate_error: str = "" # last gate-eval exception reason (failed open)
|
|
92
|
+
last_gate_skip: str = "" # currently-blocking gate reason (clean skip, not an error)
|
|
92
93
|
last_gate_commit: str = "" # HEAD at last dispatch (for gate checks)
|
|
93
94
|
last_dispatch: datetime | None = None # set BEFORE running (restart safety)
|
|
94
95
|
# Active worktree-PR tracking (set on finalize, cleared by the reaper on
|
|
@@ -199,6 +199,8 @@ def get_board_display(board: Board) -> list[dict]:
|
|
|
199
199
|
row["last_summary"] = state.last_summary
|
|
200
200
|
if state.last_gate_error:
|
|
201
201
|
row["last_gate_error"] = state.last_gate_error
|
|
202
|
+
if state.last_gate_skip:
|
|
203
|
+
row["last_gate_skip"] = state.last_gate_skip
|
|
202
204
|
rows.append(row)
|
|
203
205
|
|
|
204
206
|
# Sort: enabled first, then by overdue (most overdue first)
|
|
@@ -112,6 +112,7 @@ def load_board() -> Board:
|
|
|
112
112
|
run_count=int(s.get("run_count", 0)),
|
|
113
113
|
last_summary=str(s.get("last_summary", "")),
|
|
114
114
|
last_gate_error=str(s.get("last_gate_error", "")),
|
|
115
|
+
last_gate_skip=str(s.get("last_gate_skip", "")),
|
|
115
116
|
last_gate_commit=str(s.get("last_gate_commit", "")),
|
|
116
117
|
last_dispatch=_parse_datetime_field(s.get("last_dispatch")),
|
|
117
118
|
worktree_branch=str(s.get("worktree_branch", "")),
|
|
@@ -163,6 +164,8 @@ def _state_to_dict(board: Board) -> dict:
|
|
|
163
164
|
entry["last_summary"] = s.last_summary
|
|
164
165
|
if s.last_gate_error:
|
|
165
166
|
entry["last_gate_error"] = s.last_gate_error
|
|
167
|
+
if s.last_gate_skip:
|
|
168
|
+
entry["last_gate_skip"] = s.last_gate_skip
|
|
166
169
|
if s.last_gate_commit:
|
|
167
170
|
entry["last_gate_commit"] = s.last_gate_commit
|
|
168
171
|
if s.last_dispatch:
|
|
@@ -148,7 +148,7 @@ def _recent_activity(events: list[dict], limit: int = 5) -> list[dict]:
|
|
|
148
148
|
glance at `scheduler status` shows recent results — including the
|
|
149
149
|
fail-open gate errors that used to vanish entirely.
|
|
150
150
|
"""
|
|
151
|
-
keep = {"task_completed", "task_failed", "gate_error"}
|
|
151
|
+
keep = {"task_completed", "task_failed", "gate_error", "task_gated"}
|
|
152
152
|
out: list[dict] = []
|
|
153
153
|
for evt in reversed(events):
|
|
154
154
|
etype = evt.get("event")
|
|
@@ -165,6 +165,8 @@ def _recent_activity(events: list[dict], limit: int = 5) -> list[dict]:
|
|
|
165
165
|
detail = f"{status}" + (f" — {summary}" if summary else "")
|
|
166
166
|
elif etype == "task_failed":
|
|
167
167
|
detail = "failed — " + (evt.get("summary") or evt.get("reason") or "?")
|
|
168
|
+
elif etype == "task_gated":
|
|
169
|
+
detail = f"[gated] {evt.get('gate_type', '?')}: {evt.get('reason', '?')}"
|
|
168
170
|
else: # gate_error
|
|
169
171
|
detail = f"[gate-error] {evt.get('gate_type', '?')}: {evt.get('reason', '?')}"
|
|
170
172
|
if len(detail) > 80:
|
|
@@ -254,10 +256,14 @@ def cmd_scheduler_board(args) -> int:
|
|
|
254
256
|
)
|
|
255
257
|
|
|
256
258
|
# Surface WHY: a gate-eval error (fail-open, would otherwise be
|
|
257
|
-
# invisible) takes precedence;
|
|
259
|
+
# invisible) takes precedence; then a currently-blocking gate
|
|
260
|
+
# (so "+4h11m" reads as "waiting on gate", not silently falling
|
|
261
|
+
# behind, #803); else the summary behind a bad status.
|
|
258
262
|
detail = ""
|
|
259
263
|
if r.get("last_gate_error"):
|
|
260
264
|
detail = f"[gate-error] {r['last_gate_error']}"
|
|
265
|
+
elif r.get("last_gate_skip"):
|
|
266
|
+
detail = f"[gated] {r['last_gate_skip']}"
|
|
261
267
|
elif status_str in _BAD_STATUSES and r.get("last_summary"):
|
|
262
268
|
detail = r["last_summary"]
|
|
263
269
|
if detail:
|
|
@@ -5958,8 +5958,12 @@ body.sidebar-pinned .sidebar-tab {
|
|
|
5958
5958
|
|
|
5959
5959
|
/* ============================================
|
|
5960
5960
|
Session HUD — top-edge frosted drawer (#776, foundation shell)
|
|
5961
|
-
Two detents
|
|
5962
|
-
|
|
5961
|
+
Two detents, top-center pull handle: "peek" auto-sizes to content, floored
|
|
5962
|
+
and capped at the fixed "half" (50vh) ceiling (#802, session-hud.js's
|
|
5963
|
+
_applyAutoHeight); the 33vh height below is only the pre-JS-measurement
|
|
5964
|
+
fallback for the instant the drawer is created, before content exists.
|
|
5965
|
+
Content is mounted into .session-hud-canvas by a later issue (#777,
|
|
5966
|
+
TopologyView).
|
|
5963
5967
|
============================================ */
|
|
5964
5968
|
|
|
5965
5969
|
/* Left offset shared by the drawer and its handle so the two never drift.
|
|
@@ -6655,20 +6659,60 @@ body.sidebar-pinned { --hud-left: var(--sidebar-width); }
|
|
|
6655
6659
|
gap: 6px;
|
|
6656
6660
|
}
|
|
6657
6661
|
|
|
6658
|
-
|
|
6659
|
-
|
|
6660
|
-
|
|
6661
|
-
|
|
6662
|
-
|
|
6662
|
+
/* Full-width activity pulse strip (#800), replacing the old bar sparkline.
|
|
6663
|
+
The rules below are the `idle` resting state — dim, slow, low-amplitude,
|
|
6664
|
+
still visibly "alive". flow/awaiting/stuck override speed/amplitude/colour
|
|
6665
|
+
further down, keyed off the card's state class. */
|
|
6666
|
+
.topology-pulse {
|
|
6667
|
+
position: relative;
|
|
6668
|
+
width: 100%;
|
|
6669
|
+
height: 20px;
|
|
6670
|
+
border-radius: 4px;
|
|
6663
6671
|
}
|
|
6664
6672
|
|
|
6665
|
-
.topology-
|
|
6673
|
+
.topology-pulse-svg {
|
|
6666
6674
|
display: block;
|
|
6667
|
-
width:
|
|
6668
|
-
height:
|
|
6669
|
-
|
|
6670
|
-
|
|
6671
|
-
|
|
6675
|
+
width: 100%;
|
|
6676
|
+
height: 100%;
|
|
6677
|
+
}
|
|
6678
|
+
|
|
6679
|
+
.topology-pulse-base {
|
|
6680
|
+
stroke: var(--text-muted);
|
|
6681
|
+
stroke-width: 1px;
|
|
6682
|
+
opacity: 0.18;
|
|
6683
|
+
}
|
|
6684
|
+
|
|
6685
|
+
.topology-pulse-scroll {
|
|
6686
|
+
animation: topology-pulse-scroll 3.2s linear infinite;
|
|
6687
|
+
}
|
|
6688
|
+
|
|
6689
|
+
.topology-pulse-trace {
|
|
6690
|
+
fill: none;
|
|
6691
|
+
stroke: var(--text-muted);
|
|
6692
|
+
stroke-width: 1.6px;
|
|
6693
|
+
stroke-linecap: round;
|
|
6694
|
+
stroke-linejoin: round;
|
|
6695
|
+
opacity: 0.4;
|
|
6696
|
+
vector-effect: non-scaling-stroke;
|
|
6697
|
+
transform-box: fill-box;
|
|
6698
|
+
transform-origin: center;
|
|
6699
|
+
transform: scaleY(0.32);
|
|
6700
|
+
}
|
|
6701
|
+
|
|
6702
|
+
.topology-pulse-marker {
|
|
6703
|
+
position: absolute;
|
|
6704
|
+
top: 50%;
|
|
6705
|
+
right: 3px;
|
|
6706
|
+
width: 5px;
|
|
6707
|
+
height: 5px;
|
|
6708
|
+
margin-top: -2.5px;
|
|
6709
|
+
border-radius: 50%;
|
|
6710
|
+
opacity: 0;
|
|
6711
|
+
pointer-events: none;
|
|
6712
|
+
}
|
|
6713
|
+
|
|
6714
|
+
@keyframes topology-pulse-scroll {
|
|
6715
|
+
to { transform: translateX(-240px); }
|
|
6672
6716
|
}
|
|
6673
6717
|
|
|
6674
6718
|
.topology-card-machine {
|
|
@@ -6785,10 +6829,18 @@ body.sidebar-pinned { --hud-left: var(--sidebar-width); }
|
|
|
6785
6829
|
opacity: 0.5;
|
|
6786
6830
|
animation: topology-dot-ring 1.8s ease-out infinite;
|
|
6787
6831
|
}
|
|
6788
|
-
.topology-card--flow .topology-
|
|
6789
|
-
|
|
6790
|
-
opacity: 0.
|
|
6791
|
-
|
|
6832
|
+
.topology-card--flow .topology-pulse-base {
|
|
6833
|
+
stroke: var(--card-tint, var(--lineage-tint-1));
|
|
6834
|
+
opacity: 0.22;
|
|
6835
|
+
}
|
|
6836
|
+
.topology-card--flow .topology-pulse-scroll {
|
|
6837
|
+
animation-duration: 1.15s;
|
|
6838
|
+
}
|
|
6839
|
+
.topology-card--flow .topology-pulse-trace {
|
|
6840
|
+
stroke: var(--card-tint, var(--lineage-tint-1));
|
|
6841
|
+
opacity: 0.95;
|
|
6842
|
+
transform: scaleY(1);
|
|
6843
|
+
filter: drop-shadow(0 0 3px color-mix(in srgb, var(--card-tint, var(--lineage-tint-1)) 55%, transparent));
|
|
6792
6844
|
}
|
|
6793
6845
|
|
|
6794
6846
|
/* Failure-state parity (#749): awaiting/stuck override the lineage tint
|
|
@@ -6803,9 +6855,19 @@ body.sidebar-pinned { --hud-left: var(--sidebar-width); }
|
|
|
6803
6855
|
opacity: 0.6;
|
|
6804
6856
|
animation: topology-dot-ring 1.3s ease-out infinite;
|
|
6805
6857
|
}
|
|
6806
|
-
.topology-card--awaiting .topology-
|
|
6858
|
+
.topology-card--awaiting .topology-pulse-trace {
|
|
6859
|
+
stroke: var(--topology-awaiting);
|
|
6860
|
+
opacity: 0.9;
|
|
6861
|
+
transform: scaleY(0.7);
|
|
6862
|
+
}
|
|
6863
|
+
.topology-card--awaiting .topology-pulse-scroll {
|
|
6864
|
+
animation-duration: 2s;
|
|
6865
|
+
}
|
|
6866
|
+
.topology-card--awaiting .topology-pulse-marker {
|
|
6807
6867
|
background: var(--topology-awaiting);
|
|
6808
|
-
|
|
6868
|
+
box-shadow: 0 0 5px var(--topology-awaiting-glow);
|
|
6869
|
+
opacity: 1;
|
|
6870
|
+
animation: topology-pulse-blink 1.1s ease-in-out infinite;
|
|
6809
6871
|
}
|
|
6810
6872
|
.topology-card--stuck .topology-status-dot {
|
|
6811
6873
|
background: var(--topology-stuck);
|
|
@@ -6816,9 +6878,23 @@ body.sidebar-pinned { --hud-left: var(--sidebar-width); }
|
|
|
6816
6878
|
opacity: 0.7;
|
|
6817
6879
|
animation: topology-dot-ring 0.9s ease-out infinite;
|
|
6818
6880
|
}
|
|
6819
|
-
.topology-card--stuck .topology-
|
|
6881
|
+
.topology-card--stuck .topology-pulse-base {
|
|
6882
|
+
stroke: var(--topology-stuck);
|
|
6883
|
+
opacity: 0.3;
|
|
6884
|
+
}
|
|
6885
|
+
.topology-card--stuck .topology-pulse-trace {
|
|
6886
|
+
stroke: var(--topology-stuck);
|
|
6887
|
+
opacity: 0.9;
|
|
6888
|
+
transform: scaleY(0.16);
|
|
6889
|
+
}
|
|
6890
|
+
.topology-card--stuck .topology-pulse-scroll {
|
|
6891
|
+
animation-duration: 0.9s;
|
|
6892
|
+
}
|
|
6893
|
+
.topology-card--stuck .topology-pulse-marker {
|
|
6820
6894
|
background: var(--topology-stuck);
|
|
6821
|
-
|
|
6895
|
+
box-shadow: 0 0 6px var(--topology-stuck-glow);
|
|
6896
|
+
opacity: 1;
|
|
6897
|
+
animation: topology-pulse-blink 0.7s steps(2, jump-none) infinite;
|
|
6822
6898
|
}
|
|
6823
6899
|
|
|
6824
6900
|
/* "You-are-here" self/root card (#778) — the Session HUD's re-rooted view
|
|
@@ -6845,9 +6921,9 @@ body.sidebar-pinned { --hud-left: var(--sidebar-width); }
|
|
|
6845
6921
|
0% { transform: scale(0.6); opacity: 0.7; }
|
|
6846
6922
|
100% { transform: scale(1.9); opacity: 0; }
|
|
6847
6923
|
}
|
|
6848
|
-
@keyframes topology-
|
|
6849
|
-
0%, 100% {
|
|
6850
|
-
50% {
|
|
6924
|
+
@keyframes topology-pulse-blink {
|
|
6925
|
+
0%, 100% { opacity: 1; }
|
|
6926
|
+
50% { opacity: 0.15; }
|
|
6851
6927
|
}
|
|
6852
6928
|
|
|
6853
6929
|
.topology-link {
|
|
@@ -6886,7 +6962,8 @@ body.sidebar-pinned { --hud-left: var(--sidebar-width); }
|
|
|
6886
6962
|
|
|
6887
6963
|
@media (prefers-reduced-motion: reduce) {
|
|
6888
6964
|
.topology-status-dot::after,
|
|
6889
|
-
.topology-
|
|
6965
|
+
.topology-pulse-scroll,
|
|
6966
|
+
.topology-pulse-marker,
|
|
6890
6967
|
.topology-link--flow,
|
|
6891
6968
|
.topology-link--awaiting,
|
|
6892
6969
|
.topology-link--stuck {
|
|
@@ -6918,7 +6995,11 @@ body.sidebar-pinned { --hud-left: var(--sidebar-width); }
|
|
|
6918
6995
|
|
|
6919
6996
|
.topology-view--shade .topology-family {
|
|
6920
6997
|
flex: 0 0 auto;
|
|
6921
|
-
gap
|
|
6998
|
+
/* Vertical gap between depth rows — the connector bezier's min bend is 24px
|
|
6999
|
+
(bezierPath in topology-render.js), so give the wires at least that much
|
|
7000
|
+
room to travel between a parent row and its children (#792 was 6px, too
|
|
7001
|
+
tight for the S-curve to sit inside the gap). */
|
|
7002
|
+
gap: 26px;
|
|
6922
7003
|
}
|
|
6923
7004
|
|
|
6924
7005
|
.topology-view--shade .topology-row {
|
|
@@ -7038,7 +7119,8 @@ body.sidebar-pinned { --hud-left: var(--sidebar-width); }
|
|
|
7038
7119
|
/* Expanded card hosts a live terminal — the activity sparkline is redundant
|
|
7039
7120
|
and just steals a row, so hide it, and tighten the card's gap. Reclaims
|
|
7040
7121
|
vertical space for terminal rows (the card was mostly chrome above it). */
|
|
7041
|
-
.topology-card--expanded .topology-card-meta
|
|
7122
|
+
.topology-card--expanded .topology-card-meta,
|
|
7123
|
+
.topology-card--expanded .topology-pulse { display: none; }
|
|
7042
7124
|
.topology-card--expanded { gap: 4px; }
|
|
7043
7125
|
|
|
7044
7126
|
/* --- born-from-parent placement (#745, absorbed into the HUD by #780) ---
|
|
@@ -7121,6 +7203,21 @@ body.sidebar-pinned { --hud-left: var(--sidebar-width); }
|
|
|
7121
7203
|
text-overflow: ellipsis;
|
|
7122
7204
|
}
|
|
7123
7205
|
|
|
7206
|
+
/* Read-only git-status badges (#801) — reuses the sidebar's `.sidebar-git-badge`
|
|
7207
|
+
+ `.git-*` classes (sidebar/sessions-section.js's `renderGitBadges`) so a
|
|
7208
|
+
worktree reads identically whether it's a live session or a ghost; only the
|
|
7209
|
+
row layout is ghost-specific. Same [hidden]-override gotcha as
|
|
7210
|
+
`.topology-ghost-actions` below — the JS toggles `hidden` every render. */
|
|
7211
|
+
.topology-ghost-git[hidden] {
|
|
7212
|
+
display: none;
|
|
7213
|
+
}
|
|
7214
|
+
.topology-ghost-git {
|
|
7215
|
+
display: flex;
|
|
7216
|
+
align-items: center;
|
|
7217
|
+
gap: 4px;
|
|
7218
|
+
flex-wrap: wrap;
|
|
7219
|
+
}
|
|
7220
|
+
|
|
7124
7221
|
/* [hidden] must win over the flex display below (equal specificity, later
|
|
7125
7222
|
author rule otherwise beats the UA [hidden]{display:none} stylesheet) —
|
|
7126
7223
|
the JS toggles this element's `hidden` attribute per card every render. */
|