agentwire-dev 1.78.0__tar.gz → 1.79.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 (640) hide show
  1. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/PKG-INFO +1 -1
  2. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/__init__.py +1 -1
  3. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/core.py +34 -0
  4. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/doctor_cli.py +68 -6
  5. agentwire_dev-1.79.0/agentwire/hooks/session-start-handler.sh +23 -0
  6. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/hooks_cli.py +62 -0
  7. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety_cli.py +5 -0
  8. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety_commands.py +6 -4
  9. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety_migrate.py +63 -8
  10. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/sessions/conversation-identity.md +37 -0
  11. agentwire_dev-1.79.0/tests/unit/test_conversation_change.py +176 -0
  12. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_hooks_install.py +2 -0
  13. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_safety_deployment.py +3 -2
  14. agentwire_dev-1.79.0/tests/unit/test_safety_migrate.py +169 -0
  15. agentwire_dev-1.78.0/tests/unit/test_safety_migrate.py +0 -79
  16. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/.agentwire.yml.example +0 -0
  17. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/.claude/commands/handoff.md +0 -0
  18. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/.claude/skills/wiki/SKILL.md +0 -0
  19. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/.github/FUNDING.yml +0 -0
  20. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  21. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  22. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
  23. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  24. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/.github/workflows/pytest.yml +0 -0
  25. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/.github/workflows/ruff.yml +0 -0
  26. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/.github/workflows/security.yml +0 -0
  27. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/.github/workflows/tts-smoke.yml +0 -0
  28. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/.gitignore +0 -0
  29. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/AGENTS.md +0 -0
  30. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/CODE_OF_CONDUCT.md +0 -0
  31. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/CONTRIBUTING.md +0 -0
  32. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/Dockerfile.local +0 -0
  33. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/LICENSE +0 -0
  34. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/README.md +0 -0
  35. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/RELEASING.md +0 -0
  36. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/SECURITY.md +0 -0
  37. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/SPONSORS.md +0 -0
  38. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/__main__.py +0 -0
  39. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/agents/__init__.py +0 -0
  40. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/agents/base.py +0 -0
  41. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/agents/tmux.py +0 -0
  42. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/auth_expired.py +0 -0
  43. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/background_tasks.py +0 -0
  44. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/beta.py +0 -0
  45. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/cached_status.py +0 -0
  46. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/channels/__init__.py +0 -0
  47. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/channels/base.py +0 -0
  48. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/channels/email.py +0 -0
  49. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/channels/push.py +0 -0
  50. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/channels/quo.py +0 -0
  51. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/channels_cli.py +0 -0
  52. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/chrome_tabs.py +0 -0
  53. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/claude_settings.py +0 -0
  54. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/cohort.py +0 -0
  55. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/completion.py +0 -0
  56. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/config.py +0 -0
  57. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/config_cli.py +0 -0
  58. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/council/__init__.py +0 -0
  59. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/council/cli.py +0 -0
  60. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/council/inbox.py +0 -0
  61. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/council/minutes.py +0 -0
  62. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/council/state.py +0 -0
  63. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/council/view.py +0 -0
  64. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/devices.py +0 -0
  65. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/diff_cli.py +0 -0
  66. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/doctor_voice.py +0 -0
  67. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/ensure_cli.py +0 -0
  68. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/env_loader.py +0 -0
  69. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/fetch.py +0 -0
  70. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/handoff/__init__.py +0 -0
  71. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/handoff/git_state.py +0 -0
  72. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/handoff/instructions.py +0 -0
  73. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/handoff/parser.py +0 -0
  74. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/handoff/renderer.py +0 -0
  75. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/handoff/schema.py +0 -0
  76. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/handoff_cli.py +0 -0
  77. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/history.py +0 -0
  78. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/history_cli.py +0 -0
  79. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/history_migrate.py +0 -0
  80. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/hooks/__init__.py +0 -0
  81. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/hooks/agentwire-permission.sh +0 -0
  82. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/hooks/idle-handler.sh +0 -0
  83. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/hooks/outcome_logger.py +0 -0
  84. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/hooks/queue-processor.sh +0 -0
  85. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/inbox.py +0 -0
  86. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/limits_cli.py +0 -0
  87. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/listen.py +0 -0
  88. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/locking.py +0 -0
  89. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/machine_cli.py +0 -0
  90. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_channels.py +0 -0
  91. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_chrome.py +0 -0
  92. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_cli.py +0 -0
  93. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_core.py +0 -0
  94. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_council.py +0 -0
  95. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_desktop.py +0 -0
  96. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_handoff.py +0 -0
  97. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_history.py +0 -0
  98. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_listen.py +0 -0
  99. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_lock.py +0 -0
  100. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_machine.py +0 -0
  101. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_msg.py +0 -0
  102. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_notify.py +0 -0
  103. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_pane.py +0 -0
  104. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_projects.py +0 -0
  105. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_scheduler.py +0 -0
  106. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_scratchpad.py +0 -0
  107. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_server.py +0 -0
  108. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_services.py +0 -0
  109. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_session.py +0 -0
  110. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_status.py +0 -0
  111. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_task.py +0 -0
  112. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_tunnels.py +0 -0
  113. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_voice.py +0 -0
  114. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_wiki.py +0 -0
  115. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/mcp_worktree.py +0 -0
  116. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/msg_cli.py +0 -0
  117. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/network.py +0 -0
  118. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/notify_cli.py +0 -0
  119. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/onboarding.py +0 -0
  120. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/palette_cli.py +0 -0
  121. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/pane_cli.py +0 -0
  122. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/pane_manager.py +0 -0
  123. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/playback_lane.py +0 -0
  124. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/portal_cli.py +0 -0
  125. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/project_config.py +0 -0
  126. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/projects.py +0 -0
  127. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/prompt_router.py +0 -0
  128. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/prompts_cli.py +0 -0
  129. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/push_cli.py +0 -0
  130. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/push_store.py +0 -0
  131. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/repo_cli.py +0 -0
  132. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/research.py +0 -0
  133. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/restart_cli.py +0 -0
  134. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/role_prompts.py +0 -0
  135. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/__init__.py +0 -0
  136. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/agentwire.md +0 -0
  137. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/anchor.md +0 -0
  138. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/chatbot.md +0 -0
  139. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/contributor.md +0 -0
  140. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/correspondent.md +0 -0
  141. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/council-brain.md +0 -0
  142. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/council-conscience.md +0 -0
  143. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/council-critic.md +0 -0
  144. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/council-devils-advocate.md +0 -0
  145. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/council-gut.md +0 -0
  146. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/council-historian.md +0 -0
  147. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/council-member.md +0 -0
  148. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/council-orchestrator.md +0 -0
  149. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/init.md +0 -0
  150. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/notifications.md +0 -0
  151. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/orchestrator.md +0 -0
  152. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/reviewer-worktree.md +0 -0
  153. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/reviewer.md +0 -0
  154. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/shared-checkout.md +0 -0
  155. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/soul.md +0 -0
  156. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/task-runner.md +0 -0
  157. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/voice.md +0 -0
  158. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/worker-worktree.md +0 -0
  159. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles/worker.md +0 -0
  160. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/roles_cli.py +0 -0
  161. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/routes/__init__.py +0 -0
  162. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/routes/artifacts.py +0 -0
  163. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/routes/config.py +0 -0
  164. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/routes/council.py +0 -0
  165. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/routes/desktop.py +0 -0
  166. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/routes/history.py +0 -0
  167. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/routes/machines.py +0 -0
  168. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/routes/notify.py +0 -0
  169. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/routes/palette.py +0 -0
  170. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/routes/permission.py +0 -0
  171. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/routes/projects.py +0 -0
  172. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/routes/push.py +0 -0
  173. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/routes/safety.py +0 -0
  174. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/routes/scheduler.py +0 -0
  175. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/routes/scratchpad.py +0 -0
  176. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/routes/sessions.py +0 -0
  177. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/routes/sessions_admin.py +0 -0
  178. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/routes/voice.py +0 -0
  179. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety/__init__.py +0 -0
  180. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety/audit.py +0 -0
  181. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety/lint.py +0 -0
  182. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety/provenance.py +0 -0
  183. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety/residuals.py +0 -0
  184. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety/rule_baselines.json +0 -0
  185. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety/rules/agentwire-control-plane.json +0 -0
  186. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety/rules/agentwire-control-plane.yaml +0 -0
  187. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety/rules/agentwire-core.json +0 -0
  188. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety/rules/agentwire-core.yaml +0 -0
  189. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety/rules/agentwire-mcp-tools.json +0 -0
  190. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety/rules/agentwire-mcp-tools.yaml +0 -0
  191. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety/rules/agentwire-outbound.json +0 -0
  192. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety/rules/agentwire-outbound.yaml +0 -0
  193. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety/rules/agentwire.json +0 -0
  194. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety/rules/agentwire.yaml +0 -0
  195. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety/suggest.py +0 -0
  196. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety_ext.py +0 -0
  197. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety_notify.py +0 -0
  198. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/safety_packs_cli.py +0 -0
  199. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/scheduler/__init__.py +0 -0
  200. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/scheduler/dispatch.py +0 -0
  201. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/scheduler/gates.py +0 -0
  202. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/scheduler/loop.py +0 -0
  203. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/scheduler/models.py +0 -0
  204. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/scheduler/report.py +0 -0
  205. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/scheduler/schedule.py +0 -0
  206. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/scheduler/state.py +0 -0
  207. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/scheduler/zombie.py +0 -0
  208. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/scheduler_cli.py +0 -0
  209. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/scratchpad.py +0 -0
  210. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/security.py +0 -0
  211. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/send_cli.py +0 -0
  212. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/sent_ledger.py +0 -0
  213. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/server.py +0 -0
  214. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/services.py +0 -0
  215. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/session_cli.py +0 -0
  216. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/session_context.py +0 -0
  217. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/session_ready.py +0 -0
  218. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/session_state.py +0 -0
  219. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/ssh.py +0 -0
  220. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/agentwire-splash-logo-layers--agentwire-text.png +0 -0
  221. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/agentwire-splash-logo-layers--echo-claw-fg.png +0 -0
  222. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/agentwire-splash-logo-layers--echo.png +0 -0
  223. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/agentwire-splash-logo-layers--telephone.png +0 -0
  224. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/agentwire-splash-logo-layers--tree.png +0 -0
  225. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/announcements.json +0 -0
  226. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/apple-touch-icon.png +0 -0
  227. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/css/desktop.css +0 -0
  228. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/css/mobile.css +0 -0
  229. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/favicon-32.png +0 -0
  230. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/favicon-64.png +0 -0
  231. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/icons/sessions/bear.webp +0 -0
  232. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/icons/sessions/cat.webp +0 -0
  233. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/icons/sessions/crown.webp +0 -0
  234. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/icons/sessions/custom/agentwire-portal.webp +0 -0
  235. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/icons/sessions/custom/agentwire-tts.webp +0 -0
  236. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/icons/sessions/custom/agentwire.webp +0 -0
  237. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/icons/sessions/deer.webp +0 -0
  238. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/icons/sessions/drone.webp +0 -0
  239. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/icons/sessions/eagle.webp +0 -0
  240. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/icons/sessions/fox.webp +0 -0
  241. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/icons/sessions/hawk.webp +0 -0
  242. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/icons/sessions/horse.webp +0 -0
  243. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/icons/sessions/lion.webp +0 -0
  244. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/icons/sessions/rabbit.webp +0 -0
  245. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/icons/sessions/robot.webp +0 -0
  246. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/icons/sessions/tiger.webp +0 -0
  247. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/icons/sessions/wolf.webp +0 -0
  248. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/img/icon-192.png +0 -0
  249. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/img/icon-512.png +0 -0
  250. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/.gitkeep +0 -0
  251. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/announcement-modal.js +0 -0
  252. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/api.js +0 -0
  253. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/artifact-window.js +0 -0
  254. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/card-terminal.js +0 -0
  255. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/collage.js +0 -0
  256. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/command-palette.js +0 -0
  257. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/council-window.js +0 -0
  258. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/dead-key-residue.js +0 -0
  259. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/desktop-manager.js +0 -0
  260. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/desktop.js +0 -0
  261. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/help-modal.js +0 -0
  262. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/hotkeys.js +0 -0
  263. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/icon-manager.js +0 -0
  264. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/lineage.js +0 -0
  265. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/mobile.js +0 -0
  266. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/notification-prefs.js +0 -0
  267. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/notifications-panel.js +0 -0
  268. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/ptt.js +0 -0
  269. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/push-client.js +0 -0
  270. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/review-window.js +0 -0
  271. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/safety-shared.js +0 -0
  272. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/safety-window.js +0 -0
  273. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/scratchpad.js +0 -0
  274. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/service-classification.js +0 -0
  275. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/session-hud-controller.js +0 -0
  276. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/session-hud-notices.js +0 -0
  277. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/session-hud-spawn.js +0 -0
  278. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/session-hud.js +0 -0
  279. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/session-id.js +0 -0
  280. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/session-window.js +0 -0
  281. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/shortcuts.js +0 -0
  282. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/sidebar/artifacts-section.js +0 -0
  283. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/sidebar/config-section.js +0 -0
  284. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/sidebar/council-section.js +0 -0
  285. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/sidebar/machines-section.js +0 -0
  286. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/sidebar/projects-section.js +0 -0
  287. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/sidebar/safety-section.js +0 -0
  288. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/sidebar/scheduler-section.js +0 -0
  289. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/sidebar/services-section.js +0 -0
  290. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/sidebar/sessions-section.js +0 -0
  291. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/sidebar.js +0 -0
  292. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/spawn-ghost.js +0 -0
  293. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/taskbar-persist.js +0 -0
  294. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/terminal-font-prefs.js +0 -0
  295. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/terminal-pane.js +0 -0
  296. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/tile-manager.js +0 -0
  297. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/toast.js +0 -0
  298. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/token-modal.js +0 -0
  299. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/topology-render.js +0 -0
  300. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/utils/ansi.js +0 -0
  301. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/utils/rich-text.js +0 -0
  302. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/utils/swipe.js +0 -0
  303. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/voice/audio-unlock.js +0 -0
  304. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/voice/autosend-prefs.js +0 -0
  305. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/voice/browser-stt.js +0 -0
  306. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/voice/browser-tts.js +0 -0
  307. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/voice/jargon.js +0 -0
  308. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/voice/prompt.js +0 -0
  309. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/winbox.bundle.min.js +0 -0
  310. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/js/workspace-window.js +0 -0
  311. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/manifest.webmanifest +0 -0
  312. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/service-worker.js +0 -0
  313. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/static/topology-harness.html +0 -0
  314. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/stt/__init__.py +0 -0
  315. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/stt/base.py +0 -0
  316. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/stt/cloud.py +0 -0
  317. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/stt/engine.py +0 -0
  318. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/stt/local.py +0 -0
  319. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/stt/server_backend.py +0 -0
  320. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/stt/stt_server.py +0 -0
  321. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/system_cli.py +0 -0
  322. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/tabs_cli.py +0 -0
  323. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/tasks.py +0 -0
  324. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/tasks_cli.py +0 -0
  325. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/templates/__init__.py +0 -0
  326. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/templates/base.html +0 -0
  327. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/templates/council/minutes.html.j2 +0 -0
  328. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/templates/desktop.html +0 -0
  329. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/templates/email_notification.html +0 -0
  330. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/templates/handoff/show-the-story.html.j2 +0 -0
  331. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/templates/handoff/theme.css.j2 +0 -0
  332. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/templates/mobile.html +0 -0
  333. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/templates/pair.html +0 -0
  334. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/templates/statusline.sh +0 -0
  335. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/templates/tmux.conf +0 -0
  336. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/templating.py +0 -0
  337. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/tts/__init__.py +0 -0
  338. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/tts/audio.py +0 -0
  339. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/tts/base.py +0 -0
  340. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/tts/engines/__init__.py +0 -0
  341. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/tts/engines/chatterbox.py +0 -0
  342. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/tts/engines/kokoro.py +0 -0
  343. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/tts/engines/zonos.py +0 -0
  344. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/tts/kokoro_server.py +0 -0
  345. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/tts/local.py +0 -0
  346. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/tts/registry.py +0 -0
  347. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/tts_cli.py +0 -0
  348. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/tts_server.py +0 -0
  349. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/tunnels.py +0 -0
  350. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/tunnels_cli.py +0 -0
  351. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/usage_limit.py +0 -0
  352. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/utils/__init__.py +0 -0
  353. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/utils/chunker.py +0 -0
  354. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/utils/event_log.py +0 -0
  355. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/utils/file_io.py +0 -0
  356. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/utils/paths.py +0 -0
  357. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/utils/speech.py +0 -0
  358. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/utils/subprocess.py +0 -0
  359. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/validation.py +0 -0
  360. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/voice_status.py +0 -0
  361. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/wait_cli.py +0 -0
  362. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/wiki.py +0 -0
  363. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/wiki_audit.py +0 -0
  364. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/wiki_cli.py +0 -0
  365. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/worktree.py +0 -0
  366. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/worktree_cli.py +0 -0
  367. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/agentwire/worktree_registry.py +0 -0
  368. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/corpus/cases/bypass.yaml +0 -0
  369. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/corpus/cases/control_plane.yaml +0 -0
  370. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/corpus/cases/path_spelling.yaml +0 -0
  371. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/corpus/cases/relative_paths.yaml +0 -0
  372. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/corpus/golden/effective_rules.json +0 -0
  373. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/corpus/golden/harvested.json +0 -0
  374. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/corpus/golden/rule_ids.json +0 -0
  375. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/corpus/golden/snapshot.json +0 -0
  376. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/corpus/schema.json +0 -0
  377. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/decisions/obsidian-second-brain.md +0 -0
  378. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/design/session-card-fields.md +0 -0
  379. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/design/session-card-recommendation.md +0 -0
  380. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/logo.png +0 -0
  381. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/INDEX.md +0 -0
  382. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/architecture.md +0 -0
  383. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/auth-expired.md +0 -0
  384. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/briefing-mode.md +0 -0
  385. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/communication/channels.md +0 -0
  386. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/communication/hammerspoon.md +0 -0
  387. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/communication/handoff.md +0 -0
  388. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/concepts.md +0 -0
  389. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/council.md +0 -0
  390. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/deployment/remote-access.md +0 -0
  391. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/deployment/remote-machines.md +0 -0
  392. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/glossary.md +0 -0
  393. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/integrations/gws-google-workspace-cli.md +0 -0
  394. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/internals/damage-control.md +0 -0
  395. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/internals/parallel-refactor.md +0 -0
  396. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/internals/portal.md +0 -0
  397. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/internals/session-topology.md +0 -0
  398. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/internals/shell-escaping.md +0 -0
  399. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/internals/troubleshooting.md +0 -0
  400. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/internals/window-collage.md +0 -0
  401. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/quickstart.md +0 -0
  402. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/research/briefing-mode-feasibility.md +0 -0
  403. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/research/orchestration-transport-alternatives.md +0 -0
  404. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/scheduling/scheduled-workloads.md +0 -0
  405. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/security/damage-control-hardening.md +0 -0
  406. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/security/pip-audit.md +0 -0
  407. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/security/remote-access-hardening.md +0 -0
  408. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/security/secrets.md +0 -0
  409. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/services.md +0 -0
  410. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/sessions/claude-code-auto-mode.md +0 -0
  411. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/sessions/fan-out-cohorts.md +0 -0
  412. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/sessions/heal-line-count-cliff.md +0 -0
  413. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/sessions/helper-sessions.md +0 -0
  414. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/sessions/messaging.md +0 -0
  415. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/sessions/prompt-routing.md +0 -0
  416. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/sessions/window-sizing.md +0 -0
  417. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/sessions/worktree-sessions.md +0 -0
  418. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/usage-limit-recovery.md +0 -0
  419. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/voice/shim-contract.md +0 -0
  420. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/voice/stt-cloud.md +0 -0
  421. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/voice/stt-self-hosted.md +0 -0
  422. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/docs/wiki/voice/tts-self-hosted.md +0 -0
  423. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/pyproject.toml +0 -0
  424. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/conftest.py +0 -0
  425. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/corpus_runner.py +0 -0
  426. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/e2e/test_portal_ui.py +0 -0
  427. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/audio_unlock_harness.mjs +0 -0
  428. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/background_tasks/pane_30_shell.txt +0 -0
  429. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/background_tasks/pane_80_agent.txt +0 -0
  430. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/background_tasks/pane_80_done.txt +0 -0
  431. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/background_tasks/pane_80_interrupted.txt +0 -0
  432. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/background_tasks/pane_80_monitor.txt +0 -0
  433. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/background_tasks/pane_80_quoted_footer.txt +0 -0
  434. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/background_tasks/pane_80_second_notice.txt +0 -0
  435. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/background_tasks/pane_80_shell.txt +0 -0
  436. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/background_tasks/pane_80_shell_and_monitor.txt +0 -0
  437. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/background_tasks/transcript_bash_done.jsonl +0 -0
  438. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/background_tasks/transcript_bash_pending.jsonl +0 -0
  439. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/background_tasks/transcript_monitor_done.jsonl +0 -0
  440. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/background_tasks/transcript_monitor_events.jsonl +0 -0
  441. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/dc_msg_body_quoting_carriers.txt +0 -0
  442. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/hotkeys_harness.mjs +0 -0
  443. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/sample_agentwire.yml +0 -0
  444. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/sample_config.yaml +0 -0
  445. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/sample_scheduler.yaml +0 -0
  446. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/session_hud_detent_harness.mjs +0 -0
  447. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/taskbar_persist_harness.mjs +0 -0
  448. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/fixtures/topology_expand_harness.mjs +0 -0
  449. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/home_guard.py +0 -0
  450. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/integration/test_council_portal.py +0 -0
  451. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/integration/test_scheduler_board.py +0 -0
  452. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/integration/test_send_verified_tmux.py +0 -0
  453. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/integration/test_server_websockets.py +0 -0
  454. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/integration/test_tmux_name_rewrite.py +0 -0
  455. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/integration/test_worktree_cmd.py +0 -0
  456. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_agentwire_rules_layer.py +0 -0
  457. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_announcements.py +0 -0
  458. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_audio_unlock_js.py +0 -0
  459. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_audit_attribution.py +0 -0
  460. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_audit_outcomes.py +0 -0
  461. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_auth_expired.py +0 -0
  462. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_auth_expired_dispatch.py +0 -0
  463. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_background_tasks.py +0 -0
  464. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_background_tasks_review.py +0 -0
  465. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_beta_flag.py +0 -0
  466. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_block_rows_carry_an_id.py +0 -0
  467. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_brace_expansion_zero_access.py +0 -0
  468. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_breakglass.py +0 -0
  469. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_buddy_removal_keeps.py +0 -0
  470. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_build_agent_command.py +0 -0
  471. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_channels.py +0 -0
  472. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_chrome_tabs.py +0 -0
  473. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_claude_settings.py +0 -0
  474. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_cli_commands.py +0 -0
  475. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_cli_output.py +0 -0
  476. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_cli_smoke.py +0 -0
  477. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_cli_stderr_clean.py +0 -0
  478. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_cohort.py +0 -0
  479. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_config.py +0 -0
  480. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_config_cli.py +0 -0
  481. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_control_plane_protection.py +0 -0
  482. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_corpus.py +0 -0
  483. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_council_cli.py +0 -0
  484. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_council_inbox.py +0 -0
  485. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_council_minutes.py +0 -0
  486. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_council_state.py +0 -0
  487. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_council_view.py +0 -0
  488. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_damage_control_bypass.py +0 -0
  489. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_damage_control_delete_recursive.py +0 -0
  490. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_damage_control_hooks.py +0 -0
  491. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_damage_control_pin.py +0 -0
  492. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_dangling_worktrees.py +0 -0
  493. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_dc_install.py +0 -0
  494. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_dc_policy_packs.py +0 -0
  495. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_dc_profile_isolation.py +0 -0
  496. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_devices.py +0 -0
  497. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_diff_cli.py +0 -0
  498. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_doctor_orphaned_history.py +0 -0
  499. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_doctor_scheduler_staleness.py +0 -0
  500. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_doctor_secrets_perms.py +0 -0
  501. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_doctor_task_migration.py +0 -0
  502. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_doctor_voice.py +0 -0
  503. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_ensure_shared_dir.py +0 -0
  504. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_ensure_verified_prompt.py +0 -0
  505. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_env_loader.py +0 -0
  506. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_event_log.py +0 -0
  507. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_extension_points.py +0 -0
  508. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_golden_snapshot.py +0 -0
  509. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_guarded_launch_command.py +0 -0
  510. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_handoff_git_state.py +0 -0
  511. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_handoff_instructions.py +0 -0
  512. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_handoff_parser.py +0 -0
  513. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_handoff_renderer.py +0 -0
  514. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_helper_session.py +0 -0
  515. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_heredoc_marker_liveness.py +0 -0
  516. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_history.py +0 -0
  517. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_history_migrate.py +0 -0
  518. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_history_migrate_cli.py +0 -0
  519. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_history_resume_name.py +0 -0
  520. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_hook_fail_closed.py +0 -0
  521. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_hook_fail_closed_matrix.py +0 -0
  522. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_hook_link_guard.py +0 -0
  523. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_hook_python_floor.py +0 -0
  524. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_hook_subprocess.py +0 -0
  525. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_hotkeys_js.py +0 -0
  526. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_idle_handler.py +0 -0
  527. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_idle_nag.py +0 -0
  528. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_inbox.py +0 -0
  529. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_init_command.py +0 -0
  530. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_install_parity.py +0 -0
  531. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_launch_line_reentry.py +0 -0
  532. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_launch_via_env.py +0 -0
  533. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_limits_tick_isolation.py +0 -0
  534. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_live_target_1261.py +0 -0
  535. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_locking.py +0 -0
  536. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_mcp_nonblocking.py +0 -0
  537. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_mcp_server.py +0 -0
  538. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_mcp_tool_policy.py +0 -0
  539. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_mcp_tools_args.py +0 -0
  540. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_msg_cli.py +0 -0
  541. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_notify_cli.py +0 -0
  542. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_onboarding_reinit.py +0 -0
  543. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_owner_only_writes.py +0 -0
  544. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_palette_cli.py +0 -0
  545. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_path_case_folding.py +0 -0
  546. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_path_spelling.py +0 -0
  547. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_payload_position.py +0 -0
  548. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_pending_message_visibility.py +0 -0
  549. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_playback_lane.py +0 -0
  550. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_policy_ladder.py +0 -0
  551. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_portal_api.py +0 -0
  552. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_portal_pair_url.py +0 -0
  553. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_posture_default.py +0 -0
  554. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_powershell_matcher.py +0 -0
  555. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_project_config.py +0 -0
  556. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_projects_registry.py +0 -0
  557. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_prompt_router.py +0 -0
  558. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_prompt_router_dedup.py +0 -0
  559. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_prompt_router_resume.py +0 -0
  560. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_prose_operands.py +0 -0
  561. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_push.py +0 -0
  562. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_rebuild_guard.py +0 -0
  563. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_rebuild_uv_lock.py +0 -0
  564. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_relative_path_operands.py +0 -0
  565. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_remote_session_record.py +0 -0
  566. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_repo_cli.py +0 -0
  567. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_report_back_path_1259.py +0 -0
  568. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_restart_cli.py +0 -0
  569. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_rich_text_js.py +0 -0
  570. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_rm_recoverable.py +0 -0
  571. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_role_prompt_retention.py +0 -0
  572. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_role_prompt_sweep_wiring.py +0 -0
  573. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_roles.py +0 -0
  574. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_routes_snapshot.py +0 -0
  575. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_rule_files_load.py +0 -0
  576. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_rule_ids_pinned.py +0 -0
  577. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_rules_json_in_sync.py +0 -0
  578. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_safe_cwd.py +0 -0
  579. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_safety_ext.py +0 -0
  580. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_safety_groups.py +0 -0
  581. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_safety_install.py +0 -0
  582. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_safety_notify.py +0 -0
  583. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_safety_packs.py +0 -0
  584. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_say_lane.py +0 -0
  585. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_scan_budget.py +0 -0
  586. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_scheduler.py +0 -0
  587. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_scheduler_liveness.py +0 -0
  588. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_scheduler_zombie.py +0 -0
  589. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_scratchpad.py +0 -0
  590. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_security.py +0 -0
  591. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_sed_script_is_data.py +0 -0
  592. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_sent_ledger.py +0 -0
  593. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_server_async.py +0 -0
  594. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_services.py +0 -0
  595. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_services_command.py +0 -0
  596. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_session_context.py +0 -0
  597. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_session_created_by_env.py +0 -0
  598. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_session_hud_detent_js.py +0 -0
  599. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_session_metadata_ssot.py +0 -0
  600. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_session_metadata_write.py +0 -0
  601. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_session_ready.py +0 -0
  602. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_session_state.py +0 -0
  603. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_shared_dir_guard.py +0 -0
  604. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_shim_selfheal.py +0 -0
  605. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_skill_install.py +0 -0
  606. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_speech_tags.py +0 -0
  607. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_ssh.py +0 -0
  608. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_stt_backend.py +0 -0
  609. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_stt_cloud.py +0 -0
  610. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_stt_engine.py +0 -0
  611. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_task_cli.py +0 -0
  612. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_task_max_duration.py +0 -0
  613. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_taskbar_persist_js.py +0 -0
  614. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_tasks.py +0 -0
  615. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_tasks_cli.py +0 -0
  616. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_templating.py +0 -0
  617. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_terminal_resize.py +0 -0
  618. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_tmux_session_cwd.py +0 -0
  619. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_topology_expand_js.py +0 -0
  620. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_tts_engine_resolution.py +0 -0
  621. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_tts_local.py +0 -0
  622. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_tunnels_probe.py +0 -0
  623. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_unattended_allow.py +0 -0
  624. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_unattended_env_isolation.py +0 -0
  625. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_unattended_scoped_allow.py +0 -0
  626. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_usage_limit.py +0 -0
  627. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_voice_assistant_removed.py +0 -0
  628. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_voice_off_and_shim_bind.py +0 -0
  629. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_voice_status.py +0 -0
  630. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_watchdog_stages.py +0 -0
  631. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_wiki.py +0 -0
  632. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_wiki_audit.py +0 -0
  633. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_worktree.py +0 -0
  634. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_worktree_branch_cleanup.py +0 -0
  635. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_worktree_dot_project.py +0 -0
  636. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_worktree_git_truth.py +0 -0
  637. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_worktree_layout.py +0 -0
  638. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_worktree_registry.py +0 -0
  639. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tests/unit/test_zero_access_member_access.py +0 -0
  640. {agentwire_dev-1.78.0 → agentwire_dev-1.79.0}/tools/nonce_stt_probe.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: agentwire-dev
3
- Version: 1.78.0
3
+ Version: 1.79.0
4
4
  Summary: Multi-session voice web interface for AI coding agents
5
5
  Project-URL: Homepage, https://agentwire.dev
6
6
  Project-URL: Repository, https://github.com/dotdevdotdev/agentwire-dev
@@ -1,3 +1,3 @@
1
1
  """AgentWire - Multi-session voice web interface for AI coding agents."""
2
2
 
3
- __version__ = "1.78.0"
3
+ __version__ = "1.79.0"
@@ -1550,6 +1550,40 @@ def record_session_launch(
1550
1550
  return metadata
1551
1551
 
1552
1552
 
1553
+ def record_conversation_change(session_name: str, conversation_id: str) -> bool:
1554
+ """Make *conversation_id* the session's CURRENT conversation (#1271).
1555
+
1556
+ :func:`record_session_launch` writes the chain once, at launch. Claude
1557
+ mints a new id inside a running session on ``/clear`` and switches ids on
1558
+ ``/resume``, and nothing at launch can know — so the SessionStart hook
1559
+ reports each change here, and ``restart``'s newest-first chain walk works
1560
+ unchanged.
1561
+
1562
+ The id ends up LAST in the chain: a fresh id is appended, and an id already
1563
+ recorded (a ``/resume`` back to an earlier conversation) is moved to the
1564
+ tail, because the walk reads the tail as "what the session is in now".
1565
+ Already-last is a no-op that writes nothing, so the hook is idempotent and
1566
+ the launch's own record (which fires the same id) costs nothing.
1567
+
1568
+ Returns whether the record changed. A session with no launch record is left
1569
+ alone (False) — this must never conjure a partial record that
1570
+ ``recorded_sessions`` and ``doctor`` would then take for a launched
1571
+ session. Raises ``OSError`` if the write doesn't land (see
1572
+ :func:`store_session_metadata`); the hook decides what to do about that.
1573
+ """
1574
+ metadata = load_session_metadata(session_name)
1575
+ if not metadata.get("cwd_at_launch"):
1576
+ return False
1577
+
1578
+ chain = list(metadata.get("conversation_ids") or [])
1579
+ if chain and chain[-1] == conversation_id:
1580
+ return False
1581
+
1582
+ metadata["conversation_ids"] = [c for c in chain if c != conversation_id] + [conversation_id]
1583
+ store_session_metadata(session_name, metadata)
1584
+ return True
1585
+
1586
+
1553
1587
  def notify_portal_session_created(session_name: str, parent: str | None, role: str | None) -> None:
1554
1588
  """Tell the portal a session was just created, with topology context (#747).
1555
1589
 
@@ -497,6 +497,8 @@ def _render_damage_control_section(fix: bool = False) -> int:
497
497
  print(f" [{mark}] {finding['message']}")
498
498
  if finding["level"] == "bad":
499
499
  issues += 1
500
+ if finding["code"] == "stale-ruleset":
501
+ print(" Fix: agentwire safety install --refresh (prints the diff and acknowledges it)")
500
502
  if not package_status["ok"]:
501
503
  print(" Fix: agentwire hooks install (or: agentwire doctor --fix)")
502
504
  print(" Blocked outright? From a normal terminal (not through Claude Code):")
@@ -534,11 +536,9 @@ def _render_damage_control_section(fix: bool = False) -> int:
534
536
 
535
537
  # Rules and tooldefs ship inside the package; what lives on the machine is the host's
536
538
  # own overlay. A file there REPLACES the bundled one of the same name, so name each.
537
- for section, groups in safety_migrate.classify().items():
538
- named = groups["pristine"] + groups["edited"]
539
- if named:
540
- print(f" [..] Your {section} overlay replaces bundled files: {', '.join(named)}")
541
- print(" Fix: agentwire safety migrate (removes pristine copies, keeps your edits)")
539
+ overlay_plan = safety_migrate.classify()
540
+ for line in safety_migrate.overlay_report_lines(overlay_plan):
541
+ print(line)
542
542
 
543
543
  # Rule groups and packs (#1141): informational only, never scored — a
544
544
  # disabled pack is a choice, not drift.
@@ -580,7 +580,7 @@ def _render_damage_control_section(fix: bool = False) -> int:
580
580
  print(f" [!!] DUPLICATE rule ids in the loaded rule set: {', '.join(duplicates)}")
581
581
  print(" `disabled_rules` / `unattended_allow` naming one of these names")
582
582
  print(" BOTH rules. Usually a half-applied rule sync.")
583
- print(" Fix: agentwire safety install --yes")
583
+ print(f" Fix: {safety_migrate.duplicate_ids_fix(overlay_plan)}")
584
584
  issues += 1
585
585
  else:
586
586
  print(" [ok] Rule ids unique across the loaded rule set")
@@ -936,6 +936,56 @@ def scan_orphaned_history(sessions: list[str] | None = None) -> list[dict]:
936
936
  return findings
937
937
 
938
938
 
939
+ def scan_unrecorded_transcripts(sessions: list[str] | None = None) -> list[dict]:
940
+ """Live sessions whose project dir holds transcripts newer than the recorded head (#1271).
941
+
942
+ The SessionStart hook keeps ``conversation_ids`` current across ``/clear``
943
+ and ``/resume``; a session that took one BEFORE the hook was installed has
944
+ a chain that stops at its launch id, and ``restart`` would resume that
945
+ stale conversation. The evidence is on disk: transcripts in the session's
946
+ history dir, absent from the chain, written after the head's own.
947
+
948
+ STATED, never scored, because it cannot be certain: the history dir is
949
+ keyed by cwd, so a second session sharing the directory writes transcripts
950
+ that look identical. The finding lists the candidates and says so. Live
951
+ sessions only — the ones you might actually restart.
952
+ """
953
+ from .core import load_session_metadata, recorded_sessions
954
+ from .history import claude_projects_dir, history_key_candidates
955
+
956
+ findings: list[dict] = []
957
+ for name in sessions if sessions is not None else recorded_sessions():
958
+ metadata = load_session_metadata(name)
959
+ ids = list(metadata.get("conversation_ids") or [])
960
+ cwd = metadata.get("cwd_at_launch")
961
+ if not ids or not cwd or not tmux_session_exists(name):
962
+ continue
963
+
964
+ for key in history_key_candidates(cwd):
965
+ project = claude_projects_dir() / key
966
+ try:
967
+ head = project / f"{ids[-1]}.jsonl"
968
+ baseline = head.stat().st_mtime if head.exists() else None
969
+ if baseline is None:
970
+ continue # no head transcript to be newer than
971
+ newer = sorted(
972
+ (f for f in project.glob("*.jsonl")
973
+ if f.stem not in ids and f.stat().st_mtime > baseline),
974
+ key=lambda f: f.stat().st_mtime,
975
+ )
976
+ except OSError:
977
+ continue
978
+ if newer:
979
+ findings.append({
980
+ "session": name,
981
+ "head": ids[-1],
982
+ "newer": [f.stem for f in newer],
983
+ "project_dir": str(project),
984
+ })
985
+ break
986
+ return findings
987
+
988
+
939
989
  def _render_orphaned_history_section() -> int:
940
990
  """Doctor section: conversations a restart could not bring back (#871).
941
991
 
@@ -975,6 +1025,18 @@ def _render_orphaned_history_section() -> int:
975
1025
  print(" Not a fault. Restarting these keeps the role and starts a fresh "
976
1026
  "conversation.")
977
1027
 
1028
+ unrecorded = scan_unrecorded_transcripts()
1029
+ if unrecorded:
1030
+ print(f" [..] {len(unrecorded)} live session(s) with transcripts newer than the "
1031
+ "recorded conversation:")
1032
+ for f in unrecorded:
1033
+ print(f" - {f['session']}: recorded head {f['head'][:8]}, newer "
1034
+ f"{', '.join(c[:8] for c in f['newer'])}")
1035
+ print(" Likely a /clear or /resume taken before the session-start hook was "
1036
+ "installed (`agentwire hooks install`): `agentwire restart` would resume the "
1037
+ "recorded head, not the newer conversation. Not scored — another session in "
1038
+ "the same directory writes transcripts that look the same.")
1039
+
978
1040
  return len(orphaned)
979
1041
 
980
1042
 
@@ -0,0 +1,23 @@
1
+ #!/bin/bash
2
+ # Claude Code SessionStart hook (source: startup|resume|clear|compact).
3
+ #
4
+ # Claude mints a new conversation id on /clear and switches ids on /resume;
5
+ # nothing at launch can know. This reports the id to the owning agentwire
6
+ # session's record so `agentwire restart` resumes the CURRENT conversation
7
+ # (#1271). The logic lives in `agentwire hooks session-start` (CLI is SSOT);
8
+ # this wrapper only hands over the payload.
9
+ #
10
+ # Never blocks the session start and never fails it: the work runs detached
11
+ # and the script exits 0 unconditionally.
12
+
13
+ DEBUG_LOG="/tmp/claude-hook-debug.log"
14
+ AGENTWIRE="${AGENTWIRE_BIN:-$(which agentwire 2>/dev/null || echo "$HOME/.local/bin/agentwire")}"
15
+
16
+ input=$(cat)
17
+ [[ -n "$TMUX_PANE" ]] || exit 0
18
+
19
+ (
20
+ printf '%s' "$input" | "$AGENTWIRE" hooks session-start 2>&1 \
21
+ | sed "s|^|[$(date -Iseconds)] session-start: |" >> "$DEBUG_LOG"
22
+ ) </dev/null >/dev/null 2>&1 &
23
+ exit 0
@@ -382,6 +382,13 @@ def _managed_hook_files() -> list[ManagedHook]:
382
382
  ("PostToolUse", "PostToolUseFailure", "PermissionDenied"),
383
383
  "Outcome logger", True, "required for damage-control audit outcomes",
384
384
  ),
385
+ # Reports Claude's in-session conversation changes (/clear, /resume,
386
+ # compact) into the launch record so `restart` resumes the CURRENT one.
387
+ ManagedHook(
388
+ "session-start-handler.sh", claude_hooks_dir(), ("SessionStart",),
389
+ "Session-start hook", True,
390
+ "required for `agentwire restart` to resume after /clear or /resume",
391
+ ),
385
392
  ManagedHook(
386
393
  "queue-processor.sh", Path.home() / ".agentwire", (),
387
394
  "Queue processor", True, "required for notification queuing",
@@ -740,6 +747,54 @@ def cmd_hooks_status(args) -> int:
740
747
  return 0
741
748
 
742
749
 
750
+ def record_session_start(payload: dict) -> str:
751
+ """Apply one SessionStart payload to the owning session's record (#1271).
752
+
753
+ Returns a one-line outcome for the hook log. The owning session is resolved
754
+ from the PANE, and only pane 0 counts: a worker pane (index > 0) is not a
755
+ session and its conversation must never overwrite its owner's chain — the
756
+ same rule ``spawn`` and prompt routing apply. Raises on a failed write;
757
+ :func:`cmd_hooks_session_start` is the one place that turns that into exit 0.
758
+ """
759
+ from . import pane_manager
760
+ from .core import record_conversation_change
761
+
762
+ conversation_id = payload.get("session_id")
763
+ if not isinstance(conversation_id, str) or not conversation_id:
764
+ return "skipped: payload has no session_id"
765
+
766
+ session = pane_manager.get_current_session()
767
+ pane_index = pane_manager.get_current_pane_index()
768
+ if not session or pane_index is None:
769
+ return "skipped: not in a tmux pane"
770
+ if pane_index > 0:
771
+ return f"skipped: worker pane {session}.{pane_index}"
772
+
773
+ source = payload.get("source", "?")
774
+ if record_conversation_change(session, conversation_id):
775
+ return f"recorded {conversation_id} for {session} (source={source})"
776
+ return f"unchanged: {session} already at {conversation_id} or has no launch record"
777
+
778
+
779
+ def cmd_hooks_session_start(args) -> int:
780
+ """Claude Code SessionStart hook body: payload on stdin, ALWAYS exits 0.
781
+
782
+ A hook that can fail a session start is worse than a stale chain, so every
783
+ error — unreadable payload, tmux gone, store unwritable — is logged to
784
+ stderr (the hook script routes that to the debug log) and swallowed.
785
+ """
786
+ import sys
787
+
788
+ try:
789
+ payload = json.loads(sys.stdin.read() or "{}")
790
+ if not isinstance(payload, dict):
791
+ raise ValueError("payload is not a JSON object")
792
+ print(record_session_start(payload), file=sys.stderr)
793
+ except Exception as e:
794
+ print(f"session-start hook error: {type(e).__name__}: {e}", file=sys.stderr)
795
+ return 0
796
+
797
+
743
798
  def register_hooks_parser(subparsers) -> None:
744
799
  hooks_parser = subparsers.add_parser(
745
800
  "hooks", help="Manage agentwire hook files (permission, idle handler, queue processor)"
@@ -775,3 +830,10 @@ def register_hooks_parser(subparsers) -> None:
775
830
  "status", help="Check hook installation status"
776
831
  )
777
832
  hooks_status.set_defaults(func=cmd_hooks_status)
833
+
834
+ # hooks session-start (invoked by the SessionStart hook, not by humans)
835
+ hooks_session_start = hooks_subparsers.add_parser(
836
+ "session-start",
837
+ help="SessionStart hook body: record the new conversation id (reads the payload on stdin; always exits 0)",
838
+ )
839
+ hooks_session_start.set_defaults(func=cmd_hooks_session_start)
@@ -54,6 +54,7 @@ def cmd_safety_install(args) -> int:
54
54
  assume_yes=getattr(args, "yes", False),
55
55
  force=getattr(args, "force", False),
56
56
  allow_foreign=getattr(args, "allow_foreign_source", False),
57
+ refresh=getattr(args, "refresh", False),
57
58
  )
58
59
 
59
60
 
@@ -163,6 +164,10 @@ def register_safety_parser(subparsers) -> None:
163
164
  "--force", action="store_true",
164
165
  help="Override the downgrade refusal (this package is older than the recorded install)",
165
166
  )
167
+ safety_install.add_argument(
168
+ "--refresh", action="store_true",
169
+ help="Print and acknowledge the ruleset diff since the last install (loosening is marked !!)",
170
+ )
166
171
  safety_install.add_argument(
167
172
  "--allow-foreign-source", action="store_true",
168
173
  help="Let a checkout that is NOT the installed tool write these "
@@ -606,16 +606,18 @@ def safety_install_cmd(
606
606
  assume_yes: bool = False,
607
607
  force: bool = False,
608
608
  allow_foreign: bool = False,
609
+ refresh: bool = False,
609
610
  ) -> int:
610
611
  """CLI command: ``agentwire safety install``: the package's ``init`` under AgentWire's profile.
611
612
 
612
- Without ``--yes`` it asks once first. Returns non-zero on any refusal, so a script can never
613
- read a refusal as success (the whole of #936's operator picture).
613
+ Without ``--yes`` it asks once first (``--refresh`` only prints and acknowledges the ruleset
614
+ diff, so it does not ask). Returns non-zero on any refusal, so a script can never read a
615
+ refusal as success (the whole of #936's operator picture).
614
616
  """
615
- if not assume_yes:
617
+ if not assume_yes and not refresh:
616
618
  print("This registers the damage-control hooks (damage-control-dev) in Claude Code's user settings:")
617
619
  print(f" {sys.executable} -I -m damage_control.hook <bash|edit|write|read|mcp>")
618
620
  if input("Proceed with installation? [y/N] ").strip().lower() != "y":
619
621
  print("Installation cancelled.")
620
622
  return 0
621
- return safety_ext.install(force=force, allow_foreign=allow_foreign).code
623
+ return safety_ext.install(force=force, allow_foreign=allow_foreign, refresh=refresh).code
@@ -6,7 +6,9 @@ REPLACES the bundled file of the same name (a stale copy is not protection, it i
6
6
  a script registration runs code that no longer ships. This command classifies what is on the
7
7
  machine with ``rule_baselines.json`` (the sha256 of every version we ever shipped):
8
8
 
9
- * an overlay file matching a shipped hash holds nothing the bundle lacks, so it is deleted;
9
+ * an overlay file matching a shipped hash whose name the bundle still ships holds nothing the
10
+ bundle lacks, so it is deleted;
11
+ * a shipped-hash file the bundle no longer ships (``gws.yaml``, #1143) stays: it may be the only copy;
10
12
  * any other overlay file is a human's edit, so it stays (and is named; it still overrides by name);
11
13
  * pack decisions that the old always-on files implied are recorded (``packs:`` in the policy);
12
14
  * registrations of the old scripts, and the scripts, are removed once the package hooks are
@@ -27,7 +29,12 @@ from typing import Any, Callable, Dict, List, Optional
27
29
  from damage_control import harness_config as hc
28
30
  from damage_control import install as dc_install
29
31
  from damage_control import packs
30
- from damage_control.engine import config_override_dir, policy_file_path
32
+ from damage_control.engine import (
33
+ bundled_rule_sources,
34
+ bundled_tooldefs_dir,
35
+ config_override_dir,
36
+ policy_file_path,
37
+ )
31
38
 
32
39
  from . import safety_ext
33
40
 
@@ -62,29 +69,74 @@ def _sha256(path: Path) -> Optional[str]:
62
69
 
63
70
 
64
71
  def _dirs() -> Dict[str, Path]:
72
+ safety_ext.activate() # judge by AgentWire's profile: without it config_override_dir() is ~/.damage-control (#1268)
65
73
  base = config_override_dir()
66
74
  return {"rules": base / "damage-control", "tooldefs": base / "tooldefs"}
67
75
 
68
76
 
69
77
  def _legacy_dir() -> Path:
78
+ safety_ext.activate()
70
79
  return config_override_dir() / "hooks" / "damage-control"
71
80
 
72
81
 
82
+ def bundled_names() -> Dict[str, set]:
83
+ """File names the CURRENT bundle provides: the engine's plus AgentWire's rules layer (#1269)."""
84
+ rule_sources = [*bundled_rule_sources(), safety_ext.RULES_DIR]
85
+ return {
86
+ "rules": {p.name for d in rule_sources for p in d.glob("*.yaml")},
87
+ "tooldefs": {p.name for p in bundled_tooldefs_dir().glob("*.yaml")},
88
+ }
89
+
90
+
73
91
  def classify() -> Dict[str, Dict[str, List[str]]]:
74
- """``{section: {"pristine": [...], "edited": [...]}}`` for the shipped-named files on the machine."""
92
+ """``{section: {"pristine", "edited", "unbundled"}}`` for the shipped-named files on the machine.
93
+
94
+ ``pristine`` is redundant: it matches a version we shipped AND the bundle still provides that
95
+ name. ``unbundled`` matches a shipped version but the bundle no longer ships the name (baselines
96
+ keep retired history), so the copy may be the only protection there is and is never retired
97
+ (#1269). ``edited`` is a human's change.
98
+ """
75
99
  out: Dict[str, Dict[str, List[str]]] = {}
76
100
  baselines = load_baselines()
101
+ bundled = bundled_names()
77
102
  for section, live in _dirs().items():
78
- pristine: List[str] = []
79
- edited: List[str] = []
103
+ groups: Dict[str, List[str]] = {"pristine": [], "edited": [], "unbundled": []}
80
104
  for name, hashes in sorted(baselines[section].items()):
81
105
  target = live / name
82
- if target.is_file():
83
- (pristine if _sha256(target) in hashes else edited).append(name)
84
- out[section] = {"pristine": pristine, "edited": edited}
106
+ if not target.is_file():
107
+ continue
108
+ if _sha256(target) not in hashes:
109
+ groups["edited"].append(name)
110
+ elif name in bundled[section]:
111
+ groups["pristine"].append(name)
112
+ else:
113
+ groups["unbundled"].append(name)
114
+ out[section] = groups
85
115
  return out
86
116
 
87
117
 
118
+ def overlay_report_lines(plan: Dict[str, Dict[str, List[str]]]) -> List[str]:
119
+ """Doctor's overlay lines. Only a pristine copy has a Fix (migrate retires it); edited and
120
+ unbundled files are information, because migrate deliberately keeps them (#1270)."""
121
+ lines: List[str] = []
122
+ for section, groups in plan.items():
123
+ if groups["pristine"]:
124
+ lines.append(f" [..] Redundant {section} copies of bundled files: {', '.join(groups['pristine'])}")
125
+ lines.append(" Fix: agentwire safety migrate (removes the pristine copies)")
126
+ kept = groups["edited"] + groups["unbundled"]
127
+ if kept:
128
+ lines.append(f" [..] Your {section} overlay replaces or adds to the bundle: {', '.join(kept)}")
129
+ return lines
130
+
131
+
132
+ def duplicate_ids_fix(plan: Dict[str, Dict[str, List[str]]]) -> str:
133
+ """Legacy overlay copies shadow the bundle and are what duplicate rule ids come from on a
134
+ pre-package install; ``install`` does not touch them, ``migrate`` does (#1270)."""
135
+ if any(groups["pristine"] for groups in plan.values()):
136
+ return "agentwire safety migrate (retires the old overlay copies that duplicate the bundle)"
137
+ return "agentwire safety install --yes"
138
+
139
+
88
140
  def legacy_files() -> List[Path]:
89
141
  return [p for name in LEGACY_HOOK_FILES if (p := _legacy_dir() / name).exists()]
90
142
 
@@ -170,6 +222,7 @@ def migrate(
170
222
  log: Callable[[str], None] = print,
171
223
  ) -> int:
172
224
  """Classify, install the package hooks, then retire what only the old install needed. Returns an exit code."""
225
+ safety_ext.activate()
173
226
  plan = classify()
174
227
  legacy = legacy_files()
175
228
  for section, groups in plan.items():
@@ -177,6 +230,8 @@ def migrate(
177
230
  log(f"{'would remove' if dry_run else 'remove'} {section[:-1]} copy {name} (the package ships it)")
178
231
  for name in groups["edited"]:
179
232
  log(f"keep {section[:-1]} {name}: edited, so it replaces the bundled file of that name")
233
+ for name in groups["unbundled"]:
234
+ log(f"keep {section[:-1]} {name}: the package no longer ships it, so this copy is the only one")
180
235
  for path in legacy:
181
236
  log(f"{'would remove' if dry_run else 'remove'} legacy hook script {path.name}")
182
237
  if dry_run:
@@ -266,6 +266,43 @@ against the installed Claude Code, the same way #878 established tmux's
266
266
  mapping. Encoding only `/` (#892) produced a key no directory ever had for any
267
267
  path with a dot, underscore or space.
268
268
 
269
+ ## The chain follows the conversation, not just the launch (#1271)
270
+
271
+ `record_session_launch` writes the chain **once**. Claude mints a new id inside
272
+ a running session on `/clear` and switches ids on `/resume`, so a chain that
273
+ only knew launches resumed a week-old conversation after six `/clear`s — the
274
+ record named the id the session *started* with, not the one it was *in*. A
275
+ single-launch test cannot see this; the bug only exists after a second step.
276
+
277
+ A Claude Code `SessionStart` hook (`source`: `startup|resume|clear|compact`,
278
+ carrying the new `session_id`) reports each change:
279
+
280
+ - `hooks/session-start-handler.sh` is registered by `agentwire hooks install`
281
+ like the other managed hooks (drift checks in `hooks status` / `doctor`
282
+ included). It runs the work detached and exits 0 unconditionally — a hook
283
+ must never fail or slow a session start.
284
+ - The body is `agentwire hooks session-start` (CLI is SSOT). It resolves the
285
+ owning session from `$TMUX_PANE` via `pane_manager`, **skips worker panes
286
+ (index > 0)** — a pane is not a session and must not write its owner's
287
+ chain, same rule as `spawn` — and calls `core.record_conversation_change`,
288
+ which uses the same atomic `store_session_metadata` write.
289
+ - `record_conversation_change` puts the id **last** in the chain (an id already
290
+ present — `/resume` back to an earlier conversation — moves to the tail,
291
+ because the tail is what restart reads as "current"). Already-last is a no-op,
292
+ so it is idempotent and the launch's own id costs nothing. A session with no
293
+ launch record is left alone: the hook never conjures a partial record.
294
+ - Errors are logged to `/tmp/claude-hook-debug.log`, never raised.
295
+
296
+ `restart`'s newest-first walk is unchanged: a `/clear`ed conversation that
297
+ never took a turn has no transcript yet (written lazily), so the walk falls
298
+ back to the previous id that does.
299
+
300
+ **Sessions that took a `/clear` before the hook was installed** have a chain
301
+ frozen at launch. `doctor` states (never scores) live sessions whose history
302
+ dir holds transcripts newer than the recorded head and absent from the chain.
303
+ It cannot be certain — another session in the same directory writes transcripts
304
+ that look identical — hence a note, not a fault.
305
+
269
306
  ## Restarting in place
270
307
 
271
308
  `agentwire restart -s <session>` is the verb the record exists for: `/exit`,
@@ -0,0 +1,176 @@
1
+ """#1271: ``conversation_ids`` follows Claude's in-session id changes.
2
+
3
+ A single-launch test cannot see this bug: the chain is written at launch, so a
4
+ session that never ``/clear``s always restarts correctly. Every test here takes
5
+ a SECOND step after the launch.
6
+ """
7
+
8
+ import io
9
+ import json
10
+ import types
11
+
12
+ import pytest
13
+
14
+ from agentwire import doctor_cli, hooks_cli, restart_cli
15
+ from agentwire.history import encode_project_path
16
+
17
+ TURN = '{"type":"user","message":{"role":"user","content":"hi"}}\n'
18
+
19
+
20
+ @pytest.fixture
21
+ def store(tmp_path, monkeypatch):
22
+ monkeypatch.setattr("agentwire.core.CONFIG_DIR", tmp_path / "agentwire")
23
+ monkeypatch.setattr("agentwire.history.claude_projects_dir", lambda: tmp_path / "projects")
24
+ cwd = tmp_path / "worktree"
25
+ cwd.mkdir()
26
+ (tmp_path / "projects").mkdir()
27
+ return types.SimpleNamespace(root=tmp_path, cwd=cwd, projects=tmp_path / "projects")
28
+
29
+
30
+ @pytest.fixture
31
+ def pane(monkeypatch):
32
+ """Where the hook believes it runs: (session, pane_index)."""
33
+ where = types.SimpleNamespace(session="sess", index=0)
34
+ monkeypatch.setattr("agentwire.pane_manager.get_current_session", lambda: where.session)
35
+ monkeypatch.setattr("agentwire.pane_manager.get_current_pane_index", lambda: where.index)
36
+ return where
37
+
38
+
39
+ def transcript(store, cid):
40
+ d = store.projects / encode_project_path(str(store.cwd))
41
+ d.mkdir(parents=True, exist_ok=True)
42
+ (d / f"{cid}.jsonl").write_text(TURN)
43
+ return d / f"{cid}.jsonl"
44
+
45
+
46
+ def launch(store, session="sess"):
47
+ from agentwire.core import build_agent_command, record_session_launch
48
+
49
+ agent = build_agent_command("bypass")
50
+ record_session_launch(session, agent, store.cwd)
51
+ return agent.conversation_id
52
+
53
+
54
+ def session_start(cid, source="clear"):
55
+ return hooks_cli.record_session_start({"session_id": cid, "source": source})
56
+
57
+
58
+ def chain(session="sess"):
59
+ from agentwire.core import load_session_metadata
60
+
61
+ return load_session_metadata(session)["conversation_ids"]
62
+
63
+
64
+ def test_restart_resumes_the_post_clear_conversation(store, pane, monkeypatch):
65
+ launched = launch(store)
66
+ transcript(store, launched)
67
+ session_start("after-clear-1")
68
+ transcript(store, "after-clear-1")
69
+ session_start("after-clear-2")
70
+ transcript(store, "after-clear-2")
71
+
72
+ assert chain() == [launched, "after-clear-1", "after-clear-2"]
73
+
74
+ captured = []
75
+ monkeypatch.setattr(restart_cli, "tmux_session_exists", lambda n: False)
76
+ monkeypatch.setattr(restart_cli, "_notify_portal_sessions_changed", lambda: None)
77
+ monkeypatch.setattr(restart_cli.pane_manager, "get_current_session", lambda: None)
78
+ monkeypatch.setattr(
79
+ restart_cli, "_launch_tmux_session",
80
+ lambda name, path, env, cmd: captured.append(cmd),
81
+ )
82
+ args = types.SimpleNamespace(session="sess", json=False, no_wait=True)
83
+ assert restart_cli.cmd_restart(args) == 0
84
+ assert '--resume "after-clear-2" --fork-session' in captured[0]
85
+
86
+
87
+ def test_a_cleared_but_unprompted_conversation_falls_back_to_the_last_real_one(store, pane):
88
+ launched = launch(store)
89
+ transcript(store, launched)
90
+ session_start("cleared-never-prompted") # no transcript: written lazily
91
+
92
+ resume_id, _ = restart_cli.resolve_resume_target(chain(), str(store.cwd))
93
+ assert resume_id == launched
94
+
95
+
96
+ def test_the_hook_is_idempotent_and_resume_moves_an_old_id_to_the_tail(store, pane):
97
+ from agentwire.core import record_conversation_change
98
+
99
+ launched = launch(store)
100
+ assert record_conversation_change("sess", launched) is False # the launch's own id
101
+ session_start("b")
102
+ assert session_start("b").startswith("unchanged")
103
+ assert chain() == [launched, "b"]
104
+
105
+ # /resume back to the launch conversation: it is now the CURRENT one.
106
+ session_start(launched, source="resume")
107
+ assert chain() == ["b", launched]
108
+
109
+
110
+ def test_the_hook_never_writes_outside_its_own_session_record(store, pane):
111
+ launch(store)
112
+ before = chain()
113
+
114
+ pane.index = 1 # a worker pane is not a session
115
+ assert session_start("worker-conv").startswith("skipped: worker pane")
116
+
117
+ pane.index, pane.session = 0, "no-such-session" # no launch record: nothing to extend
118
+ assert session_start("x").startswith("unchanged")
119
+ from agentwire.core import load_session_metadata, session_metadata_path
120
+
121
+ assert not session_metadata_path("no-such-session").exists()
122
+ assert load_session_metadata("no-such-session") == {}
123
+ assert chain() == before
124
+
125
+
126
+ def test_the_hook_command_exits_zero_on_every_bad_input(store, pane, monkeypatch, capsys):
127
+ launch(store)
128
+ bad = ["", "{{{", "[1]", '{"no":"id"}', '{"session_id": 5}']
129
+ codes = []
130
+ for raw in bad:
131
+ monkeypatch.setattr("sys.stdin", io.StringIO(raw))
132
+ codes.append(hooks_cli.cmd_hooks_session_start(types.SimpleNamespace()))
133
+
134
+ def boom(*_):
135
+ raise OSError("read-only store")
136
+
137
+ monkeypatch.setattr("agentwire.core.store_session_metadata", boom)
138
+ monkeypatch.setattr("sys.stdin", io.StringIO(json.dumps({"session_id": "new"})))
139
+ codes.append(hooks_cli.cmd_hooks_session_start(types.SimpleNamespace()))
140
+
141
+ assert codes == [0] * len(codes)
142
+ assert "read-only store" in capsys.readouterr().err # logged, not swallowed silently
143
+
144
+
145
+ class TestDoctorUnrecordedTranscripts:
146
+ @pytest.fixture(autouse=True)
147
+ def live(self, monkeypatch):
148
+ monkeypatch.setattr(doctor_cli, "tmux_session_exists", lambda n: True)
149
+
150
+ def test_newer_unrecorded_transcript_is_stated(self, store):
151
+ import os
152
+
153
+ launched = launch(store)
154
+ head = transcript(store, launched)
155
+ cleared = transcript(store, "cleared")
156
+ os.utime(head, (1000, 1000))
157
+ os.utime(cleared, (2000, 2000))
158
+
159
+ [f] = doctor_cli.scan_unrecorded_transcripts(["sess"])
160
+ assert (f["head"], f["newer"]) == (launched, ["cleared"])
161
+
162
+ def test_a_recorded_or_older_transcript_is_silent(self, store, pane):
163
+ import os
164
+
165
+ launched = launch(store)
166
+ head = transcript(store, launched)
167
+ older = transcript(store, "older")
168
+ os.utime(older, (500, 500))
169
+ os.utime(head, (1000, 1000))
170
+ assert doctor_cli.scan_unrecorded_transcripts(["sess"]) == []
171
+
172
+ newer = transcript(store, "cleared")
173
+ os.utime(newer, (2000, 2000))
174
+ session_start("cleared") # the hook caught it
175
+ os.utime(newer, (2000, 2000))
176
+ assert doctor_cli.scan_unrecorded_transcripts(["sess"]) == []
@@ -109,6 +109,8 @@ class TestInstallHooks:
109
109
  for e in events["PermissionRequest"] for h in e["hooks"])
110
110
  assert any(h["command"].endswith("idle-handler.sh")
111
111
  for e in events["Notification"] for h in e["hooks"])
112
+ assert any(h["command"].endswith("session-start-handler.sh")
113
+ for e in events["SessionStart"] for h in e["hooks"])
112
114
 
113
115
 
114
116
  def test_stale_installed_copy_refreshed(self, env):