agentwire-dev 1.65.0__tar.gz → 1.65.1__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 (509) hide show
  1. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/PKG-INFO +1 -1
  2. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/__init__.py +1 -1
  3. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/core.py +12 -0
  4. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/inbox.py +65 -32
  5. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/sessions/messaging.md +8 -2
  6. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/conftest.py +1 -1
  7. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_core_created_by_rooting.py +11 -0
  8. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_inbox.py +71 -7
  9. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/.agentwire.yml.example +0 -0
  10. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/.claude/commands/handoff.md +0 -0
  11. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/.claude/skills/wiki/SKILL.md +0 -0
  12. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/.github/FUNDING.yml +0 -0
  13. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  14. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  15. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/.github/ISSUE_TEMPLATE/question.md +0 -0
  16. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  17. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/.github/workflows/pytest.yml +0 -0
  18. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/.github/workflows/ruff.yml +0 -0
  19. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/.github/workflows/security.yml +0 -0
  20. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/.github/workflows/tts-smoke.yml +0 -0
  21. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/.gitignore +0 -0
  22. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/AGENTS.md +0 -0
  23. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/CODE_OF_CONDUCT.md +0 -0
  24. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/CONTRIBUTING.md +0 -0
  25. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/Dockerfile.local +0 -0
  26. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/LICENSE +0 -0
  27. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/README.md +0 -0
  28. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/RELEASING.md +0 -0
  29. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/SECURITY.md +0 -0
  30. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/SPONSORS.md +0 -0
  31. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/__main__.py +0 -0
  32. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/agents/__init__.py +0 -0
  33. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/agents/base.py +0 -0
  34. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/agents/tmux.py +0 -0
  35. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/cached_status.py +0 -0
  36. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/channels/__init__.py +0 -0
  37. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/channels/base.py +0 -0
  38. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/channels/email.py +0 -0
  39. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/channels/push.py +0 -0
  40. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/channels/quo.py +0 -0
  41. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/channels_cli.py +0 -0
  42. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/chrome_tabs.py +0 -0
  43. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/completion.py +0 -0
  44. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/config.py +0 -0
  45. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/config_cli.py +0 -0
  46. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/council/__init__.py +0 -0
  47. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/council/cli.py +0 -0
  48. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/council/inbox.py +0 -0
  49. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/council/minutes.py +0 -0
  50. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/council/state.py +0 -0
  51. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/council/view.py +0 -0
  52. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/devices.py +0 -0
  53. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/diff_cli.py +0 -0
  54. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/doctor_cli.py +0 -0
  55. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/doctor_voice.py +0 -0
  56. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/ensure_cli.py +0 -0
  57. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/fetch.py +0 -0
  58. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/handoff/__init__.py +0 -0
  59. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/handoff/git_state.py +0 -0
  60. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/handoff/instructions.py +0 -0
  61. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/handoff/parser.py +0 -0
  62. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/handoff/renderer.py +0 -0
  63. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/handoff/schema.py +0 -0
  64. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/handoff_cli.py +0 -0
  65. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/history.py +0 -0
  66. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/history_cli.py +0 -0
  67. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/__init__.py +0 -0
  68. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/agentwire-permission.sh +0 -0
  69. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/__init__.py +0 -0
  70. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/audit_logger.py +0 -0
  71. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/bash-tool-damage-control.py +0 -0
  72. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/edit-tool-damage-control.py +0 -0
  73. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/mcp-tool-damage-control.py +0 -0
  74. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/read-tool-damage-control.py +0 -0
  75. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/rules/agentwire.yaml +0 -0
  76. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/rules/aws.yaml +0 -0
  77. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/rules/cloud-hosting.yaml +0 -0
  78. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/rules/containers.yaml +0 -0
  79. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/rules/control-plane.yaml +0 -0
  80. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/rules/core.yaml +0 -0
  81. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/rules/databases.yaml +0 -0
  82. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/rules/firebase.yaml +0 -0
  83. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/rules/gcp.yaml +0 -0
  84. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/rules/git.yaml +0 -0
  85. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/rules/gws.yaml +0 -0
  86. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/rules/infrastructure.yaml +0 -0
  87. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/rules/outbound.yaml +0 -0
  88. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/rules/publish.yaml +0 -0
  89. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/rules/remote.yaml +0 -0
  90. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/damage-control/write-tool-damage-control.py +0 -0
  91. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/idle-handler.sh +0 -0
  92. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks/queue-processor.sh +0 -0
  93. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/hooks_cli.py +0 -0
  94. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/limits_cli.py +0 -0
  95. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/listen.py +0 -0
  96. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/locking.py +0 -0
  97. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/machine_cli.py +0 -0
  98. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_channels.py +0 -0
  99. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_chrome.py +0 -0
  100. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_cli.py +0 -0
  101. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_core.py +0 -0
  102. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_council.py +0 -0
  103. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_desktop.py +0 -0
  104. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_handoff.py +0 -0
  105. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_history.py +0 -0
  106. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_listen.py +0 -0
  107. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_lock.py +0 -0
  108. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_machine.py +0 -0
  109. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_msg.py +0 -0
  110. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_notify.py +0 -0
  111. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_pane.py +0 -0
  112. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_projects.py +0 -0
  113. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_scheduler.py +0 -0
  114. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_scratchpad.py +0 -0
  115. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_server.py +0 -0
  116. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_services.py +0 -0
  117. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_session.py +0 -0
  118. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_status.py +0 -0
  119. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_task.py +0 -0
  120. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_tunnels.py +0 -0
  121. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_voice.py +0 -0
  122. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_wiki.py +0 -0
  123. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/mcp_worktree.py +0 -0
  124. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/msg_cli.py +0 -0
  125. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/network.py +0 -0
  126. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/notify_cli.py +0 -0
  127. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/onboarding.py +0 -0
  128. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/palette_cli.py +0 -0
  129. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/pane_cli.py +0 -0
  130. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/pane_manager.py +0 -0
  131. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/portal_cli.py +0 -0
  132. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/project_config.py +0 -0
  133. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/projects.py +0 -0
  134. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/prompt_router.py +0 -0
  135. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/prompts_cli.py +0 -0
  136. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/push_cli.py +0 -0
  137. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/push_store.py +0 -0
  138. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/repo_cli.py +0 -0
  139. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/research.py +0 -0
  140. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/__init__.py +0 -0
  141. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/agentwire.md +0 -0
  142. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/anchor.md +0 -0
  143. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/chatbot.md +0 -0
  144. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/contributor.md +0 -0
  145. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/correspondent.md +0 -0
  146. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/council-brain.md +0 -0
  147. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/council-conscience.md +0 -0
  148. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/council-critic.md +0 -0
  149. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/council-devils-advocate.md +0 -0
  150. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/council-gut.md +0 -0
  151. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/council-historian.md +0 -0
  152. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/council-member.md +0 -0
  153. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/council-orchestrator.md +0 -0
  154. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/init.md +0 -0
  155. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/notifications.md +0 -0
  156. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/orchestrator.md +0 -0
  157. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/reviewer-worktree.md +0 -0
  158. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/reviewer.md +0 -0
  159. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/soul.md +0 -0
  160. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/task-runner.md +0 -0
  161. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/voice.md +0 -0
  162. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/worker-worktree.md +0 -0
  163. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles/worker.md +0 -0
  164. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/roles_cli.py +0 -0
  165. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/routes/__init__.py +0 -0
  166. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/routes/artifacts.py +0 -0
  167. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/routes/config.py +0 -0
  168. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/routes/council.py +0 -0
  169. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/routes/desktop.py +0 -0
  170. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/routes/history.py +0 -0
  171. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/routes/machines.py +0 -0
  172. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/routes/notify.py +0 -0
  173. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/routes/palette.py +0 -0
  174. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/routes/permission.py +0 -0
  175. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/routes/projects.py +0 -0
  176. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/routes/push.py +0 -0
  177. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/routes/safety.py +0 -0
  178. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/routes/scheduler.py +0 -0
  179. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/routes/scratchpad.py +0 -0
  180. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/routes/sessions.py +0 -0
  181. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/routes/sessions_admin.py +0 -0
  182. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/routes/voice.py +0 -0
  183. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/safety/__init__.py +0 -0
  184. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/safety/_core.py +0 -0
  185. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/safety_cli.py +0 -0
  186. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/safety_commands.py +0 -0
  187. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/scheduler/__init__.py +0 -0
  188. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/scheduler/dispatch.py +0 -0
  189. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/scheduler/gates.py +0 -0
  190. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/scheduler/loop.py +0 -0
  191. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/scheduler/models.py +0 -0
  192. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/scheduler/report.py +0 -0
  193. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/scheduler/schedule.py +0 -0
  194. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/scheduler/state.py +0 -0
  195. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/scheduler/zombie.py +0 -0
  196. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/scheduler_cli.py +0 -0
  197. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/scratchpad.py +0 -0
  198. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/security.py +0 -0
  199. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/send_cli.py +0 -0
  200. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/server.py +0 -0
  201. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/services.py +0 -0
  202. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/session_cli.py +0 -0
  203. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/session_context.py +0 -0
  204. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/session_ready.py +0 -0
  205. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/ssh.py +0 -0
  206. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/agentwire-splash-logo-layers--agentwire-text.png +0 -0
  207. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/agentwire-splash-logo-layers--echo-claw-fg.png +0 -0
  208. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/agentwire-splash-logo-layers--echo.png +0 -0
  209. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/agentwire-splash-logo-layers--telephone.png +0 -0
  210. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/agentwire-splash-logo-layers--tree.png +0 -0
  211. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/announcements.json +0 -0
  212. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/apple-touch-icon.png +0 -0
  213. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/css/desktop.css +0 -0
  214. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/css/mobile.css +0 -0
  215. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/favicon-32.png +0 -0
  216. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/favicon-64.png +0 -0
  217. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/icons/sessions/bear.webp +0 -0
  218. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/icons/sessions/cat.webp +0 -0
  219. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/icons/sessions/crown.webp +0 -0
  220. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/icons/sessions/custom/agentwire-portal.webp +0 -0
  221. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/icons/sessions/custom/agentwire-tts.webp +0 -0
  222. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/icons/sessions/custom/agentwire.webp +0 -0
  223. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/icons/sessions/deer.webp +0 -0
  224. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/icons/sessions/drone.webp +0 -0
  225. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/icons/sessions/eagle.webp +0 -0
  226. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/icons/sessions/fox.webp +0 -0
  227. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/icons/sessions/hawk.webp +0 -0
  228. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/icons/sessions/horse.webp +0 -0
  229. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/icons/sessions/lion.webp +0 -0
  230. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/icons/sessions/rabbit.webp +0 -0
  231. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/icons/sessions/robot.webp +0 -0
  232. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/icons/sessions/tiger.webp +0 -0
  233. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/icons/sessions/wolf.webp +0 -0
  234. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/img/icon-192.png +0 -0
  235. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/img/icon-512.png +0 -0
  236. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/.gitkeep +0 -0
  237. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/announcement-modal.js +0 -0
  238. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/api.js +0 -0
  239. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/artifact-window.js +0 -0
  240. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/card-terminal.js +0 -0
  241. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/collage.js +0 -0
  242. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/command-palette.js +0 -0
  243. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/council-window.js +0 -0
  244. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/dead-key-suppressor.js +0 -0
  245. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/desktop-manager.js +0 -0
  246. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/desktop.js +0 -0
  247. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/help-modal.js +0 -0
  248. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/icon-manager.js +0 -0
  249. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/lineage.js +0 -0
  250. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/mobile.js +0 -0
  251. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/notification-prefs.js +0 -0
  252. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/notifications-panel.js +0 -0
  253. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/ptt.js +0 -0
  254. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/push-client.js +0 -0
  255. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/review-window.js +0 -0
  256. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/safety-shared.js +0 -0
  257. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/safety-window.js +0 -0
  258. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/scratchpad.js +0 -0
  259. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/service-classification.js +0 -0
  260. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/session-hud-controller.js +0 -0
  261. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/session-hud-notices.js +0 -0
  262. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/session-hud-spawn.js +0 -0
  263. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/session-hud.js +0 -0
  264. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/session-id.js +0 -0
  265. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/session-window.js +0 -0
  266. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/shortcuts.js +0 -0
  267. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/sidebar/artifacts-section.js +0 -0
  268. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/sidebar/config-section.js +0 -0
  269. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/sidebar/council-section.js +0 -0
  270. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/sidebar/machines-section.js +0 -0
  271. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/sidebar/projects-section.js +0 -0
  272. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/sidebar/safety-section.js +0 -0
  273. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/sidebar/scheduler-section.js +0 -0
  274. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/sidebar/services-section.js +0 -0
  275. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/sidebar/sessions-section.js +0 -0
  276. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/sidebar.js +0 -0
  277. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/spawn-ghost.js +0 -0
  278. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/terminal-font-prefs.js +0 -0
  279. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/terminal-pane.js +0 -0
  280. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/tile-manager.js +0 -0
  281. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/toast.js +0 -0
  282. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/token-modal.js +0 -0
  283. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/topology-render.js +0 -0
  284. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/utils/ansi.js +0 -0
  285. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/utils/rich-text.js +0 -0
  286. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/utils/swipe.js +0 -0
  287. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/voice/autosend-prefs.js +0 -0
  288. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/voice/browser-stt.js +0 -0
  289. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/voice/browser-tts.js +0 -0
  290. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/voice/jargon.js +0 -0
  291. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/voice/prompt.js +0 -0
  292. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/winbox.bundle.min.js +0 -0
  293. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/js/workspace-window.js +0 -0
  294. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/manifest.webmanifest +0 -0
  295. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/service-worker.js +0 -0
  296. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/static/topology-harness.html +0 -0
  297. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/stt/__init__.py +0 -0
  298. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/stt/base.py +0 -0
  299. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/stt/cloud.py +0 -0
  300. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/stt/engine.py +0 -0
  301. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/stt/local.py +0 -0
  302. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/stt/server_backend.py +0 -0
  303. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/stt/stt_server.py +0 -0
  304. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/system_cli.py +0 -0
  305. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tabs_cli.py +0 -0
  306. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tasks.py +0 -0
  307. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tasks_cli.py +0 -0
  308. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/templates/__init__.py +0 -0
  309. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/templates/base.html +0 -0
  310. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/templates/council/minutes.html.j2 +0 -0
  311. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/templates/desktop.html +0 -0
  312. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/templates/email_notification.html +0 -0
  313. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/templates/handoff/show-the-story.html.j2 +0 -0
  314. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/templates/handoff/theme.css.j2 +0 -0
  315. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/templates/mobile.html +0 -0
  316. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/templates/pair.html +0 -0
  317. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/templates/tmux.conf +0 -0
  318. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/templating.py +0 -0
  319. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tooldefs/aws.yaml +0 -0
  320. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tooldefs/docker.yaml +0 -0
  321. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tooldefs/gcp.yaml +0 -0
  322. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tooldefs/gh.yaml +0 -0
  323. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tooldefs/git.yaml +0 -0
  324. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tooldefs/gws.yaml +0 -0
  325. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tooldefs/kubectl.yaml +0 -0
  326. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tooldefs/npm.yaml +0 -0
  327. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tooldefs/terraform.yaml +0 -0
  328. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tooldefs/uv.yaml +0 -0
  329. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tts/__init__.py +0 -0
  330. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tts/audio.py +0 -0
  331. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tts/base.py +0 -0
  332. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tts/engines/__init__.py +0 -0
  333. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tts/engines/chatterbox.py +0 -0
  334. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tts/engines/kokoro.py +0 -0
  335. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tts/engines/zonos.py +0 -0
  336. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tts/kokoro_server.py +0 -0
  337. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tts/local.py +0 -0
  338. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tts/registry.py +0 -0
  339. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tts_cli.py +0 -0
  340. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tts_server.py +0 -0
  341. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tunnels.py +0 -0
  342. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/tunnels_cli.py +0 -0
  343. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/usage_limit.py +0 -0
  344. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/utils/__init__.py +0 -0
  345. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/utils/chunker.py +0 -0
  346. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/utils/event_log.py +0 -0
  347. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/utils/file_io.py +0 -0
  348. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/utils/paths.py +0 -0
  349. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/utils/speech.py +0 -0
  350. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/utils/subprocess.py +0 -0
  351. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/validation.py +0 -0
  352. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/voice_status.py +0 -0
  353. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/wiki.py +0 -0
  354. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/wiki_audit.py +0 -0
  355. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/wiki_cli.py +0 -0
  356. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/worktree.py +0 -0
  357. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/agentwire/worktree_registry.py +0 -0
  358. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/decisions/obsidian-second-brain.md +0 -0
  359. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/design/session-card-fields.md +0 -0
  360. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/design/session-card-recommendation.md +0 -0
  361. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/logo.png +0 -0
  362. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/INDEX.md +0 -0
  363. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/architecture.md +0 -0
  364. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/briefing-mode.md +0 -0
  365. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/communication/channels.md +0 -0
  366. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/communication/hammerspoon.md +0 -0
  367. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/communication/handoff.md +0 -0
  368. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/concepts.md +0 -0
  369. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/council.md +0 -0
  370. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/deployment/remote-access.md +0 -0
  371. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/deployment/remote-machines.md +0 -0
  372. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/glossary.md +0 -0
  373. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/integrations/gws-google-workspace-cli.md +0 -0
  374. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/internals/damage-control.md +0 -0
  375. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/internals/parallel-refactor.md +0 -0
  376. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/internals/portal.md +0 -0
  377. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/internals/session-topology.md +0 -0
  378. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/internals/shell-escaping.md +0 -0
  379. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/internals/troubleshooting.md +0 -0
  380. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/internals/window-collage.md +0 -0
  381. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/quickstart.md +0 -0
  382. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/research/briefing-mode-feasibility.md +0 -0
  383. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/research/orchestration-transport-alternatives.md +0 -0
  384. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/scheduling/scheduled-workloads.md +0 -0
  385. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/security/damage-control-hardening.md +0 -0
  386. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/security/pip-audit.md +0 -0
  387. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/security/remote-access-hardening.md +0 -0
  388. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/security/secrets.md +0 -0
  389. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/services.md +0 -0
  390. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/sessions/claude-code-auto-mode.md +0 -0
  391. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/sessions/prompt-routing.md +0 -0
  392. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/sessions/window-sizing.md +0 -0
  393. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/sessions/worktree-sessions.md +0 -0
  394. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/usage-limit-recovery.md +0 -0
  395. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/voice/shim-contract.md +0 -0
  396. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/voice/stt-cloud.md +0 -0
  397. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/voice/stt-self-hosted.md +0 -0
  398. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/docs/wiki/voice/tts-self-hosted.md +0 -0
  399. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/pyproject.toml +0 -0
  400. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/e2e/test_portal_ui.py +0 -0
  401. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/fixtures/sample_agentwire.yml +0 -0
  402. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/fixtures/sample_config.yaml +0 -0
  403. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/fixtures/sample_scheduler.yaml +0 -0
  404. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/integration/test_council_portal.py +0 -0
  405. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/integration/test_scheduler_board.py +0 -0
  406. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/integration/test_send_verified_tmux.py +0 -0
  407. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/integration/test_server_websockets.py +0 -0
  408. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/integration/test_worktree_cmd.py +0 -0
  409. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_announcements.py +0 -0
  410. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_build_agent_command.py +0 -0
  411. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_channels.py +0 -0
  412. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_chrome_tabs.py +0 -0
  413. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_cli_commands.py +0 -0
  414. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_cli_output.py +0 -0
  415. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_cli_smoke.py +0 -0
  416. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_config.py +0 -0
  417. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_config_cli.py +0 -0
  418. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_control_plane_protection.py +0 -0
  419. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_council_cli.py +0 -0
  420. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_council_inbox.py +0 -0
  421. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_council_minutes.py +0 -0
  422. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_council_state.py +0 -0
  423. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_council_view.py +0 -0
  424. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_damage_control_bypass.py +0 -0
  425. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_damage_control_hooks.py +0 -0
  426. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_damage_control_sync.py +0 -0
  427. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_dangling_worktrees.py +0 -0
  428. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_devices.py +0 -0
  429. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_diff_cli.py +0 -0
  430. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_doctor_scheduler_staleness.py +0 -0
  431. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_doctor_task_migration.py +0 -0
  432. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_doctor_voice.py +0 -0
  433. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_event_log.py +0 -0
  434. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_file_io.py +0 -0
  435. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_guarded_launch_command.py +0 -0
  436. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_handoff_git_state.py +0 -0
  437. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_handoff_instructions.py +0 -0
  438. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_handoff_parser.py +0 -0
  439. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_handoff_renderer.py +0 -0
  440. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_history.py +0 -0
  441. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_hooks_install.py +0 -0
  442. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_idle_handler.py +0 -0
  443. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_idle_nag.py +0 -0
  444. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_init_command.py +0 -0
  445. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_install_parity.py +0 -0
  446. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_limits_tick_isolation.py +0 -0
  447. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_locking.py +0 -0
  448. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_mcp_server.py +0 -0
  449. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_mcp_tools_args.py +0 -0
  450. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_msg_cli.py +0 -0
  451. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_notify_cli.py +0 -0
  452. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_onboarding_reinit.py +0 -0
  453. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_palette_cli.py +0 -0
  454. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_pip_environment.py +0 -0
  455. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_portal_api.py +0 -0
  456. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_posture_default.py +0 -0
  457. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_project_config.py +0 -0
  458. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_projects_registry.py +0 -0
  459. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_prompt_router.py +0 -0
  460. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_push.py +0 -0
  461. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_rebuild_guard.py +0 -0
  462. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_repo_cli.py +0 -0
  463. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_rich_text_js.py +0 -0
  464. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_roles.py +0 -0
  465. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_routes_snapshot.py +0 -0
  466. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_safety_commands.py +0 -0
  467. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_safety_disabled_rules.py +0 -0
  468. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_safety_escape_hatch.py +0 -0
  469. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_safety_heal.py +0 -0
  470. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_safety_kill_switch.py +0 -0
  471. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_scheduler.py +0 -0
  472. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_scheduler_parsing.py +0 -0
  473. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_scheduler_zombie.py +0 -0
  474. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_scratchpad.py +0 -0
  475. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_security.py +0 -0
  476. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_server_async.py +0 -0
  477. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_server_pure.py +0 -0
  478. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_services.py +0 -0
  479. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_session_context.py +0 -0
  480. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_session_created_by_env.py +0 -0
  481. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_session_ready.py +0 -0
  482. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_shared_dir_guard.py +0 -0
  483. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_shim_selfheal.py +0 -0
  484. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_skill_install.py +0 -0
  485. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_speech_tags.py +0 -0
  486. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_ssh.py +0 -0
  487. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_stt_backend.py +0 -0
  488. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_stt_cloud.py +0 -0
  489. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_stt_engine.py +0 -0
  490. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_task_cli.py +0 -0
  491. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_tasks.py +0 -0
  492. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_tasks_cli.py +0 -0
  493. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_templating.py +0 -0
  494. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_terminal_resize.py +0 -0
  495. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_tmux_template.py +0 -0
  496. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_tts_engine_resolution.py +0 -0
  497. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_tts_local.py +0 -0
  498. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_tunnels_probe.py +0 -0
  499. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_unattended_env_isolation.py +0 -0
  500. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_usage_limit.py +0 -0
  501. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_validation.py +0 -0
  502. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_voice_status.py +0 -0
  503. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_wiki.py +0 -0
  504. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_wiki_audit.py +0 -0
  505. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_window_cycling_binding.py +0 -0
  506. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_worktree.py +0 -0
  507. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_worktree_branch_cleanup.py +0 -0
  508. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/tests/unit/test_worktree_layout.py +0 -0
  509. {agentwire_dev-1.65.0 → agentwire_dev-1.65.1}/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.65.0
