agentwire-dev 1.56.0__tar.gz → 1.57.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 (486) hide show
  1. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/PKG-INFO +1 -1
  2. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/__init__.py +1 -1
  3. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/__main__.py +4 -2
  4. agentwire_dev-1.57.0/agentwire/chrome_tabs.py +124 -0
  5. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/config.py +7 -5
  6. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/core.py +71 -16
  7. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/diff_cli.py +1 -1
  8. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/doctor_cli.py +23 -2
  9. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/ensure_cli.py +11 -1
  10. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/bash-tool-damage-control.py +105 -13
  11. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/edit-tool-damage-control.py +105 -13
  12. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/mcp-tool-damage-control.py +105 -13
  13. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/read-tool-damage-control.py +105 -13
  14. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/rules/agentwire.yaml +6 -0
  15. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/write-tool-damage-control.py +105 -13
  16. agentwire_dev-1.57.0/agentwire/mcp_chrome.py +90 -0
  17. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_server.py +1 -0
  18. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_session.py +38 -1
  19. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_worktree.py +126 -25
  20. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/project_config.py +28 -25
  21. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/__init__.py +56 -26
  22. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/agentwire.md +2 -0
  23. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/contributor.md +1 -1
  24. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/correspondent.md +3 -3
  25. agentwire_dev-1.56.0/agentwire/roles/worktree-session.md → agentwire_dev-1.57.0/agentwire/roles/worker-worktree.md +11 -8
  26. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/worker.md +4 -2
  27. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/safety/_core.py +105 -13
  28. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/scheduler/dispatch.py +6 -6
  29. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/session_cli.py +488 -121
  30. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/css/desktop.css +65 -61
  31. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/css/mobile.css +9 -7
  32. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/manifest.webmanifest +1 -1
  33. agentwire_dev-1.57.0/agentwire/tabs_cli.py +89 -0
  34. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tasks.py +16 -6
  35. agentwire_dev-1.57.0/agentwire/tasks_cli.py +299 -0
  36. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/templates/base.html +1 -1
  37. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/templates/pair.html +1 -1
  38. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/worktree.py +41 -10
  39. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/worktree_registry.py +9 -0
  40. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/INDEX.md +3 -3
  41. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/architecture.md +8 -4
  42. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/briefing-mode.md +2 -2
  43. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/glossary.md +2 -2
  44. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/internals/damage-control.md +80 -5
  45. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/internals/parallel-refactor.md +1 -1
  46. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/quickstart.md +5 -1
  47. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/research/briefing-mode-feasibility.md +2 -0
  48. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/scheduling/scheduled-workloads.md +13 -3
  49. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/security/damage-control-hardening.md +12 -4
  50. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/sessions/prompt-routing.md +10 -3
  51. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/sessions/worktree-sessions.md +36 -2
  52. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/integration/test_scheduler_board.py +4 -4
  53. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/integration/test_worktree_cmd.py +330 -2
  54. agentwire_dev-1.57.0/tests/unit/test_chrome_tabs.py +110 -0
  55. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_cli_commands.py +111 -12
  56. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_control_plane_protection.py +146 -18
  57. agentwire_dev-1.57.0/tests/unit/test_core_created_by_rooting.py +114 -0
  58. agentwire_dev-1.57.0/tests/unit/test_dangling_worktrees.py +142 -0
  59. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_mcp_tools_args.py +101 -2
  60. agentwire_dev-1.57.0/tests/unit/test_posture_default.py +71 -0
  61. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_project_config.py +40 -8
  62. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_roles.py +69 -31
  63. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_scheduler.py +2 -2
  64. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_task_cli.py +2 -2
  65. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_tasks.py +14 -6
  66. agentwire_dev-1.57.0/tests/unit/test_tasks_cli.py +171 -0
  67. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_worktree.py +61 -0
  68. agentwire_dev-1.57.0/tests/unit/test_worktree_branch_cleanup.py +165 -0
  69. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/.agentwire.yml.example +0 -0
  70. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/.claude/commands/handoff.md +0 -0
  71. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/.claude/skills/wiki/SKILL.md +0 -0
  72. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/.github/FUNDING.yml +0 -0
  73. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  74. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  75. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
  76. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  77. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/.github/workflows/pytest.yml +0 -0
  78. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/.github/workflows/ruff.yml +0 -0
  79. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/.github/workflows/security.yml +0 -0
  80. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/.github/workflows/tts-smoke.yml +0 -0
  81. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/.gitignore +0 -0
  82. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/AGENTS.md +0 -0
  83. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/CODE_OF_CONDUCT.md +0 -0
  84. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/CONTRIBUTING.md +0 -0
  85. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/Dockerfile.local +0 -0
  86. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/LICENSE +0 -0
  87. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/README.md +0 -0
  88. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/RELEASING.md +0 -0
  89. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/SECURITY.md +0 -0
  90. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/SPONSORS.md +0 -0
  91. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/agents/__init__.py +0 -0
  92. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/agents/base.py +0 -0
  93. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/agents/tmux.py +0 -0
  94. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/cached_status.py +0 -0
  95. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/channels/__init__.py +0 -0
  96. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/channels/base.py +0 -0
  97. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/channels/email.py +0 -0
  98. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/channels/push.py +0 -0
  99. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/channels/quo.py +0 -0
  100. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/channels_cli.py +0 -0
  101. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/completion.py +0 -0
  102. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/config_cli.py +0 -0
  103. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/council/__init__.py +0 -0
  104. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/council/cli.py +0 -0
  105. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/council/inbox.py +0 -0
  106. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/council/minutes.py +0 -0
  107. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/council/state.py +0 -0
  108. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/council/view.py +0 -0
  109. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/devices.py +0 -0
  110. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/doctor_voice.py +0 -0
  111. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/fetch.py +0 -0
  112. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/handoff/__init__.py +0 -0
  113. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/handoff/git_state.py +0 -0
  114. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/handoff/instructions.py +0 -0
  115. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/handoff/parser.py +0 -0
  116. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/handoff/renderer.py +0 -0
  117. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/handoff/schema.py +0 -0
  118. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/handoff_cli.py +0 -0
  119. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/history.py +0 -0
  120. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/history_cli.py +0 -0
  121. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/__init__.py +0 -0
  122. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/agentwire-permission.sh +0 -0
  123. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/__init__.py +0 -0
  124. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/audit_logger.py +0 -0
  125. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/rules/aws.yaml +0 -0
  126. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/rules/cloud-hosting.yaml +0 -0
  127. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/rules/containers.yaml +0 -0
  128. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/rules/control-plane.yaml +0 -0
  129. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/rules/core.yaml +0 -0
  130. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/rules/databases.yaml +0 -0
  131. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/rules/firebase.yaml +0 -0
  132. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/rules/gcp.yaml +0 -0
  133. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/rules/git.yaml +0 -0
  134. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/rules/gws.yaml +0 -0
  135. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/rules/infrastructure.yaml +0 -0
  136. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/rules/outbound.yaml +0 -0
  137. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/rules/publish.yaml +0 -0
  138. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/damage-control/rules/remote.yaml +0 -0
  139. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/idle-handler.sh +0 -0
  140. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks/queue-processor.sh +0 -0
  141. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/hooks_cli.py +0 -0
  142. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/inbox.py +0 -0
  143. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/limits_cli.py +0 -0
  144. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/listen.py +0 -0
  145. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/locking.py +0 -0
  146. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/machine_cli.py +0 -0
  147. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_channels.py +0 -0
  148. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_cli.py +0 -0
  149. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_core.py +0 -0
  150. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_council.py +0 -0
  151. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_desktop.py +0 -0
  152. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_handoff.py +0 -0
  153. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_history.py +0 -0
  154. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_listen.py +0 -0
  155. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_lock.py +0 -0
  156. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_machine.py +0 -0
  157. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_msg.py +0 -0
  158. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_notify.py +0 -0
  159. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_pane.py +0 -0
  160. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_projects.py +0 -0
  161. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_scheduler.py +0 -0
  162. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_scratchpad.py +0 -0
  163. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_services.py +0 -0
  164. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_status.py +0 -0
  165. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_task.py +0 -0
  166. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_tunnels.py +0 -0
  167. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_voice.py +0 -0
  168. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_voiceclone.py +0 -0
  169. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/mcp_wiki.py +0 -0
  170. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/msg_cli.py +0 -0
  171. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/network.py +0 -0
  172. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/notify_cli.py +0 -0
  173. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/onboarding.py +0 -0
  174. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/palette_cli.py +0 -0
  175. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/pane_cli.py +0 -0
  176. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/pane_manager.py +0 -0
  177. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/portal_cli.py +0 -0
  178. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/projects.py +0 -0
  179. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/prompt_router.py +0 -0
  180. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/prompts_cli.py +0 -0
  181. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/push_cli.py +0 -0
  182. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/push_store.py +0 -0
  183. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/repo_cli.py +0 -0
  184. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/research.py +0 -0
  185. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/anchor.md +0 -0
  186. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/chatbot.md +0 -0
  187. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/council-brain.md +0 -0
  188. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/council-conscience.md +0 -0
  189. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/council-critic.md +0 -0
  190. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/council-devils-advocate.md +0 -0
  191. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/council-gut.md +0 -0
  192. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/council-historian.md +0 -0
  193. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/council-member.md +0 -0
  194. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/council-orchestrator.md +0 -0
  195. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/init.md +0 -0
  196. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/notifications.md +0 -0
  197. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/orchestrator.md +0 -0
  198. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/soul.md +0 -0
  199. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/task-runner.md +0 -0
  200. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles/voice.md +0 -0
  201. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/roles_cli.py +0 -0
  202. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/routes/__init__.py +0 -0
  203. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/routes/artifacts.py +0 -0
  204. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/routes/config.py +0 -0
  205. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/routes/council.py +0 -0
  206. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/routes/desktop.py +0 -0
  207. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/routes/history.py +0 -0
  208. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/routes/machines.py +0 -0
  209. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/routes/notify.py +0 -0
  210. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/routes/palette.py +0 -0
  211. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/routes/permission.py +0 -0
  212. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/routes/projects.py +0 -0
  213. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/routes/push.py +0 -0
  214. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/routes/safety.py +0 -0
  215. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/routes/scheduler.py +0 -0
  216. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/routes/scratchpad.py +0 -0
  217. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/routes/sessions.py +0 -0
  218. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/routes/sessions_admin.py +0 -0
  219. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/routes/voice.py +0 -0
  220. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/safety/__init__.py +0 -0
  221. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/safety_cli.py +0 -0
  222. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/safety_commands.py +0 -0
  223. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/scheduler/__init__.py +0 -0
  224. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/scheduler/gates.py +0 -0
  225. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/scheduler/loop.py +0 -0
  226. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/scheduler/models.py +0 -0
  227. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/scheduler/report.py +0 -0
  228. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/scheduler/schedule.py +0 -0
  229. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/scheduler/state.py +0 -0
  230. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/scheduler_cli.py +0 -0
  231. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/scratchpad.py +0 -0
  232. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/security.py +0 -0
  233. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/send_cli.py +0 -0
  234. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/server.py +0 -0
  235. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/services.py +0 -0
  236. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/session_context.py +0 -0
  237. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/session_ready.py +0 -0
  238. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/ssh.py +0 -0
  239. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/agentwire-splash-logo-layers--agentwire-text.png +0 -0
  240. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/agentwire-splash-logo-layers--echo-claw-fg.png +0 -0
  241. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/agentwire-splash-logo-layers--echo.png +0 -0
  242. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/agentwire-splash-logo-layers--telephone.png +0 -0
  243. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/agentwire-splash-logo-layers--tree.png +0 -0
  244. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/announcements.json +0 -0
  245. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/apple-touch-icon.png +0 -0
  246. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/favicon-32.png +0 -0
  247. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/favicon-64.png +0 -0
  248. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/icons/sessions/bear.webp +0 -0
  249. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/icons/sessions/cat.webp +0 -0
  250. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/icons/sessions/crown.webp +0 -0
  251. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/icons/sessions/custom/agentwire-portal.webp +0 -0
  252. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/icons/sessions/custom/agentwire-tts.webp +0 -0
  253. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/icons/sessions/custom/agentwire.webp +0 -0
  254. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/icons/sessions/deer.webp +0 -0
  255. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/icons/sessions/drone.webp +0 -0
  256. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/icons/sessions/eagle.webp +0 -0
  257. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/icons/sessions/fox.webp +0 -0
  258. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/icons/sessions/hawk.webp +0 -0
  259. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/icons/sessions/horse.webp +0 -0
  260. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/icons/sessions/lion.webp +0 -0
  261. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/icons/sessions/rabbit.webp +0 -0
  262. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/icons/sessions/robot.webp +0 -0
  263. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/icons/sessions/tiger.webp +0 -0
  264. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/icons/sessions/wolf.webp +0 -0
  265. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/img/icon-192.png +0 -0
  266. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/img/icon-512.png +0 -0
  267. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/.gitkeep +0 -0
  268. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/announcement-modal.js +0 -0
  269. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/api.js +0 -0
  270. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/artifact-window.js +0 -0
  271. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/collage.js +0 -0
  272. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/command-palette.js +0 -0
  273. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/council-window.js +0 -0
  274. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/dead-key-suppressor.js +0 -0
  275. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/desktop-manager.js +0 -0
  276. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/desktop.js +0 -0
  277. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/help-modal.js +0 -0
  278. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/icon-manager.js +0 -0
  279. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/mobile.js +0 -0
  280. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/notification-prefs.js +0 -0
  281. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/notifications-panel.js +0 -0
  282. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/ptt.js +0 -0
  283. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/push-client.js +0 -0
  284. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/review-window.js +0 -0
  285. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/safety-shared.js +0 -0
  286. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/safety-window.js +0 -0
  287. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/scratchpad.js +0 -0
  288. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/service-classification.js +0 -0
  289. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/session-id.js +0 -0
  290. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/session-window.js +0 -0
  291. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/shortcuts.js +0 -0
  292. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/sidebar/artifacts-section.js +0 -0
  293. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/sidebar/config-section.js +0 -0
  294. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/sidebar/council-section.js +0 -0
  295. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/sidebar/machines-section.js +0 -0
  296. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/sidebar/projects-section.js +0 -0
  297. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/sidebar/safety-section.js +0 -0
  298. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/sidebar/scheduler-section.js +0 -0
  299. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/sidebar/services-section.js +0 -0
  300. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/sidebar/sessions-section.js +0 -0
  301. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/sidebar.js +0 -0
  302. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/terminal-font-prefs.js +0 -0
  303. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/tile-manager.js +0 -0
  304. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/toast.js +0 -0
  305. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/token-modal.js +0 -0
  306. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/utils/ansi.js +0 -0
  307. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/utils/swipe.js +0 -0
  308. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/voice/autosend-prefs.js +0 -0
  309. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/voice/browser-stt.js +0 -0
  310. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/voice/browser-tts.js +0 -0
  311. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/voice/jargon.js +0 -0
  312. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/voice/prompt.js +0 -0
  313. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/js/winbox.bundle.min.js +0 -0
  314. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/static/service-worker.js +0 -0
  315. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/stt/__init__.py +0 -0
  316. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/stt/base.py +0 -0
  317. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/stt/cloud.py +0 -0
  318. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/stt/engine.py +0 -0
  319. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/stt/local.py +0 -0
  320. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/stt/server_backend.py +0 -0
  321. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/stt/stt_server.py +0 -0
  322. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/system_cli.py +0 -0
  323. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/templates/__init__.py +0 -0
  324. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/templates/council/minutes.html.j2 +0 -0
  325. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/templates/desktop.html +0 -0
  326. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/templates/email_notification.html +0 -0
  327. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/templates/handoff/show-the-story.html.j2 +0 -0
  328. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/templates/handoff/theme.css.j2 +0 -0
  329. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/templates/mobile.html +0 -0
  330. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/templates/tmux.conf +0 -0
  331. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/templating.py +0 -0
  332. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tooldefs/aws.yaml +0 -0
  333. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tooldefs/docker.yaml +0 -0
  334. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tooldefs/gcp.yaml +0 -0
  335. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tooldefs/gh.yaml +0 -0
  336. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tooldefs/git.yaml +0 -0
  337. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tooldefs/gws.yaml +0 -0
  338. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tooldefs/kubectl.yaml +0 -0
  339. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tooldefs/npm.yaml +0 -0
  340. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tooldefs/terraform.yaml +0 -0
  341. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tooldefs/uv.yaml +0 -0
  342. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tts/__init__.py +0 -0
  343. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tts/audio.py +0 -0
  344. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tts/base.py +0 -0
  345. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tts/engines/__init__.py +0 -0
  346. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tts/engines/chatterbox.py +0 -0
  347. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tts/engines/kokoro.py +0 -0
  348. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tts/engines/zonos.py +0 -0
  349. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tts/kokoro_server.py +0 -0
  350. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tts/local.py +0 -0
  351. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tts/registry.py +0 -0
  352. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tts_cli.py +0 -0
  353. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tts_server.py +0 -0
  354. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tunnels.py +0 -0
  355. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/tunnels_cli.py +0 -0
  356. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/usage_limit.py +0 -0
  357. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/utils/__init__.py +0 -0
  358. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/utils/chunker.py +0 -0
  359. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/utils/event_log.py +0 -0
  360. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/utils/file_io.py +0 -0
  361. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/utils/paths.py +0 -0
  362. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/utils/speech.py +0 -0
  363. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/utils/subprocess.py +0 -0
  364. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/validation.py +0 -0
  365. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/voice_status.py +0 -0
  366. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/voiceclone.py +0 -0
  367. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/wiki.py +0 -0
  368. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/wiki_audit.py +0 -0
  369. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/agentwire/wiki_cli.py +0 -0
  370. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/decisions/obsidian-second-brain.md +0 -0
  371. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/logo.png +0 -0
  372. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/communication/channels.md +0 -0
  373. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/communication/hammerspoon.md +0 -0
  374. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/communication/handoff.md +0 -0
  375. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/concepts.md +0 -0
  376. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/council.md +0 -0
  377. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/deployment/remote-access.md +0 -0
  378. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/deployment/remote-machines.md +0 -0
  379. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/integrations/gws-google-workspace-cli.md +0 -0
  380. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/internals/portal.md +0 -0
  381. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/internals/shell-escaping.md +0 -0
  382. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/internals/troubleshooting.md +0 -0
  383. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/internals/window-collage.md +0 -0
  384. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/research/orchestration-transport-alternatives.md +0 -0
  385. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/security/pip-audit.md +0 -0
  386. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/security/remote-access-hardening.md +0 -0
  387. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/security/secrets.md +0 -0
  388. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/services.md +0 -0
  389. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/sessions/claude-code-auto-mode.md +0 -0
  390. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/sessions/messaging.md +0 -0
  391. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/sessions/pi.md +0 -0
  392. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/sessions/window-sizing.md +0 -0
  393. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/usage-limit-recovery.md +0 -0
  394. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/voice/shim-contract.md +0 -0
  395. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/voice/stt-cloud.md +0 -0
  396. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/voice/stt-self-hosted.md +0 -0
  397. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/docs/wiki/voice/tts-self-hosted.md +0 -0
  398. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/pyproject.toml +0 -0
  399. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/conftest.py +0 -0
  400. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/e2e/test_portal_ui.py +0 -0
  401. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/fixtures/sample_agentwire.yml +0 -0
  402. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/fixtures/sample_config.yaml +0 -0
  403. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/fixtures/sample_scheduler.yaml +0 -0
  404. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/integration/test_council_portal.py +0 -0
  405. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/integration/test_send_verified_tmux.py +0 -0
  406. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/integration/test_server_websockets.py +0 -0
  407. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_announcements.py +0 -0
  408. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_build_agent_command.py +0 -0
  409. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_channels.py +0 -0
  410. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_cli_output.py +0 -0
  411. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_cli_smoke.py +0 -0
  412. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_config.py +0 -0
  413. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_config_cli.py +0 -0
  414. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_council_cli.py +0 -0
  415. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_council_inbox.py +0 -0
  416. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_council_minutes.py +0 -0
  417. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_council_state.py +0 -0
  418. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_council_view.py +0 -0
  419. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_damage_control_bypass.py +0 -0
  420. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_damage_control_hooks.py +0 -0
  421. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_damage_control_sync.py +0 -0
  422. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_devices.py +0 -0
  423. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_diff_cli.py +0 -0
  424. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_doctor_voice.py +0 -0
  425. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_event_log.py +0 -0
  426. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_file_io.py +0 -0
  427. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_handoff_git_state.py +0 -0
  428. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_handoff_instructions.py +0 -0
  429. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_handoff_parser.py +0 -0
  430. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_handoff_renderer.py +0 -0
  431. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_history.py +0 -0
  432. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_hooks_install.py +0 -0
  433. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_idle_handler.py +0 -0
  434. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_idle_nag.py +0 -0
  435. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_inbox.py +0 -0
  436. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_init_command.py +0 -0
  437. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_install_parity.py +0 -0
  438. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_limits_tick_isolation.py +0 -0
  439. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_locking.py +0 -0
  440. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_mcp_server.py +0 -0
  441. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_msg_cli.py +0 -0
  442. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_notify_cli.py +0 -0
  443. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_onboarding_reinit.py +0 -0
  444. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_palette_cli.py +0 -0
  445. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_pip_environment.py +0 -0
  446. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_portal_api.py +0 -0
  447. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_prompt_router.py +0 -0
  448. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_push.py +0 -0
  449. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_rebuild_guard.py +0 -0
  450. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_repo_cli.py +0 -0
  451. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_routes_snapshot.py +0 -0
  452. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_safety_commands.py +0 -0
  453. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_safety_disabled_rules.py +0 -0
  454. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_safety_escape_hatch.py +0 -0
  455. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_safety_heal.py +0 -0
  456. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_safety_kill_switch.py +0 -0
  457. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_scheduler_parsing.py +0 -0
  458. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_scratchpad.py +0 -0
  459. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_security.py +0 -0
  460. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_server_async.py +0 -0
  461. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_server_pure.py +0 -0
  462. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_services.py +0 -0
  463. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_session_context.py +0 -0
  464. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_session_ready.py +0 -0
  465. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_shared_dir_guard.py +0 -0
  466. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_skill_install.py +0 -0
  467. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_speech_tags.py +0 -0
  468. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_ssh.py +0 -0
  469. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_stt_backend.py +0 -0
  470. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_stt_cloud.py +0 -0
  471. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_stt_engine.py +0 -0
  472. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_templating.py +0 -0
  473. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_terminal_resize.py +0 -0
  474. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_tmux_template.py +0 -0
  475. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_tts_engine_resolution.py +0 -0
  476. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_tts_local.py +0 -0
  477. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_tunnels_probe.py +0 -0
  478. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_unattended_env_isolation.py +0 -0
  479. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_usage_limit.py +0 -0
  480. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_validation.py +0 -0
  481. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_voice_status.py +0 -0
  482. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_wiki.py +0 -0
  483. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_wiki_audit.py +0 -0
  484. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_window_cycling_binding.py +0 -0
  485. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_worktree_layout.py +0 -0
  486. {agentwire_dev-1.56.0 → agentwire_dev-1.57.0}/tests/unit/test_worktree_registry.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentwire-dev
