agentwire-dev 1.80.0__tar.gz → 1.81.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 (653) hide show
  1. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/.github/workflows/pytest.yml +25 -0
  2. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/PKG-INFO +2 -2
  3. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/RELEASING.md +2 -1
  4. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/__init__.py +1 -1
  5. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/core.py +17 -0
  6. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/doctor_cli.py +20 -5
  7. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/history.py +16 -0
  8. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/history_cli.py +102 -0
  9. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/hooks_cli.py +11 -1
  10. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_worktree.py +5 -2
  11. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/session_cli.py +43 -1
  12. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/worktree.py +20 -0
  13. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/INDEX.md +1 -0
  14. agentwire_dev-1.81.0/docs/wiki/research/orchestrator-comparison.md +57 -0
  15. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/sessions/conversation-identity.md +31 -1
  16. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/pyproject.toml +1 -1
  17. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_conversation_change.py +32 -3
  18. agentwire_dev-1.81.0/tests/unit/test_doctor_orphaned_history.py +183 -0
  19. agentwire_dev-1.80.0/tests/unit/test_doctor_orphaned_history.py +0 -88
  20. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/.agentwire.yml.example +0 -0
  21. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/.claude/commands/handoff.md +0 -0
  22. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/.claude/skills/wiki/SKILL.md +0 -0
  23. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/.github/FUNDING.yml +0 -0
  24. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  25. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  26. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
  27. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  28. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/.github/workflows/ruff.yml +0 -0
  29. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/.github/workflows/security.yml +0 -0
  30. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/.github/workflows/tts-smoke.yml +0 -0
  31. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/.gitignore +0 -0
  32. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/AGENTS.md +0 -0
  33. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/CODE_OF_CONDUCT.md +0 -0
  34. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/CONTRIBUTING.md +0 -0
  35. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/Dockerfile.local +0 -0
  36. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/LICENSE +0 -0
  37. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/README.md +0 -0
  38. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/SECURITY.md +0 -0
  39. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/SPONSORS.md +0 -0
  40. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/__main__.py +0 -0
  41. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/agents/__init__.py +0 -0
  42. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/agents/base.py +0 -0
  43. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/agents/tmux.py +0 -0
  44. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/auth_expired.py +0 -0
  45. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/background_tasks.py +0 -0
  46. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/beta.py +0 -0
  47. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/cached_status.py +0 -0
  48. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/channels/__init__.py +0 -0
  49. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/channels/base.py +0 -0
  50. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/channels/email.py +0 -0
  51. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/channels/push.py +0 -0
  52. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/channels/quo.py +0 -0
  53. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/channels_cli.py +0 -0
  54. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/chrome_tabs.py +0 -0
  55. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/claude_settings.py +0 -0
  56. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/cohort.py +0 -0
  57. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/completion.py +0 -0
  58. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/config.py +0 -0
  59. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/config_cli.py +0 -0
  60. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/council/__init__.py +0 -0
  61. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/council/cli.py +0 -0
  62. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/council/inbox.py +0 -0
  63. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/council/minutes.py +0 -0
  64. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/council/state.py +0 -0
  65. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/council/view.py +0 -0
  66. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/devices.py +0 -0
  67. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/diff_cli.py +0 -0
  68. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/doctor_voice.py +0 -0
  69. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/ensure_cli.py +0 -0
  70. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/env_loader.py +0 -0
  71. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/fetch.py +0 -0
  72. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/fleet.py +0 -0
  73. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/fleet_cli.py +0 -0
  74. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/handoff/__init__.py +0 -0
  75. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/handoff/git_state.py +0 -0
  76. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/handoff/instructions.py +0 -0
  77. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/handoff/parser.py +0 -0
  78. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/handoff/renderer.py +0 -0
  79. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/handoff/schema.py +0 -0
  80. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/handoff_cli.py +0 -0
  81. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/history_migrate.py +0 -0
  82. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/hooks/__init__.py +0 -0
  83. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/hooks/agentwire-permission.sh +0 -0
  84. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/hooks/idle-handler.sh +0 -0
  85. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/hooks/outcome_logger.py +0 -0
  86. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/hooks/queue-processor.sh +0 -0
  87. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/hooks/session-start-handler.sh +0 -0
  88. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/inbox.py +0 -0
  89. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/limits_cli.py +0 -0
  90. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/listen.py +0 -0
  91. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/locking.py +0 -0
  92. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/machine_cli.py +0 -0
  93. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_channels.py +0 -0
  94. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_chrome.py +0 -0
  95. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_cli.py +0 -0
  96. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_core.py +0 -0
  97. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_council.py +0 -0
  98. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_desktop.py +0 -0
  99. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_handoff.py +0 -0
  100. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_history.py +0 -0
  101. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_listen.py +0 -0
  102. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_lock.py +0 -0
  103. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_machine.py +0 -0
  104. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_msg.py +0 -0
  105. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_notify.py +0 -0
  106. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_pane.py +0 -0
  107. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_projects.py +0 -0
  108. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_scheduler.py +0 -0
  109. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_scratchpad.py +0 -0
  110. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_server.py +0 -0
  111. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_services.py +0 -0
  112. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_session.py +0 -0
  113. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_status.py +0 -0
  114. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_task.py +0 -0
  115. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_tunnels.py +0 -0
  116. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_voice.py +0 -0
  117. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/mcp_wiki.py +0 -0
  118. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/msg_cli.py +0 -0
  119. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/network.py +0 -0
  120. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/notify_cli.py +0 -0
  121. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/onboarding.py +0 -0
  122. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/palette_cli.py +0 -0
  123. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/pane_cli.py +0 -0
  124. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/pane_manager.py +0 -0
  125. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/playback_lane.py +0 -0
  126. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/portal_cli.py +0 -0
  127. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/project_config.py +0 -0
  128. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/projects.py +0 -0
  129. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/prompt_router.py +0 -0
  130. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/prompts_cli.py +0 -0
  131. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/push_cli.py +0 -0
  132. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/push_store.py +0 -0
  133. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/repo_cli.py +0 -0
  134. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/research.py +0 -0
  135. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/restart_cli.py +0 -0
  136. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/role_prompts.py +0 -0
  137. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/__init__.py +0 -0
  138. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/agentwire.md +0 -0
  139. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/anchor.md +0 -0
  140. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/chatbot.md +0 -0
  141. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/contributor.md +0 -0
  142. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/correspondent.md +0 -0
  143. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/council-brain.md +0 -0
  144. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/council-conscience.md +0 -0
  145. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/council-critic.md +0 -0
  146. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/council-devils-advocate.md +0 -0
  147. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/council-gut.md +0 -0
  148. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/council-historian.md +0 -0
  149. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/council-member.md +0 -0
  150. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/council-orchestrator.md +0 -0
  151. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/init.md +0 -0
  152. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/notifications.md +0 -0
  153. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/orchestrator.md +0 -0
  154. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/reviewer-worktree.md +0 -0
  155. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/reviewer.md +0 -0
  156. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/shared-checkout.md +0 -0
  157. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/soul.md +0 -0
  158. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/task-runner.md +0 -0
  159. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/voice.md +0 -0
  160. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/worker-worktree.md +0 -0
  161. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles/worker.md +0 -0
  162. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/roles_cli.py +0 -0
  163. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/routes/__init__.py +0 -0
  164. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/routes/artifacts.py +0 -0
  165. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/routes/config.py +0 -0
  166. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/routes/council.py +0 -0
  167. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/routes/desktop.py +0 -0
  168. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/routes/history.py +0 -0
  169. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/routes/machines.py +0 -0
  170. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/routes/notify.py +0 -0
  171. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/routes/palette.py +0 -0
  172. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/routes/permission.py +0 -0
  173. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/routes/projects.py +0 -0
  174. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/routes/push.py +0 -0
  175. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/routes/safety.py +0 -0
  176. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/routes/scheduler.py +0 -0
  177. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/routes/scratchpad.py +0 -0
  178. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/routes/sessions.py +0 -0
  179. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/routes/sessions_admin.py +0 -0
  180. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/routes/voice.py +0 -0
  181. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety/__init__.py +0 -0
  182. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety/audit.py +0 -0
  183. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety/lint.py +0 -0
  184. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety/provenance.py +0 -0
  185. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety/residuals.py +0 -0
  186. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety/rule_baselines.json +0 -0
  187. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety/rules/agentwire-control-plane.json +0 -0
  188. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety/rules/agentwire-control-plane.yaml +0 -0
  189. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety/rules/agentwire-core.json +0 -0
  190. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety/rules/agentwire-core.yaml +0 -0
  191. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety/rules/agentwire-mcp-tools.json +0 -0
  192. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety/rules/agentwire-mcp-tools.yaml +0 -0
  193. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety/rules/agentwire-outbound.json +0 -0
  194. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety/rules/agentwire-outbound.yaml +0 -0
  195. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety/rules/agentwire.json +0 -0
  196. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety/rules/agentwire.yaml +0 -0
  197. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety/suggest.py +0 -0
  198. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety_cli.py +0 -0
  199. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety_commands.py +0 -0
  200. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety_ext.py +0 -0
  201. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety_migrate.py +0 -0
  202. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety_notify.py +0 -0
  203. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/safety_packs_cli.py +0 -0
  204. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/sandbox.py +0 -0
  205. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/scheduler/__init__.py +0 -0
  206. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/scheduler/dispatch.py +0 -0
  207. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/scheduler/gates.py +0 -0
  208. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/scheduler/loop.py +0 -0
  209. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/scheduler/models.py +0 -0
  210. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/scheduler/report.py +0 -0
  211. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/scheduler/schedule.py +0 -0
  212. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/scheduler/state.py +0 -0
  213. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/scheduler/zombie.py +0 -0
  214. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/scheduler_cli.py +0 -0
  215. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/scratchpad.py +0 -0
  216. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/security.py +0 -0
  217. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/send_cli.py +0 -0
  218. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/sent_ledger.py +0 -0
  219. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/server.py +0 -0
  220. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/services.py +0 -0
  221. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/session_context.py +0 -0
  222. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/session_ready.py +0 -0
  223. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/session_state.py +0 -0
  224. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/ssh.py +0 -0
  225. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/agentwire-splash-logo-layers--agentwire-text.png +0 -0
  226. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/agentwire-splash-logo-layers--echo-claw-fg.png +0 -0
  227. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/agentwire-splash-logo-layers--echo.png +0 -0
  228. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/agentwire-splash-logo-layers--telephone.png +0 -0
  229. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/agentwire-splash-logo-layers--tree.png +0 -0
  230. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/announcements.json +0 -0
  231. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/apple-touch-icon.png +0 -0
  232. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/css/desktop.css +0 -0
  233. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/css/mobile.css +0 -0
  234. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/favicon-32.png +0 -0
  235. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/favicon-64.png +0 -0
  236. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/icons/sessions/bear.webp +0 -0
  237. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/icons/sessions/cat.webp +0 -0
  238. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/icons/sessions/crown.webp +0 -0
  239. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/icons/sessions/custom/agentwire-portal.webp +0 -0
  240. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/icons/sessions/custom/agentwire-tts.webp +0 -0
  241. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/icons/sessions/custom/agentwire.webp +0 -0
  242. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/icons/sessions/deer.webp +0 -0
  243. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/icons/sessions/drone.webp +0 -0
  244. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/icons/sessions/eagle.webp +0 -0
  245. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/icons/sessions/fox.webp +0 -0
  246. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/icons/sessions/hawk.webp +0 -0
  247. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/icons/sessions/horse.webp +0 -0
  248. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/icons/sessions/lion.webp +0 -0
  249. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/icons/sessions/rabbit.webp +0 -0
  250. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/icons/sessions/robot.webp +0 -0
  251. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/icons/sessions/tiger.webp +0 -0
  252. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/icons/sessions/wolf.webp +0 -0
  253. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/img/icon-192.png +0 -0
  254. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/img/icon-512.png +0 -0
  255. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/.gitkeep +0 -0
  256. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/announcement-modal.js +0 -0
  257. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/api.js +0 -0
  258. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/artifact-window.js +0 -0
  259. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/card-terminal.js +0 -0
  260. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/collage.js +0 -0
  261. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/command-palette.js +0 -0
  262. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/council-window.js +0 -0
  263. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/dead-key-residue.js +0 -0
  264. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/desktop-manager.js +0 -0
  265. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/desktop.js +0 -0
  266. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/help-modal.js +0 -0
  267. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/hotkeys.js +0 -0
  268. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/icon-manager.js +0 -0
  269. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/lineage.js +0 -0
  270. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/mobile.js +0 -0
  271. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/notification-prefs.js +0 -0
  272. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/notifications-panel.js +0 -0
  273. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/ptt.js +0 -0
  274. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/push-client.js +0 -0
  275. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/review-window.js +0 -0
  276. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/safety-shared.js +0 -0
  277. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/safety-window.js +0 -0
  278. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/scratchpad.js +0 -0
  279. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/service-classification.js +0 -0
  280. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/session-hud-controller.js +0 -0
  281. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/session-hud-notices.js +0 -0
  282. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/session-hud-spawn.js +0 -0
  283. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/session-hud.js +0 -0
  284. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/session-id.js +0 -0
  285. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/session-window.js +0 -0
  286. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/shortcuts.js +0 -0
  287. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/sidebar/artifacts-section.js +0 -0
  288. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/sidebar/config-section.js +0 -0
  289. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/sidebar/council-section.js +0 -0
  290. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/sidebar/fleet-section.js +0 -0
  291. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/sidebar/machines-section.js +0 -0
  292. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/sidebar/projects-section.js +0 -0
  293. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/sidebar/safety-section.js +0 -0
  294. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/sidebar/scheduler-section.js +0 -0
  295. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/sidebar/services-section.js +0 -0
  296. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/sidebar/sessions-section.js +0 -0
  297. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/sidebar.js +0 -0
  298. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/spawn-ghost.js +0 -0
  299. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/taskbar-persist.js +0 -0
  300. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/terminal-font-prefs.js +0 -0
  301. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/terminal-pane.js +0 -0
  302. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/tile-manager.js +0 -0
  303. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/toast.js +0 -0
  304. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/token-modal.js +0 -0
  305. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/topology-render.js +0 -0
  306. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/utils/ansi.js +0 -0
  307. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/utils/rich-text.js +0 -0
  308. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/utils/swipe.js +0 -0
  309. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/voice/audio-unlock.js +0 -0
  310. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/voice/autosend-prefs.js +0 -0
  311. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/voice/browser-stt.js +0 -0
  312. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/voice/browser-tts.js +0 -0
  313. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/voice/jargon.js +0 -0
  314. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/voice/prompt.js +0 -0
  315. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/winbox.bundle.min.js +0 -0
  316. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/js/workspace-window.js +0 -0
  317. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/manifest.webmanifest +0 -0
  318. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/service-worker.js +0 -0
  319. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/static/topology-harness.html +0 -0
  320. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/stt/__init__.py +0 -0
  321. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/stt/base.py +0 -0
  322. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/stt/cloud.py +0 -0
  323. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/stt/engine.py +0 -0
  324. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/stt/local.py +0 -0
  325. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/stt/server_backend.py +0 -0
  326. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/stt/stt_server.py +0 -0
  327. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/system_cli.py +0 -0
  328. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/tabs_cli.py +0 -0
  329. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/tasks.py +0 -0
  330. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/tasks_cli.py +0 -0
  331. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/templates/__init__.py +0 -0
  332. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/templates/base.html +0 -0
  333. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/templates/council/minutes.html.j2 +0 -0
  334. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/templates/desktop.html +0 -0
  335. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/templates/email_notification.html +0 -0
  336. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/templates/handoff/show-the-story.html.j2 +0 -0
  337. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/templates/handoff/theme.css.j2 +0 -0
  338. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/templates/mobile.html +0 -0
  339. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/templates/pair.html +0 -0
  340. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/templates/statusline.sh +0 -0
  341. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/templates/tmux.conf +0 -0
  342. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/templating.py +0 -0
  343. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/tts/__init__.py +0 -0
  344. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/tts/audio.py +0 -0
  345. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/tts/base.py +0 -0
  346. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/tts/engines/__init__.py +0 -0
  347. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/tts/engines/chatterbox.py +0 -0
  348. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/tts/engines/kokoro.py +0 -0
  349. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/tts/engines/zonos.py +0 -0
  350. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/tts/kokoro_server.py +0 -0
  351. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/tts/local.py +0 -0
  352. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/tts/registry.py +0 -0
  353. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/tts_cli.py +0 -0
  354. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/tts_server.py +0 -0
  355. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/tunnels.py +0 -0
  356. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/tunnels_cli.py +0 -0
  357. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/usage_limit.py +0 -0
  358. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/utils/__init__.py +0 -0
  359. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/utils/chunker.py +0 -0
  360. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/utils/event_log.py +0 -0
  361. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/utils/file_io.py +0 -0
  362. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/utils/paths.py +0 -0
  363. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/utils/speech.py +0 -0
  364. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/utils/subprocess.py +0 -0
  365. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/validation.py +0 -0
  366. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/voice_status.py +0 -0
  367. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/wait_cli.py +0 -0
  368. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/wiki.py +0 -0
  369. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/wiki_audit.py +0 -0
  370. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/wiki_cli.py +0 -0
  371. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/worktree_cli.py +0 -0
  372. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/agentwire/worktree_registry.py +0 -0
  373. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/corpus/cases/bypass.yaml +0 -0
  374. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/corpus/cases/control_plane.yaml +0 -0
  375. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/corpus/cases/path_spelling.yaml +0 -0
  376. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/corpus/cases/relative_paths.yaml +0 -0
  377. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/corpus/golden/effective_rules.json +0 -0
  378. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/corpus/golden/harvested.json +0 -0
  379. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/corpus/golden/rule_ids.json +0 -0
  380. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/corpus/golden/snapshot.json +0 -0
  381. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/corpus/schema.json +0 -0
  382. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/decisions/obsidian-second-brain.md +0 -0
  383. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/design/session-card-fields.md +0 -0
  384. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/design/session-card-recommendation.md +0 -0
  385. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/logo.png +0 -0
  386. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/architecture.md +0 -0
  387. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/auth-expired.md +0 -0
  388. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/briefing-mode.md +0 -0
  389. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/communication/channels.md +0 -0
  390. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/communication/hammerspoon.md +0 -0
  391. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/communication/handoff.md +0 -0
  392. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/concepts.md +0 -0
  393. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/council.md +0 -0
  394. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/deployment/remote-access.md +0 -0
  395. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/deployment/remote-machines.md +0 -0
  396. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/glossary.md +0 -0
  397. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/integrations/gws-google-workspace-cli.md +0 -0
  398. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/internals/damage-control.md +0 -0
  399. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/internals/parallel-refactor.md +0 -0
  400. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/internals/portal.md +0 -0
  401. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/internals/session-topology.md +0 -0
  402. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/internals/shell-escaping.md +0 -0
  403. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/internals/troubleshooting.md +0 -0
  404. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/internals/upgrade-test.md +0 -0
  405. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/internals/window-collage.md +0 -0
  406. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/quickstart.md +0 -0
  407. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/research/briefing-mode-feasibility.md +0 -0
  408. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/research/orchestration-transport-alternatives.md +0 -0
  409. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/scheduling/scheduled-workloads.md +0 -0
  410. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/security/damage-control-hardening.md +0 -0
  411. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/security/pip-audit.md +0 -0
  412. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/security/remote-access-hardening.md +0 -0
  413. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/security/sandbox-spike.md +0 -0
  414. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/security/secrets.md +0 -0
  415. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/services.md +0 -0
  416. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/sessions/claude-code-auto-mode.md +0 -0
  417. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/sessions/fan-out-cohorts.md +0 -0
  418. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/sessions/fleet.md +0 -0
  419. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/sessions/heal-line-count-cliff.md +0 -0
  420. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/sessions/helper-sessions.md +0 -0
  421. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/sessions/messaging.md +0 -0
  422. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/sessions/prompt-routing.md +0 -0
  423. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/sessions/window-sizing.md +0 -0
  424. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/sessions/worktree-sessions.md +0 -0
  425. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/usage-limit-recovery.md +0 -0
  426. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/voice/shim-contract.md +0 -0
  427. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/voice/stt-cloud.md +0 -0
  428. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/voice/stt-self-hosted.md +0 -0
  429. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/docs/wiki/voice/tts-self-hosted.md +0 -0
  430. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/conftest.py +0 -0
  431. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/corpus_runner.py +0 -0
  432. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/e2e/test_portal_ui.py +0 -0
  433. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/audio_unlock_harness.mjs +0 -0
  434. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/background_tasks/pane_30_shell.txt +0 -0
  435. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/background_tasks/pane_80_agent.txt +0 -0
  436. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/background_tasks/pane_80_done.txt +0 -0
  437. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/background_tasks/pane_80_interrupted.txt +0 -0
  438. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/background_tasks/pane_80_monitor.txt +0 -0
  439. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/background_tasks/pane_80_quoted_footer.txt +0 -0
  440. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/background_tasks/pane_80_second_notice.txt +0 -0
  441. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/background_tasks/pane_80_shell.txt +0 -0
  442. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/background_tasks/pane_80_shell_and_monitor.txt +0 -0
  443. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/background_tasks/transcript_bash_done.jsonl +0 -0
  444. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/background_tasks/transcript_bash_pending.jsonl +0 -0
  445. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/background_tasks/transcript_monitor_done.jsonl +0 -0
  446. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/background_tasks/transcript_monitor_events.jsonl +0 -0
  447. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/dc_msg_body_quoting_carriers.txt +0 -0
  448. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/hotkeys_harness.mjs +0 -0
  449. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/sample_agentwire.yml +0 -0
  450. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/sample_config.yaml +0 -0
  451. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/sample_scheduler.yaml +0 -0
  452. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/session_hud_detent_harness.mjs +0 -0
  453. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/taskbar_persist_harness.mjs +0 -0
  454. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/topology_expand_harness.mjs +0 -0
  455. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/fixtures/upgrade/gws.yaml +0 -0
  456. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/home_guard.py +0 -0
  457. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/integration/test_council_portal.py +0 -0
  458. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/integration/test_scheduler_board.py +0 -0
  459. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/integration/test_send_verified_tmux.py +0 -0
  460. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/integration/test_server_websockets.py +0 -0
  461. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/integration/test_tmux_name_rewrite.py +0 -0
  462. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/integration/test_upgrade_from_release.py +0 -0
  463. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/integration/test_worktree_cmd.py +0 -0
  464. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_agentwire_rules_layer.py +0 -0
  465. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_announcements.py +0 -0
  466. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_audio_unlock_js.py +0 -0
  467. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_audit_attribution.py +0 -0
  468. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_audit_outcomes.py +0 -0
  469. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_auth_expired.py +0 -0
  470. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_auth_expired_dispatch.py +0 -0
  471. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_background_tasks.py +0 -0
  472. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_background_tasks_review.py +0 -0
  473. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_beta_flag.py +0 -0
  474. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_block_rows_carry_an_id.py +0 -0
  475. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_brace_expansion_zero_access.py +0 -0
  476. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_breakglass.py +0 -0
  477. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_buddy_removal_keeps.py +0 -0
  478. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_build_agent_command.py +0 -0
  479. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_channels.py +0 -0
  480. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_chrome_tabs.py +0 -0
  481. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_claude_settings.py +0 -0
  482. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_cli_commands.py +0 -0
  483. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_cli_output.py +0 -0
  484. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_cli_smoke.py +0 -0
  485. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_cli_stderr_clean.py +0 -0
  486. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_cohort.py +0 -0
  487. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_config.py +0 -0
  488. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_config_cli.py +0 -0
  489. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_control_plane_protection.py +0 -0
  490. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_corpus.py +0 -0
  491. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_council_cli.py +0 -0
  492. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_council_inbox.py +0 -0
  493. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_council_minutes.py +0 -0
  494. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_council_state.py +0 -0
  495. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_council_view.py +0 -0
  496. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_damage_control_bypass.py +0 -0
  497. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_damage_control_delete_recursive.py +0 -0
  498. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_damage_control_hooks.py +0 -0
  499. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_damage_control_pin.py +0 -0
  500. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_dangling_worktrees.py +0 -0
  501. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_dc_install.py +0 -0
  502. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_dc_policy_packs.py +0 -0
  503. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_dc_profile_isolation.py +0 -0
  504. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_devices.py +0 -0
  505. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_diff_cli.py +0 -0
  506. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_doctor_scheduler_staleness.py +0 -0
  507. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_doctor_secrets_perms.py +0 -0
  508. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_doctor_task_migration.py +0 -0
  509. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_doctor_voice.py +0 -0
  510. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_ensure_shared_dir.py +0 -0
  511. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_ensure_verified_prompt.py +0 -0
  512. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_env_loader.py +0 -0
  513. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_escape_ask_routing.py +0 -0
  514. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_event_log.py +0 -0
  515. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_extension_points.py +0 -0
  516. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_fleet.py +0 -0
  517. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_golden_snapshot.py +0 -0
  518. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_guarded_launch_command.py +0 -0
  519. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_handoff_git_state.py +0 -0
  520. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_handoff_instructions.py +0 -0
  521. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_handoff_parser.py +0 -0
  522. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_handoff_renderer.py +0 -0
  523. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_helper_session.py +0 -0
  524. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_heredoc_marker_liveness.py +0 -0
  525. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_history.py +0 -0
  526. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_history_migrate.py +0 -0
  527. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_history_migrate_cli.py +0 -0
  528. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_history_resume_name.py +0 -0
  529. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_hook_fail_closed.py +0 -0
  530. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_hook_fail_closed_matrix.py +0 -0
  531. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_hook_link_guard.py +0 -0
  532. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_hook_python_floor.py +0 -0
  533. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_hook_subprocess.py +0 -0
  534. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_hooks_install.py +0 -0
  535. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_hotkeys_js.py +0 -0
  536. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_idle_handler.py +0 -0
  537. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_idle_nag.py +0 -0
  538. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_inbox.py +0 -0
  539. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_init_command.py +0 -0
  540. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_install_parity.py +0 -0
  541. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_launch_line_reentry.py +0 -0
  542. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_launch_via_env.py +0 -0
  543. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_limits_tick_isolation.py +0 -0
  544. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_live_target_1261.py +0 -0
  545. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_locking.py +0 -0
  546. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_mcp_nonblocking.py +0 -0
  547. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_mcp_server.py +0 -0
  548. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_mcp_tool_policy.py +0 -0
  549. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_mcp_tools_args.py +0 -0
  550. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_msg_cli.py +0 -0
  551. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_notify_cli.py +0 -0
  552. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_onboarding_reinit.py +0 -0
  553. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_owner_only_writes.py +0 -0
  554. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_palette_cli.py +0 -0
  555. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_path_case_folding.py +0 -0
  556. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_path_spelling.py +0 -0
  557. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_payload_position.py +0 -0
  558. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_pending_message_visibility.py +0 -0
  559. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_playback_lane.py +0 -0
  560. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_policy_ladder.py +0 -0
  561. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_portal_api.py +0 -0
  562. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_portal_pair_url.py +0 -0
  563. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_posture_default.py +0 -0
  564. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_powershell_matcher.py +0 -0
  565. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_project_config.py +0 -0
  566. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_projects_registry.py +0 -0
  567. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_prompt_router.py +0 -0
  568. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_prompt_router_dedup.py +0 -0
  569. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_prompt_router_resume.py +0 -0
  570. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_prose_operands.py +0 -0
  571. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_push.py +0 -0
  572. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_rebuild_guard.py +0 -0
  573. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_rebuild_uv_lock.py +0 -0
  574. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_relative_path_operands.py +0 -0
  575. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_remote_session_record.py +0 -0
  576. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_repo_cli.py +0 -0
  577. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_report_back_path_1259.py +0 -0
  578. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_restart_cli.py +0 -0
  579. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_rich_text_js.py +0 -0
  580. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_rm_recoverable.py +0 -0
  581. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_role_prompt_retention.py +0 -0
  582. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_role_prompt_sweep_wiring.py +0 -0
  583. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_roles.py +0 -0
  584. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_routes_snapshot.py +0 -0
  585. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_rule_files_load.py +0 -0
  586. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_rule_ids_pinned.py +0 -0
  587. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_rules_json_in_sync.py +0 -0
  588. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_safe_cwd.py +0 -0
  589. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_safety_deployment.py +0 -0
  590. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_safety_ext.py +0 -0
  591. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_safety_groups.py +0 -0
  592. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_safety_install.py +0 -0
  593. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_safety_migrate.py +0 -0
  594. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_safety_notify.py +0 -0
  595. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_safety_packs.py +0 -0
  596. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_sandbox.py +0 -0
  597. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_say_lane.py +0 -0
  598. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_scan_budget.py +0 -0
  599. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_scheduler.py +0 -0
  600. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_scheduler_liveness.py +0 -0
  601. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_scheduler_zombie.py +0 -0
  602. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_scratchpad.py +0 -0
  603. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_security.py +0 -0
  604. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_sed_script_is_data.py +0 -0
  605. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_sent_ledger.py +0 -0
  606. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_server_async.py +0 -0
  607. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_services.py +0 -0
  608. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_services_command.py +0 -0
  609. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_session_context.py +0 -0
  610. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_session_created_by_env.py +0 -0
  611. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_session_hud_detent_js.py +0 -0
  612. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_session_metadata_ssot.py +0 -0
  613. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_session_metadata_write.py +0 -0
  614. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_session_ready.py +0 -0
  615. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_session_state.py +0 -0
  616. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_shared_dir_guard.py +0 -0
  617. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_shim_selfheal.py +0 -0
  618. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_skill_install.py +0 -0
  619. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_speech_tags.py +0 -0
  620. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_ssh.py +0 -0
  621. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_stt_backend.py +0 -0
  622. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_stt_cloud.py +0 -0
  623. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_stt_engine.py +0 -0
  624. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_task_cli.py +0 -0
  625. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_task_max_duration.py +0 -0
  626. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_taskbar_persist_js.py +0 -0
  627. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_tasks.py +0 -0
  628. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_tasks_cli.py +0 -0
  629. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_templating.py +0 -0
  630. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_terminal_resize.py +0 -0
  631. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_tmux_session_cwd.py +0 -0
  632. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_topology_expand_js.py +0 -0
  633. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_tts_engine_resolution.py +0 -0
  634. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_tts_local.py +0 -0
  635. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_tunnels_probe.py +0 -0
  636. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_unattended_allow.py +0 -0
  637. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_unattended_env_isolation.py +0 -0
  638. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_unattended_scoped_allow.py +0 -0
  639. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_usage_limit.py +0 -0
  640. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_voice_assistant_removed.py +0 -0
  641. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_voice_off_and_shim_bind.py +0 -0
  642. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_voice_status.py +0 -0
  643. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_watchdog_stages.py +0 -0
  644. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_wiki.py +0 -0
  645. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_wiki_audit.py +0 -0
  646. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_worktree.py +0 -0
  647. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_worktree_branch_cleanup.py +0 -0
  648. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_worktree_dot_project.py +0 -0
  649. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_worktree_git_truth.py +0 -0
  650. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_worktree_layout.py +0 -0
  651. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_worktree_registry.py +0 -0
  652. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tests/unit/test_zero_access_member_access.py +0 -0
  653. {agentwire_dev-1.80.0 → agentwire_dev-1.81.0}/tools/nonce_stt_probe.py +0 -0
