agentwire-dev 1.3.1__tar.gz → 1.4.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 (265) hide show
  1. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/PKG-INFO +1 -1
  2. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/__init__.py +1 -1
  3. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/__main__.py +139 -19
  4. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/agents/tmux.py +47 -18
  5. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/config.py +22 -0
  6. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/mcp_server.py +843 -0
  7. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/notifications.py +1 -1
  8. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/onboarding.py +59 -0
  9. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/pane_manager.py +14 -6
  10. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/server.py +262 -3
  11. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/css/desktop.css +80 -0
  12. agentwire_dev-1.4.0/agentwire/static/js/artifact-window.js +211 -0
  13. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/js/desktop-manager.js +44 -0
  14. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/js/desktop.js +92 -0
  15. agentwire_dev-1.4.0/agentwire/static/js/windows/artifacts-window.js +90 -0
  16. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/js/windows/projects-window.js +1 -0
  17. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/templates/desktop.html +1 -0
  18. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/templates/email_notification.html +12 -4
  19. agentwire_dev-1.4.0/agentwire/templates/tmux.conf +98 -0
  20. agentwire_dev-1.4.0/docs/issues/projects-dedup-ignores-machine.md +34 -0
  21. agentwire_dev-1.4.0/docs/issues/tmux-config-onboarding.md +120 -0
  22. agentwire_dev-1.4.0/docs/issues/tmux-paste-freeze.md +89 -0
  23. agentwire_dev-1.4.0/docs/issues/tmux-recommended-config.md +90 -0
  24. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/pyproject.toml +1 -0
  25. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/.github/FUNDING.yml +0 -0
  26. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  27. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  28. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
  29. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  30. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/.github/workflows/ci.yml +0 -0
  31. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/.github/workflows/publish.yml +0 -0
  32. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/.gitignore +0 -0
  33. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/CHANGELOG.md +0 -0
  34. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/CLA.md +0 -0
  35. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/CODE_OF_CONDUCT.md +0 -0
  36. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/CONTRIBUTING.md +0 -0
  37. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/Dockerfile.local +0 -0
  38. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/Dockerfile.runpod +0 -0
  39. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/LICENSE +0 -0
  40. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/README.md +0 -0
  41. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/RELEASING.md +0 -0
  42. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/SECURITY.md +0 -0
  43. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/SPONSORS.md +0 -0
  44. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/agents/__init__.py +0 -0
  45. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/agents/base.py +0 -0
  46. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/cached_status.py +0 -0
  47. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/cli_safety.py +0 -0
  48. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/completion.py +0 -0
  49. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/errors.py +0 -0
  50. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/history.py +0 -0
  51. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/hooks/__init__.py +0 -0
  52. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/hooks/agentwire-permission.sh +0 -0
  53. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/hooks/damage-control/__init__.py +0 -0
  54. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/hooks/damage-control/audit_logger.py +0 -0
  55. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/hooks/damage-control/bash-tool-damage-control.py +0 -0
  56. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/hooks/damage-control/edit-tool-damage-control.py +0 -0
  57. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/hooks/damage-control/patterns.yaml +0 -0
  58. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/hooks/damage-control/write-tool-damage-control.py +0 -0
  59. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/hooks/idle-handler.sh +0 -0
  60. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/init_agentwire.py +0 -0
  61. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/listen.py +0 -0
  62. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/locking.py +0 -0
  63. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/network.py +0 -0
  64. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/project_config.py +0 -0
  65. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/projects.py +0 -0
  66. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/prompts/__init__.py +0 -0
  67. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/prompts/init.md +0 -0
  68. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/roles/__init__.py +0 -0
  69. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/roles/chatbot.md +0 -0
  70. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/roles/claude-delegation.md +0 -0
  71. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/roles/claude-worker-haiku.md +0 -0
  72. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/roles/claude-worker-sonnet.md +0 -0
  73. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/roles/claude-worker.md +0 -0
  74. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/roles/glm-delegation.md +0 -0
  75. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/roles/glm-worker-flash.md +0 -0
  76. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/roles/glm-worker.md +0 -0
  77. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/roles/init.md +0 -0
  78. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/roles/leader-claude.md +0 -0
  79. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/roles/leader-glm.md +0 -0
  80. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/roles/leader-openai.md +0 -0
  81. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/roles/leader.md +0 -0
  82. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/roles/openai-delegation.md +0 -0
  83. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/roles/openai-worker-mini.md +0 -0
  84. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/roles/openai-worker.md +0 -0
  85. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/roles/task-runner.md +0 -0
  86. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/roles/voice.md +0 -0
  87. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/roles/worker.md +0 -0
  88. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/agentwire-Echo--black.png +0 -0
  89. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/agentwire-Echo--transparent.png +0 -0
  90. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/agentwire-Echo.png +0 -0
  91. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/agentwire-email-banner.png +0 -0
  92. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/agentwire-splash-logo-layers--agentwire-text.png +0 -0
  93. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/agentwire-splash-logo-layers--echo-claw-fg.png +0 -0
  94. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/agentwire-splash-logo-layers--echo.png +0 -0
  95. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/agentwire-splash-logo-layers--full--transparent-top.png +0 -0
  96. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/agentwire-splash-logo-layers--full-black.png +0 -0
  97. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/agentwire-splash-logo-layers--telephone-fg.png +0 -0
  98. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/agentwire-splash-logo-layers--telephone.png +0 -0
  99. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/agentwire-splash-logo-layers--transparent-top.png +0 -0
  100. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/agentwire-splash-logo-layers--tree.png +0 -0
  101. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/agentwire-splash-logo-layers.png +0 -0
  102. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/favicon.png +0 -0
  103. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/machines/android.jpeg +0 -0
  104. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/machines/automaton.jpeg +0 -0
  105. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/machines/bot.jpeg +0 -0
  106. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/machines/cyborg.jpeg +0 -0
  107. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/machines/droid.jpeg +0 -0
  108. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/machines/drone.jpeg +0 -0
  109. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/machines/guardian.jpeg +0 -0
  110. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/machines/mech.jpeg +0 -0
  111. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/machines/probe.jpeg +0 -0
  112. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/machines/robot.jpeg +0 -0
  113. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/machines/sentinel.jpeg +0 -0
  114. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/machines/unit.jpeg +0 -0
  115. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/projects/blob.jpeg +0 -0
  116. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/projects/cloud.jpeg +0 -0
  117. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/projects/crystal.jpeg +0 -0
  118. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/projects/cyclops.jpeg +0 -0
  119. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/projects/flame.jpeg +0 -0
  120. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/projects/fuzzy.jpeg +0 -0
  121. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/projects/horned.jpeg +0 -0
  122. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/projects/moon.jpeg +0 -0
  123. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/projects/slime.jpeg +0 -0
  124. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/projects/star.jpeg +0 -0
  125. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/projects/tentacle.jpeg +0 -0
  126. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/projects/winged.jpeg +0 -0
  127. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/sessions/bear.jpeg +0 -0
  128. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/sessions/cat.jpeg +0 -0
  129. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/sessions/crown.jpeg +0 -0
  130. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/sessions/custom/agentwire-portal.png +0 -0
  131. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/sessions/custom/agentwire-tts.png +0 -0
  132. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/sessions/custom/agentwire.png +0 -0
  133. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/sessions/deer.jpeg +0 -0
  134. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/sessions/drone.jpeg +0 -0
  135. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/sessions/eagle.jpeg +0 -0
  136. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/sessions/fox.jpeg +0 -0
  137. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/sessions/hawk.jpeg +0 -0
  138. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/sessions/horse.jpeg +0 -0
  139. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/sessions/lion.jpeg +0 -0
  140. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/sessions/rabbit.jpeg +0 -0
  141. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/sessions/robot.jpeg +0 -0
  142. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/sessions/tiger.jpeg +0 -0
  143. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/icons/sessions/wolf.jpeg +0 -0
  144. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/js/.gitkeep +0 -0
  145. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/js/components/icon-picker.js +0 -0
  146. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/js/components/list-card.js +0 -0
  147. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/js/components/type-tag.js +0 -0
  148. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/js/icon-manager.js +0 -0
  149. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/js/list-window.js +0 -0
  150. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/js/session-window.js +0 -0
  151. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/js/tile-manager.js +0 -0
  152. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/js/utils/auto-refresh.js +0 -0
  153. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/js/winbox.bundle.min.js +0 -0
  154. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/js/windows/chat-window.js +0 -0
  155. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/js/windows/config-window.js +0 -0
  156. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/js/windows/machines-window.js +0 -0
  157. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/static/js/windows/sessions-window.js +0 -0
  158. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/stt/__init__.py +0 -0
  159. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/stt/base.py +0 -0
  160. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/stt/server_backend.py +0 -0
  161. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/stt/stt_server.py +0 -0
  162. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/stt/whisperkit.py +0 -0
  163. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/tasks.py +0 -0
  164. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/templates/__init__.py +0 -0
  165. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/templates/base.html +0 -0
  166. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/templating.py +0 -0
  167. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/tts/__init__.py +0 -0
  168. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/tts/base.py +0 -0
  169. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/tts/engines/__init__.py +0 -0
  170. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/tts/engines/chatterbox.py +0 -0
  171. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/tts/engines/qwen_base.py +0 -0
  172. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/tts/engines/qwen_custom.py +0 -0
  173. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/tts/engines/qwen_design.py +0 -0
  174. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/tts/registry.py +0 -0
  175. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/tts/runpod_handler.py +0 -0
  176. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/tts_server.py +0 -0
  177. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/tunnels.py +0 -0
  178. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/utils/__init__.py +0 -0
  179. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/utils/chunker.py +0 -0
  180. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/utils/file_io.py +0 -0
  181. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/utils/paths.py +0 -0
  182. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/utils/subprocess.py +0 -0
  183. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/validation.py +0 -0
  184. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/voiceclone.py +0 -0
  185. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/voices/darren.wav +0 -0
  186. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/voices/default.wav +0 -0
  187. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/voices/jessica.wav +0 -0
  188. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/voices/lisa.wav +0 -0
  189. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/voices/may.wav +0 -0
  190. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/agentwire/worktree.py +0 -0
  191. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/PORTAL.md +0 -0
  192. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/SHELL_ESCAPING.md +0 -0
  193. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/SPONSORS.md +0 -0
  194. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/TROUBLESHOOTING.md +0 -0
  195. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/README.md +0 -0
  196. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-agent-hot-swap.md +0 -0
  197. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-ambient-context-stream.md +0 -0
  198. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-ambient-listening-mode.md +0 -0
  199. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-audio-cues.md +0 -0
  200. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-checkpoint-commits.md +0 -0
  201. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-context-compression-protocol.md +0 -0
  202. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-context-window-gauge.md +0 -0
  203. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-contextual-bookmarks.md +0 -0
  204. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-conversation-archaeology.md +0 -0
  205. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-cost-tracking-dashboard.md +0 -0
  206. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-cross-session-events.md +0 -0
  207. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-delegation-replay.md +0 -0
  208. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-device-session-tethering.md +0 -0
  209. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-failure-memory.md +0 -0
  210. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-notification-escalation.md +0 -0
  211. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-periodic-voice-briefings.md +0 -0
  212. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-presence-aware-sessions.md +0 -0
  213. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-session-drift-detection.md +0 -0
  214. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-session-energy-model.md +0 -0
  215. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-session-handshake.md +0 -0
  216. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-session-momentum.md +0 -0
  217. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-session-replay.md +0 -0
  218. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-session-snapshots.md +0 -0
  219. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-session-templates.md +0 -0
  220. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-session-thermal-throttling.md +0 -0
  221. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-smart-session-routing.md +0 -0
  222. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-spatial-voice-mixing.md +0 -0
  223. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-speculative-execution.md +0 -0
  224. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-task-pipeline-chaining.md +0 -0
  225. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-task-pivot-protocol.md +0 -0
  226. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-task-time-budgets.md +0 -0
  227. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-voice-activity-zones.md +0 -0
  228. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-voice-breakpoints.md +0 -0
  229. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-voice-code-review.md +0 -0
  230. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-voice-command-undo.md +0 -0
  231. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-voice-handoff.md +0 -0
  232. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-voice-identity.md +0 -0
  233. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-voice-interrupts-v2.md +0 -0
  234. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-voice-interrupts.md +0 -0
  235. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-voice-macros.md +0 -0
  236. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-voice-transcript-logs.md +0 -0
  237. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-watchdog-mode.md +0 -0
  238. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-worker-fencing.md +0 -0
  239. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-worker-file-coordination.md +0 -0
  240. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-worker-health-dashboard.md +0 -0
  241. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-worker-heartbeat-watchdog.md +0 -0
  242. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-worker-progress-streaming.md +0 -0
  243. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-worker-proof-of-work.md +0 -0
  244. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-worker-warmup.md +0 -0
  245. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/brainstorms/idea-x-api-integration.md +0 -0
  246. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/critical-analysis.md +0 -0
  247. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/demo-script.md +0 -0
  248. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/issues/pending-code-changes.md +0 -0
  249. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/issues/remote-tts-session-detection.md +0 -0
  250. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/logo.png +0 -0
  251. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/notification-hooks.md +0 -0
  252. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/progressive-loading-pattern.md +0 -0
  253. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/prompts/agentwire-website.md +0 -0
  254. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/releasing.md +0 -0
  255. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/remote-access.md +0 -0
  256. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/remote-machines.md +0 -0
  257. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/runpod-tts.md +0 -0
  258. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/scheduled-workloads.md +0 -0
  259. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/security/damage-control-migration.md +0 -0
  260. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/security/damage-control.md +0 -0
  261. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/tmux-hooks.md +0 -0
  262. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/tts-self-hosted.md +0 -0
  263. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/docs/youtube-channel.md +0 -0
  264. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/opencode-plugin/agentwire-notify.ts +0 -0
  265. {agentwire_dev-1.3.1 → agentwire_dev-1.4.0}/requirements-tts.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentwire-dev
