agentwire-dev 1.46.0__tar.gz → 1.48.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 (550) hide show
  1. agentwire_dev-1.48.0/.claude/commands/handoff.md +142 -0
  2. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/.gitignore +3 -0
  3. agentwire_dev-1.48.0/AGENTS.md +5 -0
  4. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/CONTRIBUTING.md +4 -2
  5. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/PKG-INFO +5 -6
  6. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/README.md +4 -4
  7. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/RELEASING.md +5 -2
  8. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/__init__.py +1 -1
  9. agentwire_dev-1.48.0/agentwire/__main__.py +391 -0
  10. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/agents/base.py +0 -27
  11. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/agents/tmux.py +0 -141
  12. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/channels/email.py +1 -1
  13. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/channels/quo.py +3 -3
  14. agentwire_dev-1.48.0/agentwire/channels_cli.py +553 -0
  15. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/completion.py +4 -17
  16. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/config.py +2 -3
  17. agentwire_dev-1.48.0/agentwire/core.py +1162 -0
  18. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/council/cli.py +0 -54
  19. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/diff_cli.py +1 -1
  20. agentwire_dev-1.48.0/agentwire/doctor_cli.py +914 -0
  21. agentwire_dev-1.48.0/agentwire/ensure_cli.py +1068 -0
  22. agentwire_dev-1.48.0/agentwire/handoff_cli.py +378 -0
  23. agentwire_dev-1.48.0/agentwire/history_cli.py +361 -0
  24. agentwire_dev-1.48.0/agentwire/hooks_cli.py +618 -0
  25. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/inbox.py +119 -8
  26. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/limits_cli.py +53 -0
  27. agentwire_dev-1.48.0/agentwire/machine_cli.py +235 -0
  28. agentwire_dev-1.48.0/agentwire/mcp_channels.py +88 -0
  29. agentwire_dev-1.48.0/agentwire/mcp_cli.py +27 -0
  30. agentwire_dev-1.48.0/agentwire/mcp_core.py +288 -0
  31. agentwire_dev-1.48.0/agentwire/mcp_council.py +193 -0
  32. agentwire_dev-1.48.0/agentwire/mcp_desktop.py +296 -0
  33. agentwire_dev-1.48.0/agentwire/mcp_handoff.py +95 -0
  34. agentwire_dev-1.48.0/agentwire/mcp_history.py +94 -0
  35. agentwire_dev-1.48.0/agentwire/mcp_listen.py +51 -0
  36. agentwire_dev-1.48.0/agentwire/mcp_lock.py +64 -0
  37. agentwire_dev-1.48.0/agentwire/mcp_machine.py +62 -0
  38. agentwire_dev-1.48.0/agentwire/mcp_msg.py +219 -0
  39. agentwire_dev-1.48.0/agentwire/mcp_notify.py +98 -0
  40. agentwire_dev-1.48.0/agentwire/mcp_pane.py +232 -0
  41. agentwire_dev-1.48.0/agentwire/mcp_projects.py +69 -0
  42. agentwire_dev-1.48.0/agentwire/mcp_scheduler.py +281 -0
  43. agentwire_dev-1.48.0/agentwire/mcp_scratchpad.py +50 -0
  44. agentwire_dev-1.48.0/agentwire/mcp_server.py +51 -0
  45. agentwire_dev-1.48.0/agentwire/mcp_services.py +69 -0
  46. agentwire_dev-1.48.0/agentwire/mcp_session.py +342 -0
  47. agentwire_dev-1.48.0/agentwire/mcp_status.py +92 -0
  48. agentwire_dev-1.48.0/agentwire/mcp_task.py +163 -0
  49. agentwire_dev-1.48.0/agentwire/mcp_tunnels.py +48 -0
  50. agentwire_dev-1.48.0/agentwire/mcp_voice.py +197 -0
  51. agentwire_dev-1.48.0/agentwire/mcp_voiceclone.py +81 -0
  52. agentwire_dev-1.48.0/agentwire/mcp_wiki.py +85 -0
  53. agentwire_dev-1.48.0/agentwire/mcp_worktree.py +202 -0
  54. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/msg_cli.py +59 -4
  55. agentwire_dev-1.48.0/agentwire/notify_cli.py +290 -0
  56. agentwire_dev-1.48.0/agentwire/pane_cli.py +1150 -0
  57. agentwire_dev-1.48.0/agentwire/portal_cli.py +557 -0
  58. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/prompt_router.py +22 -9
  59. agentwire_dev-1.48.0/agentwire/push_cli.py +20 -0
  60. agentwire_dev-1.48.0/agentwire/repo_cli.py +159 -0
  61. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/init.md +1 -1
  62. agentwire_dev-1.48.0/agentwire/roles_cli.py +304 -0
  63. agentwire_dev-1.48.0/agentwire/routes/__init__.py +22 -0
  64. agentwire_dev-1.48.0/agentwire/routes/artifacts.py +120 -0
  65. agentwire_dev-1.48.0/agentwire/routes/config.py +159 -0
  66. agentwire_dev-1.48.0/agentwire/routes/council.py +318 -0
  67. agentwire_dev-1.48.0/agentwire/routes/desktop.py +238 -0
  68. agentwire_dev-1.48.0/agentwire/routes/history.py +145 -0
  69. agentwire_dev-1.48.0/agentwire/routes/machines.py +330 -0
  70. agentwire_dev-1.48.0/agentwire/routes/notify.py +169 -0
  71. agentwire_dev-1.48.0/agentwire/routes/permission.py +379 -0
  72. agentwire_dev-1.48.0/agentwire/routes/projects.py +394 -0
  73. agentwire_dev-1.48.0/agentwire/routes/push.py +60 -0
  74. agentwire_dev-1.48.0/agentwire/routes/safety.py +117 -0
  75. agentwire_dev-1.48.0/agentwire/routes/scheduler.py +189 -0
  76. agentwire_dev-1.48.0/agentwire/routes/scratchpad.py +71 -0
  77. agentwire_dev-1.48.0/agentwire/routes/sessions.py +160 -0
  78. agentwire_dev-1.48.0/agentwire/routes/sessions_admin.py +609 -0
  79. agentwire_dev-1.48.0/agentwire/routes/voice.py +400 -0
  80. agentwire_dev-1.48.0/agentwire/safety_cli.py +131 -0
  81. agentwire_dev-1.46.0/agentwire/cli_safety.py → agentwire_dev-1.48.0/agentwire/safety_commands.py +17 -11
  82. agentwire_dev-1.48.0/agentwire/scheduler_cli.py +995 -0
  83. agentwire_dev-1.48.0/agentwire/send_cli.py +323 -0
  84. agentwire_dev-1.48.0/agentwire/server.py +2871 -0
  85. agentwire_dev-1.48.0/agentwire/session_cli.py +1750 -0
  86. agentwire_dev-1.48.0/agentwire/session_ready.py +312 -0
  87. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/css/desktop.css +0 -148
  88. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/icon-manager.js +0 -2
  89. agentwire_dev-1.48.0/agentwire/system_cli.py +708 -0
  90. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tts/base.py +1 -1
  91. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tts/engines/__init__.py +1 -4
  92. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tts/registry.py +1 -1
  93. agentwire_dev-1.48.0/agentwire/tts_cli.py +1055 -0
  94. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tts_server.py +3 -32
  95. agentwire_dev-1.48.0/agentwire/tunnels_cli.py +253 -0
  96. agentwire_dev-1.48.0/agentwire/wiki_cli.py +139 -0
  97. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/decisions/obsidian-second-brain.md +2 -0
  98. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/INDEX.md +5 -1
  99. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/briefing-mode.md +1 -1
  100. agentwire_dev-1.48.0/docs/wiki/internals/parallel-refactor.md +117 -0
  101. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/internals/portal.md +1 -1
  102. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/internals/troubleshooting.md +1 -1
  103. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/sessions/messaging.md +33 -0
  104. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/sessions/worktree-sessions.md +1 -1
  105. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/voice/shim-contract.md +3 -3
  106. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/voice/tts-self-hosted.md +3 -20
  107. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/pyproject.toml +38 -19
  108. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/integration/test_worktree_cmd.py +28 -2
  109. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_build_agent_command.py +7 -7
  110. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_channels.py +0 -9
  111. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_cli_commands.py +27 -26
  112. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_config.py +0 -16
  113. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_control_plane_protection.py +1 -1
  114. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_council_cli.py +0 -19
  115. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_damage_control_bypass.py +1 -1
  116. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_hooks_install.py +3 -3
  117. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_inbox.py +161 -0
  118. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_init_command.py +3 -3
  119. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_mcp_server.py +44 -44
  120. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_mcp_tools_args.py +74 -74
  121. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_msg_cli.py +44 -1
  122. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_portal_api.py +6 -8
  123. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_prompt_router.py +3 -3
  124. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_rebuild_guard.py +5 -4
  125. agentwire_dev-1.48.0/tests/unit/test_repo_cli.py +115 -0
  126. agentwire_dev-1.48.0/tests/unit/test_routes_snapshot.py +205 -0
  127. agentwire_dev-1.46.0/tests/unit/test_cli_safety.py → agentwire_dev-1.48.0/tests/unit/test_safety_commands.py +22 -22
  128. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_safety_disabled_rules.py +1 -1
  129. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_safety_escape_hatch.py +1 -1
  130. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_safety_heal.py +59 -45
  131. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_safety_kill_switch.py +1 -1
  132. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_scratchpad.py +6 -6
  133. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_services.py +1 -1
  134. agentwire_dev-1.48.0/tests/unit/test_session_ready.py +305 -0
  135. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_skill_install.py +4 -4
  136. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_task_cli.py +1 -1
  137. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_tts_engine_resolution.py +4 -4
  138. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_tts_local.py +10 -10
  139. agentwire_dev-1.46.0/.agents/skills/agentwire-cli/SKILL.md +0 -260
  140. agentwire_dev-1.46.0/.agents/skills/agentwire-config/SKILL.md +0 -236
  141. agentwire_dev-1.46.0/.agents/skills/agentwire-desktop-ui/SKILL.md +0 -76
  142. agentwire_dev-1.46.0/.agents/skills/agentwire-mcp-tools/SKILL.md +0 -176
  143. agentwire_dev-1.46.0/.agents/skills/agentwire-pi/SKILL.md +0 -205
  144. agentwire_dev-1.46.0/.agents/skills/agentwire-project-config/SKILL.md +0 -195
  145. agentwire_dev-1.46.0/.agents/skills/agentwire-scheduler/SKILL.md +0 -133
  146. agentwire_dev-1.46.0/.agents/skills/wiki/SKILL.md +0 -105
  147. agentwire_dev-1.46.0/AGENTS.md +0 -155
  148. agentwire_dev-1.46.0/Dockerfile.runpod +0 -60
  149. agentwire_dev-1.46.0/agentwire/__main__.py +0 -12854
  150. agentwire_dev-1.46.0/agentwire/mcp_server.py +0 -3454
  151. agentwire_dev-1.46.0/agentwire/prompts/__init__.py +0 -1
  152. agentwire_dev-1.46.0/agentwire/prompts/init.md +0 -155
  153. agentwire_dev-1.46.0/agentwire/server.py +0 -6383
  154. agentwire_dev-1.46.0/agentwire/session_ready.py +0 -226
  155. agentwire_dev-1.46.0/agentwire/static/agentwire-Echo--black.png +0 -0
  156. agentwire_dev-1.46.0/agentwire/static/agentwire-Echo--transparent.png +0 -0
  157. agentwire_dev-1.46.0/agentwire/static/agentwire-Echo.png +0 -0
  158. agentwire_dev-1.46.0/agentwire/static/agentwire-email-banner.png +0 -0
  159. agentwire_dev-1.46.0/agentwire/static/agentwire-splash-logo-layers--full--transparent-top.png +0 -0
  160. agentwire_dev-1.46.0/agentwire/static/agentwire-splash-logo-layers--full-black.png +0 -0
  161. agentwire_dev-1.46.0/agentwire/static/agentwire-splash-logo-layers--telephone-fg.png +0 -0
  162. agentwire_dev-1.46.0/agentwire/static/agentwire-splash-logo-layers--transparent-top.png +0 -0
  163. agentwire_dev-1.46.0/agentwire/static/agentwire-splash-logo-layers--transparent.png +0 -0
  164. agentwire_dev-1.46.0/agentwire/static/agentwire-splash-logo-layers.png +0 -0
  165. agentwire_dev-1.46.0/agentwire/static/icons/machines/android.jpeg +0 -0
  166. agentwire_dev-1.46.0/agentwire/static/icons/machines/android.webp +0 -0
  167. agentwire_dev-1.46.0/agentwire/static/icons/machines/automaton.jpeg +0 -0
  168. agentwire_dev-1.46.0/agentwire/static/icons/machines/automaton.webp +0 -0
  169. agentwire_dev-1.46.0/agentwire/static/icons/machines/bot.jpeg +0 -0
  170. agentwire_dev-1.46.0/agentwire/static/icons/machines/bot.webp +0 -0
  171. agentwire_dev-1.46.0/agentwire/static/icons/machines/cyborg.jpeg +0 -0
  172. agentwire_dev-1.46.0/agentwire/static/icons/machines/cyborg.webp +0 -0
  173. agentwire_dev-1.46.0/agentwire/static/icons/machines/droid.jpeg +0 -0
  174. agentwire_dev-1.46.0/agentwire/static/icons/machines/droid.webp +0 -0
  175. agentwire_dev-1.46.0/agentwire/static/icons/machines/drone.jpeg +0 -0
  176. agentwire_dev-1.46.0/agentwire/static/icons/machines/drone.webp +0 -0
  177. agentwire_dev-1.46.0/agentwire/static/icons/machines/guardian.jpeg +0 -0
  178. agentwire_dev-1.46.0/agentwire/static/icons/machines/guardian.webp +0 -0
  179. agentwire_dev-1.46.0/agentwire/static/icons/machines/mech.jpeg +0 -0
  180. agentwire_dev-1.46.0/agentwire/static/icons/machines/mech.webp +0 -0
  181. agentwire_dev-1.46.0/agentwire/static/icons/machines/probe.jpeg +0 -0
  182. agentwire_dev-1.46.0/agentwire/static/icons/machines/probe.webp +0 -0
  183. agentwire_dev-1.46.0/agentwire/static/icons/machines/robot.jpeg +0 -0
  184. agentwire_dev-1.46.0/agentwire/static/icons/machines/robot.webp +0 -0
  185. agentwire_dev-1.46.0/agentwire/static/icons/machines/sentinel.jpeg +0 -0
  186. agentwire_dev-1.46.0/agentwire/static/icons/machines/sentinel.webp +0 -0
  187. agentwire_dev-1.46.0/agentwire/static/icons/machines/unit.jpeg +0 -0
  188. agentwire_dev-1.46.0/agentwire/static/icons/machines/unit.webp +0 -0
  189. agentwire_dev-1.46.0/agentwire/static/icons/projects/blob.jpeg +0 -0
  190. agentwire_dev-1.46.0/agentwire/static/icons/projects/blob.webp +0 -0
  191. agentwire_dev-1.46.0/agentwire/static/icons/projects/cloud.jpeg +0 -0
  192. agentwire_dev-1.46.0/agentwire/static/icons/projects/cloud.webp +0 -0
  193. agentwire_dev-1.46.0/agentwire/static/icons/projects/crystal.jpeg +0 -0
  194. agentwire_dev-1.46.0/agentwire/static/icons/projects/crystal.webp +0 -0
  195. agentwire_dev-1.46.0/agentwire/static/icons/projects/cyclops.jpeg +0 -0
  196. agentwire_dev-1.46.0/agentwire/static/icons/projects/cyclops.webp +0 -0
  197. agentwire_dev-1.46.0/agentwire/static/icons/projects/flame.jpeg +0 -0
  198. agentwire_dev-1.46.0/agentwire/static/icons/projects/flame.webp +0 -0
  199. agentwire_dev-1.46.0/agentwire/static/icons/projects/fuzzy.jpeg +0 -0
  200. agentwire_dev-1.46.0/agentwire/static/icons/projects/fuzzy.webp +0 -0
  201. agentwire_dev-1.46.0/agentwire/static/icons/projects/horned.jpeg +0 -0
  202. agentwire_dev-1.46.0/agentwire/static/icons/projects/horned.webp +0 -0
  203. agentwire_dev-1.46.0/agentwire/static/icons/projects/moon.jpeg +0 -0
  204. agentwire_dev-1.46.0/agentwire/static/icons/projects/moon.webp +0 -0
  205. agentwire_dev-1.46.0/agentwire/static/icons/projects/slime.jpeg +0 -0
  206. agentwire_dev-1.46.0/agentwire/static/icons/projects/slime.webp +0 -0
  207. agentwire_dev-1.46.0/agentwire/static/icons/projects/star.jpeg +0 -0
  208. agentwire_dev-1.46.0/agentwire/static/icons/projects/star.webp +0 -0
  209. agentwire_dev-1.46.0/agentwire/static/icons/projects/tentacle.jpeg +0 -0
  210. agentwire_dev-1.46.0/agentwire/static/icons/projects/tentacle.webp +0 -0
  211. agentwire_dev-1.46.0/agentwire/static/icons/projects/winged.jpeg +0 -0
  212. agentwire_dev-1.46.0/agentwire/static/icons/projects/winged.webp +0 -0
  213. agentwire_dev-1.46.0/agentwire/static/icons/sessions/bear.jpeg +0 -0
  214. agentwire_dev-1.46.0/agentwire/static/icons/sessions/cat.jpeg +0 -0
  215. agentwire_dev-1.46.0/agentwire/static/icons/sessions/crown.jpeg +0 -0
  216. agentwire_dev-1.46.0/agentwire/static/icons/sessions/custom/agentwire-portal.png +0 -0
  217. agentwire_dev-1.46.0/agentwire/static/icons/sessions/custom/agentwire-tts.png +0 -0
  218. agentwire_dev-1.46.0/agentwire/static/icons/sessions/custom/agentwire.png +0 -0
  219. agentwire_dev-1.46.0/agentwire/static/icons/sessions/deer.jpeg +0 -0
  220. agentwire_dev-1.46.0/agentwire/static/icons/sessions/drone.jpeg +0 -0
  221. agentwire_dev-1.46.0/agentwire/static/icons/sessions/eagle.jpeg +0 -0
  222. agentwire_dev-1.46.0/agentwire/static/icons/sessions/fox.jpeg +0 -0
  223. agentwire_dev-1.46.0/agentwire/static/icons/sessions/hawk.jpeg +0 -0
  224. agentwire_dev-1.46.0/agentwire/static/icons/sessions/horse.jpeg +0 -0
  225. agentwire_dev-1.46.0/agentwire/static/icons/sessions/lion.jpeg +0 -0
  226. agentwire_dev-1.46.0/agentwire/static/icons/sessions/rabbit.jpeg +0 -0
  227. agentwire_dev-1.46.0/agentwire/static/icons/sessions/robot.jpeg +0 -0
  228. agentwire_dev-1.46.0/agentwire/static/icons/sessions/tiger.jpeg +0 -0
  229. agentwire_dev-1.46.0/agentwire/static/icons/sessions/wolf.jpeg +0 -0
  230. agentwire_dev-1.46.0/agentwire/static/js/components/icon-picker.js +0 -136
  231. agentwire_dev-1.46.0/agentwire/static/js/components/list-card.js +0 -156
  232. agentwire_dev-1.46.0/agentwire/static/js/components/type-tag.js +0 -45
  233. agentwire_dev-1.46.0/agentwire/static/js/utils/auto-refresh.js +0 -66
  234. agentwire_dev-1.46.0/agentwire/tts/engines/qwen_base.py +0 -192
  235. agentwire_dev-1.46.0/agentwire/tts/engines/qwen_custom.py +0 -189
  236. agentwire_dev-1.46.0/agentwire/tts/engines/qwen_design.py +0 -170
  237. agentwire_dev-1.46.0/requirements-tts.txt +0 -24
  238. agentwire_dev-1.46.0/tests/unit/test_session_ready.py +0 -244
  239. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/.claude/skills/wiki/SKILL.md +0 -0
  240. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/.github/FUNDING.yml +0 -0
  241. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  242. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  243. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
  244. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  245. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/.github/workflows/pytest.yml +0 -0
  246. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/.github/workflows/ruff.yml +0 -0
  247. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/.github/workflows/security.yml +0 -0
  248. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/.github/workflows/tts-smoke.yml +0 -0
  249. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/CODE_OF_CONDUCT.md +0 -0
  250. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/Dockerfile.local +0 -0
  251. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/LICENSE +0 -0
  252. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/SECURITY.md +0 -0
  253. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/SPONSORS.md +0 -0
  254. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/agents/__init__.py +0 -0
  255. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/cached_status.py +0 -0
  256. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/channels/__init__.py +0 -0
  257. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/channels/base.py +0 -0
  258. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/channels/push.py +0 -0
  259. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/council/__init__.py +0 -0
  260. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/council/inbox.py +0 -0
  261. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/council/state.py +0 -0
  262. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/council/view.py +0 -0
  263. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/devices.py +0 -0
  264. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/doctor_voice.py +0 -0
  265. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/fetch.py +0 -0
  266. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/handoff/__init__.py +0 -0
  267. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/handoff/git_state.py +0 -0
  268. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/handoff/instructions.py +0 -0
  269. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/handoff/parser.py +0 -0
  270. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/handoff/renderer.py +0 -0
  271. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/handoff/schema.py +0 -0
  272. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/history.py +0 -0
  273. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/__init__.py +0 -0
  274. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/agentwire-permission.sh +0 -0
  275. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/__init__.py +0 -0
  276. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/audit_logger.py +0 -0
  277. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/bash-tool-damage-control.py +0 -0
  278. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/edit-tool-damage-control.py +0 -0
  279. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/mcp-tool-damage-control.py +0 -0
  280. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/read-tool-damage-control.py +0 -0
  281. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/rules/agentwire.yaml +0 -0
  282. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/rules/aws.yaml +0 -0
  283. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/rules/cloud-hosting.yaml +0 -0
  284. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/rules/containers.yaml +0 -0
  285. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/rules/control-plane.yaml +0 -0
  286. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/rules/core.yaml +0 -0
  287. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/rules/databases.yaml +0 -0
  288. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/rules/firebase.yaml +0 -0
  289. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/rules/gcp.yaml +0 -0
  290. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/rules/git.yaml +0 -0
  291. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/rules/gws.yaml +0 -0
  292. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/rules/infrastructure.yaml +0 -0
  293. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/rules/outbound.yaml +0 -0
  294. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/rules/publish.yaml +0 -0
  295. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/rules/remote.yaml +0 -0
  296. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/damage-control/write-tool-damage-control.py +0 -0
  297. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/idle-handler.sh +0 -0
  298. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/hooks/queue-processor.sh +0 -0
  299. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/listen.py +0 -0
  300. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/locking.py +0 -0
  301. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/network.py +0 -0
  302. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/onboarding.py +0 -0
  303. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/pane_manager.py +0 -0
  304. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/project_config.py +0 -0
  305. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/projects.py +0 -0
  306. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/prompts_cli.py +0 -0
  307. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/push_store.py +0 -0
  308. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/research.py +0 -0
  309. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/__init__.py +0 -0
  310. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/agentwire.md +0 -0
  311. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/anchor.md +0 -0
  312. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/chatbot.md +0 -0
  313. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/correspondent.md +0 -0
  314. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/council-brain.md +0 -0
  315. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/council-conscience.md +0 -0
  316. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/council-critic.md +0 -0
  317. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/council-devils-advocate.md +0 -0
  318. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/council-gut.md +0 -0
  319. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/council-historian.md +0 -0
  320. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/council-member.md +0 -0
  321. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/council-orchestrator.md +0 -0
  322. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/notifications.md +0 -0
  323. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/orchestrator.md +0 -0
  324. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/soul.md +0 -0
  325. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/task-runner.md +0 -0
  326. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/voice.md +0 -0
  327. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/worker.md +0 -0
  328. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/roles/worktree-session.md +0 -0
  329. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/safety/__init__.py +0 -0
  330. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/safety/_core.py +0 -0
  331. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/scheduler.py +0 -0
  332. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/scratchpad.py +0 -0
  333. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/security.py +0 -0
  334. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/services.py +0 -0
  335. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/session_context.py +0 -0
  336. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/ssh.py +0 -0
  337. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/agentwire-splash-logo-layers--agentwire-text.png +0 -0
  338. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/agentwire-splash-logo-layers--echo-claw-fg.png +0 -0
  339. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/agentwire-splash-logo-layers--echo.png +0 -0
  340. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/agentwire-splash-logo-layers--telephone.png +0 -0
  341. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/agentwire-splash-logo-layers--tree.png +0 -0
  342. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/announcements.json +0 -0
  343. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/css/mobile.css +0 -0
  344. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/favicon.png +0 -0
  345. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/icons/sessions/bear.webp +0 -0
  346. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/icons/sessions/cat.webp +0 -0
  347. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/icons/sessions/crown.webp +0 -0
  348. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/icons/sessions/custom/agentwire-portal.webp +0 -0
  349. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/icons/sessions/custom/agentwire-tts.webp +0 -0
  350. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/icons/sessions/custom/agentwire.webp +0 -0
  351. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/icons/sessions/deer.webp +0 -0
  352. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/icons/sessions/drone.webp +0 -0
  353. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/icons/sessions/eagle.webp +0 -0
  354. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/icons/sessions/fox.webp +0 -0
  355. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/icons/sessions/hawk.webp +0 -0
  356. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/icons/sessions/horse.webp +0 -0
  357. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/icons/sessions/lion.webp +0 -0
  358. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/icons/sessions/rabbit.webp +0 -0
  359. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/icons/sessions/robot.webp +0 -0
  360. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/icons/sessions/tiger.webp +0 -0
  361. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/icons/sessions/wolf.webp +0 -0
  362. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/img/icon-192.png +0 -0
  363. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/img/icon-512.png +0 -0
  364. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/.gitkeep +0 -0
  365. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/announcement-modal.js +0 -0
  366. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/api.js +0 -0
  367. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/artifact-window.js +0 -0
  368. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/collage.js +0 -0
  369. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/command-palette.js +0 -0
  370. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/council-window.js +0 -0
  371. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/dead-key-suppressor.js +0 -0
  372. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/desktop-manager.js +0 -0
  373. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/desktop.js +0 -0
  374. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/mobile.js +0 -0
  375. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/notification-prefs.js +0 -0
  376. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/notifications-panel.js +0 -0
  377. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/push-client.js +0 -0
  378. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/review-window.js +0 -0
  379. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/safety-shared.js +0 -0
  380. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/safety-window.js +0 -0
  381. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/scratchpad.js +0 -0
  382. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/service-classification.js +0 -0
  383. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/session-id.js +0 -0
  384. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/session-window.js +0 -0
  385. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/sidebar/artifacts-section.js +0 -0
  386. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/sidebar/config-section.js +0 -0
  387. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/sidebar/council-section.js +0 -0
  388. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/sidebar/machines-section.js +0 -0
  389. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/sidebar/projects-section.js +0 -0
  390. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/sidebar/safety-section.js +0 -0
  391. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/sidebar/scheduler-section.js +0 -0
  392. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/sidebar/services-section.js +0 -0
  393. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/sidebar/sessions-section.js +0 -0
  394. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/sidebar.js +0 -0
  395. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/terminal-font-prefs.js +0 -0
  396. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/tile-manager.js +0 -0
  397. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/toast.js +0 -0
  398. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/token-modal.js +0 -0
  399. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/utils/ansi.js +0 -0
  400. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/utils/swipe.js +0 -0
  401. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/voice/autosend-prefs.js +0 -0
  402. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/voice/browser-stt.js +0 -0
  403. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/voice/browser-tts.js +0 -0
  404. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/voice/jargon.js +0 -0
  405. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/voice/prompt.js +0 -0
  406. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/js/winbox.bundle.min.js +0 -0
  407. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/manifest.webmanifest +0 -0
  408. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/static/service-worker.js +0 -0
  409. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/stt/__init__.py +0 -0
  410. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/stt/base.py +0 -0
  411. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/stt/cloud.py +0 -0
  412. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/stt/engine.py +0 -0
  413. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/stt/local.py +0 -0
  414. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/stt/server_backend.py +0 -0
  415. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/stt/stt_server.py +0 -0
  416. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tasks.py +0 -0
  417. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/templates/__init__.py +0 -0
  418. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/templates/base.html +0 -0
  419. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/templates/desktop.html +0 -0
  420. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/templates/email_notification.html +0 -0
  421. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/templates/handoff/show-the-story.html.j2 +0 -0
  422. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/templates/handoff/theme.css.j2 +0 -0
  423. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/templates/mobile.html +0 -0
  424. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/templates/pair.html +0 -0
  425. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/templates/tmux.conf +0 -0
  426. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/templating.py +0 -0
  427. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tooldefs/aws.yaml +0 -0
  428. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tooldefs/docker.yaml +0 -0
  429. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tooldefs/gcp.yaml +0 -0
  430. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tooldefs/gh.yaml +0 -0
  431. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tooldefs/git.yaml +0 -0
  432. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tooldefs/gws.yaml +0 -0
  433. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tooldefs/kubectl.yaml +0 -0
  434. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tooldefs/npm.yaml +0 -0
  435. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tooldefs/terraform.yaml +0 -0
  436. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tooldefs/uv.yaml +0 -0
  437. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tts/__init__.py +0 -0
  438. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tts/audio.py +0 -0
  439. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tts/engines/chatterbox.py +0 -0
  440. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tts/engines/kokoro.py +0 -0
  441. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tts/engines/zonos.py +0 -0
  442. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tts/kokoro_server.py +0 -0
  443. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tts/local.py +0 -0
  444. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/tunnels.py +0 -0
  445. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/usage_limit.py +0 -0
  446. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/utils/__init__.py +0 -0
  447. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/utils/chunker.py +0 -0
  448. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/utils/event_log.py +0 -0
  449. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/utils/file_io.py +0 -0
  450. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/utils/paths.py +0 -0
  451. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/utils/speech.py +0 -0
  452. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/utils/subprocess.py +0 -0
  453. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/validation.py +0 -0
  454. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/voice_status.py +0 -0
  455. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/voiceclone.py +0 -0
  456. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/voices/darren.wav +0 -0
  457. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/voices/default.wav +0 -0
  458. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/voices/jessica.wav +0 -0
  459. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/voices/lisa.wav +0 -0
  460. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/voices/may.wav +0 -0
  461. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/wiki.py +0 -0
  462. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/wiki_audit.py +0 -0
  463. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/worktree.py +0 -0
  464. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/agentwire/worktree_registry.py +0 -0
  465. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/logo.png +0 -0
  466. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/architecture.md +0 -0
  467. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/communication/channels.md +0 -0
  468. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/communication/hammerspoon.md +0 -0
  469. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/communication/handoff.md +0 -0
  470. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/concepts.md +0 -0
  471. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/council.md +0 -0
  472. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/deployment/remote-access.md +0 -0
  473. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/deployment/remote-machines.md +0 -0
  474. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/glossary.md +0 -0
  475. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/integrations/gws-google-workspace-cli.md +0 -0
  476. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/internals/damage-control.md +0 -0
  477. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/internals/shell-escaping.md +0 -0
  478. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/internals/window-collage.md +0 -0
  479. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/quickstart.md +0 -0
  480. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/research/briefing-mode-feasibility.md +0 -0
  481. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/research/orchestration-transport-alternatives.md +0 -0
  482. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/scheduling/scheduled-workloads.md +0 -0
  483. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/security/damage-control-hardening.md +0 -0
  484. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/security/pip-audit.md +0 -0
  485. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/security/remote-access-hardening.md +0 -0
  486. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/security/secrets.md +0 -0
  487. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/services.md +0 -0
  488. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/sessions/claude-code-auto-mode.md +0 -0
  489. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/sessions/pi.md +0 -0
  490. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/sessions/prompt-routing.md +0 -0
  491. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/sessions/window-sizing.md +0 -0
  492. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/usage-limit-recovery.md +0 -0
  493. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/voice/stt-cloud.md +0 -0
  494. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/docs/wiki/voice/stt-self-hosted.md +0 -0
  495. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/conftest.py +0 -0
  496. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/e2e/test_portal_ui.py +0 -0
  497. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/fixtures/sample_agentwire.yml +0 -0
  498. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/fixtures/sample_config.yaml +0 -0
  499. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/fixtures/sample_scheduler.yaml +0 -0
  500. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/integration/test_council_portal.py +0 -0
  501. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/integration/test_scheduler_board.py +0 -0
  502. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/integration/test_server_websockets.py +0 -0
  503. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_announcements.py +0 -0
  504. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_cli_output.py +0 -0
  505. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_cli_smoke.py +0 -0
  506. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_council_inbox.py +0 -0
  507. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_council_state.py +0 -0
  508. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_council_view.py +0 -0
  509. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_damage_control_hooks.py +0 -0
  510. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_damage_control_sync.py +0 -0
  511. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_devices.py +0 -0
  512. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_diff_cli.py +0 -0
  513. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_doctor_voice.py +0 -0
  514. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_event_log.py +0 -0
  515. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_file_io.py +0 -0
  516. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_handoff_git_state.py +0 -0
  517. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_handoff_instructions.py +0 -0
  518. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_handoff_parser.py +0 -0
  519. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_handoff_renderer.py +0 -0
  520. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_history.py +0 -0
  521. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_idle_handler.py +0 -0
  522. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_idle_nag.py +0 -0
  523. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_limits_tick_isolation.py +0 -0
  524. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_locking.py +0 -0
  525. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_project_config.py +0 -0
  526. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_push.py +0 -0
  527. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_roles.py +0 -0
  528. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_scheduler.py +0 -0
  529. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_scheduler_parsing.py +0 -0
  530. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_security.py +0 -0
  531. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_server_async.py +0 -0
  532. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_server_pure.py +0 -0
  533. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_session_context.py +0 -0
  534. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_speech_tags.py +0 -0
  535. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_ssh.py +0 -0
  536. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_stt_backend.py +0 -0
  537. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_stt_cloud.py +0 -0
  538. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_stt_engine.py +0 -0
  539. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_tasks.py +0 -0
  540. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_templating.py +0 -0
  541. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_terminal_resize.py +0 -0
  542. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_tmux_template.py +0 -0
  543. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_tunnels_probe.py +0 -0
  544. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_usage_limit.py +0 -0
  545. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_validation.py +0 -0
  546. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_voice_status.py +0 -0
  547. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_wiki.py +0 -0
  548. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_wiki_audit.py +0 -0
  549. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_worktree.py +0 -0
  550. {agentwire_dev-1.46.0 → agentwire_dev-1.48.0}/tests/unit/test_worktree_registry.py +0 -0
@@ -0,0 +1,142 @@
1
+ ---
2
+ description: Distill this conversation into a shareable handoff bundle (ai-handoff.md + show-the-story.html)
3
+ ---
4
+
5
+ # /handoff
6
+
7
+ You are about to compile this conversation into a **shareable handoff bundle**. The output is two artifacts:
8
+
9
+ 1. **`ai-handoff.md`** — XML-tagged markdown a teammate can paste into another LLM (Opus 4.7) to roughly continue the conversation.
10
+ 2. **`show-the-story.html`** — single-file presentation a human can open in a browser.
11
+
12
+ You are uniquely positioned to do this well: you already have full conversation context. Don't ask the user clarifying questions unless something is genuinely ambiguous — distill what you know.
13
+
14
+ ## Workflow
15
+
16
+ ### 1. Initialize the bundle
17
+
18
+ Call the MCP tool to create the bundle dir and pre-fill the template with git state and the CLAUDE.md/rules/memory chain:
19
+
20
+ ```
21
+ mcp__agentwire__handoff_init(title="<short slug>")
22
+ ```
23
+
24
+ The tool returns a `bundle_dir` and an `ai_handoff_path`. The pre-filled template at `ai_handoff_path` already has:
25
+ - `<metadata>` populated with cwd, branch, commit, repo url
26
+ - `<instructions>` populated with the full CLAUDE.md chain (verbatim)
27
+ - `<project_state>` populated with `git status`, `git log`, and uncommitted diff
28
+
29
+ You **must not touch** the `<instructions>` section unless redacting something sensitive — it's what makes the bundle portable across machines.
30
+
31
+ ### 2. Read the pre-filled template
32
+
33
+ Use Read on `ai_handoff_path` to see exactly what got pre-filled.
34
+
35
+ ### 3. Fill in the rest
36
+
37
+ Use Write (or Edit) on `ai_handoff_path` to replace every `{{ ... }}` placeholder with real content. Specifically:
38
+
39
+ #### `<title>`
40
+ One short line summarizing the session — what it was about, not what was decided. Roughly 4-8 words.
41
+
42
+ #### `<metadata>` extras
43
+ Fill `started_at` / `ended_at` if you can estimate them, `user_identity` (if mentioned), and `mcp_servers` (the ones actually used in this conversation).
44
+
45
+ #### `<environment>`
46
+ What the receiver can't see from `cwd` alone. Active panes, channels (Slack/Discord/email), scheduler state if relevant. If nothing notable, write a one-line "no special environment" note.
47
+
48
+ #### `<conversation_summary>`
49
+ This is the most load-bearing section. Be dense and structured.
50
+
51
+ - `<goal>` — one sentence: what this session set out to do.
52
+ - `<tldr>` — one paragraph the receiver reads first. Convey decisions made, current state, and what's next.
53
+ - `<decisions>` — every meaningful decision. For each: `<title>` (short name), `<rationale>` (why), `<alternatives>` (what was considered and not picked). If a user message confirmed a choice, that's a decision.
54
+ - `<dead_ends>` — things tried and rejected. Critical: this saves the receiver from retracing your steps.
55
+ - `<open_threads>` — what's unresolved. Be specific. "tests/handoff/test_parser.py needs malformed-input cases" beats "tests pending".
56
+ - `<stats>` — turns, files_touched, tools_used, duration_minutes. Estimates are fine.
57
+
58
+ #### `<journey>`
59
+ 3-7 narrative beats — the *story* of the session, not the transcript. For each beat:
60
+ - `<beat title="...">` — short headline.
61
+ - `<quote>...</quote>` — optional verbatim line from the conversation that captured the turn (user or assistant).
62
+ - `<what_happened>...</what_happened>` — what actually changed.
63
+
64
+ This drives the visual presentation in show-the-story.html. Aim for memorable beats: turning points, surprises, decisions, blockers.
65
+
66
+ #### `<recent_turns>`
67
+ The last ~10-20 turns, **filtered**:
68
+ - Drop tool noise (file reads, searches) unless the result drove a decision.
69
+ - Keep all user turns verbatim — they're the signal of intent.
70
+ - Keep assistant turns that made decisions, asked questions, or summarized.
71
+ - Use markdown: `**user:**` / `**assistant:**` labels, blockquotes for quoted content.
72
+
73
+ #### `<handoff>`
74
+ Direct instructions to the next agent.
75
+ - `<one_sentence>` — what they should do first.
76
+ - `<resume_at>` — concrete file path / TODO id / step number.
77
+ - `<caveats>` — permission boundaries ("don't push", "don't edit X without asking"), env-specific notes, anything the receiver could trip on.
78
+
79
+ #### `<theme>`
80
+ Pick a palette and vibe that matches the **emotional tone** of the session. A debugging crisis at 2am gets different colors than a clean greenfield design pass. Be honest in `mood`. The shape:
81
+
82
+ ```json
83
+ {
84
+ "name": "short-slug",
85
+ "mood": "honest read of the session's emotional tone — 1 short sentence",
86
+ "palette": {
87
+ "bg": "#hex",
88
+ "surface": "#hex",
89
+ "fg": "#hex",
90
+ "muted": "#hex",
91
+ "accent": "#hex",
92
+ "accent_2": "#hex",
93
+ "border": "#hex"
94
+ },
95
+ "fonts": {
96
+ "heading": "css font-family stack",
97
+ "body": "css font-family stack"
98
+ },
99
+ "motion": "subtle"
100
+ }
101
+ ```
102
+
103
+ Tips:
104
+ - Dark backgrounds work better in this template — `bg` should be deep.
105
+ - `accent` is the dominant interactive color (tabs, headlines, highlights). Pick something that signals the mood.
106
+ - `accent_2` is for warnings / dead-ends. Often a warm color.
107
+ - Keep `fonts.heading` monospace-leaning, `fonts.body` sans-serif. Override only if the mood justifies it.
108
+ - `motion`: `"subtle"` (default), `"playful"` (longer transitions), `"none"` (instant).
109
+
110
+ ### 4. Render the HTML
111
+
112
+ After writing `ai-handoff.md`, render the HTML:
113
+
114
+ ```
115
+ mcp__agentwire__handoff_render(bundle_dir="<from step 1>", story=true)
116
+ ```
117
+
118
+ If render fails, the parser will tell you which tag is missing or malformed — fix and re-run.
119
+
120
+ ### 5. Report
121
+
122
+ Give the user:
123
+ - The bundle dir path
124
+ - A one-sentence summary of what you produced
125
+ - An explicit pointer to open `show-the-story.html` in a browser
126
+
127
+ Don't paste the full ai-handoff.md back — it's long. Just confirm it's saved and mention the highlights you captured (number of decisions, dead ends, journey beats, theme name/mood).
128
+
129
+ ## Quality bar
130
+
131
+ The receiver's first impression is everything. A great handoff:
132
+ - Reads cold — the receiver doesn't need to be in this folder.
133
+ - Is honest about dead ends. Hiding what didn't work wastes the receiver's tokens.
134
+ - Names specific files and line numbers, not vague pointers.
135
+ - Picks a theme that captures the session's actual feel. Don't pick "professional blue" for a chaotic debug session.
136
+
137
+ ## Don't
138
+
139
+ - Don't ask the user "should I include X?" — make the call yourself.
140
+ - Don't paste the entire conversation as `<recent_turns>` — filter aggressively.
141
+ - Don't over-design the theme. The structure is fixed; you're picking colors and vibes, not a layout.
142
+ - Don't edit `<instructions>` (the CLAUDE.md chain) unless redacting secrets.
@@ -57,3 +57,6 @@ htmlcov/
57
57
 
