agentwire-dev 1.23.0__tar.gz → 1.24.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 (402) hide show
  1. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/.gitignore +3 -0
  2. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/CHANGELOG.md +20 -0
  3. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/PKG-INFO +4 -1
  4. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/__init__.py +1 -1
  5. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/__main__.py +241 -92
  6. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/channels/email.py +33 -6
  7. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/config.py +30 -0
  8. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/agentwire-permission.sh +19 -0
  9. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/bash-tool-damage-control.py +12 -3
  10. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/mcp_server.py +6 -3
  11. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/overnight.py +40 -27
  12. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/project_config.py +4 -0
  13. agentwire_dev-1.24.0/agentwire/repl/__init__.py +12 -0
  14. agentwire_dev-1.24.0/agentwire/repl/app.py +185 -0
  15. agentwire_dev-1.24.0/agentwire/repl/commands.py +320 -0
  16. agentwire_dev-1.24.0/agentwire/repl/context.py +96 -0
  17. agentwire_dev-1.24.0/agentwire/repl/mentions.py +165 -0
  18. agentwire_dev-1.24.0/agentwire/repl/persistence.py +253 -0
  19. agentwire_dev-1.24.0/agentwire/repl/state.py +96 -0
  20. agentwire_dev-1.24.0/agentwire/repl/textual_app.py +1273 -0
  21. agentwire_dev-1.24.0/agentwire/repl/views/__init__.py +7 -0
  22. agentwire_dev-1.24.0/agentwire/repl/views/fanout.py +568 -0
  23. agentwire_dev-1.24.0/agentwire/sdk/__init__.py +42 -0
  24. agentwire_dev-1.24.0/agentwire/sdk/capabilities.py +129 -0
  25. agentwire_dev-1.24.0/agentwire/sdk/client.py +187 -0
  26. agentwire_dev-1.24.0/agentwire/sdk/damage_control.py +147 -0
  27. agentwire_dev-1.24.0/agentwire/sdk/errors.py +27 -0
  28. agentwire_dev-1.24.0/agentwire/sdk/events.py +214 -0
  29. agentwire_dev-1.24.0/agentwire/sdk/render.py +339 -0
  30. agentwire_dev-1.24.0/agentwire/sdk/sinks/__init__.py +11 -0
  31. agentwire_dev-1.24.0/agentwire/sdk/sinks/base.py +27 -0
  32. agentwire_dev-1.24.0/agentwire/sdk/sinks/textual.py +147 -0
  33. agentwire_dev-1.24.0/agentwire/sdk/state.py +169 -0
  34. agentwire_dev-1.24.0/agentwire/search.py +164 -0
  35. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/server.py +202 -0
  36. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/css/desktop.css +296 -2
  37. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/desktop.js +48 -1
  38. agentwire_dev-1.24.0/agentwire/static/js/sidebar/sdk-sessions-section.js +77 -0
  39. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/sidebar/sessions-section.js +4 -1
  40. agentwire_dev-1.24.0/agentwire/static/js/sidebar/workflows-section.js +114 -0
  41. agentwire_dev-1.24.0/agentwire/static/js/windows/sdk-watch-window.js +257 -0
  42. agentwire_dev-1.24.0/agentwire/static/js/windows/workflow-window.js +166 -0
  43. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/workflows/cli.py +60 -7
  44. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/workflows/definitions.py +62 -6
  45. agentwire_dev-1.24.0/agentwire/workflows/node.py +166 -0
  46. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/workflows/pi_runner.py +6 -5
  47. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/workflows/runner.py +19 -5
  48. agentwire_dev-1.24.0/agentwire/workflows/runners/__init__.py +67 -0
  49. agentwire_dev-1.24.0/agentwire/workflows/runners/anthropic.py +248 -0
  50. agentwire_dev-1.24.0/agentwire/workflows/runners/human_gate.py +133 -0
  51. agentwire_dev-1.24.0/agentwire/workflows/runners/pi.py +35 -0
  52. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/workflows/storage.py +13 -1
  53. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/PORTAL.md +2 -0
  54. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/pi-zai.md +3 -3
  55. agentwire_dev-1.24.0/docs/repl-tui.md +286 -0
  56. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/scheduled-workloads.md +1 -1
  57. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/workflows.md +135 -6
  58. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/pyproject.toml +9 -0
  59. agentwire_dev-1.24.0/tests/integration/test_anthropic_runner_live.py +218 -0
  60. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/integration/test_build_agent_command.py +36 -25
  61. agentwire_dev-1.24.0/tests/snapshot/__snapshots__/test_repl_snapshots/test_empty_boot_snapshot.raw +202 -0
  62. agentwire_dev-1.24.0/tests/snapshot/apps/repl_empty.py +59 -0
  63. agentwire_dev-1.24.0/tests/snapshot/test_repl_snapshots.py +44 -0
  64. agentwire_dev-1.24.0/tests/unit/test_anthropic_capabilities.py +149 -0
  65. agentwire_dev-1.24.0/tests/unit/test_anthropic_classify.py +36 -0
  66. agentwire_dev-1.24.0/tests/unit/test_anthropic_events.py +209 -0
  67. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_channels.py +37 -0
  68. agentwire_dev-1.24.0/tests/unit/test_human_gate_runner.py +151 -0
  69. agentwire_dev-1.24.0/tests/unit/test_overnight_resume_flags.py +72 -0
  70. agentwire_dev-1.24.0/tests/unit/test_repl_commands.py +562 -0
  71. agentwire_dev-1.24.0/tests/unit/test_repl_context.py +137 -0
  72. agentwire_dev-1.24.0/tests/unit/test_repl_damage_control.py +188 -0
  73. agentwire_dev-1.24.0/tests/unit/test_repl_dispatch.py +8 -0
  74. agentwire_dev-1.24.0/tests/unit/test_repl_fanout.py +466 -0
  75. agentwire_dev-1.24.0/tests/unit/test_repl_mentions.py +117 -0
  76. agentwire_dev-1.24.0/tests/unit/test_repl_persistence.py +256 -0
  77. agentwire_dev-1.24.0/tests/unit/test_repl_sdk.py +1106 -0
  78. agentwire_dev-1.24.0/tests/unit/test_repl_sink_wrap.py +94 -0
  79. agentwire_dev-1.24.0/tests/unit/test_repl_tail.py +98 -0
  80. agentwire_dev-1.24.0/tests/unit/test_repl_textual_app.py +1052 -0
  81. agentwire_dev-1.24.0/tests/unit/test_runner_on_event.py +86 -0
  82. agentwire_dev-1.24.0/tests/unit/test_runner_override.py +65 -0
  83. agentwire_dev-1.24.0/tests/unit/test_runners_registry.py +108 -0
  84. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_scheduler.py +12 -0
  85. agentwire_dev-1.24.0/tests/unit/test_sdk_session_types.py +95 -0
  86. agentwire_dev-1.24.0/tests/unit/test_search.py +196 -0
  87. agentwire_dev-1.24.0/tests/unit/test_server_sdk_watch.py +78 -0
  88. agentwire_dev-1.24.0/tests/unit/test_server_workflow_history.py +173 -0
  89. agentwire_dev-1.24.0/tests/unit/test_workflow_cli.py +172 -0
  90. agentwire_dev-1.24.0/tests/unit/test_workflow_storage.py +128 -0
  91. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_workflows.py +29 -9
  92. agentwire_dev-1.23.0/agentwire/workflows/node.py +0 -115
  93. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/.github/FUNDING.yml +0 -0
  94. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  95. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  96. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
  97. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  98. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/CLA.md +0 -0
  99. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/CODE_OF_CONDUCT.md +0 -0
  100. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/CONTRIBUTING.md +0 -0
  101. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/Dockerfile.local +0 -0
  102. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/Dockerfile.runpod +0 -0
  103. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/LICENSE +0 -0
  104. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/README.md +0 -0
  105. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/RELEASING.md +0 -0
  106. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/SECURITY.md +0 -0
  107. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/SPONSORS.md +0 -0
  108. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/agents/__init__.py +0 -0
  109. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/agents/base.py +0 -0
  110. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/agents/tmux.py +0 -0
  111. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/bridges/__init__.py +0 -0
  112. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/bridges/telegram.py +0 -0
  113. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/cached_status.py +0 -0
  114. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/channels/__init__.py +0 -0
  115. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/channels/_template.py +0 -0
  116. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/channels/base.py +0 -0
  117. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/channels/discord.py +0 -0
  118. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/channels/quo.py +0 -0
  119. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/channels/slack.py +0 -0
  120. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/channels/sms.py +0 -0
  121. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/channels/telegram.py +0 -0
  122. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/channels/webhook.py +0 -0
  123. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/cli_safety.py +0 -0
  124. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/completion.py +0 -0
  125. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/errors.py +0 -0
  126. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/history.py +0 -0
  127. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/__init__.py +0 -0
  128. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/__init__.py +0 -0
  129. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/audit_logger.py +0 -0
  130. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/edit-tool-damage-control.py +0 -0
  131. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/agentwire.yaml +0 -0
  132. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/aws.yaml +0 -0
  133. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/cloud-hosting.yaml +0 -0
  134. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/containers.yaml +0 -0
  135. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/core.yaml +0 -0
  136. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/databases.yaml +0 -0
  137. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/firebase.yaml +0 -0
  138. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/gcp.yaml +0 -0
  139. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/git.yaml +0 -0
  140. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/gws.yaml +0 -0
  141. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/infrastructure.yaml +0 -0
  142. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/rules/remote.yaml +0 -0
  143. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/damage-control/write-tool-damage-control.py +0 -0
  144. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/hooks/idle-handler.sh +0 -0
  145. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/init_agentwire.py +0 -0
  146. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/listen.py +0 -0
  147. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/locking.py +0 -0
  148. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/network.py +0 -0
  149. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/onboarding.py +0 -0
  150. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/pane_manager.py +0 -0
  151. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/projects.py +0 -0
  152. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/prompts/__init__.py +0 -0
  153. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/prompts/init.md +0 -0
  154. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/__init__.py +0 -0
  155. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/agentwire.md +0 -0
  156. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/channel-admin.md +0 -0
  157. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/chatbot.md +0 -0
  158. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/discord-dm.md +0 -0
  159. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/init.md +0 -0
  160. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/notifications.md +0 -0
  161. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/orchestrator.md +0 -0
  162. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/slack-dm.md +0 -0
  163. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/task-runner.md +0 -0
  164. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/voice.md +0 -0
  165. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/roles/worker.md +0 -0
  166. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/scheduler.py +0 -0
  167. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-Echo--black.png +0 -0
  168. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-Echo--transparent.png +0 -0
  169. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-Echo.png +0 -0
  170. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-email-banner.png +0 -0
  171. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers--agentwire-text.png +0 -0
  172. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers--echo-claw-fg.png +0 -0
  173. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers--echo.png +0 -0
  174. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers--full--transparent-top.png +0 -0
  175. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers--full-black.png +0 -0
  176. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers--telephone-fg.png +0 -0
  177. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers--telephone.png +0 -0
  178. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers--transparent-top.png +0 -0
  179. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers--transparent.png +0 -0
  180. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers--tree.png +0 -0
  181. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/agentwire-splash-logo-layers.png +0 -0
  182. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/favicon.png +0 -0
  183. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/android.jpeg +0 -0
  184. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/automaton.jpeg +0 -0
  185. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/bot.jpeg +0 -0
  186. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/cyborg.jpeg +0 -0
  187. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/droid.jpeg +0 -0
  188. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/drone.jpeg +0 -0
  189. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/guardian.jpeg +0 -0
  190. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/mech.jpeg +0 -0
  191. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/probe.jpeg +0 -0
  192. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/robot.jpeg +0 -0
  193. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/sentinel.jpeg +0 -0
  194. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/machines/unit.jpeg +0 -0
  195. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/blob.jpeg +0 -0
  196. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/cloud.jpeg +0 -0
  197. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/crystal.jpeg +0 -0
  198. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/cyclops.jpeg +0 -0
  199. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/flame.jpeg +0 -0
  200. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/fuzzy.jpeg +0 -0
  201. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/horned.jpeg +0 -0
  202. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/moon.jpeg +0 -0
  203. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/slime.jpeg +0 -0
  204. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/star.jpeg +0 -0
  205. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/tentacle.jpeg +0 -0
  206. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/projects/winged.jpeg +0 -0
  207. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/bear.jpeg +0 -0
  208. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/cat.jpeg +0 -0
  209. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/crown.jpeg +0 -0
  210. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/custom/agentwire-portal.png +0 -0
  211. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/custom/agentwire-tts.png +0 -0
  212. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/custom/agentwire.png +0 -0
  213. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/deer.jpeg +0 -0
  214. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/drone.jpeg +0 -0
  215. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/eagle.jpeg +0 -0
  216. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/fox.jpeg +0 -0
  217. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/hawk.jpeg +0 -0
  218. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/horse.jpeg +0 -0
  219. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/lion.jpeg +0 -0
  220. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/rabbit.jpeg +0 -0
  221. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/robot.jpeg +0 -0
  222. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/tiger.jpeg +0 -0
  223. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/icons/sessions/wolf.jpeg +0 -0
  224. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/.gitkeep +0 -0
  225. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/artifact-window.js +0 -0
  226. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/components/icon-picker.js +0 -0
  227. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/components/list-card.js +0 -0
  228. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/components/type-tag.js +0 -0
  229. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/desktop-manager.js +0 -0
  230. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/icon-manager.js +0 -0
  231. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/notifications-panel.js +0 -0
  232. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/session-window.js +0 -0
  233. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/sidebar/artifacts-section.js +0 -0
  234. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/sidebar/config-section.js +0 -0
  235. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/sidebar/machines-section.js +0 -0
  236. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/sidebar/projects-section.js +0 -0
  237. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/sidebar/scheduler-section.js +0 -0
  238. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/sidebar/services-section.js +0 -0
  239. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/sidebar/socials-section.js +0 -0
  240. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/sidebar.js +0 -0
  241. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/tile-manager.js +0 -0
  242. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/utils/auto-refresh.js +0 -0
  243. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/winbox.bundle.min.js +0 -0
  244. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/static/js/windows/chat-window.js +0 -0
  245. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/stt/__init__.py +0 -0
  246. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/stt/base.py +0 -0
  247. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/stt/server_backend.py +0 -0
  248. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/stt/stt_server.py +0 -0
  249. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/stt/whisperkit.py +0 -0
  250. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tasks.py +0 -0
  251. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/templates/__init__.py +0 -0
  252. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/templates/base.html +0 -0
  253. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/templates/desktop.html +0 -0
  254. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/templates/email_notification.html +0 -0
  255. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/templates/tmux.conf +0 -0
  256. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/templating.py +0 -0
  257. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tooldefs/aws.yaml +0 -0
  258. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tooldefs/docker.yaml +0 -0
  259. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tooldefs/gcp.yaml +0 -0
  260. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tooldefs/gh.yaml +0 -0
  261. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tooldefs/git.yaml +0 -0
  262. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tooldefs/gws.yaml +0 -0
  263. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tooldefs/kubectl.yaml +0 -0
  264. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tooldefs/npm.yaml +0 -0
  265. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tooldefs/terraform.yaml +0 -0
  266. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tooldefs/uv.yaml +0 -0
  267. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/__init__.py +0 -0
  268. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/base.py +0 -0
  269. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/engines/__init__.py +0 -0
  270. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/engines/chatterbox.py +0 -0
  271. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/engines/kokoro.py +0 -0
  272. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/engines/qwen_base.py +0 -0
  273. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/engines/qwen_custom.py +0 -0
  274. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/engines/qwen_design.py +0 -0
  275. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/engines/zonos.py +0 -0
  276. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/registry.py +0 -0
  277. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts/runpod_handler.py +0 -0
  278. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tts_server.py +0 -0
  279. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/tunnels.py +0 -0
  280. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/utils/__init__.py +0 -0
  281. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/utils/chunker.py +0 -0
  282. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/utils/file_io.py +0 -0
  283. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/utils/paths.py +0 -0
  284. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/utils/subprocess.py +0 -0
  285. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/validation.py +0 -0
  286. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/voiceclone.py +0 -0
  287. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/voices/darren.wav +0 -0
  288. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/voices/default.wav +0 -0
  289. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/voices/jessica.wav +0 -0
  290. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/voices/lisa.wav +0 -0
  291. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/voices/may.wav +0 -0
  292. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/workflows/__init__.py +0 -0
  293. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/workflows/context.py +0 -0
  294. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/workflows/outputs.py +0 -0
  295. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/agentwire/worktree.py +0 -0
  296. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/FEATURE-REQUESTS.md +0 -0
  297. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/FR-auto-mode-session-type.md +0 -0
  298. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/SHELL_ESCAPING.md +0 -0
  299. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/SPONSORS.md +0 -0
  300. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/TROUBLESHOOTING.md +0 -0
  301. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/README.md +0 -0
  302. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-agent-hot-swap.md +0 -0
  303. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-ambient-context-stream.md +0 -0
  304. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-ambient-listening-mode.md +0 -0
  305. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-audio-cues.md +0 -0
  306. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-checkpoint-commits.md +0 -0
  307. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-context-compression-protocol.md +0 -0
  308. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-context-window-gauge.md +0 -0
  309. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-contextual-bookmarks.md +0 -0
  310. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-conversation-archaeology.md +0 -0
  311. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-cost-tracking-dashboard.md +0 -0
  312. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-cross-session-events.md +0 -0
  313. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-delegation-replay.md +0 -0
  314. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-device-session-tethering.md +0 -0
  315. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-failure-memory.md +0 -0
  316. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-notification-escalation.md +0 -0
  317. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-periodic-voice-briefings.md +0 -0
  318. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-presence-aware-sessions.md +0 -0
  319. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-session-drift-detection.md +0 -0
  320. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-session-energy-model.md +0 -0
  321. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-session-handshake.md +0 -0
  322. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-session-momentum.md +0 -0
  323. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-session-replay.md +0 -0
  324. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-session-snapshots.md +0 -0
  325. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-session-templates.md +0 -0
  326. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-session-thermal-throttling.md +0 -0
  327. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-smart-session-routing.md +0 -0
  328. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-spatial-voice-mixing.md +0 -0
  329. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-speculative-execution.md +0 -0
  330. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-task-pipeline-chaining.md +0 -0
  331. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-task-pivot-protocol.md +0 -0
  332. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-task-time-budgets.md +0 -0
  333. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-voice-activity-zones.md +0 -0
  334. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-voice-breakpoints.md +0 -0
  335. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-voice-code-review.md +0 -0
  336. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-voice-command-undo.md +0 -0
  337. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-voice-handoff.md +0 -0
  338. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-voice-identity.md +0 -0
  339. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-voice-interrupts-v2.md +0 -0
  340. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-voice-interrupts.md +0 -0
  341. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-voice-macros.md +0 -0
  342. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-voice-transcript-logs.md +0 -0
  343. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-watchdog-mode.md +0 -0
  344. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-worker-fencing.md +0 -0
  345. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-worker-file-coordination.md +0 -0
  346. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-worker-health-dashboard.md +0 -0
  347. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-worker-heartbeat-watchdog.md +0 -0
  348. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-worker-progress-streaming.md +0 -0
  349. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-worker-proof-of-work.md +0 -0
  350. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-worker-warmup.md +0 -0
  351. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/brainstorms/idea-x-api-integration.md +0 -0
  352. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/channels.md +0 -0
  353. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/claude-code-auto-mode.md +0 -0
  354. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/critical-analysis.md +0 -0
  355. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/demo-script.md +0 -0
  356. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/gws-google-workspace-cli.md +0 -0
  357. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/hammerspoon.md +0 -0
  358. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/issues/pending-code-changes.md +0 -0
  359. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/issues/projects-dedup-ignores-machine.md +0 -0
  360. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/issues/remote-tts-session-detection.md +0 -0
  361. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/issues/tmux-config-onboarding.md +0 -0
  362. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/issues/tmux-paste-freeze.md +0 -0
  363. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/issues/tmux-recommended-config.md +0 -0
  364. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/logo.png +0 -0
  365. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/notification-hooks.md +0 -0
  366. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/progressive-loading-pattern.md +0 -0
  367. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/prompts/agentwire-website.md +0 -0
  368. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/releasing.md +0 -0
  369. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/remote-access.md +0 -0
  370. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/remote-machines.md +0 -0
  371. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/runpod-tts.md +0 -0
  372. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/security/damage-control-migration.md +0 -0
  373. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/security/damage-control.md +0 -0
  374. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/tmux-hooks.md +0 -0
  375. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/tts-self-hosted.md +0 -0
  376. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/docs/youtube-channel.md +0 -0
  377. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/requirements-tts.txt +0 -0
  378. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/conftest.py +0 -0
  379. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/e2e/test_portal_ui.py +0 -0
  380. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/fixtures/sample_agentwire.yml +0 -0
  381. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/fixtures/sample_config.yaml +0 -0
  382. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/fixtures/sample_scheduler.yaml +0 -0
  383. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/integration/test_channels_cli.py +0 -0
  384. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/integration/test_cli_commands.py +0 -0
  385. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/integration/test_cli_output.py +0 -0
  386. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/integration/test_mcp_tools.py +0 -0
  387. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/integration/test_portal_api.py +0 -0
  388. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/integration/test_scheduler_board.py +0 -0
  389. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/integration/test_scheduler_workflow.py +0 -0
  390. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_cli_safety.py +0 -0
  391. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_config.py +0 -0
  392. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_file_io.py +0 -0
  393. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_history.py +0 -0
  394. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_locking.py +0 -0
  395. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_mcp_server.py +0 -0
  396. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_project_config.py +0 -0
  397. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_roles.py +0 -0
  398. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_server_async.py +0 -0
  399. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_server_pure.py +0 -0
  400. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_tasks.py +0 -0
  401. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_templating.py +0 -0
  402. {agentwire_dev-1.23.0 → agentwire_dev-1.24.0}/tests/unit/test_worktree.py +0 -0
