agentwire-dev 1.59.0__tar.gz → 1.61.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 (489) hide show
  1. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/PKG-INFO +1 -1
  2. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/__init__.py +1 -1
  3. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/core.py +69 -20
  4. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/doctor_cli.py +106 -0
  5. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/limits_cli.py +16 -6
  6. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/scheduler/__init__.py +4 -0
  7. agentwire_dev-1.61.0/agentwire/scheduler/zombie.py +160 -0
  8. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/server.py +10 -8
  9. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/session_cli.py +92 -42
  10. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tts_cli.py +107 -14
  11. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/integration/test_worktree_cmd.py +72 -0
  12. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_cli_commands.py +77 -0
  13. agentwire_dev-1.61.0/tests/unit/test_guarded_launch_command.py +73 -0
  14. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_limits_tick_isolation.py +5 -2
  15. agentwire_dev-1.61.0/tests/unit/test_scheduler_zombie.py +269 -0
  16. agentwire_dev-1.61.0/tests/unit/test_session_created_by_env.py +56 -0
  17. agentwire_dev-1.61.0/tests/unit/test_shim_selfheal.py +202 -0
  18. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/.agentwire.yml.example +0 -0
  19. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/.claude/commands/handoff.md +0 -0
  20. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/.claude/skills/wiki/SKILL.md +0 -0
  21. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/.github/FUNDING.yml +0 -0
  22. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  23. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  24. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
  25. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  26. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/.github/workflows/pytest.yml +0 -0
  27. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/.github/workflows/ruff.yml +0 -0
  28. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/.github/workflows/security.yml +0 -0
  29. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/.github/workflows/tts-smoke.yml +0 -0
  30. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/.gitignore +0 -0
  31. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/AGENTS.md +0 -0
  32. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/CODE_OF_CONDUCT.md +0 -0
  33. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/CONTRIBUTING.md +0 -0
  34. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/Dockerfile.local +0 -0
  35. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/LICENSE +0 -0
  36. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/README.md +0 -0
  37. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/RELEASING.md +0 -0
  38. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/SECURITY.md +0 -0
  39. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/SPONSORS.md +0 -0
  40. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/__main__.py +0 -0
  41. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/agents/__init__.py +0 -0
  42. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/agents/base.py +0 -0
  43. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/agents/tmux.py +0 -0
  44. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/cached_status.py +0 -0
  45. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/channels/__init__.py +0 -0
  46. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/channels/base.py +0 -0
  47. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/channels/email.py +0 -0
  48. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/channels/push.py +0 -0
  49. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/channels/quo.py +0 -0
  50. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/channels_cli.py +0 -0
  51. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/chrome_tabs.py +0 -0
  52. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/completion.py +0 -0
  53. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/config.py +0 -0
  54. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/config_cli.py +0 -0
  55. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/council/__init__.py +0 -0
  56. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/council/cli.py +0 -0
  57. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/council/inbox.py +0 -0
  58. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/council/minutes.py +0 -0
  59. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/council/state.py +0 -0
  60. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/council/view.py +0 -0
  61. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/devices.py +0 -0
  62. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/diff_cli.py +0 -0
  63. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/doctor_voice.py +0 -0
  64. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/ensure_cli.py +0 -0
  65. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/fetch.py +0 -0
  66. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/handoff/__init__.py +0 -0
  67. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/handoff/git_state.py +0 -0
  68. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/handoff/instructions.py +0 -0
  69. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/handoff/parser.py +0 -0
  70. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/handoff/renderer.py +0 -0
  71. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/handoff/schema.py +0 -0
  72. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/handoff_cli.py +0 -0
  73. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/history.py +0 -0
  74. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/history_cli.py +0 -0
  75. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/__init__.py +0 -0
  76. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/agentwire-permission.sh +0 -0
  77. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/__init__.py +0 -0
  78. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/audit_logger.py +0 -0
  79. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/bash-tool-damage-control.py +0 -0
  80. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/edit-tool-damage-control.py +0 -0
  81. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/mcp-tool-damage-control.py +0 -0
  82. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/read-tool-damage-control.py +0 -0
  83. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/rules/agentwire.yaml +0 -0
  84. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/rules/aws.yaml +0 -0
  85. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/rules/cloud-hosting.yaml +0 -0
  86. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/rules/containers.yaml +0 -0
  87. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/rules/control-plane.yaml +0 -0
  88. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/rules/core.yaml +0 -0
  89. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/rules/databases.yaml +0 -0
  90. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/rules/firebase.yaml +0 -0
  91. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/rules/gcp.yaml +0 -0
  92. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/rules/git.yaml +0 -0
  93. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/rules/gws.yaml +0 -0
  94. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/rules/infrastructure.yaml +0 -0
  95. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/rules/outbound.yaml +0 -0
  96. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/rules/publish.yaml +0 -0
  97. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/rules/remote.yaml +0 -0
  98. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/damage-control/write-tool-damage-control.py +0 -0
  99. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/idle-handler.sh +0 -0
  100. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks/queue-processor.sh +0 -0
  101. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/hooks_cli.py +0 -0
  102. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/inbox.py +0 -0
  103. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/listen.py +0 -0
  104. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/locking.py +0 -0
  105. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/machine_cli.py +0 -0
  106. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_channels.py +0 -0
  107. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_chrome.py +0 -0
  108. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_cli.py +0 -0
  109. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_core.py +0 -0
  110. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_council.py +0 -0
  111. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_desktop.py +0 -0
  112. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_handoff.py +0 -0
  113. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_history.py +0 -0
  114. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_listen.py +0 -0
  115. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_lock.py +0 -0
  116. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_machine.py +0 -0
  117. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_msg.py +0 -0
  118. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_notify.py +0 -0
  119. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_pane.py +0 -0
  120. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_projects.py +0 -0
  121. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_scheduler.py +0 -0
  122. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_scratchpad.py +0 -0
  123. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_server.py +0 -0
  124. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_services.py +0 -0
  125. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_session.py +0 -0
  126. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_status.py +0 -0
  127. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_task.py +0 -0
  128. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_tunnels.py +0 -0
  129. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_voice.py +0 -0
  130. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_wiki.py +0 -0
  131. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/mcp_worktree.py +0 -0
  132. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/msg_cli.py +0 -0
  133. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/network.py +0 -0
  134. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/notify_cli.py +0 -0
  135. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/onboarding.py +0 -0
  136. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/palette_cli.py +0 -0
  137. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/pane_cli.py +0 -0
  138. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/pane_manager.py +0 -0
  139. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/portal_cli.py +0 -0
  140. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/project_config.py +0 -0
  141. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/projects.py +0 -0
  142. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/prompt_router.py +0 -0
  143. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/prompts_cli.py +0 -0
  144. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/push_cli.py +0 -0
  145. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/push_store.py +0 -0
  146. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/repo_cli.py +0 -0
  147. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/research.py +0 -0
  148. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/__init__.py +0 -0
  149. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/agentwire.md +0 -0
  150. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/anchor.md +0 -0
  151. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/chatbot.md +0 -0
  152. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/contributor.md +0 -0
  153. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/correspondent.md +0 -0
  154. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/council-brain.md +0 -0
  155. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/council-conscience.md +0 -0
  156. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/council-critic.md +0 -0
  157. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/council-devils-advocate.md +0 -0
  158. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/council-gut.md +0 -0
  159. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/council-historian.md +0 -0
  160. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/council-member.md +0 -0
  161. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/council-orchestrator.md +0 -0
  162. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/init.md +0 -0
  163. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/notifications.md +0 -0
  164. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/orchestrator.md +0 -0
  165. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/soul.md +0 -0
  166. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/task-runner.md +0 -0
  167. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/voice.md +0 -0
  168. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/worker-worktree.md +0 -0
  169. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles/worker.md +0 -0
  170. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/roles_cli.py +0 -0
  171. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/routes/__init__.py +0 -0
  172. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/routes/artifacts.py +0 -0
  173. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/routes/config.py +0 -0
  174. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/routes/council.py +0 -0
  175. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/routes/desktop.py +0 -0
  176. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/routes/history.py +0 -0
  177. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/routes/machines.py +0 -0
  178. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/routes/notify.py +0 -0
  179. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/routes/palette.py +0 -0
  180. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/routes/permission.py +0 -0
  181. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/routes/projects.py +0 -0
  182. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/routes/push.py +0 -0
  183. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/routes/safety.py +0 -0
  184. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/routes/scheduler.py +0 -0
  185. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/routes/scratchpad.py +0 -0
  186. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/routes/sessions.py +0 -0
  187. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/routes/sessions_admin.py +0 -0
  188. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/routes/voice.py +0 -0
  189. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/safety/__init__.py +0 -0
  190. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/safety/_core.py +0 -0
  191. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/safety_cli.py +0 -0
  192. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/safety_commands.py +0 -0
  193. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/scheduler/dispatch.py +0 -0
  194. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/scheduler/gates.py +0 -0
  195. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/scheduler/loop.py +0 -0
  196. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/scheduler/models.py +0 -0
  197. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/scheduler/report.py +0 -0
  198. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/scheduler/schedule.py +0 -0
  199. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/scheduler/state.py +0 -0
  200. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/scheduler_cli.py +0 -0
  201. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/scratchpad.py +0 -0
  202. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/security.py +0 -0
  203. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/send_cli.py +0 -0
  204. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/services.py +0 -0
  205. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/session_context.py +0 -0
  206. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/session_ready.py +0 -0
  207. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/ssh.py +0 -0
  208. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/agentwire-splash-logo-layers--agentwire-text.png +0 -0
  209. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/agentwire-splash-logo-layers--echo-claw-fg.png +0 -0
  210. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/agentwire-splash-logo-layers--echo.png +0 -0
  211. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/agentwire-splash-logo-layers--telephone.png +0 -0
  212. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/agentwire-splash-logo-layers--tree.png +0 -0
  213. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/announcements.json +0 -0
  214. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/apple-touch-icon.png +0 -0
  215. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/css/desktop.css +0 -0
  216. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/css/mobile.css +0 -0
  217. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/favicon-32.png +0 -0
  218. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/favicon-64.png +0 -0
  219. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/icons/sessions/bear.webp +0 -0
  220. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/icons/sessions/cat.webp +0 -0
  221. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/icons/sessions/crown.webp +0 -0
  222. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/icons/sessions/custom/agentwire-portal.webp +0 -0
  223. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/icons/sessions/custom/agentwire-tts.webp +0 -0
  224. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/icons/sessions/custom/agentwire.webp +0 -0
  225. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/icons/sessions/deer.webp +0 -0
  226. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/icons/sessions/drone.webp +0 -0
  227. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/icons/sessions/eagle.webp +0 -0
  228. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/icons/sessions/fox.webp +0 -0
  229. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/icons/sessions/hawk.webp +0 -0
  230. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/icons/sessions/horse.webp +0 -0
  231. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/icons/sessions/lion.webp +0 -0
  232. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/icons/sessions/rabbit.webp +0 -0
  233. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/icons/sessions/robot.webp +0 -0
  234. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/icons/sessions/tiger.webp +0 -0
  235. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/icons/sessions/wolf.webp +0 -0
  236. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/img/icon-192.png +0 -0
  237. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/img/icon-512.png +0 -0
  238. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/.gitkeep +0 -0
  239. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/announcement-modal.js +0 -0
  240. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/api.js +0 -0
  241. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/artifact-window.js +0 -0
  242. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/collage.js +0 -0
  243. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/command-palette.js +0 -0
  244. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/council-window.js +0 -0
  245. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/dead-key-suppressor.js +0 -0
  246. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/desktop-manager.js +0 -0
  247. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/desktop.js +0 -0
  248. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/help-modal.js +0 -0
  249. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/icon-manager.js +0 -0
  250. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/mobile.js +0 -0
  251. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/notification-prefs.js +0 -0
  252. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/notifications-panel.js +0 -0
  253. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/ptt.js +0 -0
  254. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/push-client.js +0 -0
  255. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/review-window.js +0 -0
  256. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/safety-shared.js +0 -0
  257. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/safety-window.js +0 -0
  258. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/scratchpad.js +0 -0
  259. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/service-classification.js +0 -0
  260. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/session-id.js +0 -0
  261. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/session-window.js +0 -0
  262. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/shortcuts.js +0 -0
  263. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/sidebar/artifacts-section.js +0 -0
  264. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/sidebar/config-section.js +0 -0
  265. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/sidebar/council-section.js +0 -0
  266. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/sidebar/machines-section.js +0 -0
  267. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/sidebar/projects-section.js +0 -0
  268. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/sidebar/safety-section.js +0 -0
  269. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/sidebar/scheduler-section.js +0 -0
  270. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/sidebar/services-section.js +0 -0
  271. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/sidebar/sessions-section.js +0 -0
  272. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/sidebar.js +0 -0
  273. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/terminal-font-prefs.js +0 -0
  274. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/tile-manager.js +0 -0
  275. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/toast.js +0 -0
  276. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/token-modal.js +0 -0
  277. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/utils/ansi.js +0 -0
  278. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/utils/swipe.js +0 -0
  279. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/voice/autosend-prefs.js +0 -0
  280. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/voice/browser-stt.js +0 -0
  281. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/voice/browser-tts.js +0 -0
  282. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/voice/jargon.js +0 -0
  283. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/voice/prompt.js +0 -0
  284. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/js/winbox.bundle.min.js +0 -0
  285. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/manifest.webmanifest +0 -0
  286. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/static/service-worker.js +0 -0
  287. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/stt/__init__.py +0 -0
  288. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/stt/base.py +0 -0
  289. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/stt/cloud.py +0 -0
  290. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/stt/engine.py +0 -0
  291. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/stt/local.py +0 -0
  292. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/stt/server_backend.py +0 -0
  293. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/stt/stt_server.py +0 -0
  294. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/system_cli.py +0 -0
  295. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tabs_cli.py +0 -0
  296. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tasks.py +0 -0
  297. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tasks_cli.py +0 -0
  298. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/templates/__init__.py +0 -0
  299. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/templates/base.html +0 -0
  300. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/templates/council/minutes.html.j2 +0 -0
  301. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/templates/desktop.html +0 -0
  302. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/templates/email_notification.html +0 -0
  303. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/templates/handoff/show-the-story.html.j2 +0 -0
  304. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/templates/handoff/theme.css.j2 +0 -0
  305. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/templates/mobile.html +0 -0
  306. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/templates/pair.html +0 -0
  307. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/templates/tmux.conf +0 -0
  308. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/templating.py +0 -0
  309. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tooldefs/aws.yaml +0 -0
  310. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tooldefs/docker.yaml +0 -0
  311. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tooldefs/gcp.yaml +0 -0
  312. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tooldefs/gh.yaml +0 -0
  313. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tooldefs/git.yaml +0 -0
  314. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tooldefs/gws.yaml +0 -0
  315. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tooldefs/kubectl.yaml +0 -0
  316. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tooldefs/npm.yaml +0 -0
  317. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tooldefs/terraform.yaml +0 -0
  318. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tooldefs/uv.yaml +0 -0
  319. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tts/__init__.py +0 -0
  320. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tts/audio.py +0 -0
  321. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tts/base.py +0 -0
  322. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tts/engines/__init__.py +0 -0
  323. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tts/engines/chatterbox.py +0 -0
  324. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tts/engines/kokoro.py +0 -0
  325. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tts/engines/zonos.py +0 -0
  326. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tts/kokoro_server.py +0 -0
  327. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tts/local.py +0 -0
  328. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tts/registry.py +0 -0
  329. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tts_server.py +0 -0
  330. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tunnels.py +0 -0
  331. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/tunnels_cli.py +0 -0
  332. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/usage_limit.py +0 -0
  333. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/utils/__init__.py +0 -0
  334. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/utils/chunker.py +0 -0
  335. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/utils/event_log.py +0 -0
  336. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/utils/file_io.py +0 -0
  337. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/utils/paths.py +0 -0
  338. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/utils/speech.py +0 -0
  339. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/utils/subprocess.py +0 -0
  340. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/validation.py +0 -0
  341. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/voice_status.py +0 -0
  342. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/wiki.py +0 -0
  343. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/wiki_audit.py +0 -0
  344. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/wiki_cli.py +0 -0
  345. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/worktree.py +0 -0
  346. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/agentwire/worktree_registry.py +0 -0
  347. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/decisions/obsidian-second-brain.md +0 -0
  348. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/logo.png +0 -0
  349. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/INDEX.md +0 -0
  350. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/architecture.md +0 -0
  351. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/briefing-mode.md +0 -0
  352. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/communication/channels.md +0 -0
  353. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/communication/hammerspoon.md +0 -0
  354. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/communication/handoff.md +0 -0
  355. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/concepts.md +0 -0
  356. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/council.md +0 -0
  357. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/deployment/remote-access.md +0 -0
  358. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/deployment/remote-machines.md +0 -0
  359. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/glossary.md +0 -0
  360. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/integrations/gws-google-workspace-cli.md +0 -0
  361. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/internals/damage-control.md +0 -0
  362. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/internals/parallel-refactor.md +0 -0
  363. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/internals/portal.md +0 -0
  364. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/internals/shell-escaping.md +0 -0
  365. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/internals/troubleshooting.md +0 -0
  366. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/internals/window-collage.md +0 -0
  367. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/quickstart.md +0 -0
  368. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/research/briefing-mode-feasibility.md +0 -0
  369. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/research/orchestration-transport-alternatives.md +0 -0
  370. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/scheduling/scheduled-workloads.md +0 -0
  371. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/security/damage-control-hardening.md +0 -0
  372. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/security/pip-audit.md +0 -0
  373. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/security/remote-access-hardening.md +0 -0
  374. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/security/secrets.md +0 -0
  375. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/services.md +0 -0
  376. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/sessions/claude-code-auto-mode.md +0 -0
  377. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/sessions/messaging.md +0 -0
  378. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/sessions/prompt-routing.md +0 -0
  379. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/sessions/window-sizing.md +0 -0
  380. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/sessions/worktree-sessions.md +0 -0
  381. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/usage-limit-recovery.md +0 -0
  382. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/voice/shim-contract.md +0 -0
  383. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/voice/stt-cloud.md +0 -0
  384. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/voice/stt-self-hosted.md +0 -0
  385. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/docs/wiki/voice/tts-self-hosted.md +0 -0
  386. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/pyproject.toml +0 -0
  387. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/conftest.py +0 -0
  388. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/e2e/test_portal_ui.py +0 -0
  389. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/fixtures/sample_agentwire.yml +0 -0
  390. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/fixtures/sample_config.yaml +0 -0
  391. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/fixtures/sample_scheduler.yaml +0 -0
  392. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/integration/test_council_portal.py +0 -0
  393. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/integration/test_scheduler_board.py +0 -0
  394. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/integration/test_send_verified_tmux.py +0 -0
  395. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/integration/test_server_websockets.py +0 -0
  396. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_announcements.py +0 -0
  397. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_build_agent_command.py +0 -0
  398. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_channels.py +0 -0
  399. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_chrome_tabs.py +0 -0
  400. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_cli_output.py +0 -0
  401. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_cli_smoke.py +0 -0
  402. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_config.py +0 -0
  403. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_config_cli.py +0 -0
  404. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_control_plane_protection.py +0 -0
  405. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_core_created_by_rooting.py +0 -0
  406. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_council_cli.py +0 -0
  407. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_council_inbox.py +0 -0
  408. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_council_minutes.py +0 -0
  409. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_council_state.py +0 -0
  410. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_council_view.py +0 -0
  411. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_damage_control_bypass.py +0 -0
  412. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_damage_control_hooks.py +0 -0
  413. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_damage_control_sync.py +0 -0
  414. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_dangling_worktrees.py +0 -0
  415. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_devices.py +0 -0
  416. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_diff_cli.py +0 -0
  417. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_doctor_task_migration.py +0 -0
  418. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_doctor_voice.py +0 -0
  419. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_event_log.py +0 -0
  420. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_file_io.py +0 -0
  421. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_handoff_git_state.py +0 -0
  422. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_handoff_instructions.py +0 -0
  423. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_handoff_parser.py +0 -0
  424. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_handoff_renderer.py +0 -0
  425. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_history.py +0 -0
  426. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_hooks_install.py +0 -0
  427. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_idle_handler.py +0 -0
  428. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_idle_nag.py +0 -0
  429. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_inbox.py +0 -0
  430. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_init_command.py +0 -0
  431. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_install_parity.py +0 -0
  432. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_locking.py +0 -0
  433. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_mcp_server.py +0 -0
  434. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_mcp_tools_args.py +0 -0
  435. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_msg_cli.py +0 -0
  436. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_notify_cli.py +0 -0
  437. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_onboarding_reinit.py +0 -0
  438. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_palette_cli.py +0 -0
  439. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_pip_environment.py +0 -0
  440. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_portal_api.py +0 -0
  441. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_posture_default.py +0 -0
  442. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_project_config.py +0 -0
  443. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_prompt_router.py +0 -0
  444. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_push.py +0 -0
  445. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_rebuild_guard.py +0 -0
  446. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_repo_cli.py +0 -0
  447. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_roles.py +0 -0
  448. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_routes_snapshot.py +0 -0
  449. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_safety_commands.py +0 -0
  450. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_safety_disabled_rules.py +0 -0
  451. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_safety_escape_hatch.py +0 -0
  452. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_safety_heal.py +0 -0
  453. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_safety_kill_switch.py +0 -0
  454. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_scheduler.py +0 -0
  455. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_scheduler_parsing.py +0 -0
  456. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_scratchpad.py +0 -0
  457. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_security.py +0 -0
  458. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_server_async.py +0 -0
  459. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_server_pure.py +0 -0
  460. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_services.py +0 -0
  461. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_session_context.py +0 -0
  462. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_session_ready.py +0 -0
  463. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_shared_dir_guard.py +0 -0
  464. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_skill_install.py +0 -0
  465. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_speech_tags.py +0 -0
  466. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_ssh.py +0 -0
  467. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_stt_backend.py +0 -0
  468. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_stt_cloud.py +0 -0
  469. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_stt_engine.py +0 -0
  470. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_task_cli.py +0 -0
  471. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_tasks.py +0 -0
  472. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_tasks_cli.py +0 -0
  473. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_templating.py +0 -0
  474. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_terminal_resize.py +0 -0
  475. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_tmux_template.py +0 -0
  476. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_tts_engine_resolution.py +0 -0
  477. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_tts_local.py +0 -0
  478. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_tunnels_probe.py +0 -0
  479. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_unattended_env_isolation.py +0 -0
  480. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_usage_limit.py +0 -0
  481. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_validation.py +0 -0
  482. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_voice_status.py +0 -0
  483. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_wiki.py +0 -0
  484. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_wiki_audit.py +0 -0
  485. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_window_cycling_binding.py +0 -0
  486. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_worktree.py +0 -0
  487. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_worktree_branch_cleanup.py +0 -0
  488. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_worktree_layout.py +0 -0
  489. {agentwire_dev-1.59.0 → agentwire_dev-1.61.0}/tests/unit/test_worktree_registry.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentwire-dev