@@ -93,6 +93,31 @@ jobs:
93
93
  - name: Upgrade test
94
94
  run: uv run --no-sync pytest -q -m upgrade tests/integration/test_upgrade_from_release.py
95
95
 
96
+ # Scoped-allow mutation check (#1293): scripts/mutate_scoped_allow.py breaks each #914 safety
97
+ # property once and demands a red test. It exits 1 on any surviving mutation AND on a stale
98
+ # anchor (a skipped mutation counts as a survivor), so engine or source drift that silently
99
+ # detaches an anchor turns this job red. Pushes to main only, not the PR gate.
100
+ # Budget: ~10 min timeout, ~30 s typical (19 mutations x one test file).
101
+ mutation:
102
+ name: scoped-allow mutation check
103
+ if: github.event_name == 'push'
104
+ runs-on: ubuntu-latest
105
+ timeout-minutes: 10
106
+ steps:
107
+ - uses: actions/checkout@v4
108
+
109
+ - name: Install uv
110
+ uses: astral-sh/setup-uv@v5
111
+ with:
112
+ python-version: "3.12"
113
+
114
+ # The script mutates the engine inside this checkout's .venv, so it must exist.
115
+ - name: Sync dependencies
116
+ run: uv sync --extra dev
117
+
118
+ - name: Mutation check
119
+ run: uv run --extra dev python scripts/mutate_scoped_allow.py
120
+
96
121
  # The hook is `python -I -m damage_control.hook` and runs under whatever `python3` the user
