agentwire-dev 1.66.0__tar.gz → 1.67.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.66.0 → agentwire_dev-1.67.0}/PKG-INFO +2 -2
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/__init__.py +1 -1
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/__main__.py +1 -1
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/completion.py +25 -2
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/core.py +269 -40
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/doctor_cli.py +114 -10
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/ensure_cli.py +116 -8
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/history_cli.py +30 -1
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/inbox.py +80 -11
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_task.py +5 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/routes/scheduler.py +34 -20
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/scheduler/__init__.py +1 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/scheduler/report.py +83 -1
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/scheduler/zombie.py +1 -1
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/scheduler_cli.py +60 -5
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/session_cli.py +43 -23
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/system_cli.py +3 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tasks.py +36 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tasks_cli.py +7 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/worktree.py +22 -6
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/INDEX.md +1 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/scheduling/scheduled-workloads.md +145 -1
- agentwire_dev-1.67.0/docs/wiki/sessions/conversation-identity.md +151 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/sessions/messaging.md +32 -9
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/pyproject.toml +5 -1
- agentwire_dev-1.67.0/tests/integration/test_tmux_name_rewrite.py +166 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/integration/test_worktree_cmd.py +122 -12
- agentwire_dev-1.67.0/tests/unit/test_build_agent_command.py +358 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_cli_commands.py +7 -9
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_doctor_scheduler_staleness.py +58 -15
- agentwire_dev-1.67.0/tests/unit/test_ensure_verified_prompt.py +155 -0
- agentwire_dev-1.67.0/tests/unit/test_history_resume_name.py +126 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_inbox.py +101 -4
- agentwire_dev-1.67.0/tests/unit/test_pending_message_visibility.py +149 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_prompt_router.py +24 -5
- agentwire_dev-1.67.0/tests/unit/test_scheduler_liveness.py +351 -0
- agentwire_dev-1.67.0/tests/unit/test_task_max_duration.py +171 -0
- agentwire_dev-1.67.0/tests/unit/test_worktree_dot_project.py +146 -0
- agentwire_dev-1.66.0/tests/unit/test_build_agent_command.py +0 -163
- agentwire_dev-1.66.0/tests/unit/test_worktree_dot_project.py +0 -84
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/.agentwire.yml.example +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/.claude/commands/handoff.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/.claude/skills/wiki/SKILL.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/.github/FUNDING.yml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/.github/workflows/pytest.yml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/.github/workflows/ruff.yml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/.github/workflows/security.yml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/.github/workflows/tts-smoke.yml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/.gitignore +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/AGENTS.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/CODE_OF_CONDUCT.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/CONTRIBUTING.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/Dockerfile.local +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/LICENSE +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/README.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/RELEASING.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/SECURITY.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/SPONSORS.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/agents/__init__.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/agents/base.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/agents/tmux.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/cached_status.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/channels/__init__.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/channels/base.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/channels/email.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/channels/push.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/channels/quo.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/channels_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/chrome_tabs.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/cohort.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/config.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/config_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/council/__init__.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/council/cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/council/inbox.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/council/minutes.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/council/state.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/council/view.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/devices.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/diff_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/doctor_voice.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/fetch.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/handoff/__init__.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/handoff/git_state.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/handoff/instructions.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/handoff/parser.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/handoff/renderer.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/handoff/schema.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/handoff_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/history.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/__init__.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/agentwire-permission.sh +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/__init__.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/audit_logger.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/bash-tool-damage-control.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/edit-tool-damage-control.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/mcp-tool-damage-control.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/read-tool-damage-control.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/rules/agentwire.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/rules/aws.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/rules/cloud-hosting.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/rules/containers.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/rules/control-plane.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/rules/core.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/rules/databases.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/rules/firebase.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/rules/gcp.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/rules/git.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/rules/gws.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/rules/infrastructure.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/rules/outbound.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/rules/publish.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/rules/remote.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/damage-control/write-tool-damage-control.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/idle-handler.sh +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks/queue-processor.sh +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/hooks_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/limits_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/listen.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/locking.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/machine_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_channels.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_chrome.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_core.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_council.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_desktop.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_handoff.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_history.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_listen.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_lock.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_machine.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_msg.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_notify.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_pane.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_projects.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_scheduler.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_scratchpad.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_server.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_services.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_session.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_status.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_tunnels.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_voice.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_wiki.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/mcp_worktree.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/msg_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/network.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/notify_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/onboarding.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/palette_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/pane_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/pane_manager.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/portal_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/project_config.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/projects.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/prompt_router.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/prompts_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/push_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/push_store.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/repo_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/research.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/__init__.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/agentwire.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/anchor.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/chatbot.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/contributor.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/correspondent.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/council-brain.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/council-conscience.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/council-critic.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/council-devils-advocate.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/council-gut.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/council-historian.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/council-member.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/council-orchestrator.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/init.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/notifications.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/orchestrator.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/reviewer-worktree.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/reviewer.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/shared-checkout.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/soul.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/task-runner.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/voice.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/worker-worktree.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles/worker.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/roles_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/routes/__init__.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/routes/artifacts.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/routes/config.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/routes/council.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/routes/desktop.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/routes/history.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/routes/machines.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/routes/notify.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/routes/palette.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/routes/permission.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/routes/projects.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/routes/push.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/routes/safety.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/routes/scratchpad.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/routes/sessions.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/routes/sessions_admin.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/routes/voice.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/safety/__init__.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/safety/_core.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/safety_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/safety_commands.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/scheduler/dispatch.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/scheduler/gates.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/scheduler/loop.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/scheduler/models.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/scheduler/schedule.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/scheduler/state.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/scratchpad.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/security.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/send_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/server.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/services.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/session_context.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/session_ready.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/ssh.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/agentwire-splash-logo-layers--agentwire-text.png +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/agentwire-splash-logo-layers--echo-claw-fg.png +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/agentwire-splash-logo-layers--echo.png +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/agentwire-splash-logo-layers--telephone.png +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/agentwire-splash-logo-layers--tree.png +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/announcements.json +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/apple-touch-icon.png +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/css/desktop.css +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/css/mobile.css +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/favicon-32.png +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/favicon-64.png +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/icons/sessions/bear.webp +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/icons/sessions/cat.webp +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/icons/sessions/crown.webp +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/icons/sessions/custom/agentwire-portal.webp +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/icons/sessions/custom/agentwire-tts.webp +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/icons/sessions/custom/agentwire.webp +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/icons/sessions/deer.webp +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/icons/sessions/drone.webp +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/icons/sessions/eagle.webp +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/icons/sessions/fox.webp +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/icons/sessions/hawk.webp +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/icons/sessions/horse.webp +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/icons/sessions/lion.webp +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/icons/sessions/rabbit.webp +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/icons/sessions/robot.webp +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/icons/sessions/tiger.webp +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/icons/sessions/wolf.webp +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/img/icon-192.png +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/img/icon-512.png +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/.gitkeep +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/announcement-modal.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/api.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/artifact-window.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/card-terminal.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/collage.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/command-palette.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/council-window.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/dead-key-suppressor.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/desktop-manager.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/desktop.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/help-modal.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/icon-manager.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/lineage.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/mobile.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/notification-prefs.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/notifications-panel.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/ptt.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/push-client.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/review-window.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/safety-shared.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/safety-window.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/scratchpad.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/service-classification.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/session-hud-controller.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/session-hud-notices.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/session-hud-spawn.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/session-hud.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/session-id.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/session-window.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/shortcuts.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/sidebar/artifacts-section.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/sidebar/config-section.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/sidebar/council-section.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/sidebar/machines-section.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/sidebar/projects-section.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/sidebar/safety-section.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/sidebar/scheduler-section.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/sidebar/services-section.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/sidebar/sessions-section.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/sidebar.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/spawn-ghost.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/terminal-font-prefs.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/terminal-pane.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/tile-manager.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/toast.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/token-modal.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/topology-render.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/utils/ansi.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/utils/rich-text.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/utils/swipe.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/voice/autosend-prefs.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/voice/browser-stt.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/voice/browser-tts.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/voice/jargon.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/voice/prompt.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/winbox.bundle.min.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/js/workspace-window.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/manifest.webmanifest +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/service-worker.js +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/static/topology-harness.html +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/stt/__init__.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/stt/base.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/stt/cloud.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/stt/engine.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/stt/local.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/stt/server_backend.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/stt/stt_server.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tabs_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/templates/__init__.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/templates/base.html +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/templates/council/minutes.html.j2 +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/templates/desktop.html +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/templates/email_notification.html +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/templates/handoff/show-the-story.html.j2 +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/templates/handoff/theme.css.j2 +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/templates/mobile.html +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/templates/pair.html +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/templates/statusline.sh +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/templates/tmux.conf +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/templating.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tooldefs/aws.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tooldefs/docker.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tooldefs/gcp.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tooldefs/gh.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tooldefs/git.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tooldefs/gws.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tooldefs/kubectl.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tooldefs/npm.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tooldefs/terraform.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tooldefs/uv.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tts/__init__.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tts/audio.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tts/base.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tts/engines/__init__.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tts/engines/chatterbox.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tts/engines/kokoro.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tts/engines/zonos.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tts/kokoro_server.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tts/local.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tts/registry.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tts_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tts_server.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tunnels.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/tunnels_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/usage_limit.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/utils/__init__.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/utils/chunker.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/utils/event_log.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/utils/file_io.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/utils/paths.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/utils/speech.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/utils/subprocess.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/validation.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/voice_status.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/wait_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/wiki.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/wiki_audit.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/wiki_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/worktree_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/agentwire/worktree_registry.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/decisions/obsidian-second-brain.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/design/session-card-fields.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/design/session-card-recommendation.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/logo.png +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/architecture.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/briefing-mode.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/communication/channels.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/communication/hammerspoon.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/communication/handoff.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/concepts.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/council.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/deployment/remote-access.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/deployment/remote-machines.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/glossary.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/integrations/gws-google-workspace-cli.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/internals/damage-control.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/internals/parallel-refactor.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/internals/portal.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/internals/session-topology.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/internals/shell-escaping.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/internals/troubleshooting.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/internals/window-collage.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/quickstart.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/research/briefing-mode-feasibility.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/research/orchestration-transport-alternatives.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/security/damage-control-hardening.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/security/pip-audit.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/security/remote-access-hardening.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/security/secrets.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/services.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/sessions/claude-code-auto-mode.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/sessions/fan-out-cohorts.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/sessions/helper-sessions.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/sessions/prompt-routing.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/sessions/window-sizing.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/sessions/worktree-sessions.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/usage-limit-recovery.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/voice/shim-contract.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/voice/stt-cloud.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/voice/stt-self-hosted.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/docs/wiki/voice/tts-self-hosted.md +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/conftest.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/e2e/test_portal_ui.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/fixtures/sample_agentwire.yml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/fixtures/sample_config.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/fixtures/sample_scheduler.yaml +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/integration/test_council_portal.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/integration/test_scheduler_board.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/integration/test_send_verified_tmux.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/integration/test_server_websockets.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_announcements.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_channels.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_chrome_tabs.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_cli_output.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_cli_smoke.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_cohort.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_config.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_config_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_control_plane_protection.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_core_created_by_rooting.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_council_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_council_inbox.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_council_minutes.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_council_state.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_council_view.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_damage_control_bypass.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_damage_control_hooks.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_damage_control_sync.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_dangling_worktrees.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_devices.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_diff_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_doctor_task_migration.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_doctor_voice.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_ensure_shared_dir.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_event_log.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_file_io.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_guarded_launch_command.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_handoff_git_state.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_handoff_instructions.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_handoff_parser.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_handoff_renderer.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_helper_session.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_history.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_hooks_install.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_idle_handler.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_idle_nag.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_init_command.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_install_parity.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_launch_via_env.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_limits_tick_isolation.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_locking.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_mcp_server.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_mcp_tools_args.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_msg_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_notify_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_onboarding_reinit.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_palette_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_pip_environment.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_portal_api.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_posture_default.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_project_config.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_projects_registry.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_push.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_rebuild_guard.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_repo_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_rich_text_js.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_roles.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_routes_snapshot.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_safety_commands.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_safety_disabled_rules.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_safety_escape_hatch.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_safety_heal.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_safety_kill_switch.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_scheduler.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_scheduler_parsing.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_scheduler_zombie.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_scratchpad.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_security.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_server_async.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_server_pure.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_services.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_session_context.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_session_created_by_env.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_session_ready.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_shared_dir_guard.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_shim_selfheal.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_skill_install.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_speech_tags.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_ssh.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_stt_backend.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_stt_cloud.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_stt_engine.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_task_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_tasks.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_tasks_cli.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_templating.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_terminal_resize.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_tmux_template.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_tts_engine_resolution.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_tts_local.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_tunnels_probe.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_unattended_env_isolation.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_usage_limit.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_validation.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_voice_status.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_wiki.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_wiki_audit.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_window_cycling_binding.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_worktree.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_worktree_branch_cleanup.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_worktree_git_truth.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.0}/tests/unit/test_worktree_layout.py +0 -0
- {agentwire_dev-1.66.0 → agentwire_dev-1.67.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.67.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
|
|
@@ -231,7 +231,7 @@ Requires-Dist: fastapi>=0.104.0
|
|
|
231
231
|
Requires-Dist: jinja2>=3.1.0
|
|
232
232
|
Requires-Dist: kokoro-onnx>=0.4.9; python_version < '3.14'
|
|
233
233
|
Requires-Dist: markdown>=3.5
|
|
234
|
-
Requires-Dist: mcp
|
|
234
|
+
Requires-Dist: mcp<2,>=1.2.0
|
|
235
235
|
Requires-Dist: pydantic>=2.0.0
|
|
236
236
|
Requires-Dist: python-dotenv>=1.2.2
|
|
237
237
|
Requires-Dist: python-multipart>=0.0.6
|
|
@@ -37,7 +37,6 @@ from .core import ( # noqa: E402,F401 # E402: must follow load_dotenv(); F401:
|
|
|
37
37
|
_parse_session_target,
|
|
38
38
|
_portal_auth_headers,
|
|
39
39
|
_post_desktop_notification,
|
|
40
|
-
_record_session_creator,
|
|
41
40
|
_resolve_posture_from_args,
|
|
42
41
|
_run_remote,
|
|
43
42
|
_set_session_name_env,
|
|
@@ -58,6 +57,7 @@ from .core import ( # noqa: E402,F401 # E402: must follow load_dotenv(); F401:
|
|
|
58
57
|
load_config,
|
|
59
58
|
load_session_metadata,
|
|
60
59
|
parse_env_args,
|
|
60
|
+
record_session_launch,
|
|
61
61
|
store_session_metadata,
|
|
62
62
|
tmux_session_exists,
|
|
63
63
|
tmux_session_has_agent,
|
|
@@ -187,25 +187,38 @@ def wait_for_completion_signal(
|
|
|
187
187
|
session: str,
|
|
188
188
|
poll_interval: float = 10.0,
|
|
189
189
|
summary_path: Path | None = None,
|
|
190
|
+
max_duration: int = 0,
|
|
190
191
|
) -> dict:
|
|
191
192
|
"""Wait for task completion by polling the summary file directly.
|
|
192
193
|
|
|
193
194
|
Exits when:
|
|
194
195
|
1. Summary file appears (task completed normally)
|
|
195
196
|
2. Session dies (agent crashed, tmux killed)
|
|
197
|
+
3. ``max_duration`` elapses, when the task sets one
|
|
196
198
|
|
|
197
|
-
|
|
199
|
+
Completion is otherwise agent-driven: the idle hook fires, the agent writes
|
|
200
|
+
a summary, and this returns. An agent that never goes idle never produces
|
|
201
|
+
either exit — wedged on an unrecognized dialog, or blocked inside a tool
|
|
202
|
+
call — and before ``max_duration`` existed the wait was unbounded, so that
|
|
203
|
+
read as a silent multi-hour hang whose only visible end was the scheduler's
|
|
204
|
+
4h process-group watchdog (#867).
|
|
205
|
+
|
|
206
|
+
``max_duration`` is a per-attempt wall clock, not an idle timer: it can't
|
|
207
|
+
tell a wedged agent from a slow one, so a task that legitimately runs long
|
|
208
|
+
should set it high or leave it at 0 rather than get killed mid-work.
|
|
198
209
|
|
|
199
210
|
Args:
|
|
200
211
|
session: tmux session name
|
|
201
212
|
poll_interval: Seconds between checks
|
|
202
213
|
summary_path: Path to the summary .md file the agent will write
|
|
214
|
+
max_duration: Seconds before giving up (0 = unbounded)
|
|
203
215
|
|
|
204
216
|
Returns:
|
|
205
217
|
Dict with 'status', 'summary', 'summary_file' keys
|
|
206
218
|
|
|
207
219
|
Raises:
|
|
208
|
-
CompletionTimeout: If session dies
|
|
220
|
+
CompletionTimeout: If the session dies, or max_duration elapses, before
|
|
221
|
+
the task completed. The message names which.
|
|
209
222
|
"""
|
|
210
223
|
# Build glob pattern for fuzzy summary detection (agents sometimes
|
|
211
224
|
# invent their own timestamp instead of using the provided filename).
|
|
@@ -217,6 +230,8 @@ def wait_for_completion_signal(
|
|
|
217
230
|
prefix = stem[:-19] if len(stem) > 19 else stem
|
|
218
231
|
summary_glob = f"{prefix}*.md"
|
|
219
232
|
|
|
233
|
+
started = time.time()
|
|
234
|
+
|
|
220
235
|
while True:
|
|
221
236
|
# Primary: check if the agent has written the summary file AND
|
|
222
237
|
# the hook has deleted the context file (signals cleanup complete).
|
|
@@ -274,6 +289,14 @@ def wait_for_completion_signal(
|
|
|
274
289
|
f"Session '{session}' died or agent exited before task completed"
|
|
275
290
|
)
|
|
276
291
|
|
|
292
|
+
if max_duration > 0:
|
|
293
|
+
elapsed = time.time() - started
|
|
294
|
+
if elapsed >= max_duration:
|
|
295
|
+
raise CompletionTimeout(
|
|
296
|
+
f"Task exceeded max_duration ({max_duration}s) after "
|
|
297
|
+
f"{int(elapsed)}s — the agent never signalled completion"
|
|
298
|
+
)
|
|
299
|
+
|
|
277
300
|
time.sleep(poll_interval)
|
|
278
301
|
|
|
279
302
|
|
|
@@ -16,6 +16,7 @@ import sys
|
|
|
16
16
|
import sysconfig
|
|
17
17
|
import tempfile
|
|
18
18
|
import urllib.request
|
|
19
|
+
import uuid
|
|
19
20
|
from dataclasses import dataclass, field
|
|
20
21
|
from pathlib import Path
|
|
21
22
|
|
|
@@ -27,11 +28,24 @@ from .project_config import (
|
|
|
27
28
|
resolve_posture,
|
|
28
29
|
)
|
|
29
30
|
from .roles import RoleConfig, merge_roles
|
|
30
|
-
from .worktree import git_common_dir, parse_session_name
|
|
31
|
+
from .worktree import git_common_dir, git_root, main_worktree, parse_session_name
|
|
31
32
|
|
|
32
33
|
# Default config directory
|
|
33
34
|
CONFIG_DIR = Path.home() / ".agentwire"
|
|
34
35
|
|
|
36
|
+
# Durable home for the per-conversation `--append-system-prompt` file (#871).
|
|
37
|
+
#
|
|
38
|
+
# This used to be a `tempfile.NamedTemporaryFile` under /var/folders, which
|
|
39
|
+
# macOS garbage-collects. The launch line references the file by path
|
|
40
|
+
# (`--append-system-prompt "$(<path>)"`), so once the GC ran, relaunching a
|
|
41
|
+
# session older than the GC window substituted an EMPTY string: the
|
|
42
|
+
# conversation came back, the role silently did not. Nothing failed loudly —
|
|
43
|
+
# the agent just quietly stopped being a worker/orchestrator/reviewer.
|
|
44
|
+
#
|
|
45
|
+
# Keyed by conversation id so the prompt a conversation launched with stays
|
|
46
|
+
# recoverable even after its session's roles change.
|
|
47
|
+
ROLE_PROMPTS_DIR = CONFIG_DIR / "role-prompts"
|
|
48
|
+
|
|
35
49
|
|
|
36
50
|
def _check_tmux_installed() -> bool:
|
|
37
51
|
"""Check tmux is on PATH; print install hint if not. Returns False on miss."""
|
|
@@ -68,10 +82,22 @@ def _tmux_global_option(name: str) -> str | None:
|
|
|
68
82
|
|
|
69
83
|
@dataclass
|
|
70
84
|
class AgentCommand:
|
|
71
|
-
"""Result of building an agent command.
|
|
85
|
+
"""Result of building an agent command.
|
|
86
|
+
|
|
87
|
+
Carries not just the shell command but the full launch identity (#871):
|
|
88
|
+
the conversation UUID we minted, the durable role-prompt file, and the
|
|
89
|
+
posture/role names needed to REGENERATE that prompt later. The flag
|
|
90
|
+
builder is the only place that knows all four, so it stamps them here and
|
|
91
|
+
:func:`record_session_launch` copies them onto disk verbatim — no caller
|
|
92
|
+
can pair a conversation id with the wrong prompt or posture.
|
|
93
|
+
"""
|
|
72
94
|
command: str # The shell command to execute
|
|
73
|
-
|
|
95
|
+
role_prompt_path: str | None = None # Durable --append-system-prompt file (see ROLE_PROMPTS_DIR)
|
|
74
96
|
env: dict[str, str] = field(default_factory=dict) # Secrets to inject via tmux set-environment (keeps keys out of `ps`)
|
|
97
|
+
conversation_id: str | None = None # UUID passed as `claude --session-id` (None for bare)
|
|
98
|
+
resumed_from: str | None = None # Conversation this one was forked off, if any
|
|
99
|
+
posture: str = BARE
|
|
100
|
+
roles: list[str] = field(default_factory=list) # Role NAMES, in merge order
|
|
75
101
|
|
|
76
102
|
|
|
77
103
|
_UNATTENDED_ENV_KEYS = ("AGENTWIRE_UNATTENDED", "AGENTWIRE_UNATTENDED_ALLOW")
|
|
@@ -213,6 +239,99 @@ def parse_env_args(env_args: list[str] | None) -> dict[str, str]:
|
|
|
213
239
|
return result
|
|
214
240
|
|
|
215
241
|
|
|
242
|
+
# Owner-only, matching the posture of `~/.agentwire/.env` (chmod 600). A role
|
|
243
|
+
# prompt is complete system-prompt text — role content, project context,
|
|
244
|
+
# whatever else the prompt carries — and unlike the tempfile it replaced (0600
|
|
245
|
+
# and transient) this store is PERMANENT. Both modes are forced rather than
|
|
246
|
+
# requested, because `mkdir(mode=)` and `open(mode=)` are masked by umask and
|
|
247
|
+
# neither touches an already-existing path: a directory created before this
|
|
248
|
+
# rule, or under a permissive umask, must heal on the next write rather than
|
|
249
|
+
# stay world-readable forever.
|
|
250
|
+
#
|
|
251
|
+
# Same posture and same fchmod-before-any-bytes-land technique as
|
|
252
|
+
# ``security.write_token_file``; not shared with it because that one is bound
|
|
253
|
+
# to TOKEN_FILE and adds atomic-replace semantics this store doesn't need (the
|
|
254
|
+
# prompt is written before the launch line that reads it, and never rotated
|
|
255
|
+
# under a live reader). If a third owner-only writer appears, extract one.
|
|
256
|
+
_PROMPT_FILE_MODE = 0o600
|
|
257
|
+
_PROMPT_DIR_MODE = 0o700
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
def write_role_prompt(conversation_id: str, instructions: str) -> Path:
|
|
261
|
+
"""Write *instructions* to this conversation's durable role-prompt file.
|
|
262
|
+
|
|
263
|
+
The one place a role prompt is written to disk (see :data:`ROLE_PROMPTS_DIR`
|
|
264
|
+
for why "durable" is load-bearing). Returns the path the launch line
|
|
265
|
+
should read; the file deliberately OUTLIVES the launch so a later
|
|
266
|
+
relaunch can reuse it, and the recorded ``roles``/``posture`` can
|
|
267
|
+
regenerate it if it's ever gone.
|
|
268
|
+
|
|
269
|
+
Written owner-only, and never through a window where it isn't: the mode
|
|
270
|
+
is set at ``os.open`` time rather than chmod'ed after a plain write, so
|
|
271
|
+
the content is never briefly world-readable on disk.
|
|
272
|
+
"""
|
|
273
|
+
ROLE_PROMPTS_DIR.mkdir(parents=True, exist_ok=True)
|
|
274
|
+
os.chmod(ROLE_PROMPTS_DIR, _PROMPT_DIR_MODE)
|
|
275
|
+
|
|
276
|
+
path = ROLE_PROMPTS_DIR / f"{conversation_id}.txt"
|
|
277
|
+
fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, _PROMPT_FILE_MODE)
|
|
278
|
+
with os.fdopen(fd, "w") as f:
|
|
279
|
+
# umask can only CLEAR bits at create time, and an existing file keeps
|
|
280
|
+
# its old mode — so state it exactly, on the descriptor we hold.
|
|
281
|
+
os.fchmod(fd, _PROMPT_FILE_MODE)
|
|
282
|
+
f.write(instructions)
|
|
283
|
+
return path
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def mirror_role_prompt_remote(agent: "AgentCommand", machine_id: str, agent_cmd: str) -> str:
|
|
287
|
+
"""Copy a role prompt to *machine_id* and repoint the launch line at it.
|
|
288
|
+
|
|
289
|
+
The launch line references the prompt BY PATH
|
|
290
|
+
(``--append-system-prompt "$(<path>)"``), so a remote session handed a
|
|
291
|
+
local path reads a file that isn't there and starts with an EMPTY system
|
|
292
|
+
prompt — the same silent role-loss the /var/folders GC caused, just
|
|
293
|
+
reached by a different route. The one implementation of the mirror, used
|
|
294
|
+
by every remote launch (``new`` / ``recreate`` / ``fork``); only ``new``
|
|
295
|
+
had it before, and only into ``/tmp``.
|
|
296
|
+
|
|
297
|
+
Mutates ``agent.role_prompt_path`` to the remote path so the recorded
|
|
298
|
+
identity names where the prompt actually lives for that session. Returns
|
|
299
|
+
the rewritten command (unchanged on failure — best-effort, matching the
|
|
300
|
+
rest of the remote path's tolerance).
|
|
301
|
+
"""
|
|
302
|
+
if not agent.role_prompt_path or not agent_cmd:
|
|
303
|
+
return agent_cmd
|
|
304
|
+
try:
|
|
305
|
+
content = Path(agent.role_prompt_path).read_text()
|
|
306
|
+
except OSError as e:
|
|
307
|
+
print(f"Warning: Failed to read system prompt: {e}", file=sys.stderr)
|
|
308
|
+
return agent_cmd
|
|
309
|
+
|
|
310
|
+
# `$HOME`, not `~`: this path is substituted into the launch line mid-word
|
|
311
|
+
# (`"$(<...)"`) where tilde expansion is not guaranteed, and it is
|
|
312
|
+
# recorded verbatim — the remote's home isn't knowable from here.
|
|
313
|
+
remote_dir = "$HOME/.agentwire/role-prompts"
|
|
314
|
+
remote_prompt = f"{remote_dir}/{agent.conversation_id}.txt"
|
|
315
|
+
# Same owner-only posture as the local store, stated the same way: `umask
|
|
316
|
+
# 077` covers the create, and the explicit chmods cover a pre-existing
|
|
317
|
+
# path (which umask never touches) on a remote whose defaults we don't
|
|
318
|
+
# control. The heredoc body starts on the line after the full command.
|
|
319
|
+
write_cmd = (
|
|
320
|
+
f'umask 077 && mkdir -p "{remote_dir}" && chmod 700 "{remote_dir}" && '
|
|
321
|
+
f'cat > "{remote_prompt}" << \'AGENTWIRE_EOF\'\n{content}\nAGENTWIRE_EOF\n'
|
|
322
|
+
f'chmod 600 "{remote_prompt}"'
|
|
323
|
+
)
|
|
324
|
+
result = _run_remote(machine_id, write_cmd)
|
|
325
|
+
if result.returncode != 0:
|
|
326
|
+
print(f"Warning: Failed to write system prompt to {machine_id}: {result.stderr}",
|
|
327
|
+
file=sys.stderr)
|
|
328
|
+
return agent_cmd
|
|
329
|
+
|
|
330
|
+
rewritten = agent_cmd.replace(agent.role_prompt_path, remote_prompt)
|
|
331
|
+
agent.role_prompt_path = remote_prompt
|
|
332
|
+
return rewritten
|
|
333
|
+
|
|
334
|
+
|
|
216
335
|
def build_agent_command(
|
|
217
336
|
posture: str,
|
|
218
337
|
roles: list[RoleConfig] | None = None,
|
|
@@ -227,15 +346,36 @@ def build_agent_command(
|
|
|
227
346
|
is the no-agent sentinel (empty command); ``resume_session_id`` prepends the
|
|
228
347
|
``--resume/--fork-session`` pair right after ``claude`` so the resumed
|
|
229
348
|
process still gets its posture's grants (incl. auto's tool-allows).
|
|
349
|
+
|
|
350
|
+
Conversation identity (#871): agentwire MINTS the conversation UUID here
|
|
351
|
+
and passes it as ``claude --session-id``, rather than discovering it after
|
|
352
|
+
the fact by watching ``~/.claude/projects/<encoded-cwd>/`` for the newest
|
|
353
|
+
``.jsonl``. The record on disk is therefore authoritative, not a guess.
|
|
354
|
+
|
|
355
|
+
Two verified properties of the flag drive the design:
|
|
356
|
+
|
|
357
|
+
- ``--session-id`` REFUSES to start on collision ("Session ID <id> is
|
|
358
|
+
already in use.") — but the check is scoped to the launch cwd, since
|
|
359
|
+
that's what keys the history dir. A fresh uuid4 per call is the only
|
|
360
|
+
safe input; never re-pass a previously recorded id here (that's what
|
|
361
|
+
``resume_session_id`` is for).
|
|
362
|
+
- ``--resume <old> --fork-session --session-id <new>`` composes: the fork
|
|
363
|
+
lands at the id WE chose, so a resumed session's new conversation is
|
|
364
|
+
just as recorded as a fresh one's. That's what makes
|
|
365
|
+
``conversation_ids`` a chain rather than a scalar that goes stale on
|
|
366
|
+
the first resume.
|
|
230
367
|
"""
|
|
231
368
|
if posture == BARE:
|
|
232
|
-
return AgentCommand(command="")
|
|
369
|
+
return AgentCommand(command="", posture=BARE)
|
|
233
370
|
|
|
234
371
|
merged = merge_roles(roles) if roles else None
|
|
372
|
+
role_names = [r.name for r in roles] if roles else []
|
|
373
|
+
conversation_id = str(uuid.uuid4())
|
|
235
374
|
|
|
236
375
|
parts = ["claude"]
|
|
237
376
|
if resume_session_id:
|
|
238
377
|
parts.extend(["--resume", resume_session_id, "--fork-session"])
|
|
378
|
+
parts.extend(["--session-id", conversation_id])
|
|
239
379
|
|
|
240
380
|
# Permission-mode flags (one per posture; prompted adds none — hooks gate it)
|
|
241
381
|
if posture == "bypass":
|
|
@@ -255,7 +395,7 @@ def build_agent_command(
|
|
|
255
395
|
parts.append(f"--model {model}")
|
|
256
396
|
|
|
257
397
|
# Role-based flags (merged roles always apply — no tool-locking posture left)
|
|
258
|
-
|
|
398
|
+
role_prompt_path = None
|
|
259
399
|
if merged:
|
|
260
400
|
if merged.tools:
|
|
261
401
|
parts.append(f"--tools {','.join(merged.tools)}")
|
|
@@ -264,18 +404,19 @@ def build_agent_command(
|
|
|
264
404
|
parts.append(f"--disallowedTools {','.join(merged.disallowed_tools)}")
|
|
265
405
|
|
|
266
406
|
if merged.instructions:
|
|
267
|
-
#
|
|
268
|
-
#
|
|
269
|
-
#
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
f.close()
|
|
273
|
-
temp_file = f.name
|
|
274
|
-
parts.append(f'--append-system-prompt "$(<{temp_file})"')
|
|
407
|
+
# Written to a file rather than inlined to avoid shell escaping
|
|
408
|
+
# issues (see docs/wiki/internals/shell-escaping.md), and MUST be
|
|
409
|
+
# the last flag — multiline content can break subsequent args.
|
|
410
|
+
role_prompt_path = str(write_role_prompt(conversation_id, merged.instructions))
|
|
411
|
+
parts.append(f'--append-system-prompt "$(<{role_prompt_path})"')
|
|
275
412
|
|
|
276
413
|
return AgentCommand(
|
|
277
414
|
command=" ".join(parts),
|
|
278
|
-
|
|
415
|
+
role_prompt_path=role_prompt_path,
|
|
416
|
+
conversation_id=conversation_id,
|
|
417
|
+
resumed_from=resume_session_id,
|
|
418
|
+
posture=posture,
|
|
419
|
+
roles=role_names,
|
|
279
420
|
)
|
|
280
421
|
|
|
281
422
|
|
|
@@ -735,41 +876,129 @@ def store_session_metadata(session_name: str, metadata: dict) -> None:
|
|
|
735
876
|
pass
|
|
736
877
|
|
|
737
878
|
|
|
738
|
-
def
|
|
739
|
-
"""
|
|
879
|
+
def git_identity(cwd) -> dict:
|
|
880
|
+
"""The ``repo`` / ``branch`` / ``worktree_path`` triple for a launch cwd.
|
|
740
881
|
|
|
741
|
-
|
|
742
|
-
|
|
882
|
+
Asked of GIT, never string-built from a naming convention — the same rule
|
|
883
|
+
that #837 had to retrofit onto worktree paths and #868 onto session names.
|
|
884
|
+
``worktree_path`` is None when *cwd* is the repo's MAIN checkout, so its
|
|
885
|
+
presence alone answers "is this session running in a linked worktree".
|
|
743
886
|
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
since `not created_by` is also true for `''`.
|
|
887
|
+
Every value is None off-repo (and for a remote session's path, which
|
|
888
|
+
doesn't exist locally); a caller must read a missing key as "unknown",
|
|
889
|
+
never as "the conventional value".
|
|
748
890
|
"""
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
891
|
+
blank = {"repo": None, "branch": None, "worktree_path": None}
|
|
892
|
+
path = Path(cwd)
|
|
893
|
+
if not path.exists():
|
|
894
|
+
return blank
|
|
895
|
+
|
|
896
|
+
top = git_root(path)
|
|
897
|
+
if top is None:
|
|
898
|
+
return blank
|
|
899
|
+
|
|
900
|
+
main = main_worktree(top)
|
|
901
|
+
branch = subprocess.run(
|
|
902
|
+
["git", "-C", str(path), "rev-parse", "--abbrev-ref", "HEAD"],
|
|
903
|
+
capture_output=True, text=True,
|
|
904
|
+
)
|
|
905
|
+
branch_name = branch.stdout.strip() if branch.returncode == 0 else ""
|
|
906
|
+
# Detached HEAD reports the literal "HEAD" — not a branch, so record none.
|
|
907
|
+
if branch_name == "HEAD":
|
|
908
|
+
branch_name = ""
|
|
758
909
|
|
|
910
|
+
return {
|
|
911
|
+
"repo": str(main),
|
|
912
|
+
"branch": branch_name or None,
|
|
913
|
+
"worktree_path": str(top) if top.resolve() != Path(main).resolve() else None,
|
|
914
|
+
}
|
|
759
915
|
|
|
760
|
-
def _record_session_role(session_name: str, role: str | None) -> None:
|
|
761
|
-
"""Record the session's ROLE axis (orchestrator/worker/reviewer) to disk (merge-preserving).
|
|
762
916
|
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
917
|
+
def record_session_launch(
|
|
918
|
+
session_name: str,
|
|
919
|
+
agent: "AgentCommand",
|
|
920
|
+
cwd,
|
|
921
|
+
*,
|
|
922
|
+
created_by: str | None = None,
|
|
923
|
+
created_via: str | None = None,
|
|
924
|
+
role: str | None = None,
|
|
925
|
+
remote: bool = False,
|
|
926
|
+
) -> dict:
|
|
927
|
+
"""Record a session's launch identity — the ONE writer of metadata.json (#871).
|
|
928
|
+
|
|
929
|
+
Every path that starts an agent in a tmux SESSION calls this exactly once,
|
|
930
|
+
right after the launch: ``new`` (and therefore ``worktree`` /
|
|
931
|
+
``orchestrator`` / scheduler+ensure dispatch, which all delegate to it),
|
|
932
|
+
``recreate``, ``fork``, ``history resume``, and ``dev``. Routing them all
|
|
933
|
+
through one function is the point: a creation path that hand-rolls its own
|
|
934
|
+
record is exactly how the worktree-path (#837) and session-name (#868)
|
|
935
|
+
conventions each drifted into a bug that reported success while doing
|
|
936
|
+
nothing.
|
|
937
|
+
|
|
938
|
+
Deliberately NOT called by ``spawn`` — a worker pane is not a session, and
|
|
939
|
+
this store is keyed by session name, so a pane recording here would
|
|
940
|
+
overwrite its OWNING session's record. Panes still get a minted
|
|
941
|
+
conversation id and a durable role prompt from ``build_agent_command``;
|
|
942
|
+
they just have nowhere session-scoped to write it.
|
|
943
|
+
|
|
944
|
+
What comes from where:
|
|
945
|
+
|
|
946
|
+
- ``agent`` supplies conversation id, role-prompt path, posture and role
|
|
947
|
+
names — the flag builder is the only thing that knows them, and taking
|
|
948
|
+
the whole object means a caller can't pair them wrong.
|
|
949
|
+
- ``cwd`` supplies ``cwd_at_launch`` verbatim plus the git-derived
|
|
950
|
+
repo/branch/worktree triple. ``cwd_at_launch`` is what a later check
|
|
951
|
+
compares against Claude's own history key
|
|
952
|
+
(``~/.claude/projects/<encoded-cwd>/``) to detect history orphaned by a
|
|
953
|
+
moved worktree. ``remote=True`` records the path but skips the git
|
|
954
|
+
derivation — the path lives on another machine, and a same-named local
|
|
955
|
+
directory would otherwise answer with some other repo's branch.
|
|
956
|
+
- ``roles`` + ``posture`` are recorded to REGENERATE the system prompt,
|
|
957
|
+
not merely to reference it — a role-prompt file that has gone missing
|
|
958
|
+
is recoverable from them.
|
|
959
|
+
|
|
960
|
+
Merge-preserving, and ``conversation_ids`` APPENDS: ``--fork-session``
|
|
961
|
+
mints a new id on every resume, so identity is a chain, not a scalar.
|
|
767
962
|
"""
|
|
768
|
-
|
|
769
|
-
return
|
|
963
|
+
clean_name = session_name.split("@")[0]
|
|
770
964
|
metadata = load_session_metadata(session_name)
|
|
771
|
-
|
|
965
|
+
now = datetime.datetime.now(datetime.timezone.utc).isoformat()
|
|
966
|
+
|
|
967
|
+
# ``created_by`` of ``''`` means "explicitly rootless" and must still be
|
|
968
|
+
# written — otherwise a re-`new`/`recreate` that forces standalone (e.g.
|
|
969
|
+
# `--created-by ''`) leaves a stale parent from a prior creation in place,
|
|
970
|
+
# since `not created_by` is also true for `''`. ``None`` means the caller
|
|
971
|
+
# has no opinion, and must not clobber what's already recorded.
|
|
972
|
+
if created_by is not None and created_by != clean_name:
|
|
973
|
+
metadata["created_by"] = created_by
|
|
974
|
+
if created_via:
|
|
975
|
+
metadata["created_via"] = created_via
|
|
976
|
+
|
|
977
|
+
# The ROLE axis (orchestrator/worker/reviewer) — distinct from the
|
|
978
|
+
# etiquette/persona ``roles`` list below. Read back by
|
|
979
|
+
# list_local_sessions() and the session_created notify lookup.
|
|
980
|
+
if role:
|
|
981
|
+
metadata["role"] = role
|
|
982
|
+
|
|
983
|
+
if agent.conversation_id:
|
|
984
|
+
chain = list(metadata.get("conversation_ids") or [])
|
|
985
|
+
if agent.conversation_id not in chain:
|
|
986
|
+
chain.append(agent.conversation_id)
|
|
987
|
+
metadata["conversation_ids"] = chain
|
|
988
|
+
|
|
989
|
+
metadata.update({
|
|
990
|
+
"cwd_at_launch": str(cwd),
|
|
991
|
+
"posture": agent.posture,
|
|
992
|
+
"roles": list(agent.roles),
|
|
993
|
+
"role_prompt_path": agent.role_prompt_path,
|
|
994
|
+
"launched_at": now,
|
|
995
|
+
**({"repo": None, "branch": None, "worktree_path": None}
|
|
996
|
+
if remote else git_identity(cwd)),
|
|
997
|
+
})
|
|
998
|
+
metadata.setdefault("created_at", now)
|
|
999
|
+
|
|
772
1000
|
store_session_metadata(session_name, metadata)
|
|
1001
|
+
return metadata
|
|
773
1002
|
|
|
774
1003
|
|
|
775
1004
|
def notify_portal_session_created(session_name: str, parent: str | None, role: str | None) -> None:
|