3
- Version: 1.56.0
3
+ Version: 1.57.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.56.0"
3
+ __version__ = "1.57.0"
@@ -16,7 +16,6 @@ from . import ( # noqa: E402 # must follow load_dotenv() above
16
16
  from .core import ( # noqa: E402,F401 # E402: must follow load_dotenv(); F401: re-exported moved helpers
17
17
  _UNATTENDED_ENV_KEYS,
18
18
  CONFIG_DIR,
19
- KIND_DEFAULT_POSTURE,
20
19
  AgentCommand,
21
20
  _add_posture_harness_flags,
22
21
  _build_tmux_env_flags,
@@ -188,10 +187,11 @@ Command Categories:
188
187
  from . import diff_cli, limits_cli, msg_cli, pane_cli, prompts_cli, send_cli # noqa: I001 # session_cli kept on its own line below to minimize Phase 1 #495 merge conflicts
189
188
  from . import session_cli
190
189
  from . import channels_cli, config_cli, portal_cli, tts_cli
191
- from . import scheduler_cli, ensure_cli
190
+ from . import scheduler_cli, ensure_cli, tasks_cli
192
191
  from . import doctor_cli, history_cli, machine_cli, safety_cli
193
192
  from . import handoff_cli, hooks_cli, mcp_cli, roles_cli, tunnels_cli
194
193
  from . import notify_cli, palette_cli, push_cli, repo_cli, system_cli, wiki_cli
194
+ from . import tabs_cli
195
195
  from .council import cli as council_cli
196
196
 
197
197
  _REGISTRARS = [ # noqa: N806 # registry constant; Phase 1 of #495 appends here
@@ -207,6 +207,7 @@ Command Categories:
207
207
  channels_cli.register_channels_parser,
208
208
  scheduler_cli.register_scheduler_parser,
209
209
  ensure_cli.register_ensure_parser,
210
+ tasks_cli.register_tasks_parser,
210
211
  doctor_cli.register_doctor_parser,
211
212
  safety_cli.register_safety_parser,
212
213
  machine_cli.register_machine_parser,
@@ -224,6 +225,7 @@ Command Categories:
224
225
  repo_cli.register_repo_parser,
225
226
  config_cli.register_config_parser,
226
227
  palette_cli.register_palette_parser,
228
+ tabs_cli.register_tabs_parser,
227
229
  ]
228
230
  for _reg in _REGISTRARS:
229
231
  _reg(subparsers)
@@ -0,0 +1,124 @@
1
+ """Tracks claude-in-chrome tab ids opened by a session (#717).
2
+
3
+ Worktree sessions open claude-in-chrome tabs to e2e-verify their work before
4
+ opening a PR. Those tabs are never closed if the session finishes without
5
+ tidying up after itself, or dies mid-work — this module is pure bookkeeping
6
+ so a crashed session's orphaned tabs can still be identified during teardown.
7
+
8
+ agentwire has no way to call `tabs_close_mcp` itself: that MCP server runs
9
+ inside the CALLING agent's own client, not agentwire's process. So this only
10
+ tracks tab ids; the actual close always happens at the LLM/agent layer —
11
+ either the session closing its own tabs before finishing (the normal path),
12
+ or `worktree_remove` surfacing untracked-but-still-open tab ids to whichever
13
+ agent runs the teardown (the crash backstop).
14
+
15
+ Layout: one JSON file (``~/.agentwire/chrome-tabs.json``), keyed by session
16
+ name -> list of ``{tab_id, url, tracked_at}``. Plain JSON, hand-editable.
17
+ """
18
+
19
+ import contextlib
20
+ import datetime
21
+ import fcntl
22
+ import json
23
+ import os
24
+ import tempfile
25
+ from pathlib import Path
26
+
27
+ REGISTRY_FILE = Path.home() / ".agentwire" / "chrome-tabs.json"
28
+
29
+
30
+ @contextlib.contextmanager
31
+ def _locked():
32
+ """Serialize read-modify-write across processes via an flock sidecar."""
33
+ REGISTRY_FILE.parent.mkdir(parents=True, exist_ok=True)
34
+ lock_path = REGISTRY_FILE.with_suffix(REGISTRY_FILE.suffix + ".lock")
35
+ fd = os.open(str(lock_path), os.O_CREAT | os.O_RDWR, 0o644)
36
+ try:
37
+ fcntl.flock(fd, fcntl.LOCK_EX)
38
+ yield
39
+ finally:
40
+ fcntl.flock(fd, fcntl.LOCK_UN)
41
+ os.close(fd)
42
+
43
+
44
+ def _load() -> dict:
45
+ if not REGISTRY_FILE.exists():
46
+ return {}
47
+ try:
48
+ data = json.loads(REGISTRY_FILE.read_text())
49
+ return data if isinstance(data, dict) else {}
50
+ except (json.JSONDecodeError, OSError):
51
+ return {}
52
+
53
+
54
+ def _save(data: dict) -> None:
55
+ """Atomically write the registry (temp file in same dir + os.replace)."""
56
+ REGISTRY_FILE.parent.mkdir(parents=True, exist_ok=True)
57
+ payload = json.dumps(data, indent=2) + "\n"
58
+ fd, tmp = tempfile.mkstemp(dir=str(REGISTRY_FILE.parent), prefix=REGISTRY_FILE.name + ".", suffix=".tmp")
59
+ try:
60
+ with os.fdopen(fd, "w") as f:
61
+ f.write(payload)
62
+ f.flush()
63
+ os.fsync(f.fileno())
64
+ os.replace(tmp, REGISTRY_FILE) # atomic on POSIX
65
+ except BaseException:
66
+ with contextlib.suppress(OSError):
67
+ os.unlink(tmp)
68
+ raise
69
+
70
+
71
+ def track(session: str, tab_id: str, url: str | None = None) -> dict:
72
+ """Record that ``session`` opened claude-in-chrome tab ``tab_id``.
73
+
74
+ Idempotent per (session, tab_id) — re-tracking the same tab just refreshes
75
+ its entry rather than duplicating it.
76
+ """
77
+ entry = {
78
+ "tab_id": tab_id,
79
+ "url": url,
80
+ "tracked_at": datetime.datetime.now().astimezone().isoformat(timespec="seconds"),
81
+ }
82
+ with _locked():
83
+ data = _load()
84
+ tabs = [t for t in data.get(session, []) if t.get("tab_id") != tab_id]
85
+ tabs.append(entry)
86
+ data[session] = tabs
87
+ _save(data)
88
+ return entry
89
+
90
+
91
+ def untrack(session: str, tab_id: str) -> bool:
92
+ """Drop a tracked tab (the session closed it itself). Returns whether it was tracked."""
93
+ with _locked():
94
+ data = _load()
95
+ tabs = data.get(session, [])
96
+ remaining = [t for t in tabs if t.get("tab_id") != tab_id]
97
+ removed = len(remaining) != len(tabs)
98
+ if remaining:
99
+ data[session] = remaining
100
+ else:
101
+ data.pop(session, None)
102
+ if removed:
103
+ _save(data)
104
+ return removed
105
+
106
+
107
+ def tabs_for(session: str) -> list[dict]:
108
+ """All tracked tabs for a session (read-only)."""
109
+ return _load().get(session, [])
110
+
111
+
112
+ def clear(session: str) -> list[dict]:
113
+ """Drop + return every tracked tab for a session — the teardown backstop."""
114
+ with _locked():
115
+ data = _load()
116
+ tabs = data.pop(session, [])
117
+ if tabs:
118
+ _save(data)
119
+ return tabs
120
+
121
+
122
+ def all_tabs() -> dict[str, list[dict]]:
123
+ """Every session -> tracked-tabs mapping (read-only, for listing/debugging)."""
124
+ return _load()
@@ -101,9 +101,11 @@ class WorktreesConfig:
101
101
  # Gitignored files that `git worktree add` won't carry over (it only
102
102
  # checks out tracked files). These are copied from the main repo into
103
103
  # each fresh worktree so agents have the secrets/config they need.
104
- # .agentwire.yml is included because worktree-dispatched tasks can't
105
- # load their task definition without it when the project gitignores it.
106
- copy_files: list = field(default_factory=lambda: [".env", ".agentwire.yml"])
104
+ # .agentwire.yml/.agentwire.tasks.yml are included because worktree-dispatched
105
+ # tasks can't load their session/task config without them when the project
106
+ # gitignores them (the latter is the protected, host-authored task-exec file —
107
+ # #720).
108
+ copy_files: list = field(default_factory=lambda: [".env", ".agentwire.yml", ".agentwire.tasks.yml"])
107
109
 
108
110
 
109
111
  @dataclass
@@ -120,7 +122,7 @@ class ProjectsConfig:
120
122
 
121
123
  @dataclass
122
124
  class WorktreeConfig:
123
- """Standalone worktree-session orchestration (`worktree:` config key).
125
+ """Standalone worktree session orchestration (`worktree:` config key).
124
126
 
125
127
  Governs `agentwire worktree <name>` — the first-class primitive for
126
128
  spawning an isolated branch+worktree+session for one unit of work.
@@ -621,7 +623,7 @@ def _dict_to_config(data: dict) -> Config:
621
623
  enabled=worktrees_data.get("enabled", True),
622
624
  suffix=worktrees_data.get("suffix", "-worktrees"),
623
625
  auto_create_branch=worktrees_data.get("auto_create_branch", True),
624
- copy_files=worktrees_data.get("copy_files", [".env", ".agentwire.yml"]),
626
+ copy_files=worktrees_data.get("copy_files", [".env", ".agentwire.yml", ".agentwire.tasks.yml"]),
625
627
  )
626
628
  projects = ProjectsConfig(
627
629
  dir=projects_data.get("dir", "~/projects"),
@@ -28,7 +28,7 @@ from .project_config import (
28
28
  normalize_session_type,
29
29
  )
30
30
  from .roles import RoleConfig, merge_roles
31
- from .worktree import parse_session_name
31
+ from .worktree import git_common_dir, parse_session_name
32
32
 
33
33
  # Default config directory
34
34
  CONFIG_DIR = Path.home() / ".agentwire"
@@ -489,16 +489,30 @@ def wait_for_shell_prompt(target: str, timeout: float = 2.0) -> None:
489
489
  time.sleep(0.05)
490
490
 
491
491
 
492
+ def _live_session_cwd(session: str) -> Path | None:
493
+ """The session's current pane cwd, or None if it isn't a live tmux session.
494
+
495
+ Unlike ``_get_session_project_path``, this never falls back to guessing a
496
+ path from the session name — a guessed path is unsafe for an identity
497
+ comparison (#715's same-project check needs the real cwd or nothing).
498
+ """
499
+ if not tmux_session_exists(session):
500
+ return None
501
+ result = subprocess.run(
502
+ ["tmux", "display-message", "-t", session, "-p", "#{pane_current_path}"],
503
+ capture_output=True,
504
+ text=True,
505
+ )
506
+ if result.returncode == 0 and result.stdout.strip():
507
+ return Path(result.stdout.strip())
508
+ return None
509
+
510
+
492
511
  def _get_session_project_path(session: str) -> Path | None:
493
512
  """Get a session's project path from tmux cwd, falling back to session name parsing."""
494
- if tmux_session_exists(session):
495
- result = subprocess.run(
496
- ["tmux", "display-message", "-t", session, "-p", "#{pane_current_path}"],
497
- capture_output=True,
498
- text=True,
499
- )
500
- if result.returncode == 0 and result.stdout.strip():
501
- return Path(result.stdout.strip())
513
+ live = _live_session_cwd(session)
514
+ if live is not None:
515
+ return live
502
516
 
503
517
  # Fallback: derive from session name
504
518
  config = load_config()
@@ -507,6 +521,41 @@ def _get_session_project_path(session: str) -> Path | None:
507
521
  return projects_dir / project
508
522
 
509
523
 
524
+ def _same_project(path_a: Path, path_b: Path) -> bool:
525
+ """True when two paths belong to the same git repo (shared .git dir
526
+ across linked worktrees) or, outside a repo, are the same resolved path."""
527
+ common_a = git_common_dir(path_a)
528
+ if common_a is None:
529
+ return path_a.resolve() == path_b.resolve()
530
+ common_b = git_common_dir(path_b)
531
+ if common_b is None:
532
+ return path_a.resolve() == path_b.resolve()
533
+ return common_a == common_b
534
+
535
+
536
+ def resolve_default_created_by(caller: str | None, target_path: Path) -> str | None:
537
+ """The default ``created_by`` when none was explicitly given.
538
+
539
+ Inherit the caller only when the new session's project is the one the
540
+ caller is already running in — a cross-project spawn gets its own root
541
+ instead of flattening into the caller's subtree (#715). An explicit
542
+ --created-by always wins and never reaches this function.
543
+
544
+ Uses ``_live_session_cwd`` rather than ``_get_session_project_path`` —
545
+ the latter's session-name-guessing fallback isn't a safe basis for an
546
+ identity comparison (it doesn't understand the worktree naming scheme,
547
+ `{project}-{name}`, and would misjudge same/cross-project); if the
548
+ caller's real cwd can't be confirmed, treat it as unknown (no inheritance)
549
+ rather than risk a wrong guess.
550
+ """
551
+ if not caller:
552
+ return None
553
+ caller_path = _live_session_cwd(caller)
554
+ if caller_path is None:
555
+ return None
556
+ return caller if _same_project(caller_path, target_path) else None
557
+
558
+
510
559
  def tmux_session_has_agent(name: str) -> bool:
511
560
  """Check if a tmux session has an agent running (not just a bare shell).
512
561
 
@@ -1135,14 +1184,20 @@ def _post_desktop_notification(text: str, session: str | None = None, priority:
1135
1184
  return False
1136
1185
 
1137
1186
 
1138
- KIND_DEFAULT_POSTURE = {
1139
- "orchestrator": "bypass", # agentwire new you drive it, full access
1140
- "worktree-session": "bypass", # agentwire worktree — autonomous, full access
1141
- "worker": "restricted", # agentwire spawn locked-down executor
1142
- }
1187
+ def _default_posture(kind: str | None, worktree_topology: bool = False) -> str:
1188
+ """Default posture for a spawn: bypass, unless it's a worker that is NOT
1189
+ isolated on its own worktree — a pane (agentwire spawn) or a worker on
1190
+ plain main topology, both sharing a live checkout someone else may be
1191
+ watching, stay restricted. Orchestrators (main or worktree topology) and
1192
+ worktree-topology workers get full autonomous access — nothing to step
1193
+ on but their own isolated branch.
1194
+ """
1195
+ if kind == "worker" and not worktree_topology:
1196
+ return "restricted"
1197
+ return "bypass"
1143
1198
 
1144
1199
 
1145
- def _resolve_session_type_from_args(args, kind: str) -> tuple[str | None, str | None]:
1200
+ def _resolve_session_type_from_args(args, kind: str, worktree_topology: bool = False) -> tuple[str | None, str | None]:
1146
1201
  """Resolve the internal fused session type from the shared flag core.
1147
1202
 
1148
1203
  Posture × harness are the canonical axes; legacy --type (fused strings or
@@ -1158,7 +1213,7 @@ def _resolve_session_type_from_args(args, kind: str) -> tuple[str | None, str |
1158
1213
  posture = getattr(args, 'posture', None)
1159
1214
  harness = getattr(args, 'harness', None)
1160
1215
  type_arg = getattr(args, 'type', None)
1161
- default_posture = KIND_DEFAULT_POSTURE.get(kind, "bypass")
1216
+ default_posture = _default_posture(kind, worktree_topology)
1162
1217
 
1163
1218
  if posture or harness:
1164
1219
  try:
@@ -29,7 +29,7 @@ Output shape (``--json``)::
29
29
 
30
30
  Base resolution (no ``--base``): if the worktree has uncommitted changes the
31
31
  diff is vs ``HEAD`` (what the agent just did, not yet committed); otherwise it
32
- is vs ``origin/main`` (a worktree-session's committed branch work). The portal
32
+ is vs ``origin/main`` (a worktree session's committed branch work). The portal
33
33
  relies on this so a phone review needs zero flags.
34
34
  """
35
35
 
@@ -2,8 +2,9 @@
2
2
 
3
3
  ``doctor`` walks the full install (Python/deps, hooks, skills, damage control,
4
4
  source-checkout drift, services, config, SSH/tunnels, voice loop, secrets,
5
- remote machines, dead-lettered messages) and optionally auto-fixes the local
6
- ones. ``network status`` is the read-only network-health glance.
5
+ remote machines, dead-lettered messages, dangling worktree sessions) and
6
+ optionally auto-fixes the local ones. ``network status`` is the read-only
7
+ network-health glance.
7
8
 
8
9
  The hook/skill drift helpers (``get_hooks_source``, ``_managed_hook_files``,
9
10
  ``_managed_file_state``, ``skill_drift``, ``CLAUDE_SKILLS_DIR``) are owned by
@@ -869,6 +870,26 @@ def cmd_doctor(args) -> int:
869
870
  except Exception as e:
870
871
  print(f" [..] Could not check dead-lettered messages: {e}")
871
872
 
873
+ # 11. Check for dangling worktree sessions (live, open PR, no live parent
874
+ # to review/merge it — #716's concrete failure mode: a rootless-but-
875
+ # still-subordinate session that correctly refuses to self-merge).
876
+ print("\nChecking for dangling worktree sessions...")
877
+ try:
878
+ from . import worktree_registry
879
+ from .session_cli import scan_dangling_worktrees
880
+
881
+ dangling = scan_dangling_worktrees(worktree_registry.all_entries())
882
+ if not dangling:
883
+ print(" [ok] No dangling worktree sessions found")
884
+ else:
885
+ issues_found += 1
886
+ print(f" [!!] {len(dangling)} live worktree session(s) with an open PR and no live parent:")
887
+ for d in dangling:
888
+ print(f" - {d['session']} branch={d['branch']} {d.get('pr_url', '')} ({d['reason']})")
889
+ print(" Assign a parent (agentwire msg send / --created-by) or merge/close the PR yourself.")
890
+ except Exception as e:
891
+ print(f" [..] Could not check for dangling worktree sessions: {e}")
892
+
872
893
  # Summary
873
894
  print()
874
895
  print("-" * 60)
@@ -492,6 +492,16 @@ def _run_ensure_task(args, session, task, ctx, shell, project_path, json_mode) -
492
492
  self.roles = task_role if task_role else None
493
493
  self.model = None
494
494
  self.json = json_mode
495
+ # Force the pre-#715 unconditional-inherit behavior:
496
+ # ensure is the scheduler's dispatch primitive — the
497
+ # scheduler daemon fans out across many projects from
498
+ # one fixed tmux session by design, so #715's
499
+ # same-project default (meant for an interactive
500
+ # session's own cross-project spawns) would wrongly
501
+ # drop the parent link for nearly every dispatched
502
+ # task. Always parent to whichever session is
503
+ # actually running this ensure call.
504
+ self.created_by = pane_manager.get_current_session()
495
505
 
496
506
  from . import session_cli
497
507
  result = session_cli.cmd_new(NewArgs(task.role))
@@ -739,7 +749,7 @@ def cmd_task_list(args) -> int:
739
749
  return 0
740
750
 
741
751
  if not tasks:
742
- print(f"No tasks defined in {project_path / '.agentwire.yml'}")
752
+ print(f"No tasks defined in {project_path / '.agentwire.tasks.yml'}")
743
753
  return 0
744
754
 
745
755
  print(f"Tasks in {project_path.name}:\n")
@@ -766,12 +766,16 @@ PROTECTED_CONTROL_PLANE_PATHS = [
766
766
  # confused-deputy escape). Treat them as control plane (#466 lockdown).
767
767
  "~/.agentwire/scheduler.yaml", # scheduler gate commands run via shell
768
768
  "~/.agentwire/config.yaml", # service healthcheck commands run via shell
769
- # Per-project task config: ``.agentwire.yml`` also defines task pre/post/gate
770
- # commands. Protecting it closes the same escape, with an ergonomic tradeoff —
771
- # under worktree dispatch the agent can no longer author its own task config,
772
- # so task authoring becomes a host-side act (consistent with the control-plane
773
- # guarantee: loosening is always host-side).
774
- "*.agentwire.yml", # project session/task config (any dir)
769
+ # Per-project task-EXECUTION config (#720): split out of ``.agentwire.yml``,
770
+ # which is now purely declarative (type/roles/voice/parent/worktree) and
771
+ # agent-writable again it carries no exec vector. ``.agentwire.tasks.yml``
772
+ # holds the ``tasks:`` block (pre/post/on_task_end/shell/unattended_allow),
773
+ # which agentwire runs the same way (confused-deputy risk above), so it
774
+ # stays protected. Authored via propose-and-promote: an agent drafts to the
775
+ # UNPROTECTED ``.agentwire.tasks.proposed.yml`` staging file; a human reviews
776
+ # (``agentwire tasks review``) and promotes (``agentwire tasks promote``) —
777
+ # the agent never writes the live file. See ``agentwire/tasks_cli.py``.
778
+ "*.agentwire.tasks.yml", # project task-execution config (any dir)
775
779
  ]
776
780
 
777
781
 
@@ -791,12 +795,33 @@ def _protected_path_patterns() -> List[str]:
791
795
  return out
792
796
 
793
797
 
794
- def is_protected_control_plane(file_path: str) -> bool:
795
- """True if ``file_path`` is part of the damage-control control plane."""
798
+ def _matched_protected_pattern(file_path: str) -> Optional[str]:
799
+ """The protected-path pattern that matches ``file_path``, if any."""
796
800
  for pat in _protected_path_patterns():
797
801
  if match_path(file_path, pat):
798
- return True
799
- return False
802
+ return pat
803
+ return None
804
+
805
+
806
+ def is_protected_control_plane(file_path: str) -> bool:
807
+ """True if ``file_path`` is part of the damage-control control plane."""
808
+ return _matched_protected_pattern(file_path) is not None
809
+
810
+
811
+ def _protected_reason(matched_pattern: str) -> str:
812
+ """Block reason for a protected-control-plane hit, tailored to the path.
813
+
814
+ ``.agentwire.tasks.yml`` has a real, host-side remedy (propose-and-promote,
815
+ #720) — name it so the agent doesn't dead-end. Everything else keeps the
816
+ generic "edit on the host" message.
817
+ """
818
+ if matched_pattern.endswith(".agentwire.tasks.yml"):
819
+ return (
820
+ "protected task-execution control-plane file (host-owned) — draft "
821
+ "to .agentwire.tasks.proposed.yml instead, then ask the host to run "
822
+ "`agentwire tasks review` and `agentwire tasks promote`"
823
+ )
824
+ return "protected control-plane file (host-owned; edit on the host)"
800
825
 
801
826
 
802
827
  def check_protected_path(
@@ -808,10 +833,11 @@ def check_protected_path(
808
833
  Used by the edit/write hooks. The allowlist (a human opt-in) may override;
809
834
  nothing else does.
810
835
  """
811
- if is_protected_control_plane(file_path):
836
+ matched = _matched_protected_pattern(file_path)
837
+ if matched:
812
838
  if is_path_allowed_for_op(file_path, allowed_paths, "edit"):
813
839
  return False, ""
814
- return True, "protected control-plane file (host-owned; edit on the host)"
840
+ return True, _protected_reason(matched)
815
841
  return False, ""
816
842
 
817
843
 
@@ -841,7 +867,58 @@ def check_protected_command(
841
867
  op = _infer_operation_from_reason(reason)
842
868
  if is_command_path_allowed(command, allowed_paths, op):
843
869
  break
844
- return True, f"Protected control-plane path: {path}"
870
+ return True, _protected_reason(path)
871
+ return False, ""
872
+
873
+
874
+ # ============================================================================
875
+ # PROTECTED COMMANDS (escape-hatch- AND kill-switch-EXEMPT, like the protected
876
+ # control plane above, but keyed on COMMAND SHAPE rather than a file path)
877
+ # ============================================================================
878
+ #
879
+ # Some operations are dangerous no matter which file they touch — running
880
+ # them at all IS the confused-deputy escape, not merely writing a particular
881
+ # path. ``agentwire tasks promote`` is the first case (#720/#721 review):
882
+ # it's the host-trusted program that copies a vetted draft into the protected
883
+ # ``.agentwire.tasks.yml``. If a policed/unattended agent could just invoke
884
+ # the CLI itself, the file protection above is moot — so this, like the
885
+ # protected-path check, is evaluated before ``detect_escape_hatch`` and the
886
+ # kill switch, and has NO allowlist override (there's no legitimate reason
887
+ # for an agent to ever run this; unlike a path, there's nothing to allowlist
888
+ # it TO). This is defense in depth on TOP OF ``cmd_tasks_promote``'s own
889
+ # runtime refusal (unattended check + host-context gate in ``tasks_cli.py``)
890
+ # — that second gate is what actually closes the ``python3 -c
891
+ # "from agentwire.tasks_cli import cmd_tasks_promote; ..."`` bypass, since a
892
+ # raw interpreter call never matches a bash command pattern at all.
893
+
894
+ PROTECTED_COMMAND_PATTERNS: List[Tuple[str, str]] = [
895
+ (
896
+ r'\bagentwire\s+tasks\s+promote\b',
897
+ "agentwire tasks promote writes the protected .agentwire.tasks.yml — "
898
+ "host-only, run it from your own terminal (not through an agent).",
899
+ ),
900
+ ]
901
+
902
+
903
+ def check_protected_bash_command(command: str) -> Tuple[bool, str]:
904
+ """Block a command matching a ``PROTECTED_COMMAND_PATTERNS`` entry.
905
+
906
+ Unconditional — no allowlist override, no escape hatch, no kill switch
907
+ (see module note above). These are COMMAND-PREFIX patterns, so — like the
908
+ ``anchored`` tooldef bashToolPatterns (#675) — matched only against
909
+ ``masked_subcommands``: quoting/escaping of the command itself still
910
+ normalizes to the literal form (``agentwire tasks prom''ote`` can't sneak
911
+ past), but quoted CONTENT (a commit message, an echo string) that merely
912
+ *mentions* the phrase is masked out first, so it can't false-match.
913
+ """
914
+ haystacks = masked_subcommands(command)
915
+ for pattern, reason in PROTECTED_COMMAND_PATTERNS:
916
+ for hay in haystacks:
917
+ try:
918
+ if re.search(pattern, hay, re.IGNORECASE):
919
+ return True, reason
920
+ except re.error:
921
+ continue
845
922
  return False, ""
846
923
 
847
924
 
@@ -1121,6 +1198,8 @@ def check_command(command: str, config: Dict[str, Any]) -> Dict[str, Any]:
1121
1198
  0. Protected control plane → BLOCK (escape-hatch- AND kill-switch-exempt;
1122
1199
  only the user's allowlist re-permits) — runs FIRST so an agent can't
1123
1200
  self-authorize a write to the files that gate everything else.
1201
+ 0.5. Protected commands → BLOCK (same exemption, no allowlist override —
1202
+ a command whose mere invocation is the escape, not a path it touches).
1124
1203
  1. Escape hatch (``# allow: <reason>``) → ALLOW (escape=True)
1125
1204
  2. Kill switch (``config["safety"]["enabled"] is False``) → ALLOW (disabled=True)
1126
1205
  3. Hard-blocked bash patterns (skip if ``id`` in ``disabled_rules``)
@@ -1149,6 +1228,19 @@ def check_command(command: str, config: Dict[str, Any]) -> Dict[str, Any]:
1149
1228
  "protected": True,
1150
1229
  }
1151
1230
 
1231
+ # Protected COMMANDS — same tier, same reason (an agent-invoked
1232
+ # `agentwire tasks promote` is the confused-deputy escape itself, not a
1233
+ # path it happens to touch).
1234
+ cmd_blocked, cmd_reason = check_protected_bash_command(command)
1235
+ if cmd_blocked:
1236
+ return {
1237
+ "decision": "block",
1238
+ "reason": cmd_reason,
1239
+ "pattern": "protectedCommand",
1240
+ "command": command,
1241
+ "protected": True,
1242
+ }
1243
+
1152
1244
  # Parser unavailable ⇒ no rules loaded ⇒ fail closed (block), before the
1153
1245
  # escape hatch / kill switch can wave it through.
1154
1246
  if config.get("_parser_unavailable"):