97
122
  # has; the package's declared floor is 3.9 (#1223: a 3.10-only construct made the hooks crash
98
123
  # non-blocking, i.e. fail OPEN). The main job runs 3.12 and cannot see that. agentwire itself
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: agentwire-dev
3
- Version: 1.80.0
3
+ Version: 1.81.0
4
4
  Summary: Multi-session voice web interface for AI coding agents
5
5
  Project-URL: Homepage, https://agentwire.dev
6
6
  Project-URL: Repository, https://github.com/dotdevdotdev/agentwire-dev
@@ -228,7 +228,7 @@ Requires-Dist: aiohttp-jinja2>=1.6
228
228
  Requires-Dist: aiohttp>=3.13.4
229
229
  Requires-Dist: av>=12.0.0
230
230
  Requires-Dist: certifi>=2026.10.23
231
- Requires-Dist: damage-control-dev<0.4,>=0.3.0
231
+ Requires-Dist: damage-control-dev<0.5,>=0.4.0
232
232
  Requires-Dist: fastapi>=0.104.0
233
233
  Requires-Dist: jinja2>=3.1.0
234
234
  Requires-Dist: kokoro-onnx>=0.4.9; python_version < '3.14'
@@ -6,7 +6,7 @@ Every release does **both** a PyPI publish and a GitHub release. The **GitHub re
6
6
 
7
7
  ## The engine is a separate project (single source)
8
8
 
9
- The damage-control engine has exactly one source: the `damage-control-dev` repo (<https://github.com/dotdevdotdev/damage-control-dev>), published on PyPI. `agentwire-dev` only *consumes* it through the range in `pyproject.toml` (currently `damage-control-dev>=0.3.0,<0.4`); a checkout and a PyPI install both resolve it from PyPI. There is no copy of the engine in this repo and nothing to release from here. `tests/unit/test_damage_control_pin.py` checks that the declared floor/ceiling parse and that the installed engine satisfies them.
9
+ The damage-control engine has exactly one source: the `damage-control-dev` repo (<https://github.com/dotdevdotdev/damage-control-dev>), published on PyPI. `agentwire-dev` only *consumes* it through the range in `pyproject.toml` (currently `damage-control-dev>=0.4.0,<0.5`); a checkout and a PyPI install both resolve it from PyPI. There is no copy of the engine in this repo and nothing to release from here. `tests/unit/test_damage_control_pin.py` checks that the declared floor/ceiling parse and that the installed engine satisfies them.
10
10
 
11
11
  To ship an engine change:
12
12
 
@@ -20,6 +20,7 @@ An `agentwire-dev` whose floor names an engine version PyPI doesn't have yet is
20
20
  ## Pre-release checklist
21
21
 
22
22
  - The **`upgrade from previous release`** job in `.github/workflows/pytest.yml` is green on the commit you are about to tag (it runs on pushes to main and on PRs into a `release*` branch, not on ordinary PRs). It installs the previous release from PyPI, upgrades it to this checkout in a fresh `HOME`, then asserts `safety migrate` and `doctor` behave. Details: [`docs/wiki/internals/upgrade-test.md`](docs/wiki/internals/upgrade-test.md). Rerun it if the only failure is PyPI index lag.
23
+ - The **`scoped-allow mutation check`** job in the same workflow is green on that commit (pushes to main only; ~30 s). It runs `scripts/mutate_scoped_allow.py` and fails on any surviving mutation or stale anchor. If it is red after an engine floor bump, re-anchor the mutations in the script rather than skipping it.
23
24
  - Engine bumps: also follow step 3 of the engine section above.
24
25
 
25
26
  ## Steps
@@ -1,3 +1,3 @@
1
1
  """AgentWire - Multi-session voice web interface for AI coding agents."""
2
2
 
3
- __version__ = "1.80.0"
3
+ __version__ = "1.81.0"
@@ -1563,6 +1563,23 @@ def record_session_launch(
1563
1563
  return metadata
1564
1564
 
1565
1565
 
1566
+ def session_owns_cwd(metadata: dict, cwd: str) -> bool:
1567
+ """Whether *cwd* is where the recorded session runs (#1289).
1568
+
1569
+ Compared as Claude keys history: the physical path through
1570
+ ``history.encode_project_path``, against ``cwd_at_launch`` and
1571
+ ``worktree_path``. A nested ``claude -p`` started from a pane in a scratch
1572
+ directory fails this, which keeps its conversation out of the chain.
1573
+ """
1574
+ from .history import encode_project_path
1575
+
1576
+ def key(path: str) -> str:
1577
+ return encode_project_path(os.path.realpath(path))
1578
+
1579
+ owned = {key(p) for p in (metadata.get("cwd_at_launch"), metadata.get("worktree_path")) if p}
1580
+ return key(cwd) in owned
1581
+
1582
+
1566
1583
  def record_conversation_change(session_name: str, conversation_id: str) -> bool:
1567
1584
  """Make *conversation_id* the session's CURRENT conversation (#1271).
1568
1585
 
@@ -882,7 +882,7 @@ def scan_orphaned_history(sessions: list[str] | None = None) -> list[dict]:
882
882
  flag hundreds of them, most of which nobody will ever relaunch.
883
883
  """
884
884
  from .core import load_session_metadata, recorded_sessions, tmux_session_cwd
885
- from .history import locate_conversation
885
+ from .history import survey_chain
886
886
 
887
887
  findings: list[dict] = []
888
888
  for name in sessions if sessions is not None else recorded_sessions():
@@ -898,9 +898,7 @@ def scan_orphaned_history(sessions: list[str] | None = None) -> list[dict]:
898
898
  # Newest first, mirroring the order restart walks — so "the current
899
899
  # conversation" is the first link, and the orphans read in the order
900
900
  # anyone would care about them.
901
- located = [locate_conversation(cid, running_in) for cid in reversed(ids)]
902
- orphans = [loc for loc in located if loc.status == "orphaned"]
903
- resumable = next((loc for loc in located if loc.resumable), None)
901
+ located, orphans, resumable = survey_chain(ids, running_in)
904
902
 
905
903
  common = {
906
904
  "session": name,
@@ -993,7 +991,9 @@ def _render_orphaned_history_section() -> int:
993
991
  :func:`scan_orphaned_history`).
994
992
  """
995
993
  findings = scan_orphaned_history()
996
- orphaned = [f for f in findings if f["status"] == "orphaned"]
994
+ orphans_all = [f for f in findings if f["status"] == "orphaned"]
995
+ orphaned = [f for f in orphans_all if f["live"]]
996
+ dead_orphaned = [f for f in orphans_all if not f["live"]]
997
997
  gone = [f for f in findings if f["status"] == "gone"]
998
998
 
999
999
  if not orphaned:
@@ -1011,11 +1011,26 @@ def _render_orphaned_history_section() -> int:
1011
1011
  + (" [moved since launch]" if f["moved"] else ""))
1012
1012
  print(f" history: {f['found_at']}")
1013
1013
  print(f" expected: {f['expected_dir']}/")
1014
+ print(" Ids whose history sits under scratch directories are nested "
1015
+ "`claude -p` runs a worker made from its pane: before #1289 the "
1016
+ "session-start hook recorded them into the chain. The session's own "
1017
+ "conversation is the one keyed to its launch cwd.")
1014
1018
  print(" Recover with `agentwire history migrate` — the transcripts are "
1015
1019
  "intact, just keyed to the old path. Until then `agentwire restart` on a "
1016
1020
  "'current conversation' one starts FRESH (role intact) rather than "
1017
1021
  "failing, and never silences this line.")
1018
1022
 
1023
+ if dead_orphaned:
1024
+ print(f" [..] {len(dead_orphaned)} session(s) not running with orphaned "
1025
+ "conversation history (torn-down sessions keep their record; not scored):")
1026
+ for f in dead_orphaned:
1027
+ extra = len(f["orphaned_ids"]) - 1
1028
+ print(f" - {f['session']} conversation {f['conversation_id'][:8]}"
1029
+ + (f", +{extra} more orphaned" if extra > 0 else "")
1030
+ + f" — history: {f['found_at']}")
1031
+ print(" Recover: `agentwire history migrate --session <name>` (add --apply), "
1032
+ "or drop the dead records: `agentwire history prune --dead` (lists; --yes deletes).")
1033
+
1019
1034
  if gone:
1020
1035
  print(f" [..] {len(gone)} live session(s) with no conversation history on disk "
1021
1036
  "(never prompted, or evicted by Claude — not determinable here):")
@@ -297,6 +297,22 @@ def locate_conversation(
297
297
  )
298
298
 
299
299
 
300
+ def survey_chain(
301
+ conversation_ids: list[str], cwd
302
+ ) -> tuple[list[ConversationLocation], list[ConversationLocation], ConversationLocation | None]:
303
+ """Probe EVERY link of a recorded chain, newest first.
304
+
305
+ Returns ``(located, orphans, resumable)``: all links, the orphaned ones,
306
+ and the newest resumable one. The one survey ``doctor`` and teardown share,
307
+ so "this chain has orphans" has a single answer (see
308
+ :func:`locate_conversation` for the per-link predicate).
309
+ """
310
+ located = [locate_conversation(cid, cwd) for cid in reversed(conversation_ids)]
311
+ orphans = [loc for loc in located if loc.status == "orphaned"]
312
+ resumable = next((loc for loc in located if loc.resumable), None)
313
+ return located, orphans, resumable
314
+
315
+
300
316
  def _get_machine_config(machine_id: str) -> dict | None:
301
317
  """Load machine config from machines.json.
302
318
 
@@ -448,6 +448,95 @@ def cmd_history_migrate(args) -> int:
448
448
  return 1 if failed else 0
449
449
 
450
450
 
451
+ def dead_session_records(older_than_s: int | None = None, *, now: float | None = None) -> list[dict]:
452
+ """Session records whose tmux session is not running, oldest first.
453
+
454
+ ``age_s`` is the record's own mtime age (last launch/hook write), so
455
+ ``older_than_s`` spares a session torn down moments ago. Each entry says
456
+ whether its chain has orphaned conversations — the thing worth knowing
457
+ before deleting the only map from session name to conversation.
458
+ """
459
+ from .core import (
460
+ load_session_metadata,
461
+ recorded_sessions,
462
+ session_metadata_path,
463
+ tmux_session_exists,
464
+ )
465
+ from .history import survey_chain
466
+
467
+ now = time.time() if now is None else now
468
+ rows = []
469
+ for name in recorded_sessions():
470
+ if tmux_session_exists(name):
471
+ continue
472
+ path = session_metadata_path(name)
473
+ try:
474
+ age = now - path.stat().st_mtime
475
+ except OSError:
476
+ continue
477
+ if older_than_s is not None and age < older_than_s:
478
+ continue
479
+ metadata = load_session_metadata(name)
480
+ ids = list(metadata.get("conversation_ids") or [])
481
+ cwd = metadata.get("cwd_at_launch")
482
+ orphaned = [loc.conversation_id for loc in survey_chain(ids, cwd)[1]] if ids and cwd else []
483
+ rows.append({"session": name, "path": str(path.parent), "age_s": int(age),
484
+ "orphaned_ids": orphaned})
485
+ return sorted(rows, key=lambda r: -r["age_s"])
486
+
487
+
488
+ def _delete_record(session: str) -> None:
489
+ """Remove a session's record file, then its now-empty directories."""
490
+ from .core import session_metadata_path, sessions_dir
491
+
492
+ path = session_metadata_path(session)
493
+ path.unlink()
494
+ root = sessions_dir()
495
+ parent = path.parent
496
+ while parent != root:
497
+ try:
498
+ parent.rmdir()
499
+ except OSError:
500
+ break # not empty — other files live here; leave them
501
+ parent = parent.parent
502
+
503
+
504
+ def cmd_history_prune(args) -> int:
505
+ """List dead session records; delete them only with --yes."""
506
+ from .msg_cli import _parse_duration
507
+
508
+ if not args.dead:
509
+ return _output_result(False, args.json, "Usage: agentwire history prune --dead [--older-than 14d] [--yes]")
510
+ older = None
511
+ if args.older_than:
512
+ older = _parse_duration(args.older_than)
513
+ if older is None:
514
+ return _output_result(False, args.json, f"Bad --older-than {args.older_than!r} (use e.g. 14d, 12h)")
515
+
516
+ rows = dead_session_records(older)
517
+ deleted = []
518
+ if args.yes:
519
+ for r in rows:
520
+ _delete_record(r["session"])
521
+ deleted.append(r["session"])
522
+
523
+ if args.json:
524
+ return _output_json({"success": True, "deleted": deleted, "dead": rows,
525
+ "applied": args.yes})
526
+ if not rows:
527
+ print("No dead session records.")
528
+ return 0
529
+ for r in rows:
530
+ flag = f" [{len(r['orphaned_ids'])} orphaned conversation(s)]" if r["orphaned_ids"] else ""
531
+ print(f"{'deleted' if args.yes else 'dead'}: {r['session']} ({r['age_s'] // 86400}d old){flag}")
532
+ if args.yes:
533
+ print(f"\nDeleted {len(deleted)} record(s).")
534
+ else:
535
+ print(f"\n{len(rows)} dead record(s). Re-run with --yes to delete them "
536
+ "(a record is the only map from session name to conversation).")
537
+ return 0
538
+
539
+
451
540
  def register_history_parser(subparsers) -> None:
452
541
  history_parser = subparsers.add_parser("history", help="Claude Code session history")
453
542
  history_subparsers = history_parser.add_subparsers(dest="history_command")
@@ -503,3 +592,16 @@ def register_history_parser(subparsers) -> None:
503
592
  help="Delete the old history dir, but only after the copy verifies")
504
593
  history_mig.add_argument("--json", action="store_true", help="JSON output")
505
594
  history_mig.set_defaults(func=cmd_history_migrate)
595
+
596
+ # history prune
597
+ history_prune = history_subparsers.add_parser(
598
+ "prune",
599
+ help="List (or with --yes delete) session records of sessions that are not running",
600
+ )
601
+ history_prune.add_argument("--dead", action="store_true",
602
+ help="Target records whose tmux session is not running")
603
+ history_prune.add_argument("--older-than", help="Only records untouched for this long (e.g. 14d)")
604
+ history_prune.add_argument("--yes", action="store_true",
605
+ help="Delete the listed records (default is list only)")
606
+ history_prune.add_argument("--json", action="store_true", help="JSON output")
607
+ history_prune.set_defaults(func=cmd_history_prune)
@@ -757,7 +757,7 @@ def record_session_start(payload: dict) -> str:
757
757
  :func:`cmd_hooks_session_start` is the one place that turns that into exit 0.
758
758
  """
759
759
  from . import pane_manager
760
- from .core import record_conversation_change
760
+ from .core import load_session_metadata, record_conversation_change, session_owns_cwd
761
761
 
762
762
  conversation_id = payload.get("session_id")
763
763
  if not isinstance(conversation_id, str) or not conversation_id:
@@ -771,6 +771,16 @@ def record_session_start(payload: dict) -> str:
771
771
  return f"skipped: worker pane {session}.{pane_index}"
772
772
 
773
773
  source = payload.get("source", "?")
774
+ # A headless `claude -p` started from this pane inherits $TMUX_PANE and fires
775
+ # this same hook with source=startup, indistinguishable from a real start
776
+ # except by its cwd (#1289).
777
+ payload_cwd = payload.get("cwd")
778
+ if not isinstance(payload_cwd, str) or not payload_cwd:
779
+ return f"ignored: payload has no cwd, cannot tell {session}'s conversation from a nested run"
780
+ metadata = load_session_metadata(session)
781
+ if metadata.get("cwd_at_launch") and not session_owns_cwd(metadata, payload_cwd):
782
+ return (f"ignored: {conversation_id} ran in {payload_cwd}, not {session}'s "
783
+ f"{metadata['cwd_at_launch']} (nested run, source={source})")
774
784
  if record_conversation_change(session, conversation_id):
775
785
  return f"recorded {conversation_id} for {session} (source={source})"
776
786
  return f"unchanged: {session} already at {conversation_id} or has no launch record"
@@ -5,7 +5,7 @@ from .mcp_core import (
5
5
  get_caller_session,
6
6
  mcp,
7
7
  )
8
- from .worktree import teardown_session_note
8
+ from .worktree import teardown_record_note, teardown_session_note
9
9
 
10
10
 
11
11
  @mcp.tool()
@@ -304,7 +304,10 @@ def worktree_remove(
304
304
  branch_bit = (f" Branch '{data['branch']}' deleted." if data.get("branch_deleted")
305
305
  else f" Branch '{data['branch']}' kept ({data.get('branch_note', 'not deleted')}).")
306
306
  tabs_bit = _orphaned_tabs_warning(data.get("orphaned_tabs"))
307
- return f"Teardown '{name}' (session '{session}'){session_bit}; worktree deleted.{branch_bit}{tabs_bit}"
307
+ record_note = teardown_record_note(data)
308
+ record_bit = f" {record_note[0].upper()}{record_note[1:]}." if record_note else ""
309
+ return (f"Teardown '{name}' (session '{session}'){session_bit}; worktree deleted."
310
+ f"{branch_bit}{tabs_bit}{record_bit}")
308
311
 
309
312
 
310
313
  def _orphaned_tabs_warning(orphaned: list | None) -> str:
@@ -35,11 +35,13 @@ from .core import (
35
35
  _set_session_name_env,
36
36
  build_agent_command,
37
37
  load_config,
38
+ load_session_metadata,
38
39
  mirror_role_prompt_remote,
39
40
  notify_portal_session_created,
40
41
  parse_env_args,
41
42
  record_session_launch,
42
43
  resolve_default_created_by,
44
+ session_metadata_path,
43
45
  tmux_session_exists,
44
46
  unparented_delegation_warning,
45
47
  )
@@ -74,6 +76,7 @@ from .worktree import (
74
76
  register_worktree,
75
77
  remove_worktree,
76
78
  safe_worktree_name,
79
+ teardown_record_note,
77
80
  teardown_session_note,
78
81
  tmux_safe_name,
79
82
  worktree_session_name,
@@ -1686,6 +1689,7 @@ def _worktree_prune(args, project_path: Path, worktree_dir: Path, json_mode: boo
1686
1689
  gc_merged_out = []
1687
1690
  gc_refused = []
1688
1691
  gc_orphaned_tabs = []
1692
+ gc_records = []
1689
1693
  gc_merged = getattr(args, 'gc_merged', False)
1690
1694
  for e in list(worktree_registry.entries(project_path)):
1691
1695
  wt_path = Path(e.get("worktree_path", ""))
@@ -1709,6 +1713,12 @@ def _worktree_prune(args, project_path: Path, worktree_dir: Path, json_mode: boo
1709
1713
  )
1710
1714
  if result["success"]:
1711
1715
  gc_merged_out.append(e["session"])
1716
+ if result.get("record_left"):
1717
+ gc_records.append({
1718
+ "session": e["session"],
1719
+ "record_left": result["record_left"],
1720
+ "record_orphaned_ids": result["record_orphaned_ids"],
1721
+ })
1712
1722
  for t in result.get("orphaned_tabs") or []:
1713
1723
  gc_orphaned_tabs.append({**t, "session": e["session"]})
1714
1724
  else:
@@ -1720,7 +1730,8 @@ def _worktree_prune(args, project_path: Path, worktree_dir: Path, json_mode: boo
1720
1730
  capture_output=True)
1721
1731
  if json_mode:
1722
1732
  _output_json({"success": True, "pruned": removed, "gc_merged": gc_merged_out,
1723
- "gc_refused": gc_refused, "orphaned_tabs": gc_orphaned_tabs})
1733
+ "gc_refused": gc_refused, "orphaned_tabs": gc_orphaned_tabs,
1734
+ "records_left": gc_records})
1724
1735
  else:
1725
1736
  for r in gc_refused:
1726
1737
  print(f"SKIPPED {r['session']}: {r['error']}")
@@ -1732,6 +1743,8 @@ def _worktree_prune(args, project_path: Path, worktree_dir: Path, json_mode: boo
1732
1743
  f"{ids} — close via tabs_close_mcp")
1733
1744
  if gc_merged_out:
1734
1745
  print(f"GC'd {len(gc_merged_out)} merged worktree{'s' if len(gc_merged_out) != 1 else ''}: {', '.join(gc_merged_out)}")
1746
+ for r in gc_records:
1747
+ print(f" {r['session']}: {teardown_record_note({**r})}")
1735
1748
  if not removed and not gc_merged_out and not gc_refused:
1736
1749
  print("Nothing to prune.")
1737
1750
  return 0
@@ -1961,6 +1974,29 @@ def _delete_branch_if_safe(
1961
1974
  return True, "merged" if not force else "forced"
1962
1975
 
1963
1976
 
1977
+ def _session_record_state(session_name: str) -> tuple[str | None, list[str]]:
1978
+ """What teardown leaves behind: the record's path and its orphaned chain ids.
1979
+
1980
+ ``(None, [])`` when the session has no record. Read-only — teardown never
1981
+ deletes the record (see ``agentwire history prune --dead``).
1982
+ """
1983
+ from .history import survey_chain
1984
+
1985
+ try:
1986
+ path = session_metadata_path(session_name)
1987
+ except ValueError:
1988
+ return None, []
1989
+ if not path.exists():
1990
+ return None, []
1991
+ metadata = load_session_metadata(session_name)
1992
+ ids = list(metadata.get("conversation_ids") or [])
1993
+ cwd = metadata.get("cwd_at_launch")
1994
+ if not ids or not cwd:
1995
+ return str(path.parent), []
1996
+ _, orphans, _ = survey_chain(ids, cwd)
1997
+ return str(path.parent), [loc.conversation_id for loc in orphans]
1998
+
1999
+
1964
2000
  def _teardown_entry(
1965
2001
  project_path: Path, worktree_dir: Path, session_name: str, worktree_path: Path,
1966
2002
  branch: str | None, base: str | None, *, keep_branch: bool = False, force_branch: bool = False,
@@ -2096,7 +2132,10 @@ def _teardown_entry(
2096
2132
  # that closed its own tabs and untracked them normally leaves nothing here.
2097
2133
  orphaned_tabs = chrome_tabs.clear(session_name)
2098
2134
 
2135
+ record_left, record_orphaned_ids = _session_record_state(session_name)
2136
+
2099
2137
  return {"success": True, "session": session_name, "path": str(worktree_path),
2138
+ "record_left": record_left, "record_orphaned_ids": record_orphaned_ids,
2100
2139
  "killed": killed, "worktree_removed": worktree_existed,
2101
2140
  "worktree_existed": worktree_existed,
2102
2141
  "session_existed": session_existed,
@@ -2189,6 +2228,9 @@ def _worktree_remove(args, project_path: Path, worktree_dir: Path, json_mode: bo
2189
2228
  ids = ", ".join(t.get("tab_id", "?") for t in result["orphaned_tabs"])
2190
2229
  msg += (f"; WARNING: {len(result['orphaned_tabs'])} claude-in-chrome tab(s) never closed "
2191
2230
  f"by this session: {ids} — close via tabs_close_mcp")
2231
+ record_note = teardown_record_note(result)
2232
+ if record_note:
2233
+ msg += "; " + record_note
2192
2234
  print(msg)
2193
2235
  return 0 if result["success"] else 1
2194
2236
 
@@ -243,6 +243,26 @@ def teardown_session_note(result: dict) -> str:
243
243
  return f" (NO live tmux session named '{session}' — nothing killed)"
244
244
 
245
245
 
246
+ def teardown_record_note(result: dict) -> str:
247
+ """Clause saying what teardown left in the session-record store.
248
+
249
+ Teardown never deletes ``~/.agentwire/sessions/<name>`` — the record is
250
+ the only map from session name to conversation — so it states that it is
251
+ still there, and whether its chain has orphaned entries. Empty when there
252
+ was no record (or the teardown did not complete).
253
+ """
254
+ record = result.get("record_left")
255
+ if not record:
256
+ return ""
257
+ session = result.get("session") or "?"
258
+ orphaned = result.get("record_orphaned_ids") or []
259
+ note = f"session record left at {record}"
260
+ if orphaned:
261
+ note += (f" (chain has {len(orphaned)} orphaned conversation(s) — "
262
+ f"`agentwire history migrate --session {session}`)")
263
+ return note + "; drop with `agentwire history prune --dead --yes`"
264
+
265
+
246
266
  def ensure_worktree(
247
267
  project_path: Path,
248
268
  branch: str,
@@ -77,6 +77,7 @@ Running AgentWire across machines and exposing the portal.
77
77
  Recon notes and evaluations that inform direction (not yet implemented).
78
78
 
79
79
  - **[Orchestration transport alternatives](research/orchestration-transport-alternatives.md)** — the "we don't use SSH" competitor pitch, evaluated: claims-vs-reality on faster/more-secure, and why the cheap wins are SSH `ControlMaster` multiplexing + a Tailscale mesh underlay rather than a new transport ([#297](https://github.com/dotdevdotdev/agentwire-dev/issues/297))
80
+ - **[How AgentWire differs](research/orchestrator-comparison.md)** — sourced survey of Claude Squad, Conductor, Sculptor, Claude Code agent teams and Multica (license, platforms, isolation, what each does that the other doesn't; unverified claims marked) plus suggested borrows ([#1294](https://github.com/dotdevdotdev/agentwire-dev/issues/1294))
80
81
  - **[Briefing Mode feasibility](research/briefing-mode-feasibility.md)** — asymmetric-verbosity orchestration evaluation that informed the shipped Briefing Mode
81
82
 
82
83
  ## Voice (TTS & STT)
@@ -0,0 +1,57 @@
1
+ # How AgentWire differs from other multi-agent coding orchestrators
2
+
3
+ > Research note for [#1294](https://github.com/dotdevdotdev/agentwire-dev/issues/1294), from the post-1.79 brainstorm ([#1275](https://github.com/dotdevdotdev/agentwire-dev/issues/1275)). Sourced from each project's own repository and docs, read 2026-11-05. Tools move fast: re-check before quoting. **Anything marked _unverified_ was not stated on a primary page.** This is a survey, not a roadmap; the borrow candidates at the end are suggestions, not work done.
4
+
5
+ ## Summary table
6
+
7
+ | | Form | License | Platforms | Isolation |
8
+ |---|---|---|---|---|
9
+ | **AgentWire** | CLI + tmux + web portal + MCP | Apache-2.0 ([`LICENSE`](../../../LICENSE)) | macOS/Linux + tmux ([quickstart](../quickstart.md)) | git worktree per session, plus no-isolation helper sessions ([worktree sessions](../sessions/worktree-sessions.md), [helper sessions](../sessions/helper-sessions.md)) |
10
+ | [Claude Squad](https://github.com/smtg-ai/claude-squad) | terminal TUI | AGPL-3.0 ([repo](https://github.com/smtg-ai/claude-squad)) | needs tmux and `gh`; OS list _unverified_ ([README](https://github.com/smtg-ai/claude-squad/blob/main/README.md)) | "isolated git workspace" per task; the source tree has [`session/git/worktree*.go`](https://github.com/smtg-ai/claude-squad/tree/main/session/git) |
11
+ | [Conductor](https://www.conductor.build/) | desktop app | _unverified_ (not stated on the [homepage](https://www.conductor.build/) or [docs](https://www.conductor.build/docs/)) | Mac ("Run parallel coding agents on your Mac") | "own workspace, branch, files, terminal, diff, and review path"; mechanism (worktree or not) _unverified_ |
12
+ | [Sculptor](https://github.com/imbue-ai/sculptor) | desktop app | MIT per the GitHub license field ([`LICENSE.md`](https://github.com/imbue-ai/sculptor/blob/main/LICENSE.md)); README says it is not yet truly open source and takes few outside contributions | Mac (Apple Silicon), Linux, Linux ARM64 ([README](https://github.com/imbue-ai/sculptor)) | default is a git worktree; clone and container modes are experimental ([workspaces](https://github.com/imbue-ai/sculptor/blob/main/docs/help/workspaces.md), [container backend](https://github.com/imbue-ai/sculptor/blob/main/docs/help/experimental/container_backend.md)) |
13
+ | [Claude Code agent teams](https://code.claude.com/docs/en/agent-teams) | built into Claude Code | Claude Code's own terms; not an independent project | Any terminal for in-process; split panes need tmux or iTerm2 | none for teammates; the docs say "Break the work so each teammate owns a different set of files". Worktrees are a separate feature ([worktrees](https://code.claude.com/docs/en/worktrees.md)) |
14
+ | [Multica](https://github.com/multica-ai/multica) | self-hostable web workspace + daemon + CLI | Apache-2.0 plus extra conditions (no hosted-service use, branding retention) ([`LICENSE`](https://github.com/multica-ai/multica/blob/main/LICENSE)); the README calls it "source-available" | web, desktop (macOS/Windows/Linux), mobile ([README](https://github.com/multica-ai/multica)) | agents run on "a runtime you control" (a daemon on your machine); per-task isolation mechanism _unverified_ |
15
+
16
+ ## Per tool
17
+
18
+ ### Claude Squad
19
+ - **What:** "a terminal app that manages multiple Claude Code, Codex, Gemini (and other local agents including Aider) in separate workspaces" ([README](https://github.com/smtg-ai/claude-squad/blob/main/README.md)). Built on tmux and `gh`. Highlights: background tasks including auto-accept, and "Review changes before applying them, checkout changes before pushing them".
20
+ - **Does that AgentWire does not:** a single-window TUI that lists every task and reviews its changes in place. Per the README, review happens inside the app.
21
+ - **AgentWire does that it does not:** no sign in its README of voice, a web UI, remote machines, scheduled runs, a parent/child session model, report-back messaging, or a command safety layer. _Absence on a README page is not proof of absence in the code._
22
+
23
+ ### Conductor
24
+ - **What:** "Run parallel coding agents on your Mac" with Claude Code, Codex and Cursor in isolated workspaces ([homepage](https://www.conductor.build/)). The [docs](https://www.conductor.build/docs/) describe a flow of workspace, diff viewer, checks, pull request, merge, archive.
25
+ - **Does that AgentWire does not:** an integrated diff viewer and checks step per workspace, in a native app.
26
+ - **AgentWire does that it does not:** runs off the Mac (Linux, remote machines over SSH), headless and scheduled work, and an agent-facing API (MCP). Pricing, license and the isolation mechanism were not stated on the pages read: _unverified_.
27
+
28
+ ### Sculptor (Imbue)
29
+ - **What:** "a desktop app for running coding agents in parallel" ([README](https://github.com/imbue-ai/sculptor)). Workspace is "by default ... a git worktree"; harnesses are Claude Code and Pi, plus "any terminal-based agents". Experimental research preview.
30
+ - **Does that AgentWire does not:** a Files panel with Browse, Changes and Commits tabs and per-file diffs ([changes](https://github.com/imbue-ai/sculptor/blob/main/docs/help/changes.md)); in-app PR opening and status tracking ([README doc index](https://github.com/imbue-ai/sculptor)); an experimental container or remote backend.
31
+ - **AgentWire does that it does not:** tmux-resident sessions that outlive the UI, voice, channels, and the scheduler. Whether Sculptor has equivalents of the last three is _unverified_.
32
+
33
+ ### Claude Code agent teams
34
+ - **What:** "Experimental and disabled by default" (`CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1`). One lead session, teammates that are separate Claude Code instances with a shared task list and a mailbox ([docs](https://code.claude.com/docs/en/agent-teams)).
35
+ - **Does that AgentWire does not:** teammates message each other directly and self-claim tasks from a shared list with dependency tracking; hooks (`TeammateIdle`, `TaskCreated`, `TaskCompleted`) gate quality.
36
+ - **AgentWire does that it does not:** per its stated limitations, there is "No session resumption with in-process teammates", "One team per session", "No nested teams", and teammates are not worktree-isolated. AgentWire sessions are durable tmux sessions that survive the parent, nest arbitrarily, and each worktree session has its own branch. In exchange, agent teams are first-party and need no extra install.
37
+
38
+ ### Multica
39
+ - **What:** "a source-available workspace where you assign work to AI coding agents the way you'd assign it to a teammate": issue board, agents as assignees, Squads, Skills, Autopilots (cron), execution logs, usage analytics, review gates ([README](https://github.com/multica-ai/multica)). A different category: a project-management product with agents, not a terminal orchestrator.
40
+ - **Does that AgentWire does not:** a board, issue assignment, multi-user workspaces and roles, per-run cost analytics, chat integrations (Slack and others), mobile apps. AgentWire ships no PM product by design.
41
+ - **AgentWire does that it does not:** local-first terminal sessions you can attach to, voice, and a damage-control hook layer on every tool call. Whether Multica has an equivalent command guard is _unverified_.
42
+
43
+ ## Where AgentWire sits
44
+
45
+ Taken together, the sourced differences are:
46
+
47
+ - **Substrate:** AgentWire's unit is a tmux session addressable from CLI, portal, MCP and remote machines ([concepts](../concepts.md)). The desktop apps (Conductor, Sculptor) and the TUI (Claude Squad) are the UI.
48
+ - **Topology:** parent/child sessions with report-back, fan-out cohorts and a fleet view ([fan-out cohorts](../sessions/fan-out-cohorts.md), [fleet](../sessions/fleet.md)). Claude Squad, Conductor and Sculptor present flat lists of workspaces in their READMEs and homepages; Multica's Squads are leader-routed agent groups.
49
+ - **Safety:** every agent tool call passes through [damage control](../internals/damage-control.md). No other tool surveyed documents an equivalent on the pages read.
50
+ - **What AgentWire is weaker at:** no first-party diff-review UI (below), no native desktop app, and a tmux dependency.
51
+
52
+ ## Worth borrowing (suggested issues, not work done)
53
+
54
+ 1. **Worktree diff-review panel in the portal.** Conductor (diff viewer + checks) and Sculptor (Changes tab with per-file diffs and a Commits tab) both put review next to the agent; Claude Squad reviews in-app too. AgentWire has the `agentwire diff -s <session> [--base] [--json]` CLI command but no portal panel. A per-session panel that calls it, with the Changes/Commits split Sculptor uses, would close the gap.
55
+ 2. **Checks surfaced beside the diff** (Conductor's docs list a "Checks" step after the diff viewer; contents _unverified_). Worth filing only if the panel above lands and CI status is not already visible there.
56
+
57
+ Not on the list: carrying gitignored files into worktrees. Claude Code's [`.worktreeinclude`](https://code.claude.com/docs/en/worktrees.md#copy-gitignored-files-into-worktrees) does this and AgentWire already has `projects.worktrees.copy_files` ([architecture](../architecture.md)).
@@ -291,6 +291,19 @@ carrying the new `session_id`) reports each change:
291
291
  because the tail is what restart reads as "current"). Already-last is a no-op,
292
292
  so it is idempotent and the launch's own id costs nothing. A session with no
293
293
  launch record is left alone: the hook never conjures a partial record.
294
+ - **Only the session's own conversations count (#1289).** A headless
295
+ `claude -p` run from a pane (a worker's comparison or spike in a scratch dir)
296
+ inherits `$TMUX_PANE` and fires the same hook. Verified payload shape:
297
+ `{session_id, transcript_path, cwd, hook_event_name, source}` — `cwd` is the
298
+ physical path, and a headless run reports `source: "startup"`, identical to a
299
+ real start, so **`source` is no signal**; `cwd` is. The hook records an id
300
+ only when `core.session_owns_cwd` says the payload `cwd` (through
301
+ `history.encode_project_path` of the realpath) equals the recorded
302
+ `cwd_at_launch` or `worktree_path`. A mismatch, or a payload with no `cwd`,
303
+ is ignored and the reason goes to the debug log. Chains polluted before this
304
+ fix keep their stray ids (`restart` skips ids with no transcript under the
305
+ launch cwd, so they are inert there); `doctor`'s orphaned-history output
306
+ names nested runs as the likely cause.
294
307
  - Errors are logged to `/tmp/claude-hook-debug.log`, never raised.
295
308
 
296
309
  `restart`'s newest-first walk is unchanged: a `/clear`ed conversation that
@@ -353,7 +366,24 @@ else `cwd_at_launch` — which is what catches the case where the record and the
353
366
  transcript still agree with each other and are both stale because the directory
354
367
  moved underneath them.
355
368
 
356
- It scores orphans only. A conversation with no history *anywhere* is stated for
369
+ It scores orphans of **live** sessions only (#1292). A session that is not
370
+ running keeps its record under `~/.agentwire/sessions/` after
371
+ `worktree --remove`, so its orphaned chain would otherwise stay red forever;
372
+ doctor lists those as information with the recover command and does not count
373
+ them. Teardown (`worktree --remove`, `--prune --gc-merged`) never deletes the
374
+ record — it is the only map from session name to conversation — but says in its
375
+ output that it left one, and how many of its chain's conversations are
376
+ orphaned. To clean up deliberately:
377
+
378
+ ```bash
379
+ agentwire history prune --dead # list dead-session records (deletes nothing)
380
+ agentwire history prune --dead --older-than 14d # only records untouched that long
381
+ agentwire history prune --dead --yes # delete exactly what was listed
382
+ ```
383
+
384
+ `doctor`, teardown and `prune` share one chain probe, `history.survey_chain`.
385
+
386
+ Orphans aside, a conversation with no history *anywhere* is stated for
357
387
  live sessions and never counted, because this check cannot say why it's missing
358
388
  — never-prompted and Claude-evicted look identical from here — and because
359
389
  scoring it would flag hundreds of dead records. Calibration, measured on a real
@@ -29,7 +29,7 @@ dependencies = [
29
29
  # PyPI. Engine changes land there, release there, then raise this floor.
30
30
  # tests/unit/test_damage_control_pin.py checks the range and the installed engine.
31
31
  # Hooks run `python -I -m damage_control.hook`.
32
- "damage-control-dev>=0.3.0,<0.4",
32
+ "damage-control-dev>=0.4.0,<0.5",
33
33
  "aiohttp>=3.13.4", # >=3.13.4 clears CVE-2026-34515 + CVE-2026-34513 (portal-facing)
34
34
  "aiohttp-jinja2>=1.6",
35
35
  "jinja2>=3.1.0",