3
+ Version: 1.65.1
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
@@ -1,3 +1,3 @@
1
1
  """AgentWire - Multi-session voice web interface for AI coding agents."""
2
2
 
3
- __version__ = "1.65.0"
3
+ __version__ = "1.65.1"
@@ -479,9 +479,21 @@ def resolve_default_created_by(caller: str | None, target_path: Path) -> str | N
479
479
  `{project}-{name}`, and would misjudge same/cross-project); if the
480
480
  caller's real cwd can't be confirmed, treat it as unknown (no inheritance)
481
481
  rather than risk a wrong guess.
482
+
483
+ A service session (agentwire-portal, -tts, -stt, -kokoro, ...) never
484
+ qualifies as a parent: it's infrastructure, not an agent that will ever
485
+ drain its msg inbox, so anything parented to it dead-letters forever. A
486
+ subprocess the portal shells out to inherits its TMUX_PANE and resolves
487
+ ``caller`` right back to "agentwire-portal" — this was the root cause of
488
+ a 147-message dead-letter storm (each mailing the owner individually,
489
+ 2026-07-19).
482
490
  """
483
491
  if not caller:
484
492
  return None
493
+ from .services import is_service_session
494
+
495
+ if is_service_session(caller):
496
+ return None
485
497
  caller_path = _live_session_cwd(caller)
486
498
  if caller_path is None:
487
499
  return None
@@ -453,6 +453,7 @@ def gc_sender(sender: str) -> dict:
453
453
  # delivered, not lost. Skip GC for this recipient this round.
454
454
  continue
455
455
  try:
456
+ newly_dead: list[Message] = []
456
457
  for path in paths:
457
458
  if not path.exists():
458
459
  continue # delivered + unlinked just before we locked
@@ -472,7 +473,7 @@ def gc_sender(sender: str) -> dict:
472
473
  attempts=msg.attempts, reason="sender_exited",
473
474
  )
474
475
  dead += 1
475
- _escalate_dead_letter(msg, "sender_exited")
476
+ newly_dead.append(msg)
476
477
  except OSError:
477
478
  pass
478
479
  else:
@@ -481,6 +482,8 @@ def gc_sender(sender: str) -> dict:
481
482
  dropped += 1
482
483
  except OSError:
483
484
  pass
485
+ # One digest per recipient, not one email per message (#836).
486
+ _escalate_dead_letters(newly_dead, "sender_exited")
484
487
  finally:
485
488
  _release_lock(lock)
486
489
 
@@ -608,17 +611,32 @@ def _fmt_ts(ms: int) -> str:
608
611
  return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(ms / 1000))
609
612
 
610
613
 
611
- def _escalate_dead_letter(msg: Message, reason: str) -> None:
612
- """Email the owner when a load-bearing report-back dead-letters.
614
+ # A single stuck recipient (e.g. a session wrongly parented to a service
615
+ # session that can never drain its inbox) can dead-letter dozens of messages
616
+ # in one drain pass — cap the per-message detail in the digest so the email
617
+ # stays readable instead of dumping an unbounded wall of text.
618
+ _ESCALATE_DIGEST_DETAIL_CAP = 10
619
+
620
+
621
+ def _escalate_dead_letters(messages: list[Message], reason: str) -> None:
622
+ """Email the owner once per batch when load-bearing report-backs dead-letter.
613
623
 
614
624
  ``done`` / ``request`` / ``escalation`` are load-bearing — a silently-dropped
615
625
  one is a real loss, so we surface it out-of-band via the shared Resend wiring
616
626
  (the same owner-escalation channel usage-limit parking uses). ``note`` and
617
- ``ingest`` are not escalated. Best-effort: a missing key or send failure must
618
- never break the drain — the corpse already sits in ``dead/`` for
619
- ``agentwire msg dead``.
627
+ ``ingest`` are not escalated.
628
+
629
+ *messages* is everything dead-lettered by one caller's batch (one drain
630
+ pass for one recipient, or one sender's GC sweep) — a single digest email
631
+ covers the whole batch instead of one email per message, so a recipient
632
+ that's been permanently undeliverable for a while (e.g. parented to a
633
+ service session that never drains) can't spam the owner's inbox one email
634
+ per stuck message (147 individual emails in ~2s, 2026-07-19). Best-effort:
635
+ a missing key or send failure must never break the drain — each corpse
636
+ already sits in ``dead/`` for ``agentwire msg dead``.
620
637
  """