3
- Version: 1.59.0
3
+ Version: 1.61.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
@@ -1,3 +1,3 @@
1
1
  """AgentWire - Multi-session voice web interface for AI coding agents."""
2
2
 
3
- __version__ = "1.59.0"
3
+ __version__ = "1.61.0"
@@ -148,15 +148,25 @@ def _build_tmux_env_flags_shell(env: dict[str, str]) -> str:
148
148
  return " ".join(parts) + " "
149
149
 
150
150
 
151
- def _set_session_name_env(agent: "AgentCommand", session_name: str) -> None:
152
- """Stamp ``AGENTWIRE_SESSION_NAME`` onto an ``AgentCommand.env``.
151
+ def _set_session_name_env(agent: "AgentCommand", session_name: str, created_by: str | None = None) -> None:
152
+ """Stamp ``AGENTWIRE_SESSION_NAME`` (and, when there's a real parent,
153
+ ``AGENTWIRE_CREATED_BY``) onto an ``AgentCommand.env``.
153
154
 
154
155
  Every session created via ``cmd_new`` / ``cmd_spawn`` / ``cmd_recreate``
155
- / ``cmd_fork`` / scheduler-spawn paths gets this so downstream tooling
156
- (notably the worker damage-control rules in ``safety/_core.py``)
157
- can identify which agentwire session the running tool is part of.
156
+ / ``cmd_fork`` / scheduler-spawn paths gets ``AGENTWIRE_SESSION_NAME`` so
157
+ downstream tooling (notably the worker damage-control rules in
158
+ ``safety/_core.py``) can identify which agentwire session the running
159
+ tool is part of.
160
+
161
+ ``created_by`` of ``''`` (root/orchestrator) or ``None`` means no
162
+ parent — ``AGENTWIRE_CREATED_BY`` is deliberately left UNSET rather than
163
+ set to an empty string, so the bare pre-agent shell's launch-crash guard
164
+ (``_guarded_launch_command``) can tell "has a parent to escalate to"
165
+ apart from "root session, email the owner" with a plain ``-n`` test (#743).
158
166
  """
159
167
  agent.env["AGENTWIRE_SESSION_NAME"] = session_name
168
+ if created_by:
169
+ agent.env["AGENTWIRE_CREATED_BY"] = created_by
160
170
 
161
171
 
162
172
  def inject_session_env(session: str, env: dict[str, str], remote_host: str | None = None) -> None:
@@ -847,6 +857,52 @@ def _run_remote(machine_id: str, command: str) -> subprocess.CompletedProcess:
847
857
  )
848
858
 
849
859
 
860
+ def _guarded_launch_command(path_str: str, agent_cmd: str | None) -> str:
861
+ """Build the pane's ``cd <path> && <agent_cmd>`` line with a missing-dir guard (#739).
862
+
863
+ A crashed worktree create can leave ``path_str`` absent by the time the
864
+ pane actually runs its ``cd`` (race between ``agentwire new`` reporting
865
+ success and the async pane launch, or an external actor removing the
866
+ dir). Without a guard, ``cd`` fails, the shell prints an error and
867
+ carries on, and ``agent_cmd`` (e.g. ``claude``) then launches from the
868
+ WRONG cwd and crashes — dropping the pane to a bare shell that the
869
+ idle-reaper never touches (it only reaps a *running* agent going idle),
870
+ so it lingers forever.
871
+
872
+ On a missing dir this instead alerts and exits the shell, which tears the
873
+ tmux session down instead of leaving a zombie. ``agent_cmd`` never runs.
874
+
875
+ Two alert routes, both shell-runtime-gated on env vars stamped at launch
876
+ (``_set_session_name_env``), so this function stays a pure string builder
877
+ with no Python-level knowledge of the session's parent (#743):
878
+ - A real recorded parent (``$AGENTWIRE_CREATED_BY`` set) gets the crash
879
+ escalated to its msg inbox — in-band, not just an email the human has
880
+ to forward.
881
+ - No parent (root/orchestrator sessions, the genuine scheduler-dispatch
882
+ case) falls back to the original owner email, still gated on
883
+ ``$AGENTWIRE_UNATTENDED=1`` (see ``_with_unattended_env``).
884
+ """
885
+ quoted_path = shlex.quote(path_str)
886
+ session_ref = "${AGENTWIRE_SESSION_NAME:-unknown session}"
887
+ missing_body = f"cd failed at launch: {path_str}"
888
+ notify_parent = (
889
+ '[ -n "$AGENTWIRE_CREATED_BY" ] && agentwire msg send --to "$AGENTWIRE_CREATED_BY" '
890
+ f'--kind escalation --subject "agentwire: worktree missing at launch — {session_ref}" '
891
+ f'--body "{missing_body}" >/dev/null 2>&1'
892
+ )
893
+ notify_owner = (
894
+ '[ -z "$AGENTWIRE_CREATED_BY" ] && [ "$AGENTWIRE_UNATTENDED" = "1" ] && agentwire email '
895
+ f'--subject "agentwire: worktree missing — {session_ref}" '
896
+ f'--body "{missing_body}" >/dev/null 2>&1'
897
+ )
898
+ alert = (
899
+ f"echo \"agentwire: worktree missing at launch, aborting: {path_str}\" >&2; "
900
+ f"{notify_parent}; {notify_owner}"
901
+ )
902
+ guard = f"cd {quoted_path} || {{ {alert}; exit 1; }}"
903
+ return f"{guard} && {agent_cmd}" if agent_cmd else guard
904
+
905
+
850
906
  def _launch_tmux_session(
851
907
  session_name: str,
852
908
  session_path,
@@ -859,8 +915,9 @@ def _launch_tmux_session(
859
915
  The one launch sequence shared by ``new`` / ``recreate`` / ``fork`` (#630):
860
916
  `tmux new-session -e K=V` injects *env* into the session environment
861
917
  BEFORE the initial shell starts (post-hoc `set-environment` never reaches
862
- it), then `send-keys` cd's into place and, if *agent_cmd* is non-empty,
863
- starts the agent after a short settle.
918
+ it), then `send-keys` cd's into place (guarded see
919
+ ``_guarded_launch_command``) and, if *agent_cmd* is non-empty, starts the
920
+ agent after a short settle.
864
921
 
865
922
  Local (machine_id None): runs subprocess calls with check=True (raises on
866
923
  tmux failure) and returns None. Remote: runs one composite shell command
@@ -869,17 +926,14 @@ def _launch_tmux_session(
869
926
  import time
870
927
 
871
928
  path_str = str(session_path)
929
+ launch_cmd = _guarded_launch_command(path_str, agent_cmd)
872
930
  if machine_id:
873
931
  env_flags = _build_tmux_env_flags_shell(env)
874
932
  create_cmd = (
875
933
  f"tmux new-session -d -s {shlex.quote(session_name)} -c {shlex.quote(path_str)} {env_flags}&& "
876
- f"tmux send-keys -t {shlex.quote(session_name)} 'cd {shlex.quote(path_str)}' Enter"
934
+ f"sleep 0.1 && "
935
+ f"tmux send-keys -t {shlex.quote(session_name)} {shlex.quote(launch_cmd)} Enter"
877
936
  )
878
- if agent_cmd:
879
- create_cmd += (
880
- f" && sleep 0.1 && "
881
- f"tmux send-keys -t {shlex.quote(session_name)} {shlex.quote(agent_cmd)} Enter"
882
- )
883
937
  return _run_remote(machine_id, create_cmd)
884
938
 
885
939
  subprocess.run(
@@ -887,16 +941,11 @@ def _launch_tmux_session(
887
941
  *_build_tmux_env_flags(env)],
888
942
  check=True,
889
943
  )
944
+ time.sleep(0.1)
890
945
  subprocess.run(
891
- ["tmux", "send-keys", "-t", session_name, f"cd {shlex.quote(path_str)}", "Enter"],
946
+ ["tmux", "send-keys", "-t", session_name, launch_cmd, "Enter"],
892
947
  check=True,
893
948
  )
894
- time.sleep(0.1)
895
- if agent_cmd:
896
- subprocess.run(
897
- ["tmux", "send-keys", "-t", session_name, agent_cmd, "Enter"],
898
- check=True,
899
- )
900
949
  return None
901
950
 
902
951
 
@@ -404,6 +404,77 @@ def _render_task_migration_section() -> int:
404
404
  return len(unmigrated)
405
405
 
406
406
 
407
+ def _find_dead_managed_shims() -> list[dict]:
408
+ """Managed voice shims whose tmux session is alive but ``/health`` is dead.
409
+
410
+ The #734 failure mode: a wedged Kokoro (:8102) or Moonshine STT (:8101) shim
411
+ inside a live ``agentwire-kokoro``/``agentwire-stt`` session — say/transcribe
412
+ then silently fall back to browser voice/recognition with no error, and the
413
+ old session-existence-only ``ensure`` never relaunches it. Only the default
414
+ tier runs a managed shim, so we check that tier only, and reuse the same
415
+ ``_shim_session_state`` liveness predicate as ``start`` (SSOT).
416
+ """
417
+ from .config import load_config as load_config_typed
418
+ from .core import (
419
+ get_kokoro_session_name,
420
+ get_stt_session_name,
421
+ tmux_session_exists,
422
+ )
423
+ from .tts_cli import _shim_session_state
424
+
425
+ cfg = load_config_typed()
426
+ checks: list[tuple[str, str, int, str, str]] = []
427
+
428
+ if getattr(getattr(cfg, "tts", None), "backend", "default") == "default":
429
+ checks.append((
430
+ "Kokoro TTS", get_kokoro_session_name(), 8102,
431
+ "agentwire kokoro start", "say falls back to browser voice",
432
+ ))
433
+
434
+ if getattr(getattr(cfg, "stt", None), "backend", "default") == "default":
435
+ # Only the Moonshine path runs a shim; without it the default tier
436
+ # transcribes in the browser and there is nothing to probe.
437
+ from .stt import moonshine_importable
438
+
439
+ if moonshine_importable():
440
+ checks.append((
441
+ "Moonshine STT", get_stt_session_name(), 8101,
442
+ "agentwire stt start",
443
+ "transcription falls back to browser recognition",
444
+ ))
445
+
446
+ dead: list[dict] = []
447
+ for label, session, port, fix, impact in checks:
448
+ if not tmux_session_exists(session):
449
+ continue
450
+ live, status = _shim_session_state(session, port)
451
+ if not live:
452
+ dead.append({
453
+ "label": label, "session": session, "port": port,
454
+ "status": status, "fix": fix, "impact": impact,
455
+ })
456
+ return dead
457
+
458
+
459
+ def _render_shim_liveness_section() -> int:
460
+ """Doctor section: managed shim session alive but ``/health`` dead (#734)."""
461
+ dead = _find_dead_managed_shims()
462
+ if not dead:
463
+ print(" [ok] No dead-but-present voice shims")
464
+ return 0
465
+ for d in dead:
466
+ print(
467
+ f" [!!] {d['label']} shim session '{d['session']}' is alive but "
468
+ f":{d['port']}/health is not serving (state: "
469
+ f"{d['status'] or 'no response'}) — {d['impact']}."
470
+ )
471
+ print(
472
+ f" Self-heal: re-run `{dead[0]['fix']}` — it is now health-aware and "
473
+ "reaps a dead session before relaunching."
474
+ )
475
+ return len(dead)
476
+
477
+
407
478
  def cmd_doctor(args) -> int:
408
479
  """Auto-diagnose and fix common issues."""
409
480
  from .hooks_cli import _managed_file_state, _managed_hook_files, get_hooks_source
@@ -926,6 +997,41 @@ def cmd_doctor(args) -> int:
926
997
  except Exception as e:
927
998
  print(f" [..] Could not check project task migration: {e}")
928
999
 
1000
+ # 13. Managed voice shims (Kokoro :8102, Moonshine STT :8101) whose tmux
1001
+ # session is alive but whose /health is dead (#734). The old
1002
+ # session-existence-only idempotency masked a wedged engine forever, so
1003
+ # say/transcribe silently fell back to browser voice. Surfaced distinctly
1004
+ # here with the now-health-aware self-heal command.
1005
+ print("\nChecking managed voice shim liveness (#734)...")
1006
+ try:
1007
+ issues_found += _render_shim_liveness_section()
1008
+ except Exception as e:
1009
+ print(f" [..] Could not check managed voice shim liveness: {e}")
1010
+
1011
+ # 14. Zombie scheduler sessions (#739): a worktree dispatch whose launch
1012
+ # crashed before the agent started (e.g. the worktree dir went missing
1013
+ # between `agentwire new` reporting success and the pane's `cd`) drops to
1014
+ # a bare shell the idle-reaper never touches. `agentwire limits tick`
1015
+ # self-heals these every minute, so a live one here means the watchdog
1016
+ # isn't installed/running, not that reaping is broken.
1017
+ print("\nChecking for zombie scheduler sessions (#739)...")
1018
+ try:
1019
+ from .scheduler import scan_zombie_sessions
1020
+
1021
+ zombie_sessions = scan_zombie_sessions()
1022
+ if not zombie_sessions:
1023
+ print(" [ok] No zombie scheduler sessions found")
1024
+ else:
1025
+ issues_found += 1
1026
+ print(f" [!!] {len(zombie_sessions)} scheduler session(s) stuck at a bare shell:")
1027
+ for z in zombie_sessions:
1028
+ print(f" - {z['session']} ({z['command']}, {z['age_seconds']}s old)")
1029
+ print(" `agentwire limits tick` reaps these automatically — "
1030
+ "run it now, or check the usage-limit watchdog is installed "
1031
+ "(`agentwire limits install`).")
1032
+ except Exception as e:
1033
+ print(f" [..] Could not check for zombie scheduler sessions: {e}")
1034
+
929
1035
  # Summary
930
1036
  print()
931
1037
  print("-" * 60)
@@ -177,16 +177,20 @@ def cmd_limits_tick(args) -> int:
177
177
  """One watchdog pass (called by launchd every minute).
178
178
 
179
179
  Runs the usage-limit sweep FIRST, then prompt routing (#276), then the
180
- polite-message inbox drain (#296), then context auto-management (#442)
181
- the ordering guarantees a usage-limit dialog is parked before any sweep
182
- looks at the pane, that the inbox only ever delivers to panes the prompt
183
- sweep already cleared, and that auto-``/clear`` runs LAST so it never fights
184
- a pending paste/prompt for the same idle, empty box.
180
+ polite-message inbox drain (#296), then context auto-management (#442),
181
+ then the zombie-scheduler-session reap (#739) the ordering guarantees a
182
+ usage-limit dialog is parked before any sweep looks at the pane, that the
183
+ inbox only ever delivers to panes the prompt sweep already cleared, that
184
+ auto-``/clear`` runs before the reap so it never fights a pending
185
+ paste/prompt for the same idle, empty box, and that the reap runs LAST
186
+ since it kills sessions outright (nothing later should still be acting on
187
+ one).
185
188
 
186
189
  Each stage runs inside :func:`_run_stage` so an exception in one subsystem
187
190
  is logged and skipped rather than aborting the whole cycle (#490).
188
191
  """
189
192
  from agentwire import inbox, prompt_router, session_context
193
+ from agentwire.scheduler import zombie as scheduler_zombie
190
194
 
191
195
  result = _run_stage(
192
196
  "usage_limit", usage_limit.tick,
@@ -197,9 +201,12 @@ def cmd_limits_tick(args) -> int:
197
201
  "inbox", inbox.tick, {"flushed": [], "deferred": []})
198
202
  context = _run_stage(
199
203
  "session_context", session_context.tick, {"acted": [], "deferred": []})
204
+ zombies = _run_stage(
205
+ "scheduler_zombie", scheduler_zombie.tick, {"killed": []})
200
206
  if getattr(args, "json", False):
201
207
  print(json.dumps({
202
- **result, "prompts": prompts, "messages": messages, "context": context,
208
+ **result, "prompts": prompts, "messages": messages,
209
+ "context": context, "zombies": zombies,
203
210
  }))
204
211
  return 0
205
212
  if result.get("skipped"):
@@ -237,6 +244,9 @@ def cmd_limits_tick(args) -> int:
237
244
  if ctx_deferred:
238
245
  print("context deferred: " + ", ".join(
239
246
  f"{e['session']}({e['deferred']})" for e in ctx_deferred))
247
+ killed = zombies.get("killed") or []
248
+ if killed:
249
+ print("zombie scheduler sessions reaped: " + ", ".join(killed))
240
250
  return 0
241
251
 
242
252
 
@@ -24,6 +24,7 @@ from datetime import datetime, timezone
24
24
  import yaml
25
25
 
26
26
  from ..core import _atomic_write
27
+ from . import zombie
27
28
  from .dispatch import (
28
29
  _WORKFLOW_STATUS_TO_SCHED,
29
30
  _apply_max_runs,
@@ -110,3 +111,6 @@ from .state import (
110
111
  load_board,
111
112
  save_board,
112
113
  )
114
+ from .zombie import reap as reap_zombie_sessions
115
+ from .zombie import scan as scan_zombie_sessions
116
+ from .zombie import tick as zombie_tick
@@ -0,0 +1,160 @@
1
+ """Reap bare-shell scheduler sessions (#739).
2
+
3
+ ``_dispatch_worktree_task`` names every worktree branch
4
+ ``scheduler-<task>-<ts>``. If the session's launch crashes before the agent
5
+ starts (e.g. the worktree directory went missing between ``agentwire new``
6
+ reporting success and the pane's ``cd``), the tmux session drops to a bare
7
+ shell — which the idle-reaper correctly never touches, since it only reaps a
8
+ *running* agent that goes idle. Nothing else would ever clean that up, so it
9
+ lingers indefinitely. This module finds and kills those sessions.
10
+
11
+ Detected by branch naming rather than ``worktree_registry`` — scheduler
12
+ dispatch goes through ``agentwire new``, which (unlike ``agentwire
13
+ worktree``) never registers there.
14
+ """
15
+
16
+ import subprocess
17
+ import time
18
+
19
+ from ..worktree import parse_session_name
20
+
21
+ BRANCH_PREFIX = "scheduler-"
22
+
23
+ # tmux `session_created` is whole seconds. A healthy launch's pre-agent shell
24
+ # moment lasts well under a second (see `_launch_tmux_session`'s 0.1s
25
+ # settle), but this gives a slow `claude` cold start real headroom before a
26
+ # session still mid-launch could be mistaken for a zombie.
27
+ MIN_AGE_SECONDS = 60
28
+
29
+ _SHELL_COMMANDS = frozenset({"zsh", "bash", "sh", "fish", "tcsh", "csh", "dash"})
30
+
31
+
32
+ def _is_bare_shell(command: str) -> bool:
33
+ """True if *command* (a ``pane_current_command`` value) is a login shell."""
34
+ return command.strip().lstrip("-") in _SHELL_COMMANDS
35
+
36
+
37
+ def scan() -> list[dict]:
38
+ """Live scheduler-dispatched worktree sessions stuck at a bare shell.
39
+
40
+ Each entry: ``session``, ``branch``, ``command``, ``age_seconds``.
41
+ """
42
+ result = subprocess.run(
43
+ ["tmux", "list-sessions", "-F", "#{session_name}\t#{session_created}"],
44
+ capture_output=True, text=True,
45
+ )
46
+ if result.returncode != 0:
47
+ return []
48
+
49
+ now = time.time()
50
+ zombies = []
51
+ for line in result.stdout.strip().splitlines():
52
+ if "\t" not in line:
53
+ continue
54
+ session, created = line.split("\t", 1)
55
+ _, branch, machine = parse_session_name(session)
56
+ if machine or not branch or not branch.startswith(BRANCH_PREFIX):
57
+ continue
58
+ try:
59
+ age = now - float(created)
60
+ except ValueError:
61
+ continue
62
+ if age < MIN_AGE_SECONDS:
63
+ continue
64
+
65
+ panes = subprocess.run(
66
+ ["tmux", "list-panes", "-t", f"={session}", "-F", "#{pane_current_command}"],
67
+ capture_output=True, text=True,
68
+ )
69
+ if panes.returncode != 0:
70
+ continue
71
+ commands = [p for p in panes.stdout.strip().splitlines() if p]
72
+ if len(commands) == 1 and _is_bare_shell(commands[0]):
73
+ zombies.append({
74
+ "session": session, "branch": branch,
75
+ "command": commands[0], "age_seconds": int(age),
76
+ })
77
+ return zombies
78
+
79
+
80
+ def _notify(session: str, branch: str, command: str) -> None:
81
+ """Alert on a reaped zombie session (#739 + #743).
82
+
83
+ Always posts a portal toast, so the reap is visible in-band rather than
84
+ only in an email the human has to notice and forward. When the session
85
+ has a recorded parent (``created_by`` in its metadata — set at
86
+ ``agentwire new`` time, see ``_record_session_creator``), the crash is
87
+ ALSO escalated there via the msg inbox (drained by the same watchdog that
88
+ runs this reap) — a worktree worker's crash reaches its orchestrator, not
89
+ just the owner's inbox. Owner email — the reused Resend wiring, mirrors
90
+ ``dispatch._notify_dispatch_timeout`` — is strictly the fallback for a
91
+ session with no recorded parent (the genuine root/scheduler-dispatch
92
+ case #739 originally covered). Each channel is independently
93
+ best-effort; this must never raise into the caller.
94
+ """
95
+ text = (
96
+ f"agentwire: reaped zombie scheduler session `{session}` (branch "
97
+ f"`{branch}`) — launch crashed at a bare shell (`{command}`) before "
98
+ "the agent started."
99
+ )
100
+
101
+ try:
102
+ from ..core import _post_desktop_notification
103
+ _post_desktop_notification(text, session=session, priority="high")
104
+ except Exception:
105
+ pass
106
+
107
+ parent = None
108
+ try:
109
+ from ..core import load_session_metadata
110
+ parent = load_session_metadata(session).get("created_by") or None
111
+ except Exception:
112
+ parent = None
113
+
114
+ if parent:
115
+ try:
116
+ from ..inbox import enqueue
117
+ enqueue(parent, text, kind="escalation", sender="agentwire")
118
+ except Exception:
119
+ pass
120
+ return
121
+
122
+ try:
123
+ import socket
124
+
125
+ from ..channels.email import send_email
126
+ send_email(
127
+ subject=f"[agentwire] reaped zombie scheduler session: {session}",
128
+ body=(
129
+ f"Scheduler dispatch session `{session}` (branch `{branch}`) "
130
+ f"on `{socket.gethostname()}` never reached its agent — the "
131
+ f"pane was stuck at a bare shell (`{command}`), the #739 "
132
+ "failure mode where the worktree launch crashes before "
133
+ "`claude` starts (e.g. a missing worktree directory). The "
134
+ "watchdog killed the session so it can't linger.\n\n"
135
+ "Check the scheduler events log for the originating "
136
+ "dispatch failure."
137
+ ),
138
+ )
139
+ except Exception:
140
+ pass
141
+
142
+
143
+ def reap() -> dict:
144
+ """Kill every detected zombie session, logging + emailing each one."""
145
+ from agentwire import scheduler as _sched
146
+
147
+ killed = []
148
+ for z in scan():
149
+ _sched._kill_session(z["session"])
150
+ _sched._log_event("zombie_session_reaped", session=z["session"],
151
+ branch=z["branch"], command=z["command"],
152
+ age_seconds=z["age_seconds"])
153
+ _notify(z["session"], z["branch"], z["command"])
154
+ killed.append(z["session"])
155
+ return {"killed": killed}
156
+
157
+
158
+ def tick() -> dict:
159
+ """Watchdog stage entry point — same ``{"killed": [...]}`` shape as ``reap()``."""
160
+ return reap()
@@ -387,10 +387,11 @@ class AgentWireServer(
387
387
  """Ensure the default-tier Moonshine shim subprocess is running.
388
388
 
389
389
  Delegates to the CLI (single source of truth): ``agentwire stt start``
390
- is idempotent — ``cmd_stt_start`` early-returns if the ``agentwire-stt``
391
- tmux session already exists, so a user-started shim is reused with no
392
- port clash. The ~19s ONNX warm-up happens in that child process, never
393
- on the portal's event loop. Mirrors ``autostart_custom_services``."""
390
+ is idempotent and health-aware — ``cmd_stt_start`` reuses the
391
+ ``agentwire-stt`` session only when it is actually serving, and reaps +
392
+ relaunches a dead-but-present one (#734), so a wedged shim self-heals on
393
+ the next ensure. The ~19s ONNX warm-up happens in that child process,
394
+ never on the portal's event loop. Mirrors ``autostart_custom_services``."""
394
395
  await asyncio.sleep(5) # let the portal finish binding first
395
396
  try:
396
397
  success, result = await self.run_agentwire_cmd(["stt", "start"], json_output=False)
@@ -438,10 +439,11 @@ class AgentWireServer(
438
439
  """Ensure the default-tier Kokoro TTS shim subprocess is running.
439
440
 
440
441
  Delegates to the CLI (single source of truth): ``agentwire kokoro start``
441
- is idempotent — ``cmd_kokoro_start`` early-returns if the
442
- ``agentwire-kokoro`` tmux session already exists, so a user-started shim
443
- is reused with no port clash. The ~200 MB download + ONNX warm-up
444
- happens in that child process, never on the portal's event loop. Mirrors
442
+ is idempotent and health-aware — ``cmd_kokoro_start`` reuses the
443
+ ``agentwire-kokoro`` session only when it is actually serving, and reaps
444
+ + relaunches a dead-but-present one (#734), so a wedged shim self-heals
445
+ on the next ensure. The ~200 MB download + ONNX warm-up happens in that
446
+ child process, never on the portal's event loop. Mirrors
445
447
  ``ensure_managed_stt``."""
446
448
  await asyncio.sleep(5) # let the portal finish binding first
447
449
  try: