agentwire-dev 1.79.0__tar.gz → 1.80.0__tar.gz

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