621
- if msg.kind not in ESCALATE_KINDS:
638
+ batch = [m for m in messages if m.kind in ESCALATE_KINDS]
639
+ if not batch:
622
640
  return
623
641
  try:
624
642
  import socket
@@ -626,36 +644,47 @@ def _escalate_dead_letter(msg: Message, reason: str) -> None:
626
644
  from .channels.email import send_email
627
645
 
628
646
  host = socket.gethostname()
629
- subject = (
630
- f"[agentwire] undelivered {msg.kind}: {msg.sender} → {msg.to} (dead-lettered)"
631
- )
632
- body = "\n".join([
633
- f"A **{msg.kind}** message from **{msg.sender}** to **{msg.to}** on "
634
- f"`{host}` was never delivered after {msg.attempts} attempts and has "
635
- f"been dead-lettered.",
636
- "",
637
- f"- **Kind:** {msg.kind}",
638
- f"- **From:** {msg.sender}",
639
- f"- **To:** {msg.to}",
640
- f"- **Last defer reason:** {reason}",
641
- f"- **Sent:** {_fmt_ts(msg.ts)}",
642
- f"- **Dead-lettered:** {_fmt_ts(msg.dead_ts)}",
643
- "",
644
- "Message text:",
647
+ if len(batch) == 1:
648
+ msg = batch[0]
649
+ subject = (
650
+ f"[agentwire] undelivered {msg.kind}: {msg.sender} → {msg.to} (dead-lettered)"
651
+ )
652
+ else:
653
+ to = batch[0].to
654
+ subject = (
655
+ f"[agentwire] {len(batch)} undelivered messages → {to} (dead-lettered)"
656
+ )
657
+ noun = "message" if len(batch) == 1 else "messages"
658
+ verb = "was" if len(batch) == 1 else "were"
659
+ lines = [
660
+ f"{len(batch)} load-bearing {noun} on `{host}` {verb} never delivered "
661
+ f"and {'has' if len(batch) == 1 else 'have'} been dead-lettered "
662
+ f"(last defer reason: {reason}).",
645
663
  "",
646
- "```",
647
- msg.text,
648
- "```",
664
+ ]
665
+ for msg in batch[:_ESCALATE_DIGEST_DETAIL_CAP]:
666
+ lines += [
667
+ f"- **{msg.kind}** {msg.sender} → {msg.to}, sent {_fmt_ts(msg.ts)}, "
668
+ f"dead-lettered {_fmt_ts(msg.dead_ts)}, {msg.attempts} attempts:",
669
+ " ```",
670
+ f" {msg.text}",
671
+ " ```",
672
+ ]
673
+ remaining = len(batch) - _ESCALATE_DIGEST_DETAIL_CAP
674
+ if remaining > 0:
675
+ lines.append(f"- ...and {remaining} more.")
676
+ lines += [
649
677
  "",
650
- f"Saved in the dead-letter store — review with `agentwire msg dead -s {msg.to}`.",
651
- ])
652
- result = send_email(subject=subject, body=body)
678
+ f"Saved in the dead-letter store — review with "
679
+ f"`agentwire msg dead -s {batch[0].to}`.",
680
+ ]
681
+ result = send_email(subject=subject, body="\n".join(lines))
653
682
  _log_event(
654
- "dead_letter_escalated", id=msg.id, to=msg.to, kind=msg.kind,
683
+ "dead_letter_escalated", to=batch[0].to, count=len(batch), reason=reason,
655
684
  ok=bool(getattr(result, "success", False)),
656
685
  )