@@ -51,3 +51,6 @@ Thumbs.db
51
51
  test_*.wav
52
52
  test_output*.wav
53
53
  .agentwire/
54
+
55
+ # pytest-textual-snapshot diff page (regenerated each run)
56
+ snapshot_report.html
@@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ### Added
11
+
12
+ - **Anthropic workflow runner** — `runner: anthropic` alongside the existing pi runner (Phase 6, PRs 1–6)
13
+ - Pluggable runner registry (`agentwire/workflows/runners/`) with a shared `NodeRunner` Protocol; pi kept byte-for-byte identical behind a thin shim
14
+ - `AnthropicRunner` uses `claude-agent-sdk>=0.1.43` with subscription auth — no `ANTHROPIC_API_KEY` required, inherits `~/.claude/.credentials.json` (subscription-covered, no per-run billing)
15
+ - Tool execution is owned by Claude Code itself: `setting_sources=["user"]` loads `~/.claude/settings.json` so AgentWire's damage-control PreToolUse hooks fire on every Bash call (verified end-to-end by a live integration test that chmod 777's a sentinel file — hook blocks, file mode unchanged)
16
+ - Per-runner tool namespaces: pi stays lowercase (`read`, `bash`, `edit`, …), anthropic uses CamelCase (`Read`, `Bash`, `Edit`, …); parse-time validation rejects cross-namespace mixups
17
+ - Anthropic-only fields validated at parse time: `model` (required), `effort` (low|medium|high|max|xhigh — with Opus/Opus-4.7 gating), `thinking_config` (adaptive|enabled|disabled), `task_budget_tokens` (Opus 4.7 beta, min 20000), `max_thinking_tokens`, `max_budget_usd`
18
+ - Error classification: anthropic runner tags `NodeResult.error` with `transient:` / `permanent:` / `invalid:` / `error:` prefixes so rate-limited runs are distinguishable from genuine bugs
19
+ - **Live event streaming under `--verbose`** — `agentwire workflow run … -v` now streams per-event output for anthropic nodes: `[node] → tool_use Read …`, `← tool_result (ok/err)`, `▓ text`, `✓ turn 42+18 tok`, `■ agent_end 3.1s`
20
+ - **Runner recorded in metadata** — `metadata.json` bumped to `schema_version: 2` with run-level and per-node `runner` fields; `workflow show` renders a `Runner:` line + per-node tag + `Totals:` aggregation; `workflow history` gains a `runner` column
21
+ - **`--runner {pi,anthropic}` CLI override** — `agentwire workflow run` accepts `--runner` to flip every node's runner for one invocation; runner/field mismatches surface as normal validation errors
22
+ - **Canary live** — `daily-book-report` (daily 13:30) flipped to anthropic on 2026-04-17 (Sonnet 4.6 for fetch, Opus 4.7 for compose_and_send). Findings tracked in `docs/missions/anthropic-sdk-runner.md`
23
+ - **Damage-control honors session bypass modes** — `permission_mode: "bypassPermissions"` and `"auto"` now skip `ask:true` escalations for write-tier commands; hard blocks still fire. Fixes `--dangerously-skip-permissions` and autonomous-mode sessions being prompted per Bash call
24
+
25
+ ### Documentation
26
+
27
+ - New "Runners" section in `docs/workflows.md` covering per-runner fields, `--runner` usage, and live-event output
28
+ - `agentwire-workflows` skill updated — no longer claims pi-only; links to full Runners reference
29
+
10
30
  ## [1.23.0] - 2026-04-16
11
31
 
12
32
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentwire-dev
3
- Version: 1.23.0
3
+ Version: 1.24.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
@@ -694,8 +694,11 @@ Requires-Dist: python-dotenv>=1.0.0
694
694
  Requires-Dist: pyyaml>=6.0
695
695
  Requires-Dist: requests>=2.28.0
696
696
  Requires-Dist: resend>=2.0.0
697
+ Requires-Dist: rich>=13.0
698
+ Requires-Dist: textual>=0.80
697
699
  Provides-Extra: dev
698
700
  Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
701
+ Requires-Dist: pytest-textual-snapshot>=1.0.0; extra == 'dev'
699
702
  Requires-Dist: pytest>=7.0; extra == 'dev'
700
703
  Requires-Dist: ruff>=0.1.0; extra == 'dev'
701
704
  Provides-Extra: stt
@@ -1,3 +1,3 @@
1
1
  """AgentWire - Multi-session voice web interface for AI coding agents."""
2
2
 
3
- __version__ = "1.23.0"
3
+ __version__ = "1.24.0"
@@ -84,11 +84,42 @@ class AgentCommand:
84
84
  env: dict[str, str] = field(default_factory=dict) # Secrets to inject via tmux set-environment (keeps keys out of `ps`)
85
85
 
86
86
 
87
+ def _build_tmux_env_flags(env: dict[str, str]) -> list[str]:
88
+ """Build `-e KEY=VAL` flag pairs for `tmux new-session`.
89
+
90
+ Prefer this over post-creation `inject_session_env` when creating a fresh
91
+ session with secrets: `tmux new-session -e K=V` places the var in the
92
+ session environment BEFORE the initial shell starts, so that shell sees
93
+ it. `tmux set-environment` on an existing session only affects shells
94
+ spawned AFTER the call, which leaves the initial pane's shell without
95
+ the var — and the agent command runs in that initial shell.
96
+ """
97
+ flags: list[str] = []
98
+ for key, value in env.items():
99
+ flags.extend(["-e", f"{key}={value}"])
100
+ return flags
101
+
102
+
103
+ def _build_tmux_env_flags_shell(env: dict[str, str]) -> str:
104
+ """Shell-safe `-e 'K=V' -e 'K2=V2' ` fragment for inlining in remote SSH chained commands.
105
+
106
+ Returns empty string when env is empty. Trailing space when non-empty so
107
+ the caller can concatenate directly into a `tmux new-session ... && ...`
108
+ string without extra glue.
109
+ """
110
+ if not env:
111
+ return ""
112
+ parts = [f"-e {shlex.quote(f'{k}={v}')}" for k, v in env.items()]
113
+ return " ".join(parts) + " "
114
+
115
+
87
116
  def inject_session_env(session: str, env: dict[str, str], remote_host: str | None = None) -> None:
88
- """Set env vars on a tmux session so panes inherit them without exposing secrets.
117
+ """Set env vars on an existing tmux session for FUTURE shells in that session.
89
118
 
90
- Using `tmux set-environment -t <session>` keeps API keys out of the command
91
- string (which would otherwise be visible in `ps auxwww` and shell history).
119
+ Does NOT update the initial pane's shell that shell was already started
120
+ when the session was created and has a fixed env. Use
121
+ `_build_tmux_env_flags(env)` with `tmux new-session -e K=V` instead if
122
+ the agent command runs in the initial shell.
92
123
  """
93
124
  if not env:
94
125
  return
@@ -126,30 +157,13 @@ def parse_env_args(env_args: list[str] | None) -> dict[str, str]:
126
157
  return result
127
158
 
128
159
 
129
- def build_session_env_shell_fragment(session: str, env: dict[str, str]) -> str:
130
- """Build a shell fragment of `tmux set-environment` calls for chained remote commands.
131
-
132
- Returns a trailing `&& ` string ready to splice into an ssh-executed compound
133
- command. Empty string if no env.
134
- """
135
- if not env:
136
- return ""
137
- parts = []
138
- for key, value in env.items():
139
- parts.append(
140
- f"tmux set-environment -t {shlex.quote(session)} "
141
- f"{shlex.quote(key)} {shlex.quote(value)}"
142
- )
143
- return " && ".join(parts) + " && "
144
-
145
-
146
160
  def build_agent_command(session_type: str, roles: list[RoleConfig] | None = None, model: str | None = None) -> AgentCommand:
147
161
  """Build the agent command for a session.
148
162
 
149
163
  Args:
150
164
  session_type: Session type (e.g., "claude-bypass", "claude-auto", "pi-zai", "bare")
151
165
  roles: Optional list of roles to apply
152
- model: Optional model override (e.g., "haiku", "sonnet", "opus", "glm-5")
166
+ model: Optional model override (e.g., "haiku", "sonnet", "opus", "glm-5.1")
153
167
 
154
168
  Returns:
155
169
  AgentCommand with the command string and metadata
@@ -170,7 +184,7 @@ def build_agent_command(session_type: str, roles: list[RoleConfig] | None = None
170
184
  # Pi reads ZAI_API_KEY from env. We inject it via `tmux set-environment`
171
185
  # (see inject_session_env) so the key never appears in `ps auxwww`.
172
186
  pi_binary = pi_config.get("binary", "pi")
173
- default_model = pi_config.get("default_model", "glm-5")
187
+ default_model = pi_config.get("default_model", "glm-5.1")
174
188
 
175
189
  parts = [pi_binary, "--provider", "zai"]
176
190
  parts.extend(["--model", model or default_model])
@@ -204,6 +218,38 @@ def build_agent_command(session_type: str, roles: list[RoleConfig] | None = None
204
218
  env={"ZAI_API_KEY": zai.get("api_key", "")},
205
219
  )
206
220
 
221
+ # === Agentwire REPL (claude-agent-sdk) ===
222
+ # sdk-bypass / sdk-prompted / sdk-restricted — Python REPL running in a
223
+ # tmux pane, auth via Claude subscription. See docs/missions/agentwire-repl.md.
224
+ if session_type.startswith("sdk-"):
225
+ # Permission mode maps to SDK's permission_mode parameter
226
+ mode_map = {
227
+ "sdk-bypass": "bypass",
228
+ "sdk-prompted": "prompted",
229
+ "sdk-restricted": "restricted",
230
+ }
231
+ mode = mode_map.get(session_type, "bypass")
232
+
233
+ parts = ["agentwire", "repl", "--mode", mode]
234
+ if model:
235
+ parts.extend(["--model", model])
236
+
237
+ # Role-based system prompt (same temp-file pattern as claude-* / pi-zai
238
+ # to avoid shell escaping on multiline content; --append-system-prompt
239
+ # must be last).
240
+ temp_file = None
241
+ if merged and merged.instructions:
242
+ f = tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False)
243
+ f.write(merged.instructions)
244
+ f.close()
245
+ temp_file = f.name
246
+ parts.append(f'--append-system-prompt "$(<{temp_file})"')
247
+
248
+ return AgentCommand(
249
+ command=" ".join(parts),
250
+ temp_file=temp_file,
251
+ )
252
+
207
253
  # === Claude Code ===
208
254
  if session_type.startswith("claude"):
209
255
  parts = ["claude"]
@@ -3381,6 +3427,31 @@ def cmd_list(args) -> int:
3381
3427
  return 0
3382
3428
 
3383
3429
 
3430
+ def cmd_repl(args) -> int:
3431
+ """Agentwire REPL — interactive harness built on claude-agent-sdk.
3432
+
3433
+ Invoked by build_agent_command when a session is spawned with --type sdk-*.
3434
+ Interactive mode auto-persists every turn under
3435
+ `~/.agentwire/sessions/repl/<session-name>/`; `--resume NAME` continues a
3436
+ prior session by reusing its sdk_session_id.
3437
+ """
3438
+ from agentwire.repl.app import run_repl
3439
+ return run_repl(
3440
+ mode=args.mode,
3441
+ model=args.model,
3442
+ print_prompt=args.print,
3443
+ system_prompt=args.append_system_prompt,
3444
+ session_name=getattr(args, "session_name", None),
3445
+ resume=getattr(args, "resume", None),
3446
+ roles=getattr(args, "roles", None),
3447
+ view=getattr(args, "view", "chat"),
3448
+ cols=getattr(args, "cols", 3),
3449
+ col_models=getattr(args, "col_models", None),
3450
+ col_efforts=getattr(args, "col_efforts", None),
3451
+ col_roles=getattr(args, "col_roles", None),
3452
+ )
3453
+
3454
+
3384
3455
  def cmd_new(args) -> int:
3385
3456
  """Create a new agent session.
3386
3457
 
@@ -3548,21 +3619,22 @@ def cmd_new(args) -> int:
3548
3619
  except Exception as e:
3549
3620
  print(f"Warning: Failed to write system prompt to remote: {e}", file=sys.stderr)
3550
3621
 
3551
- env_fragment = build_session_env_shell_fragment(session_name, agent.env)
3622
+ env_flags = _build_tmux_env_flags_shell(agent.env)
3552
3623
 
3553
- # Create session - Agent starts immediately if not bare
3624
+ # Create session - Agent starts immediately if not bare.
3625
+ # `-e K=V` on new-session places env in the session environment BEFORE
3626
+ # the initial shell starts, so send-keys'd agent command sees it.
3554
3627
  if agent_cmd:
3555
3628
  create_cmd = (
3556
- f"tmux new-session -d -s {shlex.quote(session_name)} -c {shlex.quote(remote_path)} && "
3629
+ f"tmux new-session -d -s {shlex.quote(session_name)} -c {shlex.quote(remote_path)} {env_flags}&& "
3557
3630
  f"tmux send-keys -t {shlex.quote(session_name)} 'cd {shlex.quote(remote_path)}' Enter && "
3558
3631
  f"sleep 0.1 && "
3559
- f"{env_fragment}"
3560
3632
  f"tmux send-keys -t {shlex.quote(session_name)} {shlex.quote(agent_cmd)} Enter"
3561
3633
  )
3562
3634
  else:
3563
3635
  # Bare session - just create tmux
3564
3636
  create_cmd = (
3565
- f"tmux new-session -d -s {shlex.quote(session_name)} -c {shlex.quote(remote_path)} && "
3637
+ f"tmux new-session -d -s {shlex.quote(session_name)} -c {shlex.quote(remote_path)} {env_flags}&& "
3566
3638
  f"tmux send-keys -t {shlex.quote(session_name)} 'cd {shlex.quote(remote_path)}' Enter"
3567
3639
  )
3568
3640
 
@@ -3650,20 +3722,10 @@ def cmd_new(args) -> int:
3650
3722
  else:
3651
3723
  return _output_result(False, json_mode, f"Session '{session_name}' already exists. Use -f to replace.")
3652
3724
 
3653
- # Create new tmux session
3654
- subprocess.run(
3655
- ["tmux", "new-session", "-d", "-s", session_name, "-c", str(session_path)],
3656
- check=True
3657
- )
3658
-
3659
- # Ensure Claude starts in correct directory
3660
- subprocess.run(
3661
- ["tmux", "send-keys", "-t", session_name, f"cd {shlex.quote(str(session_path))}", "Enter"],
3662
- check=True
3663
- )
3664
- time.sleep(0.1)
3665
-
3666
- # Determine agent type and normalize session type
3725
+ # Determine agent type and normalize session type BEFORE creating the
3726
+ # tmux session, so we can inject secrets via `tmux new-session -e K=V`
3727
+ # (the only way to make the initial pane's shell see them — post-hoc
3728
+ # `tmux set-environment` only affects shells spawned AFTER the call).
3667
3729
  agent_type = detect_default_agent_type()
3668
3730
 
3669
3731
  # Determine session type from CLI --type flag or existing config
@@ -3701,8 +3763,21 @@ def cmd_new(args) -> int:
3701
3763
 
3702
3764
  agent_cmd = agent.command
3703
3765
 
3704
- # Inject secrets via tmux set-environment (keeps keys out of `ps`)
3705
- inject_session_env(session_name, agent.env)
3766
+ # Create new tmux session with env vars injected at creation time.
3767
+ # `-e K=V` places vars in the session environment before the initial
3768
+ # shell starts, so the agent command (run via send-keys below) sees them.
3769
+ subprocess.run(
3770
+ ["tmux", "new-session", "-d", "-s", session_name, "-c", str(session_path),
3771
+ *_build_tmux_env_flags(agent.env)],
3772
+ check=True
3773
+ )
3774
+
3775
+ # Ensure Claude starts in correct directory
3776
+ subprocess.run(
3777
+ ["tmux", "send-keys", "-t", session_name, f"cd {shlex.quote(str(session_path))}", "Enter"],
3778
+ check=True
3779
+ )
3780
+ time.sleep(0.1)
3706
3781
 
3707
3782
  # Start agent command if not bare
3708
3783
  if agent_cmd:
@@ -4590,13 +4665,12 @@ def cmd_recreate(args) -> int:
4590
4665
  agent = build_agent_command(session_type_str)
4591
4666
  agent.env.update(parse_env_args(getattr(args, 'env', None)))
4592
4667
  agent_cmd = agent.command
4593
- env_fragment = build_session_env_shell_fragment(session_name, agent.env)
4668
+ env_flags = _build_tmux_env_flags_shell(agent.env)
4594
4669
 
4595
4670
  create_cmd = (
4596
- f"tmux new-session -d -s {shlex.quote(session_name)} -c {shlex.quote(session_path)} && "
4671
+ f"tmux new-session -d -s {shlex.quote(session_name)} -c {shlex.quote(session_path)} {env_flags}&& "
4597
4672
  f"tmux send-keys -t {shlex.quote(session_name)} 'cd {shlex.quote(session_path)}' Enter && "
4598
4673
  f"sleep 0.1 && "
4599
- f"{env_fragment}"
4600
4674
  f"tmux send-keys -t {shlex.quote(session_name)} {shlex.quote(agent_cmd)} Enter"
4601
4675
  )
4602
4676
 
@@ -4697,9 +4771,12 @@ def cmd_recreate(args) -> int:
4697
4771
 
4698
4772
  agent_cmd = agent.command
4699
4773
 
4700
- # Step 5: Create new session
4774
+ # Step 5: Create new session with env vars injected at creation time so
4775
+ # the initial shell sees them (post-hoc set-environment doesn't reach the
4776
+ # already-running shell — see _build_tmux_env_flags docstring).
4701
4777
  subprocess.run(
4702
- ["tmux", "new-session", "-d", "-s", session_name, "-c", str(session_path)],
4778
+ ["tmux", "new-session", "-d", "-s", session_name, "-c", str(session_path),
4779
+ *_build_tmux_env_flags(agent.env)],
4703
4780
  check=True
4704
4781
  )
4705
4782
 
@@ -4710,9 +4787,6 @@ def cmd_recreate(args) -> int:
4710
4787
  )
4711
4788
  time.sleep(0.1)
4712
4789
 
4713
- # Inject secrets via tmux set-environment (keeps keys out of `ps`)
4714
- inject_session_env(session_name, agent.env)
4715
-
4716
4790
  # Start the agent with appropriate command
4717
4791
  if agent_cmd:
4718
4792
  subprocess.run(
@@ -4973,13 +5047,12 @@ def cmd_fork(args) -> int:
4973
5047
  agent.env.update(parse_env_args(getattr(args, 'env', None)))
4974
5048
 
4975
5049
  agent_cmd = agent.command
4976
- env_fragment = build_session_env_shell_fragment(target_session, agent.env)
5050
+ env_flags = _build_tmux_env_flags_shell(agent.env)
4977
5051
 
4978
5052
  create_session_cmd = (
4979
- f"tmux new-session -d -s {shlex.quote(target_session)} -c {shlex.quote(target_path)} && "
5053
+ f"tmux new-session -d -s {shlex.quote(target_session)} -c {shlex.quote(target_path)} {env_flags}&& "
4980
5054
  f"tmux send-keys -t {shlex.quote(target_session)} 'cd {shlex.quote(target_path)}' Enter && "
4981
5055
  f"sleep 0.1 && "
4982
- f"{env_fragment}"
4983
5056
  f"tmux send-keys -t {shlex.quote(target_session)} {shlex.quote(agent_cmd)} Enter"
4984
5057
  )
4985
5058
 
@@ -5039,20 +5112,8 @@ def cmd_fork(args) -> int:
5039
5112
  if check_target.returncode == 0:
5040
5113
  return _output_result(False, json_mode, f"Target session '{target_session}' already exists")
5041
5114
 
5042
- # Create new tmux session in same directory
5043
- subprocess.run(
5044
- ["tmux", "new-session", "-d", "-s", target_session, "-c", str(fork_path)],
5045
- check=True
5046
- )
5047
-
5048
- # Ensure Claude starts in correct directory
5049
- subprocess.run(
5050
- ["tmux", "send-keys", "-t", target_session, f"cd {shlex.quote(str(fork_path))}", "Enter"],
5051
- check=True
5052
- )
5053
- time.sleep(0.1)
5054
-
5055
- # Determine session type from --type flag or source config
5115
+ # Determine session type from --type flag or source config (before
5116
+ # session creation, so we can inject env via `tmux new-session -e K=V`).
5056
5117
  agent_type = detect_default_agent_type()
5057
5118
  type_arg = getattr(args, 'type', None)
5058
5119
  source_project_config = load_project_config(fork_path)
@@ -5128,8 +5189,20 @@ def cmd_fork(args) -> int:
5128
5189
  agent = build_agent_command(session_type_str, roles)
5129
5190
  agent.env.update(parse_env_args(getattr(args, 'env', None)))
5130
5191
 
5131
- # Inject secrets via tmux set-environment (keeps keys out of `ps`)
5132
- inject_session_env(target_session, agent.env)
5192
+ # Create new tmux session with env injected at creation time so the
5193
+ # initial shell sees the vars (see _build_tmux_env_flags docstring).
5194
+ subprocess.run(
5195
+ ["tmux", "new-session", "-d", "-s", target_session, "-c", str(fork_path),
5196
+ *_build_tmux_env_flags(agent.env)],
5197
+ check=True
5198
+ )
5199
+
5200
+ # Ensure Claude starts in correct directory
5201
+ subprocess.run(
5202
+ ["tmux", "send-keys", "-t", target_session, f"cd {shlex.quote(str(fork_path))}", "Enter"],
5203
+ check=True
5204
+ )
5205
+ time.sleep(0.1)
5133
5206
 
5134
5207
  agent_cmd = agent.command
5135
5208
  if agent_cmd:
@@ -5205,20 +5278,8 @@ def cmd_fork(args) -> int:
5205
5278
  if not success:
5206
5279
  return _output_result(False, json_mode, f"Failed to create worktree for branch '{target_branch}'")
5207
5280
 
5208
- # Create new session
5209
- subprocess.run(
5210
- ["tmux", "new-session", "-d", "-s", target_session, "-c", str(target_path)],
5211
- check=True
5212
- )
5213
-
5214
- # Ensure agent starts in correct directory
5215
- subprocess.run(
5216
- ["tmux", "send-keys", "-t", target_session, f"cd {shlex.quote(str(target_path))}", "Enter"],
5217
- check=True
5218
- )
5219
- time.sleep(0.1)
5220
-
5221
- # Determine session type from --type flag or source config
5281
+ # Determine session type from --type flag or source config (before
5282
+ # session creation, so we can inject env via `tmux new-session -e K=V`).
5222
5283
  agent_type = detect_default_agent_type()
5223
5284
  type_arg = getattr(args, 'type', None)
5224
5285
  config_path = source_path if source_path != project_path else project_path
@@ -5246,8 +5307,20 @@ def cmd_fork(args) -> int:
5246
5307
  agent.env.update(parse_env_args(getattr(args, 'env', None)))
5247
5308
  agent_cmd = agent.command
5248
5309
 
5249
- # Inject secrets via tmux set-environment (keeps keys out of `ps`)
5250
- inject_session_env(target_session, agent.env)
5310
+ # Create new session with env injected at creation time so the initial
5311
+ # shell sees the vars (see _build_tmux_env_flags docstring).
5312
+ subprocess.run(
5313
+ ["tmux", "new-session", "-d", "-s", target_session, "-c", str(target_path),
5314
+ *_build_tmux_env_flags(agent.env)],
5315
+ check=True
5316
+ )
5317
+
5318
+ # Ensure agent starts in correct directory
5319
+ subprocess.run(
5320
+ ["tmux", "send-keys", "-t", target_session, f"cd {shlex.quote(str(target_path))}", "Enter"],
5321
+ check=True
5322
+ )
5323
+ time.sleep(0.1)
5251
5324
 
5252
5325
  if agent_cmd:
5253
5326
  subprocess.run(
@@ -5840,15 +5913,14 @@ def cmd_dev(args) -> int:
5840
5913
 
5841
5914
  agent_cmd = agent.command
5842
5915
 
5843
- # Create session
5916
+ # Create session with env injected at creation time so the initial
5917
+ # shell sees the vars (see _build_tmux_env_flags docstring).
5844
5918
  print(f"Creating dev session '{session_name}' in {project_dir}...")
5845
5919
  subprocess.run([
5846
5920
  "tmux", "new-session", "-d", "-s", session_name, "-c", str(project_dir),
5921
+ *_build_tmux_env_flags(agent.env),
5847
5922
  ])
5848
5923
 
5849
- # Inject secrets via tmux set-environment (keeps keys out of `ps`)
5850
- inject_session_env(session_name, agent.env)
5851
-
5852
5924
  # Start agent with agentwire config
5853
5925
  if agent_cmd:
5854
5926
  wait_for_shell_prompt(session_name)
@@ -10025,7 +10097,10 @@ def main() -> int:
10025
10097
  # === email command ===
10026
10098
  from agentwire.channels.email import cmd_email
10027
10099
  email_parser = subparsers.add_parser("email", help="Send branded email notification via Resend")
10028
- email_parser.add_argument("--to", type=str, help="Recipient email (default: from config)")
10100
+ email_parser.add_argument(
10101
+ "--to", action="append", default=None,
10102
+ help="Recipient email. Repeat or pass comma-separated for multiple recipients (default: from config).",
10103
+ )
10029
10104
  email_parser.add_argument("--subject", "-s", type=str, help="Email subject")
10030
10105
  email_parser.add_argument("--body", "-b", type=str, help="Email body - markdown supported (or pipe via stdin)")
10031
10106
  email_parser.add_argument("--attach", "-a", type=str, action="append", help="Attach file (can use multiple times)")
@@ -10033,6 +10108,22 @@ def main() -> int:
10033
10108
  email_parser.add_argument("-q", "--quiet", action="store_true", help="Suppress success output")
10034
10109
  email_parser.set_defaults(func=cmd_email)
10035
10110
 
10111
+ # === brave command ===
10112
+ from agentwire.search import cmd_brave
10113
+ brave_parser = subparsers.add_parser(
10114
+ "brave",
10115
+ help="Brave Search helper — run a web search and print results optimized for LLM consumption.",
10116
+ )
10117
+ brave_parser.add_argument("query", nargs="+", help="Search query (all remaining args joined with spaces)")
10118
+ brave_parser.add_argument("--count", "-n", type=int, default=10, help="Max results (1-20, default 10)")
10119
+ brave_parser.add_argument(
10120
+ "--freshness", "-f", type=str, default="pd",
10121
+ choices=["pd", "pw", "pm", "py"],
10122
+ help="Time window: pd=past day (default), pw=past week, pm=past month, py=past year",
10123
+ )
10124
+ brave_parser.add_argument("--json", action="store_true", help="Output raw JSON instead of compact text")
10125
+ brave_parser.set_defaults(func=cmd_brave)
10126
+
10036
10127
  # === notify command ===
10037
10128
  notify_parser = subparsers.add_parser("notify", help="Notify portal of session/pane state changes")
10038
10129
  notify_parser.add_argument(
@@ -10074,12 +10165,66 @@ def main() -> int:
10074
10165
  list_parser.set_defaults(func=cmd_list)
10075
10166
 
10076
10167
  # === new command (top-level) ===
10168
+ # === repl command (top-level, internal — invoked by build_agent_command) ===
10169
+ # Users spawn it via `agentwire new -s <name> --type sdk-bypass`; this is
10170
+ # the process that runs inside the tmux pane. See docs/missions/agentwire-repl.md.
10171
+ repl_parser = subparsers.add_parser(
10172
+ "repl",
10173
+ help="Agentwire REPL (internal — runs inside tmux pane for sdk-* session types)",
10174
+ )
10175
+ repl_parser.add_argument(
10176
+ "--mode", choices=["bypass", "prompted", "restricted"], default="bypass",
10177
+ help="Permission mode (bypass=run tools without asking, prompted=ask, restricted=read-only)",
10178
+ )
10179
+ repl_parser.add_argument("--model", default=None, help="Model override (default: claude-opus-4-7)")
10180
+ repl_parser.add_argument(
10181
+ "-p", "--print", dest="print", default=None, metavar="PROMPT",
10182
+ help="One-shot mode: run PROMPT, emit output, exit (no interactive loop)",
10183
+ )
10184
+ repl_parser.add_argument(
10185
+ "--append-system-prompt", dest="append_system_prompt", default=None, metavar="TEXT",
10186
+ help="Additional system prompt content (appended after base prompt)",
10187
+ )
10188
+ repl_parser.add_argument(
10189
+ "--session-name", dest="session_name", default=None, metavar="NAME",
10190
+ help="Transcript directory name under ~/.agentwire/sessions/repl/ (default: auto-generated timestamp+hash)",
10191
+ )
10192
+ repl_parser.add_argument(
10193
+ "--resume", dest="resume", default=None, metavar="NAME",
10194
+ help="Resume the saved session NAME (reuses its sdk_session_id to continue the prior conversation)",
10195
+ )
10196
+ repl_parser.add_argument(
10197
+ "--role", dest="roles", action="append", metavar="NAME",
10198
+ help="Role name to compose into the system prompt (repeatable). Overrides .agentwire.yml roles.",
10199
+ )
10200
+ repl_parser.add_argument(
10201
+ "--view", choices=["chat", "fanout"], default="chat",
10202
+ help="UI view: 'chat' (default, single conversation) or 'fanout' (N parallel columns).",
10203
+ )
10204
+ repl_parser.add_argument(
10205
+ "--cols", type=int, default=3, metavar="N",
10206
+ help="Column count for --view fanout (2-6, default 3).",
10207
+ )
10208
+ repl_parser.add_argument(
10209
+ "--col-model", dest="col_models", action="append", metavar="N=MODEL",
10210
+ help="Per-column model override for --view fanout (e.g. --col-model 0=claude-opus-4-7 --col-model 1=claude-sonnet-4-6). Repeatable.",
10211
+ )
10212
+ repl_parser.add_argument(
10213
+ "--col-effort", dest="col_efforts", action="append", metavar="N=EFFORT",
10214
+ help="Per-column effort override for --view fanout (e.g. --col-effort 0=max --col-effort 1=high). Repeatable.",
10215
+ )
10216
+ repl_parser.add_argument(
10217
+ "--col-role", dest="col_roles", action="append", metavar="N=ROLE[,ROLE...]",
10218
+ help="Per-column role override for --view fanout (e.g. --col-role 0=skeptic --col-role 1=optimist,explainer). Repeatable.",
10219
+ )
10220
+ repl_parser.set_defaults(func=cmd_repl)
10221
+
10077
10222
  new_parser = subparsers.add_parser("new", help="Create new Claude Code session")
10078
10223
  new_parser.add_argument("-s", "--session", required=True, help="Session name (project, project/branch, or project/branch@machine)")
10079
10224
  new_parser.add_argument("-p", "--path", help="Working directory (default: ~/projects/<name>)")
10080
10225
  new_parser.add_argument("-f", "--force", action="store_true", help="Replace existing session")
10081
10226
  # Session type
10082
- new_parser.add_argument("--type", help="Session type (bare, claude-bypass, claude-prompted, claude-restricted, pi-zai, pi-zai-restricted, pi-zai-readonly, standard, worker, voice)")
10227
+ new_parser.add_argument("--type", help="Session type (bare, claude-bypass, claude-prompted, claude-restricted, pi-zai, pi-zai-restricted, pi-zai-readonly, sdk-bypass, sdk-prompted, sdk-restricted, standard, worker, voice)")
10083
10228
  # Roles
10084
10229
  new_parser.add_argument("--roles", help="Comma-separated list of roles (preserves existing config, defaults to agentwire for new projects)")
10085
10230
  new_parser.add_argument("--model", help="Model override (e.g., haiku, sonnet, opus)")
@@ -10222,6 +10367,10 @@ def main() -> int:
10222
10367
  "--input-file", metavar="PATH",
10223
10368
  help="JSON file with inputs (object mapping name → value)"
10224
10369
  )
10370
+ wf_run.add_argument(
10371
+ "--runner", choices=["pi", "anthropic"], default=None,
10372
+ help="Override runner for every node in this run (YAML declarations ignored)."
10373
+ )
10225
10374
  wf_run.add_argument("--dry-run", action="store_true", help="Print plan without running")
10226
10375
  wf_run.add_argument("--verbose", "-v", action="store_true", help="Verbose output")
10227
10376
  wf_run.add_argument("--json", action="store_true", help="Output as JSON")
@@ -166,8 +166,34 @@ def _get_email_config() -> EmailConfig:
166
166
  return EmailConfig()
167
167
 
168
168
 
169
+ def _normalize_recipients(to: Optional[str | list[str]], default_to: str) -> list[str]:
170
+ """Flatten `to` (str | list[str]) into a deduped list, splitting on commas.
171
+
172
+ Accepts: None, "a@x.com", "a@x.com,b@y.com", ["a@x.com"], ["a,b", "c"].
173
+ Falls back to `default_to` (also comma-split) when `to` is None/empty.
174
+ Preserves order, drops duplicates and empty entries.
175
+ """
176
+ raw: list[str] = []
177
+ if not to:
178
+ raw = [default_to] if default_to else []
179
+ elif isinstance(to, str):
180
+ raw = [to]
181
+ else:
182
+ raw = list(to)
183
+
184
+ out: list[str] = []
185
+ seen: set[str] = set()
186
+ for entry in raw:
187
+ for part in str(entry).split(","):
188
+ addr = part.strip()
189
+ if addr and addr not in seen:
190
+ seen.add(addr)
191
+ out.append(addr)
192
+ return out
193
+
194
+
169
195
  def send_email(
170
- to: Optional[str] = None,
196
+ to: Optional[str | list[str]] = None,
171
197
  subject: str = "",
172
198
  body: str = "",
173
199
  attachments: Optional[list[Path | str]] = None,
@@ -178,7 +204,8 @@ def send_email(
178
204
  """Send a branded email via Resend.
179
205
 
180
206
  Args:
181
- to: Recipient email address. Uses config default_to if not specified.
207
+ to: Recipient email(s). Accepts a single address, a comma-separated
208
+ string, or a list of either. Uses config default_to if not specified.
182
209
  subject: Email subject line.
183
210
  body: Email body (markdown supported, converted to HTML).
184
211
  attachments: List of file paths to attach.
@@ -202,9 +229,9 @@ def send_email(
202
229
  "or set channels.email.api_key in ~/.agentwire/config.yaml"
203
230
  )
204
231
 
205
- # Determine recipient
206
- recipient = to or email_config.default_to
207
- if not recipient:
232
+ # Determine recipients (list form — Resend's `to` field accepts an array)
233
+ recipients = _normalize_recipients(to, email_config.default_to)
234
+ if not recipients:
208
235
  raise EmailConfigError(
209
236
  "No recipient specified and no default_to configured in "
210
237
  "channels.email.default_to"
@@ -247,7 +274,7 @@ def send_email(
247
274
 
248
275
  params: dict = {
249
276
  "from": sender,
250
- "to": [recipient],
277
+ "to": recipients,
251
278
  "subject": email_subject,
252
279
  }
253
280