3
- Version: 1.3.1
3
+ Version: 1.4.0
4
4
  Summary: Multi-session voice web interface for AI coding agents
5
5
  Project-URL: Homepage, https://agentwire.dev
6
6
  Project-URL: Repository, https://github.com/dotdevdotdev/agentwire-dev
@@ -1,3 +1,3 @@
1
1
  """AgentWire - Multi-session voice web interface for AI coding agents."""
2
2
 
3
- __version__ = "1.3.1"
3
+ __version__ = "1.4.0"
@@ -2104,6 +2104,68 @@ def cmd_alert(args) -> int:
2104
2104
  return 0
2105
2105
 
2106
2106
 
2107
+ def cmd_open(args) -> int:
2108
+ """Open a URL or local file as an artifact window in the portal.
2109
+
2110
+ Examples:
2111
+ agentwire open dashboard.html --title "Dashboard"
2112
+ agentwire open https://example.com --title "External"
2113
+ agentwire open test.html --artifact-id my-test --json
2114
+ """
2115
+ import json as json_mod
2116
+ import requests
2117
+ import urllib3
2118
+ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
2119
+
2120
+ url = args.url
2121
+ title = args.title
2122
+ artifact_id = getattr(args, 'artifact_id', None)
2123
+ json_output = getattr(args, 'json', False)
2124
+
2125
+ portal_url = _get_portal_url()
2126
+
2127
+ body = {
2128
+ "type": "artifact",
2129
+ "url": url,
2130
+ "title": title,
2131
+ }
2132
+ if artifact_id:
2133
+ body["artifact_id"] = artifact_id
2134
+
2135
+ try:
2136
+ resp = requests.post(
2137
+ f"{portal_url}/api/desktop/window/open",
2138
+ json=body,
2139
+ verify=False,
2140
+ timeout=10,
2141
+ )
2142
+ data = resp.json()
2143
+
2144
+ if json_output:
2145
+ print(json_mod.dumps(data))
2146
+ elif data.get("success"):
2147
+ print(f"Opened artifact window: {title} (id: {data.get('window_id', 'unknown')})")
2148
+ else:
2149
+ print(f"Failed: {data.get('error', 'Unknown error')}", file=sys.stderr)
2150
+ return 1
2151
+
2152
+ except requests.exceptions.ConnectionError:
2153
+ msg = "Portal not reachable. Is it running? (agentwire portal status)"
2154
+ if json_output:
2155
+ print(json_mod.dumps({"success": False, "error": msg}))
2156
+ else:
2157
+ print(msg, file=sys.stderr)
2158
+ return 1
2159
+ except Exception as e:
2160
+ if json_output:
2161
+ print(json_mod.dumps({"success": False, "error": str(e)}))
2162
+ else:
2163
+ print(f"Error: {e}", file=sys.stderr)
2164
+ return 1
2165
+
2166
+ return 0
2167
+
2168
+
2107
2169
  def _handle_voice_notifications(text: str, voice: str, args, session: str | None) -> None:
2108
2170
  """Handle voice notification to parent orchestrators.
2109
2171
 
@@ -2597,14 +2659,26 @@ def cmd_send(args) -> int:
2597
2659
  print(f"Machine '{machine_id}' not found in machines.json", file=sys.stderr)
2598
2660
  return 1
2599
2661
 
2600
- # Build remote command
2662
+ # Build remote command — use load-buffer for anything non-trivial
2601
2663
  quoted_session = shlex.quote(session)
2602
- quoted_prompt = shlex.quote(prompt)
2603
-
2604
- # Send text, sleep, send Enter
2605
- cmd = f"tmux send-keys -t {quoted_session} {quoted_prompt} && sleep 0.5 && tmux send-keys -t {quoted_session} Enter"
2664
+ use_buffer = len(prompt) > 10 or "\n" in prompt
2665
+
2666
+ if use_buffer:
2667
+ import base64
2668
+ encoded = base64.b64encode(prompt.encode()).decode()
2669
+ cmd = (
2670
+ f"echo {shlex.quote(encoded)} | base64 -d > /tmp/aw-send-$$.txt && "
2671
+ f"tmux load-buffer /tmp/aw-send-$$.txt && "
2672
+ f"tmux paste-buffer -t {quoted_session} && "
2673
+ f"rm -f /tmp/aw-send-$$.txt && "
2674
+ f"sleep 0.5 && "
2675
+ f"tmux send-keys -t {quoted_session} Enter"
2676
+ )
2677
+ else:
2678
+ quoted_prompt = shlex.quote(prompt)
2679
+ cmd = f"tmux send-keys -t {quoted_session} -l {quoted_prompt} && sleep 0.5 && tmux send-keys -t {quoted_session} Enter"
2606
2680
 
2607
- # For multi-line text, add another Enter
2681
+ # For multi-line text, Claude Code shows "[Pasted text...]" and waits for Enter
2608
2682
  if "\n" in prompt or len(prompt) > 200:
2609
2683
  cmd += f" && sleep 0.5 && tmux send-keys -t {quoted_session} Enter"
2610
2684
 
@@ -2635,13 +2709,26 @@ def cmd_send(args) -> int:
2635
2709
  print(f"Session '{session}' not found", file=sys.stderr)
2636
2710
  return 1
2637
2711
 
2638
- # Send the prompt via tmux send-keys (text first, then Enter after delay)
2639
- subprocess.run(
2640
- ["tmux", "send-keys", "-t", session, prompt],
2641
- check=True
2642
- )
2712
+ # Send the prompt use load-buffer for anything non-trivial to avoid PTY flooding
2713
+ use_buffer = len(prompt) > 10 or "\n" in prompt
2714
+
2715
+ if use_buffer:
2716
+ import tempfile
2717
+ with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as f:
2718
+ f.write(prompt)
2719
+ temp_path = f.name
2720
+ try:
2721
+ subprocess.run(["tmux", "load-buffer", temp_path], check=True)
2722
+ subprocess.run(["tmux", "paste-buffer", "-t", session], check=True)
2723
+ finally:
2724
+ os.unlink(temp_path)
2725
+ else:
2726
+ subprocess.run(
2727
+ ["tmux", "send-keys", "-t", session, "-l", prompt],
2728
+ check=True
2729
+ )
2643
2730
 
2644
- # Wait for text to be fully entered before pressing Enter
2731
+ # Wait for text to be displayed before pressing Enter
2645
2732
  time.sleep(0.5)
2646
2733
 
2647
2734
  subprocess.run(
@@ -3681,11 +3768,23 @@ def cmd_split(args) -> int:
3681
3768
  print("Error: Not in a tmux session and no --session specified")
3682
3769
  return 1
3683
3770
 
3771
+ # Verify session exists
3772
+ check = subprocess.run(
3773
+ ["tmux", "has-session", "-t", session],
3774
+ capture_output=True
3775
+ )
3776
+ if check.returncode != 0:
3777
+ print(f"Error: Session '{session}' not found")
3778
+ return 1
3779
+
3684
3780
  # Add panes
3685
- for _ in range(count):
3686
- subprocess.run([
3781
+ for i in range(count):
3782
+ result = subprocess.run([
3687
3783
  "tmux", "split-window", "-v", "-t", session, "-c", cwd
3688
- ], capture_output=True)
3784
+ ], capture_output=True, text=True)
3785
+ if result.returncode != 0:
3786
+ print(f"Error: Failed to split pane: {result.stderr.strip()}")
3787
+ return 1
3689
3788
 
3690
3789
  # Apply main-top layout: orchestrator (pane 0) at top with 60%, workers below
3691
3790
  pane_manager._apply_main_top_layout(session)
@@ -3725,17 +3824,30 @@ def cmd_detach(args) -> int:
3725
3824
  )
3726
3825
  session_exists = result.returncode == 0
3727
3826
 
3827
+ # Verify source session exists
3828
+ check = subprocess.run(
3829
+ ["tmux", "has-session", "-t", source_session],
3830
+ capture_output=True
3831
+ )
3832
+ if check.returncode != 0:
3833
+ print(f"Error: Session '{source_session}' not found")
3834
+ return 1
3835
+
3728
3836
  # Move pane to new session
3729
3837
  if session_exists:
3730
3838
  # Move to existing session
3731
- subprocess.run([
3839
+ result = subprocess.run([
3732
3840
  "tmux", "move-pane", "-s", f"{source_session}:{pane_index}", "-t", f"{new_session}:"
3733
- ], capture_output=True)
3841
+ ], capture_output=True, text=True)
3734
3842
  else:
3735
3843
  # Break pane into new session
3736
- subprocess.run([
3844
+ result = subprocess.run([
3737
3845
  "tmux", "break-pane", "-d", "-s", f"{source_session}:{pane_index}", "-t", f"{new_session}:"
3738
- ], capture_output=True)
3846
+ ], capture_output=True, text=True)
3847
+
3848
+ if result.returncode != 0:
3849
+ print(f"Error: Failed to detach pane {pane_index}: {result.stderr.strip()}")
3850
+ return 1
3739
3851
 
3740
3852
  # Re-align remaining panes with main-top layout
3741
3853
  pane_manager._apply_main_top_layout(source_session)
@@ -7592,6 +7704,14 @@ def main() -> int:
7592
7704
  alert_parser.add_argument("-q", "--quiet", action="store_true", help="Suppress output")
7593
7705
  alert_parser.set_defaults(func=cmd_alert)
7594
7706
 
7707
+ # === open command (artifact windows) ===
7708
+ open_parser = subparsers.add_parser("open", help="Open a URL or local file as an artifact window in the portal")
7709
+ open_parser.add_argument("url", help="URL or filename to open (filenames served from ~/.agentwire/artifacts/)")
7710
+ open_parser.add_argument("--title", "-t", type=str, default="Artifact", help="Window title")
7711
+ open_parser.add_argument("--artifact-id", type=str, help="Unique window ID (auto-generated if omitted)")
7712
+ open_parser.add_argument("--json", action="store_true", help="Output JSON")
7713
+ open_parser.set_defaults(func=cmd_open)
7714
+
7595
7715
  # === email command ===
7596
7716
  from agentwire.notifications import cmd_email
7597
7717
  email_parser = subparsers.add_parser("email", help="Send branded email notification via Resend")
@@ -338,30 +338,59 @@ class TmuxAgent(AgentBackend):
338
338
 
339
339
  def send_input(self, name: str, text: str) -> bool:
340
340
  """Send input to a tmux session (text + Enter)."""
341
+ import os
342
+ import tempfile
341
343
  import time
342
344
  session_name, machine = self._parse_session_name(name)
343
345
 
346
+ use_buffer = len(text) > 10 or "\n" in text
347
+
344
348
  if machine:
345
- # Use base64 encoding for safe transmission of complex text
346
- import base64
347
- encoded = base64.b64encode(text.encode()).decode()
348
- cmd = (
349
- f"echo {shlex.quote(encoded)} | base64 -d | "
350
- f"xargs -0 tmux send-keys -t {shlex.quote(session_name)} -l && "
351
- f"sleep 0.2 && "
352
- f"tmux send-keys -t {shlex.quote(session_name)} Enter"
353
- )
349
+ if use_buffer:
350
+ # Use base64 + load-buffer on remote to avoid PTY flooding
351
+ import base64
352
+ encoded = base64.b64encode(text.encode()).decode()
353
+ cmd = (
354
+ f"echo {shlex.quote(encoded)} | base64 -d > /tmp/aw-send-$$.txt && "
355
+ f"tmux load-buffer /tmp/aw-send-$$.txt && "
356
+ f"tmux paste-buffer -t {shlex.quote(session_name)} && "
357
+ f"rm -f /tmp/aw-send-$$.txt && "
358
+ f"sleep 0.2 && "
359
+ f"tmux send-keys -t {shlex.quote(session_name)} Enter"
360
+ )
361
+ else:
362
+ cmd = (
363
+ f"tmux send-keys -t {shlex.quote(session_name)} -l {shlex.quote(text)} && "
364
+ f"sleep 0.2 && "
365
+ f"tmux send-keys -t {shlex.quote(session_name)} Enter"
366
+ )
354
367
  result = self._run_remote(machine, cmd)
355
368
  else:
356
- # Send text literally (no special char interpretation)
357
- result = self._run_local([
358
- "tmux", "send-keys",
359
- "-t", session_name,
360
- "-l", text,
361
- ])
362
- if result.returncode != 0:
363
- logger.error(f"Failed to send input: {result.stderr}")
364
- return False
369
+ if use_buffer:
370
+ # Write to temp file, load into tmux buffer, paste as single unit
371
+ with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as f:
372
+ f.write(text)
373
+ temp_path = f.name
374
+ try:
375
+ result = self._run_local(["tmux", "load-buffer", temp_path])
376
+ if result.returncode != 0:
377
+ logger.error(f"Failed to load buffer: {result.stderr}")
378
+ return False
379
+ result = self._run_local(["tmux", "paste-buffer", "-t", session_name])
380
+ if result.returncode != 0:
381
+ logger.error(f"Failed to paste buffer: {result.stderr}")
382
+ return False
383
+ finally:
384
+ os.unlink(temp_path)
385
+ else:
386
+ result = self._run_local([
387
+ "tmux", "send-keys",
388
+ "-t", session_name,
389
+ "-l", text,
390
+ ])
391
+ if result.returncode != 0:
392
+ logger.error(f"Failed to send input: {result.stderr}")
393
+ return False
365
394
 
366
395
  # Small delay before Enter
367
396
  time.sleep(0.2)
@@ -149,6 +149,19 @@ class UploadsConfig:
149
149
  self.dir = _expand_path(self.dir) or self.dir
150
150
 
151
151
 
152
+ @dataclass
153
+ class ArtifactsConfig:
154
+ """Artifacts directory for agent-generated HTML content."""
155
+
156
+ dir: Path = field(
157
+ default_factory=lambda: Path.home() / ".agentwire" / "artifacts"
158
+ )
159
+ max_size_mb: int = 10
160
+
161
+ def __post_init__(self):
162
+ self.dir = _expand_path(self.dir) or self.dir
163
+
164
+
152
165
  @dataclass
153
166
  class PortalConfig:
154
167
  """Portal connection settings (for remote machines)."""
@@ -213,6 +226,7 @@ class Config:
213
226
  agent: AgentConfig = field(default_factory=AgentConfig)
214
227
  machines: MachinesConfig = field(default_factory=MachinesConfig)
215
228
  uploads: UploadsConfig = field(default_factory=UploadsConfig)
229
+ artifacts: ArtifactsConfig = field(default_factory=ArtifactsConfig)
216
230
  portal: PortalConfig = field(default_factory=PortalConfig)
217
231
  services: ServicesConfig = field(default_factory=ServicesConfig)
218
232
  session: SessionConfig = field(default_factory=SessionConfig)
@@ -349,6 +363,13 @@ def _dict_to_config(data: dict) -> Config:
349
363
  cleanup_days=uploads_data.get("cleanup_days", 7),
350
364
  )
351
365
 
366
+ # Artifacts
367
+ artifacts_data = data.get("artifacts", {})
368
+ artifacts = ArtifactsConfig(
369
+ dir=artifacts_data.get("dir", "~/.agentwire/artifacts"),
370
+ max_size_mb=artifacts_data.get("max_size_mb", 10),
371
+ )
372
+
352
373
  # Portal
353
374
  portal_data = data.get("portal", {})
354
375
  portal = PortalConfig(
@@ -400,6 +421,7 @@ def _dict_to_config(data: dict) -> Config:
400
421
  agent=agent,
401
422
  machines=machines,
402
423
  uploads=uploads,
424
+ artifacts=artifacts,
403
425
  portal=portal,
404
426
  services=services,
405
427
  notifications=notifications,