657
686
  except Exception as exc: # escalation is best-effort; never break the drain
658
- _log_event("dead_letter_escalate_failed", id=msg.id, to=msg.to, error=str(exc))
687
+ _log_event("dead_letter_escalate_failed", to=batch[0].to, count=len(batch), error=str(exc))
659
688
 
660
689
 
661
690
  def _bump_attempts(messages: list[Message], reason: str = "") -> int:
@@ -675,6 +704,7 @@ def _bump_attempts(messages: list[Message], reason: str = "") -> int:
675
704
  burns out on schedule.
676
705
  """
677
706
  dead = 0
707
+ newly_dead: list[Message] = []
678
708
  for msg in messages:
679
709
  if msg.path is None:
680
710
  continue
@@ -705,7 +735,7 @@ def _bump_attempts(messages: list[Message], reason: str = "") -> int:
705
735
  attempts=msg.attempts, reason=reason,
706
736
  )
707
737
  dead += 1
708
- _escalate_dead_letter(msg, reason)
738
+ newly_dead.append(msg)
709
739
  except OSError:
710
740
  pass
711
741
  else:
@@ -713,6 +743,9 @@ def _bump_attempts(messages: list[Message], reason: str = "") -> int:
713
743
  _write_message(msg.path, msg)
714
744
  except OSError:
715
745
  pass
746
+ # One digest email for the whole batch (all share the same recipient —
747
+ # `messages` is always one session's inbox), not one per message (#836).
748
+ _escalate_dead_letters(newly_dead, reason)
716
749
  return dead
717
750
 
718
751
 
@@ -143,8 +143,14 @@ lands in a durable inbox and is injected only at a safe boundary.
143
143
  / `escalation`) does dead-letter, the owner is emailed via the shared Resend
144
144
  wiring (the same channel usage-limit parking uses) so the loss is surfaced
145
145
  even if nobody runs `msg dead`. `note` is fire-and-forget and `ingest` never
146
- auto-delivers, so neither is escalated. Escalation is best-effort a send
147
- failure is logged (`dead_letter_escalate_failed`) and never breaks the drain.
146
+ auto-delivers, so neither is escalated. Escalation is **batched per drain
147
+ pass, not per message** (#829/#830): every message dead-lettered in the
148
+ same batch for one recipient gets a single digest email (detail capped at
149
+ the first 10, "...and N more" beyond that) instead of one email each — a
150
+ recipient stuck permanently undeliverable (e.g. wrongly parented to a
151
+ service session that never drains) can't spam the owner one email per
152
+ stuck message. Escalation is best-effort — a send failure is logged
153
+ (`dead_letter_escalate_failed`) and never breaks the drain.
148
154
 
149
155
  ### `prompt_is_empty` — the collision detector
150
156
 
@@ -13,7 +13,7 @@ FIXTURES_DIR = Path(__file__).parent / "fixtures"
13
13
  def _no_real_outbound_email(request, monkeypatch):
14
14
  """No test may send real email — ever.