58
58
  # pytest-textual-snapshot diff page (regenerated each run)
59
59
  snapshot_report.html
60
+
61
+ # Node
62
+ node_modules/
@@ -0,0 +1,5 @@
1
+ # AgentWire
2
+
3
+ Voice interface for AI coding agents. Push-to-talk from any device to tmux sessions running Claude Code.
4
+
5
+ Agent instructions, conventions, and architecture live in [CLAUDE.md](CLAUDE.md).
@@ -144,7 +144,7 @@ def validate_config(config: Config) -> tuple[list[ConfigError], list[ConfigWarni
144
144
 
145
145
  ## CLI First
146
146
 
147
- All session/machine logic lives in CLI commands (`__main__.py`). The web portal is a thin wrapper that:
147
+ All session/machine logic lives in the CLI. The command tree is split per-domain (#495): shared helpers (machine config, SSH, JSON output, session resolution, etc.) live in `core.py`; each command group lives in its own `agentwire/<domain>_cli.py` exposing a `register_<domain>_parser(subparsers)` registrar, and `build_parser()` imports them and runs the `_REGISTRARS` loop. `__main__.py` is just the entry point. Adding a command means writing a new `*_cli.py` + appending its registrar, not editing a god-file. The web portal is a thin wrapper that:
148
148
 
149
149
  1. Calls CLI via `run_agentwire_cmd(["command", "args"])`
150
150
  2. Parses JSON output (`--json` flag)
@@ -159,7 +159,9 @@ When adding new functionality:
159
159
 
160
160
  ```
161
161
  agentwire/
162
- ├── __main__.py # CLI commands (entry point)
162
+ ├── __main__.py # CLI entry point (imports + runs the registrar loop)
163
+ ├── core.py # Shared CLI helpers (machine config, SSH, JSON, session resolution)
164
+ ├── *_cli.py # Per-domain command groups, each with a register_<domain>_parser()
163
165
  ├── server.py # WebSocket server
164
166
  ├── config.py # Configuration dataclasses
165
167
  ├── errors.py # Structured error classes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentwire-dev
3
- Version: 1.46.0
3
+ Version: 1.48.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
@@ -256,7 +256,6 @@ Requires-Dist: fastapi>=0.104.0; extra == 'tts'
256
256
  Requires-Dist: faster-whisper>=1.0.0; extra == 'tts'
257
257
  Requires-Dist: pydantic>=2.0.0; extra == 'tts'
258
258
  Requires-Dist: python-multipart>=0.0.6; extra == 'tts'
259
- Requires-Dist: runpod>=1.6.0; extra == 'tts'
260
259
  Requires-Dist: torch>=2.0.0; extra == 'tts'
261
260
  Requires-Dist: torchaudio>=2.0.0; extra == 'tts'
262
261
  Requires-Dist: uvicorn>=0.24.0; extra == 'tts'
@@ -295,9 +294,9 @@ structurally can't match:
295
294
  the machine.
296
295
  - **Voice-native, not voice-bolted-on.** Push-to-talk in, **neural TTS out on plain
297
296
  CPU** (Kokoro, no GPU). Want your agents to talk back in a **cloned voice**? Run a
298
- self-hosted GPU shim (Chatterbox / Qwen / Zonos) — same machine, still your keys.
297
+ self-hosted GPU shim (Chatterbox / Zonos) — same machine, still your keys.
299
298
  - **Built to orchestrate _many_ agents, not watch one.** Council (multi-soul
300
- deliberation), an overnight scheduler, briefing mode, and worktree-parallel
299
+ deliberation), a recurring scheduler, briefing mode, and worktree-parallel
301
300
  workers — tmux- and Claude-Code-native from the ground up.
302
301
 
303
302
  > **Use the official app to watch one session; use AgentWire to orchestrate many,
@@ -388,7 +387,7 @@ pip install agentwire-dev
388
387
  | **Voice Control** | Push-to-talk from any device on your network |
389
388
  | **Neural Voice + Cloning** | Kokoro neural TTS on CPU out of the box; voice cloning via a self-hosted GPU shim |
390
389
  | **Council** | Fan a prompt to multiple "soul" sessions (brain, conscience, critic…), synthesize with attribution |
391
- | **Scheduler** | Overnight / recurring autonomous tasks with gates, priorities, and usage-limit recovery |
390
+ | **Scheduler** | Recurring autonomous tasks with gates, priorities, and usage-limit recovery |
392
391
  | **Briefing Mode** | A terse human-facing anchor fans out verbose worktree correspondents, then briefs you on cue |
393
392
  | **Multi-Session** | Run multiple agents on different projects simultaneously |
394
393
  | **Git Worktrees** | Same project, multiple branches, parallel agents |
@@ -474,7 +473,7 @@ Two tiers, both sides:
474
473
  # ~/.agentwire/config.yaml
475
474
  tts:
476
475
  backend: "custom"
477
- url: "http://localhost:8100" # agentwire tts start (kokoro CPU / chatterbox GPU / qwen / zonos)
476
+ url: "http://localhost:8100" # agentwire tts start (kokoro CPU / chatterbox GPU / zonos)
478
477
  options:
479
478
  backend: kokoro
480
479
  stt:
@@ -31,9 +31,9 @@ structurally can't match:
31
31
  the machine.
32
32
  - **Voice-native, not voice-bolted-on.** Push-to-talk in, **neural TTS out on plain
33
33
  CPU** (Kokoro, no GPU). Want your agents to talk back in a **cloned voice**? Run a
34
- self-hosted GPU shim (Chatterbox / Qwen / Zonos) — same machine, still your keys.
34
+ self-hosted GPU shim (Chatterbox / Zonos) — same machine, still your keys.
35
35
  - **Built to orchestrate _many_ agents, not watch one.** Council (multi-soul
36
- deliberation), an overnight scheduler, briefing mode, and worktree-parallel
36
+ deliberation), a recurring scheduler, briefing mode, and worktree-parallel
37
37
  workers — tmux- and Claude-Code-native from the ground up.
38
38
 
39
39
  > **Use the official app to watch one session; use AgentWire to orchestrate many,
@@ -124,7 +124,7 @@ pip install agentwire-dev
124
124
  | **Voice Control** | Push-to-talk from any device on your network |
125
125
  | **Neural Voice + Cloning** | Kokoro neural TTS on CPU out of the box; voice cloning via a self-hosted GPU shim |
126
126
  | **Council** | Fan a prompt to multiple "soul" sessions (brain, conscience, critic…), synthesize with attribution |
127
- | **Scheduler** | Overnight / recurring autonomous tasks with gates, priorities, and usage-limit recovery |
127
+ | **Scheduler** | Recurring autonomous tasks with gates, priorities, and usage-limit recovery |
128
128
  | **Briefing Mode** | A terse human-facing anchor fans out verbose worktree correspondents, then briefs you on cue |
129
129
  | **Multi-Session** | Run multiple agents on different projects simultaneously |
130
130
  | **Git Worktrees** | Same project, multiple branches, parallel agents |
@@ -210,7 +210,7 @@ Two tiers, both sides:
210
210
  # ~/.agentwire/config.yaml
211
211
  tts:
212
212
  backend: "custom"
213
- url: "http://localhost:8100" # agentwire tts start (kokoro CPU / chatterbox GPU / qwen / zonos)
213
+ url: "http://localhost:8100" # agentwire tts start (kokoro CPU / chatterbox GPU / zonos)
214
214
  options:
215
215
  backend: kokoro
216
216
  stt:
@@ -34,10 +34,13 @@ unzip -l dist/agentwire_dev-{VERSION}-py3-none-any.whl | grep -E "templates/|sta
34
34
 
35
35
  ### 4. Publish to PyPI
36
36
 
37
- The `PYPI_TOKEN` lives in `~/.agentwire/.env`. Pass it explicitly:
37
+ The `PYPI_TOKEN` lives in `~/.agentwire/.env`. Don't `source` the file — it can
38
+ contain unquoted `&` in other values (e.g. a URL with query params), which makes
39
+ the shell hit a parse error before `uv publish` ever runs. Grep the token out
40
+ directly:
38
41
 
39
42
  ```bash
40
- source ~/.agentwire/.env && uv publish --token "$PYPI_TOKEN" dist/agentwire_dev-{VERSION}*
43
+ uv publish --token "$(grep '^PYPI_TOKEN=' ~/.agentwire/.env | cut -d= -f2-)" dist/agentwire_dev-{VERSION}*
41
44
  ```
42
45
 
43
46
  ### 5. Create GitHub release
@@ -1,3 +1,3 @@
1
1
  """AgentWire - Multi-session voice web interface for AI coding agents."""
2
2
 
3
- __version__ = "1.46.0"
3
+ __version__ = "1.48.0"
@@ -0,0 +1,391 @@
1
+ """CLI entry point for AgentWire."""
2
+
3
+ import argparse
4
+ import sys
5
+ from pathlib import Path
6
+
7
+ from dotenv import load_dotenv
8
+
9
+ # Load .env files (project first, then global config)
10
+ load_dotenv() # .env in current directory
11
+ load_dotenv(Path.home() / ".agentwire" / ".env") # Global config
12
+
13
+ from . import ( # noqa: E402 # must follow load_dotenv() above
14
+ __version__,
15
+ )
16
+ from .core import ( # noqa: E402,F401 # E402: must follow load_dotenv(); F401: re-exported moved helpers
17
+ _UNATTENDED_ENV_KEYS,
18
+ CONFIG_DIR,
19
+ KIND_DEFAULT_POSTURE,
20
+ AgentCommand,
21
+ _add_posture_harness_flags,
22
+ _build_tmux_env_flags,
23
+ _build_tmux_env_flags_shell,
24
+ _check_portal_health,
25
+ _check_tmux_installed,
26
+ _default_portal_url,
27
+ _display_parent,
28
+ _get_agentwire_path,
29
+ _get_all_machines,
30
+ _get_machine_config,
31
+ _get_portal_url,
32
+ _get_session_project_path,
33
+ _git_behind_origin,
34
+ _install_global_tmux_hooks,
35
+ _notify_portal_sessions_changed,
36
+ _output_json,
37
+ _output_result,
38
+ _parse_session_target,
39
+ _portal_auth_headers,
40
+ _post_desktop_notification,
41
+ _record_session_creator,
42
+ _resolve_session_type_from_args,
43
+ _run_remote,
44
+ _set_session_name_env,
45
+ _start_portal_local,
46
+ _tmux_global_option,
47
+ _with_unattended_env,
48
+ build_agent_command,
49
+ check_pip_environment,
50
+ check_python_version,
51
+ format_relative_time,
52
+ generate_certs,
53
+ get_kokoro_session_name,
54
+ get_portal_session_name,
55
+ get_source_dir,
56
+ get_stt_session_name,
57
+ get_tts_session_name,
58
+ inject_session_env,
59
+ load_config,
60
+ load_session_metadata,
61
+ parse_env_args,
62
+ store_session_metadata,
63
+ tmux_session_exists,
64
+ tmux_session_has_agent,
65
+ wait_for_shell_prompt,
66
+ )
67
+
68
+
69
+ class VersionAction(argparse.Action):
70
+ """Custom version action that checks Python version and pip environment."""
71
+
72
+ def __init__(self, option_strings, dest=argparse.SUPPRESS, default=argparse.SUPPRESS, help=None):
73
+ super().__init__(option_strings, dest=dest, default=default, nargs=0, help=help)
74
+
75
+ def __call__(self, parser, namespace, values, option_string=None):
76
+ # Print version
77
+ print(f"agentwire {__version__}")
78
+ print(f"Python {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}")
79
+
80
+ # Check version compatibility
81
+ version_ok = check_python_version()
82
+ env_ok = check_pip_environment()
83
+
84
+ if version_ok and env_ok:
85
+ print("\n✓ System is ready for AgentWire")
86
+ else:
87
+ print("\n⚠️ Please resolve the issues above before installing/running AgentWire")
88
+
89
+ parser.exit()
90
+
91
+
92
+ def build_parser() -> argparse.ArgumentParser:
93
+ """Build the top-level argparse parser with every registered subcommand.
94
+
95
+ Extracted from ``main()`` so the parser tree can be constructed without
96
+ dispatching, which the CLI smoke tests rely on to enumerate subcommands
97
+ and invoke their ``--help`` (see ``tests/unit/test_cli_smoke.py``).
98
+ """
99
+ parser = argparse.ArgumentParser(
100
+ prog="agentwire",
101
+ description="Multi-session voice web interface for AI coding agents.",
102
+ formatter_class=argparse.RawDescriptionHelpFormatter,
103
+ epilog="""
104
+ Command Categories:
105
+ Getting Started:
106
+ init Interactive setup wizard
107
+ portal Manage the web portal
108
+ new Create a new Claude Code session
109
+ say Speak text via TTS
110
+
111
+ Sessions:
112
+ list List panes or sessions
113
+ info Get session information
114
+ kill Kill a session or pane
115
+ spawn Spawn a worker pane in current session
116
+ worktree Create a git worktree + session
117
+ send Send prompt to a session or pane
118
+ output Read session or pane output
119
+
120
+ Voice:
121
+ listen Voice input recording
122
+ voiceclone Record and upload voice clones
123
+ tts Manage TTS server
124
+ stt Manage STT server
125
+
126
+ Diagnostics:
127
+ doctor Auto-diagnose and fix common issues
128
+ network Network diagnostics and status
129
+ safety Damage control security commands
130
+ hooks Manage agentwire hook files
131
+
132
+ Advanced:
133
+ council Multi-soul council operations
134
+ scheduler Manage the task scheduler
135
+ ensure Run named task with reliable session management
136
+ limits Usage-limit recovery management
137
+ """
138
+ )
139
+ parser.add_argument(
140
+ "--version",
141
+ action=VersionAction,
142
+ help="Show version and check system compatibility",
143
+ )
144
+
145
+ subparsers = parser.add_subparsers(dest="command", help="Commands")
146
+
147
+ # === quo command ===
148
+ from agentwire.channels.quo import cmd_quo
149
+ quo_parser = subparsers.add_parser("quo", help="Send SMS via Quo (OpenPhone)")
150
+ quo_parser.add_argument("--body", "-b", type=str, help="Message body (or pipe via stdin)")
151
+ quo_parser.add_argument("--to", type=str, help="Recipient phone number (+E.164 format)")
152
+ quo_parser.add_argument("-q", "--quiet", action="store_true", help="Suppress success output")
153
+ quo_parser.set_defaults(func=cmd_quo)
154
+
155
+ # === email command ===
156
+ from agentwire.channels.email import cmd_email
157
+ email_parser = subparsers.add_parser("email", help="Send branded email notification via Resend")
158
+ email_parser.add_argument(
159
+ "--to", action="append", default=None,
160
+ help="Recipient email. Repeat or pass comma-separated for multiple recipients (default: from config).",
161
+ )
162
+ email_parser.add_argument("--subject", "-s", type=str, help="Email subject")
163
+ email_parser.add_argument("--body", "-b", type=str, help="Email body - markdown supported (or pipe via stdin)")
164
+ email_parser.add_argument("--attach", "-a", type=str, action="append", help="Attach file (can use multiple times)")
165
+ email_parser.add_argument("--plain", action="store_true", help="Send plain text only (no HTML template)")
166
+ email_parser.add_argument("-q", "--quiet", action="store_true", help="Suppress success output")
167
+ email_parser.set_defaults(func=cmd_email)
168
+
169
+ # === fetch command ===
170
+ from agentwire.fetch import cmd_fetch
171
+ fetch_parser = subparsers.add_parser(
172
+ "fetch",
173
+ help="Fetch a URL via Jina Reader — handles JS-rendered pages, returns clean markdown.",
174
+ )
175
+ fetch_parser.add_argument("url", help="URL to fetch")
176
+ fetch_parser.add_argument(
177
+ "--limit", "-l", type=int, default=8000,
178
+ help="Max characters to return (default: 8000, 0 = no limit)",
179
+ )
180
+ fetch_parser.set_defaults(func=cmd_fetch)
181
+
182
+ # === Extracted command groups (each registrar owns its own subparser) ===
183
+ # Phase 1 of #495 appends one entry here per extracted domain.
184
+ # - limits: usage-limit recovery (detect dialog, park, auto-resume)
185
+ # - diff: structured git diff for the mobile Review window
186
+ # - prompts: prompt routing (rides the limits watchdog)
187
+ # - msg: polite agent-to-agent inbox (rides the watchdog)
188
+ 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
+ from . import session_cli
190
+ from . import channels_cli, portal_cli, tts_cli
191
+ from . import scheduler_cli, ensure_cli
192
+ from . import doctor_cli, history_cli, machine_cli, safety_cli
193
+ from . import handoff_cli, hooks_cli, mcp_cli, roles_cli, tunnels_cli
194
+ from . import notify_cli, push_cli, repo_cli, system_cli, wiki_cli
195
+ from .council import cli as council_cli
196
+
197
+ _REGISTRARS = [ # noqa: N806 # registry constant; Phase 1 of #495 appends here
198
+ diff_cli.register_diff_parser,
199
+ prompts_cli.register_prompts_parser,
200
+ msg_cli.register_msg_parser,
201
+ limits_cli.register_limits_parser,
202
+ pane_cli.register_pane_parser,
203
+ send_cli.register_send_parser,
204
+ session_cli.register_session_parser,
205
+ portal_cli.register_portal_parser,
206
+ tts_cli.register_tts_parser,
207
+ channels_cli.register_channels_parser,
208
+ scheduler_cli.register_scheduler_parser,
209
+ ensure_cli.register_ensure_parser,
210
+ doctor_cli.register_doctor_parser,
211
+ safety_cli.register_safety_parser,
212
+ machine_cli.register_machine_parser,
213
+ history_cli.register_history_parser,
214
+ roles_cli.register_roles_parser,
215
+ roles_cli.register_projects_parser,
216
+ hooks_cli.register_hooks_parser,
217
+ tunnels_cli.register_tunnels_parser,
218
+ handoff_cli.register_handoff_parser,
219
+ mcp_cli.register_mcp_parser,
220
+ notify_cli.register_notify_parser,
221
+ wiki_cli.register_wiki_parser,
222
+ system_cli.register_system_parser,
223
+ push_cli.register_push_parser,
224
+ repo_cli.register_repo_parser,
225
+ ]
226
+ for _reg in _REGISTRARS:
227
+ _reg(subparsers)
228
+
229
+ # === council command group ===
230
+ council_parser = subparsers.add_parser(
231
+ "council",
232
+ help="Multi-soul council: fan a prompt out to lens sessions, synthesize",
233
+ description=(
234
+ "An agentwire-council orchestrator session fans prompts out to a "
235
+ "roster of lens souls (brain, conscience, gut, critic, historian, "
236
+ "devils-advocate), collects their takes through a file inbox, and "
237
+ "synthesizes. See docs/wiki/council.md."
238
+ ),
239
+ )
240
+ council_subparsers = council_parser.add_subparsers(dest="council_command")
241
+
242
+ # Targeting is shared: --name picks the sitting; absent, the cwd-repo-slug
243
+ # if it matches a live sitting, else the sole live sitting, else error.
244
+ _name_help = "Sitting name (default: cwd-repo-slug / sole live sitting)"
245
+
246
+ # council start
247
+ c_start = council_subparsers.add_parser(
248
+ "start", help="Start a sitting: orchestrator + all soul sessions"
249
+ )
250
+ c_start.add_argument(
251
+ "--name", help="Sitting name (default: cwd-repo-slug)"
252
+ )
253
+ c_start.add_argument(
254
+ "--roster", help="Comma-separated lens names (default: full bundled roster)"
255
+ )
256
+ c_start.add_argument("--type", help="Session type (default: claude-bypass)")
257
+ c_start.add_argument("--model", help="Model override for all council sessions")
258
+ c_start.add_argument(
259
+ "--force", action="store_true", help="Tear down a live sitting first"
260
+ )
261
+ c_start.add_argument("--json", action="store_true", help="Output JSON")
262
+ c_start.set_defaults(func=council_cli.cmd_council_start)
263
+
264
+ # council stop
265
+ c_stop = council_subparsers.add_parser(
266
+ "stop", help="Kill the sitting's sessions (prompt history kept)"
267
+ )
268
+ c_stop.add_argument("--name", help=_name_help)
269
+ c_stop.add_argument("--json", action="store_true", help="Output JSON")
270
+ c_stop.set_defaults(func=council_cli.cmd_council_stop)
271
+
272
+ # council status
273
+ c_status = council_subparsers.add_parser(
274
+ "status", help="Sitting state, session liveness, open prompts"
275
+ )
276
+ c_status.add_argument("--name", help=_name_help)
277
+ c_status.add_argument("--json", action="store_true", help="Output JSON")
278
+ c_status.set_defaults(func=council_cli.cmd_council_status)
279
+
280
+ # council list
281
+ c_list = council_subparsers.add_parser(
282
+ "list", help="Every known sitting: name, cwd, age, live sessions, prompts"
283
+ )
284
+ c_list.add_argument("--json", action="store_true", help="Output JSON")
285
+ c_list.set_defaults(func=council_cli.cmd_council_list)
286
+
287
+ # council ask
288
+ c_ask = council_subparsers.add_parser(
289
+ "ask", help="Fan a prompt out to every soul in the sitting"
290
+ )
291
+ c_ask.add_argument("prompt", nargs="?", help="Prompt text (or --file / stdin)")
292
+ c_ask.add_argument("--name", help=_name_help)
293
+ c_ask.add_argument("--file", help="Read prompt text from a file")
294
+ c_ask.add_argument("--json", action="store_true", help="Output JSON")
295
+ c_ask.set_defaults(func=council_cli.cmd_council_ask)
296
+
297
+ # council collect
298
+ c_collect = council_subparsers.add_parser(
299
+ "collect", help="Wait for every soul's take/ack/pass (or timeout)"
300
+ )
301
+ c_collect.add_argument("--name", help=_name_help)
302
+ c_collect.add_argument("--prompt", type=int, help="Prompt id (default: latest)")
303
+ c_collect.add_argument(
304
+ "--timeout", type=float, default=120, help="Soft timeout in seconds (default: 120)"
305
+ )
306
+ c_collect.add_argument(
307
+ "--no-wait", action="store_true", help="Snapshot once, don't block"
308
+ )
309
+ c_collect.add_argument("--json", action="store_true", help="Output JSON")
310
+ c_collect.set_defaults(func=council_cli.cmd_council_collect)
311
+
312
+ # council reply (run by souls)
313
+ c_reply = council_subparsers.add_parser(
314
+ "reply", help="File a soul's reply: --take / --ack / --pass"
315
+ )
316
+ c_reply.add_argument("--name", help=_name_help)
317
+ c_reply.add_argument("--prompt", type=int, help="Prompt id (default: latest)")
318
+ c_reply.add_argument(
319
+ "--take", action="store_true", help="Substantive take (text required)"
320
+ )
321
+ c_reply.add_argument(
322
+ "--ack", action="store_true", help="Researching — follow-up coming"
323
+ )
324
+ c_reply.add_argument(
325
+ "--pass", action="store_true", help="Nothing to add through this lens"
326
+ )
327
+ c_reply.add_argument("--soul", help="Lens name (default: inferred from session)")
328
+ c_reply.add_argument("--text", help="Reply text")
329
+ c_reply.add_argument("--file", help="Read reply text from a file")
330
+ c_reply.add_argument("--json", action="store_true", help="Output JSON")
331
+ c_reply.set_defaults(func=council_cli.cmd_council_reply)
332
+
333
+ return parser
334
+
335
+
336
+ def _find_subparser(parser: argparse.ArgumentParser, *names: str):
337
+ """Walk the subparser tree by command name(s); return the parser or None."""
338
+ current = parser
339
+ for name in names:
340
+ sub = None
341
+ for action in current._actions:
342
+ if isinstance(action, argparse._SubParsersAction):
343
+ sub = action.choices.get(name)
344
+ break
345
+ if sub is None:
346
+ return None
347
+ current = sub
348
+ return current
349
+
350
+
351
+ # Command groups whose bare invocation (no subcommand) prints group help.
352
+ _GROUP_COMMANDS = [
353
+ "portal", "tts", "stt", "tunnels", "machine", "history", "handoff",
354
+ "wiki", "hooks", "projects", "safety", "network", "listen",
355
+ "voiceclone", "roles", "task", "lock", "scheduler", "council", "limits",
356
+ ]
357
+
358
+
359
+ def main() -> int:
360
+ """Main entry point."""
361
+ parser = build_parser()
362
+ args = parser.parse_args()
363
+
364
+ if args.command is None:
365
+ parser.print_help()
366
+ return 0
367
+
368
+ if (
369
+ args.command in _GROUP_COMMANDS
370
+ and getattr(args, f"{args.command}_command", None) is None
371
+ ):
372
+ _find_subparser(parser, args.command).print_help()
373
+ return 0
374
+
375
+ if (
376
+ args.command == "safety"
377
+ and getattr(args, "safety_command", None) == "tooldefs"
378
+ and getattr(args, "tooldefs_command", None) is None
379
+ ):
380
+ _find_subparser(parser, "safety", "tooldefs").print_help()
381
+ return 0
382
+
383
+ if hasattr(args, "func"):
384
+ return args.func(args)
385
+
386
+ parser.print_help()
387
+ return 0
388
+
389
+
390
+ if __name__ == "__main__":
391
+ sys.exit(main())