15
15
 
16
- ``_escalate_dead_letter`` (and friends) call the live Resend wiring, so a
16
+ ``_escalate_dead_letters`` (and friends) call the live Resend wiring, so a
17
17
  test that dead-letters a done/request/escalation message without mocking
18
18
  ``send_email`` silently emails the owner on every suite run (found the hard
19
19
  way: ``test_purge_leaves_ingest_and_dead`` flooded the inbox with
@@ -115,3 +115,14 @@ class TestResolveDefaultCreatedBy:
115
115
  monkeypatch.setattr(core, "tmux_session_exists", lambda s: False)
116
116
  repo = _make_repo(tmp_path)
117
117
  assert core.resolve_default_created_by("myproject-fix-bug", repo) is None
118
+
119
+ def test_service_session_caller_returns_none(self, monkeypatch, tmp_path):
120
+ # Regression (2026-07-19): a session created via the portal web UI
121
+ # inherits the portal server subprocess's TMUX_PANE, so `caller`
122
+ # resolves to the "agentwire-portal" service session. Parenting to it
123
+ # is a bug even when same_project would otherwise match — a service
124
+ # session never drains its msg inbox, so anything parented to it
125
+ # dead-letters forever (147-message escalation-email storm).
126
+ repo = _make_repo(tmp_path)
127
+ monkeypatch.setattr(core, "_live_session_cwd", lambda s: repo)
128
+ assert core.resolve_default_created_by("agentwire-portal", repo) is None
@@ -760,6 +760,8 @@ class TestDeadLetterEscalation:
760
760
  assert len(inbox.list_dead("s")) == 1 # still archived for audit
761
761
 
762
762
  def test_request_and_escalation_also_email(self, isolate, monkeypatch):
763
+ # Both dead-letter in the same drain pass (same recipient) — one
764
+ # digest email covers the batch, not one email per kind (#836).
763
765
  inbox.enqueue("s", "need creds", kind="request", sender="w")
764
766
  inbox.enqueue("s", "stuck!", kind="escalation", sender="w")
765
767
  self._occupied_agent(monkeypatch)
@@ -767,8 +769,9 @@ class TestDeadLetterEscalation:
767
769
  self._capture_email(monkeypatch, sent)
768
770
  for _ in range(inbox.MAX_ATTEMPTS):
769
771
  inbox.flush_session("s")
770
- kinds = sorted(k["subject"].split("undelivered ")[1].split(":")[0] for k in sent)
771
- assert kinds == ["escalation", "request"]
772
+ assert len(sent) == 1
773
+ assert "2 undelivered messages" in sent[0]["subject"]
774
+ assert "request" in sent[0]["body"] and "escalation" in sent[0]["body"]
772
775
 
773
776
  def test_note_dead_letter_does_not_email(self, isolate, monkeypatch):
774
777
  inbox.enqueue("s", "fyi", kind="note", sender="worker")
@@ -792,6 +795,49 @@ class TestDeadLetterEscalation:
792
795
  inbox.flush_session("s")
793
796
  assert len(inbox.list_dead("s")) == 1 # drain survived; corpse archived
794
797
 
798
+ def test_large_batch_sends_one_digest_not_one_per_message(self, isolate, monkeypatch):
799
+ # Regression (2026-07-19): a recipient stuck permanently undeliverable
800
+ # (e.g. wrongly parented to a service session) can accumulate a large
801
+ # backlog that all crosses MAX_ATTEMPTS in the same drain pass. That
802
+ # must fire ONE digest email, not one per message (147 individual
803
+ # emails in ~2s was the real incident).
804
+ for i in range(20):
805
+ inbox.enqueue("s", f"report {i}", kind="done", sender="w")
806
+ self._occupied_agent(monkeypatch)
807
+ sent = []
808
+ self._capture_email(monkeypatch, sent)
809
+ for _ in range(inbox.MAX_ATTEMPTS):
810
+ inbox.flush_session("s")
811
+ assert len(inbox.list_dead("s")) == 20
812
+ assert len(sent) == 1
813
+ assert "20 undelivered messages" in sent[0]["subject"]
814
+
815
+ def _msg(self, i):
816
+ return inbox.Message(
817
+ id=f"id{i}", sender="w", to="s", kind="done", text=f"report {i}",
818
+ ts=1000 + i, dead_ts=2000 + i,
819
+ )
820
+
821
+ def test_digest_detail_cap_boundary(self, isolate, monkeypatch):
822
+ # Exactly at the cap: every message gets detail, no truncation line.
823
+ sent = []
824
+ self._capture_email(monkeypatch, sent)
825
+ batch = [self._msg(i) for i in range(inbox._ESCALATE_DIGEST_DETAIL_CAP)]
826
+ inbox._escalate_dead_letters(batch, "target_gone")
827
+ assert len(sent) == 1
828
+ assert "...and" not in sent[0]["body"]
829
+ assert all(f"report {i}" in sent[0]["body"] for i in range(len(batch)))
830
+
831
+ def test_digest_detail_cap_truncates_beyond_boundary(self, isolate, monkeypatch):
832
+ # One over the cap: detail for the first CAP, a single "...and 1 more."
833
+ sent = []
834
+ self._capture_email(monkeypatch, sent)
835
+ batch = [self._msg(i) for i in range(inbox._ESCALATE_DIGEST_DETAIL_CAP + 1)]
836
+ inbox._escalate_dead_letters(batch, "target_gone")
837
+ assert len(sent) == 1
838
+ assert "...and 1 more." in sent[0]["body"]
839
+ assert f"report {inbox._ESCALATE_DIGEST_DETAIL_CAP}" not in sent[0]["body"]
840
+
795
841
 
796
842
  class TestIdempotentDelivery:
797
843
  """#621: a delivery_unverified false-negative must NOT re-inject a landed
@@ -959,8 +1005,8 @@ class TestForceFlush:
959
1005
  class TestGcSender:
960
1006
  def test_gc_dead_letters_load_bearing(self, isolate, monkeypatch):
961
1007
  emailed = []
962
- monkeypatch.setattr(inbox, "_escalate_dead_letter",
963
- lambda m, r: emailed.append((m.kind, r)))
1008
+ monkeypatch.setattr(inbox, "_escalate_dead_letters",
1009
+ lambda batch, r: emailed.extend((m.kind, r) for m in batch))
964
1010
  inbox.enqueue("orch", "PR drafted", kind="done", sender="worker")
965
1011
  inbox.enqueue("orch", "need review", kind="request", sender="worker")
966
1012
  res = inbox.gc_sender("worker")
@@ -970,7 +1016,7 @@ class TestGcSender:
970
1016
  assert emailed and all(r == "sender_exited" for _, r in emailed)
971
1017
 
972
1018
  def test_gc_drops_non_load_bearing(self, isolate, monkeypatch):
973
- monkeypatch.setattr(inbox, "_escalate_dead_letter", lambda m, r: None)
1019
+ monkeypatch.setattr(inbox, "_escalate_dead_letters", lambda batch, r: None)
974
1020
  inbox.enqueue("orch", "fyi", kind="note", sender="worker")
975
1021
  res = inbox.gc_sender("worker")
976
1022
  assert res["dropped"] == 1 and res["dead"] == 0
@@ -981,8 +1027,8 @@ class TestGcSender:
981
1027
  # A flush draining this inbox holds the per-session lock; gc must NOT
982
1028
  # dead-letter (and email) a message that flush is mid-delivery on.
983
1029
  emailed = []
984
- monkeypatch.setattr(inbox, "_escalate_dead_letter",
985
- lambda m, r: emailed.append(m.id))
1030
+ monkeypatch.setattr(inbox, "_escalate_dead_letters",
1031
+ lambda batch, r: emailed.extend(m.id for m in batch))
986
1032
  inbox.enqueue("orch", "in flight", kind="done", sender="worker")
987
1033
  held = inbox._acquire_lock("orch") # simulate an in-flight flush
988
1034
  try:
@@ -1001,6 +1047,24 @@ class TestGcSender:
1001
1047
  assert len(inbox.list_messages("orch")) == 1 # other sender's done kept
1002
1048
  assert inbox.list_ingest("orch") # ingest untouched
1003
1049
 
1050
+ def test_gc_batches_one_email_per_recipient(self, isolate, monkeypatch):
1051
+ # Regression (#829/#830): gc_sender must send ONE digest email per
1052
+ # recipient, not one per dead-lettered message — exercised against the
1053
+ # real send_email seam (not a stubbed _escalate_dead_letters), so a
1054
+ # regression back to per-message escalation inside the gc loop would
1055
+ # actually be caught here.
1056
+ sent = []
1057
+ monkeypatch.setattr(
1058
+ "agentwire.channels.email.send_email",
1059
+ lambda **kw: sent.append(kw) or SimpleNamespace(success=True),
1060
+ )
1061
+ inbox.enqueue("orch", "PR drafted", kind="done", sender="worker")
1062
+ inbox.enqueue("orch", "need review", kind="request", sender="worker")
1063
+ res = inbox.gc_sender("worker")
1064
+ assert res["dead"] == 2
1065
+ assert len(sent) == 1
1066
+ assert "2 undelivered messages" in sent[0]["subject"]
1067
+
1004
1068
 
1005
1069
  # =============================================================================
1006
1070
  # Session-name validation — path-traversal hardening
File without changes
File without changes
File without changes