agentwire-dev 1.31.0__tar.gz → 1.32.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 (355) hide show
  1. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/PKG-INFO +1 -1
  2. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/__init__.py +1 -1
  3. agentwire_dev-1.32.0/agentwire/static/announcements.json +31 -0
  4. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/css/desktop.css +198 -0
  5. agentwire_dev-1.32.0/agentwire/static/js/announcement-modal.js +178 -0
  6. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/desktop.js +5 -0
  7. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/templates/desktop.html +1 -0
  8. agentwire_dev-1.32.0/tests/unit/test_announcements.py +60 -0
  9. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/.github/FUNDING.yml +0 -0
  10. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  11. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  12. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
  13. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  14. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/.gitignore +0 -0
  15. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/CHANGELOG.md +0 -0
  16. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/CLA.md +0 -0
  17. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/CODE_OF_CONDUCT.md +0 -0
  18. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/CONTRIBUTING.md +0 -0
  19. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/Dockerfile.local +0 -0
  20. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/Dockerfile.runpod +0 -0
  21. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/LICENSE +0 -0
  22. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/README.md +0 -0
  23. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/RELEASING.md +0 -0
  24. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/SECURITY.md +0 -0
  25. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/SPONSORS.md +0 -0
  26. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/__main__.py +0 -0
  27. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/agents/__init__.py +0 -0
  28. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/agents/base.py +0 -0
  29. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/agents/tmux.py +0 -0
  30. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/cached_status.py +0 -0
  31. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/channels/__init__.py +0 -0
  32. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/channels/base.py +0 -0
  33. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/channels/email.py +0 -0
  34. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/channels/quo.py +0 -0
  35. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/cli_safety.py +0 -0
  36. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/completion.py +0 -0
  37. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/config.py +0 -0
  38. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/council/__init__.py +0 -0
  39. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/council/cli.py +0 -0
  40. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/council/inbox.py +0 -0
  41. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/council/state.py +0 -0
  42. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/fetch.py +0 -0
  43. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/handoff/__init__.py +0 -0
  44. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/handoff/git_state.py +0 -0
  45. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/handoff/instructions.py +0 -0
  46. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/handoff/parser.py +0 -0
  47. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/handoff/renderer.py +0 -0
  48. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/handoff/schema.py +0 -0
  49. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/history.py +0 -0
  50. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/__init__.py +0 -0
  51. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/agentwire-permission.sh +0 -0
  52. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/damage-control/__init__.py +0 -0
  53. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/damage-control/audit_logger.py +0 -0
  54. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/damage-control/bash-tool-damage-control.py +0 -0
  55. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/damage-control/edit-tool-damage-control.py +0 -0
  56. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/damage-control/rules/agentwire.yaml +0 -0
  57. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/damage-control/rules/aws.yaml +0 -0
  58. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/damage-control/rules/cloud-hosting.yaml +0 -0
  59. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/damage-control/rules/containers.yaml +0 -0
  60. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/damage-control/rules/core.yaml +0 -0
  61. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/damage-control/rules/databases.yaml +0 -0
  62. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/damage-control/rules/firebase.yaml +0 -0
  63. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/damage-control/rules/gcp.yaml +0 -0
  64. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/damage-control/rules/git.yaml +0 -0
  65. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/damage-control/rules/gws.yaml +0 -0
  66. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/damage-control/rules/infrastructure.yaml +0 -0
  67. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/damage-control/rules/remote.yaml +0 -0
  68. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/damage-control/write-tool-damage-control.py +0 -0
  69. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/idle-handler.sh +0 -0
  70. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/hooks/queue-processor.sh +0 -0
  71. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/listen.py +0 -0
  72. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/locking.py +0 -0
  73. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/mcp_server.py +0 -0
  74. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/missions/__init__.py +0 -0
  75. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/missions/cli.py +0 -0
  76. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/missions/config.py +0 -0
  77. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/missions/dispatcher.py +0 -0
  78. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/missions/eligibility.py +0 -0
  79. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/missions/feedback_router.py +0 -0
  80. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/missions/gc.py +0 -0
  81. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/missions/github.py +0 -0
  82. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/missions/naming.py +0 -0
  83. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/missions/state.py +0 -0
  84. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/network.py +0 -0
  85. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/onboarding.py +0 -0
  86. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/overnight.py +0 -0
  87. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/pane_manager.py +0 -0
  88. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/project_config.py +0 -0
  89. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/projects.py +0 -0
  90. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/prompts/__init__.py +0 -0
  91. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/prompts/init.md +0 -0
  92. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/roles/__init__.py +0 -0
  93. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/roles/agentwire.md +0 -0
  94. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/roles/chatbot.md +0 -0
  95. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/roles/council-brain.md +0 -0
  96. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/roles/council-conscience.md +0 -0
  97. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/roles/council-critic.md +0 -0
  98. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/roles/council-devils-advocate.md +0 -0
  99. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/roles/council-gut.md +0 -0
  100. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/roles/council-historian.md +0 -0
  101. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/roles/council-member.md +0 -0
  102. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/roles/council-orchestrator.md +0 -0
  103. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/roles/init.md +0 -0
  104. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/roles/notifications.md +0 -0
  105. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/roles/orchestrator.md +0 -0
  106. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/roles/soul.md +0 -0
  107. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/roles/task-runner.md +0 -0
  108. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/roles/voice.md +0 -0
  109. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/roles/worker.md +0 -0
  110. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/safety/__init__.py +0 -0
  111. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/safety/_core.py +0 -0
  112. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/scheduler.py +0 -0
  113. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/scratchpad.py +0 -0
  114. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/search.py +0 -0
  115. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/security.py +0 -0
  116. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/server.py +0 -0
  117. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/services.py +0 -0
  118. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/session_ready.py +0 -0
  119. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/agentwire-Echo--black.png +0 -0
  120. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/agentwire-Echo--transparent.png +0 -0
  121. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/agentwire-Echo.png +0 -0
  122. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/agentwire-email-banner.png +0 -0
  123. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/agentwire-splash-logo-layers--agentwire-text.png +0 -0
  124. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/agentwire-splash-logo-layers--echo-claw-fg.png +0 -0
  125. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/agentwire-splash-logo-layers--echo.png +0 -0
  126. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/agentwire-splash-logo-layers--full--transparent-top.png +0 -0
  127. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/agentwire-splash-logo-layers--full-black.png +0 -0
  128. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/agentwire-splash-logo-layers--telephone-fg.png +0 -0
  129. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/agentwire-splash-logo-layers--telephone.png +0 -0
  130. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/agentwire-splash-logo-layers--transparent-top.png +0 -0
  131. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/agentwire-splash-logo-layers--transparent.png +0 -0
  132. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/agentwire-splash-logo-layers--tree.png +0 -0
  133. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/agentwire-splash-logo-layers.png +0 -0
  134. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/favicon.png +0 -0
  135. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/machines/android.jpeg +0 -0
  136. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/machines/automaton.jpeg +0 -0
  137. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/machines/bot.jpeg +0 -0
  138. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/machines/cyborg.jpeg +0 -0
  139. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/machines/droid.jpeg +0 -0
  140. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/machines/drone.jpeg +0 -0
  141. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/machines/guardian.jpeg +0 -0
  142. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/machines/mech.jpeg +0 -0
  143. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/machines/probe.jpeg +0 -0
  144. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/machines/robot.jpeg +0 -0
  145. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/machines/sentinel.jpeg +0 -0
  146. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/machines/unit.jpeg +0 -0
  147. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/projects/blob.jpeg +0 -0
  148. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/projects/cloud.jpeg +0 -0
  149. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/projects/crystal.jpeg +0 -0
  150. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/projects/cyclops.jpeg +0 -0
  151. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/projects/flame.jpeg +0 -0
  152. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/projects/fuzzy.jpeg +0 -0
  153. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/projects/horned.jpeg +0 -0
  154. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/projects/moon.jpeg +0 -0
  155. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/projects/slime.jpeg +0 -0
  156. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/projects/star.jpeg +0 -0
  157. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/projects/tentacle.jpeg +0 -0
  158. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/projects/winged.jpeg +0 -0
  159. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/sessions/bear.jpeg +0 -0
  160. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/sessions/cat.jpeg +0 -0
  161. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/sessions/crown.jpeg +0 -0
  162. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/sessions/custom/agentwire-portal.png +0 -0
  163. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/sessions/custom/agentwire-tts.png +0 -0
  164. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/sessions/custom/agentwire.png +0 -0
  165. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/sessions/deer.jpeg +0 -0
  166. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/sessions/drone.jpeg +0 -0
  167. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/sessions/eagle.jpeg +0 -0
  168. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/sessions/fox.jpeg +0 -0
  169. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/sessions/hawk.jpeg +0 -0
  170. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/sessions/horse.jpeg +0 -0
  171. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/sessions/lion.jpeg +0 -0
  172. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/sessions/rabbit.jpeg +0 -0
  173. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/sessions/robot.jpeg +0 -0
  174. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/sessions/tiger.jpeg +0 -0
  175. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/icons/sessions/wolf.jpeg +0 -0
  176. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/.gitkeep +0 -0
  177. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/api.js +0 -0
  178. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/artifact-window.js +0 -0
  179. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/collage.js +0 -0
  180. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/command-palette.js +0 -0
  181. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/components/icon-picker.js +0 -0
  182. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/components/list-card.js +0 -0
  183. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/components/type-tag.js +0 -0
  184. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/dead-key-suppressor.js +0 -0
  185. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/desktop-manager.js +0 -0
  186. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/icon-manager.js +0 -0
  187. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/notifications-panel.js +0 -0
  188. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/safety-shared.js +0 -0
  189. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/safety-window.js +0 -0
  190. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/scratchpad.js +0 -0
  191. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/session-id.js +0 -0
  192. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/session-window.js +0 -0
  193. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/sidebar/artifacts-section.js +0 -0
  194. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/sidebar/config-section.js +0 -0
  195. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/sidebar/machines-section.js +0 -0
  196. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/sidebar/missions-section.js +0 -0
  197. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/sidebar/projects-section.js +0 -0
  198. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/sidebar/safety-section.js +0 -0
  199. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/sidebar/scheduler-section.js +0 -0
  200. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/sidebar/services-section.js +0 -0
  201. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/sidebar/sessions-section.js +0 -0
  202. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/sidebar.js +0 -0
  203. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/terminal-font-prefs.js +0 -0
  204. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/tile-manager.js +0 -0
  205. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/token-modal.js +0 -0
  206. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/utils/ansi.js +0 -0
  207. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/utils/auto-refresh.js +0 -0
  208. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/voice/browser-stt.js +0 -0
  209. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/voice/browser-tts.js +0 -0
  210. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/voice/jargon.js +0 -0
  211. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/voice/prompt.js +0 -0
  212. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/static/js/winbox.bundle.min.js +0 -0
  213. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/stt/__init__.py +0 -0
  214. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/stt/base.py +0 -0
  215. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/stt/server_backend.py +0 -0
  216. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/stt/stt_server.py +0 -0
  217. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tasks.py +0 -0
  218. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/templates/__init__.py +0 -0
  219. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/templates/base.html +0 -0
  220. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/templates/email_notification.html +0 -0
  221. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/templates/handoff/show-the-story.html.j2 +0 -0
  222. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/templates/handoff/theme.css.j2 +0 -0
  223. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/templates/tmux.conf +0 -0
  224. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/templating.py +0 -0
  225. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tooldefs/aws.yaml +0 -0
  226. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tooldefs/docker.yaml +0 -0
  227. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tooldefs/gcp.yaml +0 -0
  228. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tooldefs/gh.yaml +0 -0
  229. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tooldefs/git.yaml +0 -0
  230. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tooldefs/gws.yaml +0 -0
  231. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tooldefs/kubectl.yaml +0 -0
  232. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tooldefs/npm.yaml +0 -0
  233. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tooldefs/terraform.yaml +0 -0
  234. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tooldefs/uv.yaml +0 -0
  235. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tts/__init__.py +0 -0
  236. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tts/base.py +0 -0
  237. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tts/engines/__init__.py +0 -0
  238. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tts/engines/chatterbox.py +0 -0
  239. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tts/engines/kokoro.py +0 -0
  240. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tts/engines/qwen_base.py +0 -0
  241. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tts/engines/qwen_custom.py +0 -0
  242. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tts/engines/qwen_design.py +0 -0
  243. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tts/engines/zonos.py +0 -0
  244. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tts/registry.py +0 -0
  245. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tts_server.py +0 -0
  246. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/tunnels.py +0 -0
  247. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/utils/__init__.py +0 -0
  248. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/utils/chunker.py +0 -0
  249. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/utils/file_io.py +0 -0
  250. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/utils/paths.py +0 -0
  251. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/utils/speech.py +0 -0
  252. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/utils/subprocess.py +0 -0
  253. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/validation.py +0 -0
  254. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/voiceclone.py +0 -0
  255. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/voices/darren.wav +0 -0
  256. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/voices/default.wav +0 -0
  257. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/voices/jessica.wav +0 -0
  258. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/voices/lisa.wav +0 -0
  259. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/voices/may.wav +0 -0
  260. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/agentwire/worktree.py +0 -0
  261. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/decisions/obsidian-second-brain.md +0 -0
  262. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/logo.png +0 -0
  263. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/INDEX.md +0 -0
  264. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/architecture.md +0 -0
  265. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/communication/channels.md +0 -0
  266. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/communication/hammerspoon.md +0 -0
  267. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/communication/handoff.md +0 -0
  268. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/concepts.md +0 -0
  269. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/council.md +0 -0
  270. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/deployment/remote-access.md +0 -0
  271. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/deployment/remote-machines.md +0 -0
  272. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/glossary.md +0 -0
  273. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/integrations/gws-google-workspace-cli.md +0 -0
  274. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/internals/damage-control.md +0 -0
  275. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/internals/portal.md +0 -0
  276. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/internals/shell-escaping.md +0 -0
  277. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/internals/troubleshooting.md +0 -0
  278. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/internals/window-collage.md +0 -0
  279. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/missions.md +0 -0
  280. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/quickstart.md +0 -0
  281. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/scheduling/scheduled-workloads.md +0 -0
  282. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/services.md +0 -0
  283. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/sessions/claude-code-auto-mode.md +0 -0
  284. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/sessions/pi.md +0 -0
  285. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/voice/shim-contract.md +0 -0
  286. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/voice/stt-self-hosted.md +0 -0
  287. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/docs/wiki/voice/tts-self-hosted.md +0 -0
  288. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/pyproject.toml +0 -0
  289. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/requirements-tts.txt +0 -0
  290. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/templates/launchd/dev.agentwire.mission-dispatcher.plist +0 -0
  291. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/templates/launchd/dev.agentwire.mission-feedback-router.plist +0 -0
  292. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/templates/launchd/dev.agentwire.mission-janitor.plist +0 -0
  293. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/conftest.py +0 -0
  294. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/e2e/test_portal_ui.py +0 -0
  295. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/fixtures/sample_agentwire.yml +0 -0
  296. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/fixtures/sample_config.yaml +0 -0
  297. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/fixtures/sample_scheduler.yaml +0 -0
  298. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/integration/test_missions_concurrency.py +0 -0
  299. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/integration/test_missions_lifecycle.py +0 -0
  300. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/integration/test_scheduler_board.py +0 -0
  301. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/integration/test_server_websockets.py +0 -0
  302. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_build_agent_command.py +0 -0
  303. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_channels.py +0 -0
  304. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_cli_commands.py +0 -0
  305. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_cli_output.py +0 -0
  306. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_cli_safety.py +0 -0
  307. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_config.py +0 -0
  308. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_council_cli.py +0 -0
  309. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_council_inbox.py +0 -0
  310. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_council_state.py +0 -0
  311. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_damage_control_hooks.py +0 -0
  312. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_damage_control_sync.py +0 -0
  313. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_file_io.py +0 -0
  314. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_handoff_git_state.py +0 -0
  315. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_handoff_instructions.py +0 -0
  316. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_handoff_parser.py +0 -0
  317. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_handoff_renderer.py +0 -0
  318. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_history.py +0 -0
  319. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_hooks_install.py +0 -0
  320. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_idle_handler.py +0 -0
  321. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_locking.py +0 -0
  322. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_mcp_server.py +0 -0
  323. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_mcp_tools_args.py +0 -0
  324. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_missions_cli.py +0 -0
  325. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_missions_config.py +0 -0
  326. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_missions_dispatcher.py +0 -0
  327. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_missions_eligibility.py +0 -0
  328. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_missions_feedback_router.py +0 -0
  329. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_missions_gc.py +0 -0
  330. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_missions_github.py +0 -0
  331. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_missions_naming.py +0 -0
  332. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_missions_state.py +0 -0
  333. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_overnight_resume_flags.py +0 -0
  334. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_portal_api.py +0 -0
  335. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_project_config.py +0 -0
  336. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_roles.py +0 -0
  337. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_safety_disabled_rules.py +0 -0
  338. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_safety_escape_hatch.py +0 -0
  339. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_safety_kill_switch.py +0 -0
  340. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_safety_mission_worker.py +0 -0
  341. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_scheduler.py +0 -0
  342. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_scheduler_parsing.py +0 -0
  343. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_scratchpad.py +0 -0
  344. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_search.py +0 -0
  345. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_security.py +0 -0
  346. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_server_async.py +0 -0
  347. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_server_pure.py +0 -0
  348. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_services.py +0 -0
  349. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_session_ready.py +0 -0
  350. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_speech_tags.py +0 -0
  351. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_stt_backend.py +0 -0
  352. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_tasks.py +0 -0
  353. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_templating.py +0 -0
  354. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_tmux_template.py +0 -0
  355. {agentwire_dev-1.31.0 → agentwire_dev-1.32.0}/tests/unit/test_worktree.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentwire-dev
3
- Version: 1.31.0
3
+ Version: 1.32.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.31.0"
3
+ __version__ = "1.32.0"
@@ -0,0 +1,31 @@
1
+ {
2
+ "announcements": [
3
+ {
4
+ "id": "evergreen-feedback-2026-06",
5
+ "placement": "banner",
6
+ "emoji": "👋",
7
+ "title": "You're an early one",
8
+ "body": "AgentWire is young and shaped by the handful of people running it. Bug, idea, or just hello — open an issue, it's read.",
9
+ "cta": {
10
+ "label": "Open an issue",
11
+ "url": "https://github.com/dotdevdotdev/agentwire-dev/issues/new"
12
+ }
13
+ },
14
+ {
15
+ "id": "2026-06-idea-first-capture",
16
+ "placement": "modal",
17
+ "emoji": "💡",
18
+ "title": "New idea? Cmd+K and go.",
19
+ "date": "2026-06-08",
20
+ "body": "AgentWire can now spin up a whole project from a single sentence. Press Cmd/Ctrl+K (or the New idea button), type — or speak — what you want to build, and it scaffolds the folder, starts an agent, and hands it your idea as the first message. You watch it get to work the moment the window opens.",
21
+ "highlights": [
22
+ "Idea-first capture — type an idea, get a running agent",
23
+ "Instant voice mode — browser speech in and out, zero setup"
24
+ ],
25
+ "cta": {
26
+ "label": "See what's in v1.31",
27
+ "url": "https://github.com/dotdevdotdev/agentwire-dev/releases/tag/v1.31.0"
28
+ }
29
+ }
30
+ ]
31
+ }
@@ -1000,6 +1000,151 @@ body {
1000
1000
  font-weight: 500;
1001
1001
  }
1002
1002
 
1003
+ /* =========================================================================
1004
+ Announcement modal (userbase welcome card)
1005
+ ========================================================================= */
1006
+
1007
+ .announcement-overlay {
1008
+ z-index: 2100; /* above standard modals, below the command palette */
1009
+ animation: announcement-fade 180ms ease-out;
1010
+ }
1011
+
1012
+ .announcement-overlay .announcement-modal {
1013
+ width: 460px;
1014
+ max-width: 92vw;
1015
+ padding: 28px 28px 22px;
1016
+ text-align: center;
1017
+ background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 7%, var(--chrome)) 0%, var(--chrome) 60%);
1018
+ border: 1px solid color-mix(in srgb, var(--accent) 35%, var(--chrome-border));
1019
+ border-radius: 12px;
1020
+ animation: announcement-rise 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
1021
+ }
1022
+
1023
+ .announcement-dismiss {
1024
+ position: absolute;
1025
+ top: 12px;
1026
+ right: 12px;
1027
+ background: transparent;
1028
+ border: none;
1029
+ color: var(--text-muted);
1030
+ font-size: 15px;
1031
+ cursor: pointer;
1032
+ line-height: 1;
1033
+ padding: 4px 6px;
1034
+ border-radius: 4px;
1035
+ }
1036
+
1037
+ .announcement-dismiss:hover {
1038
+ color: var(--text);
1039
+ background: var(--background);
1040
+ }
1041
+
1042
+ .announcement-emoji {
1043
+ font-size: 40px;
1044
+ line-height: 1;
1045
+ margin-bottom: 10px;
1046
+ }
1047
+
1048
+ .announcement-title {
1049
+ margin: 0 0 4px;
1050
+ font-size: 21px;
1051
+ font-weight: 700;
1052
+ color: var(--text);
1053
+ }
1054
+
1055
+ .announcement-date {
1056
+ font-size: 12px;
1057
+ color: var(--text-muted);
1058
+ margin-bottom: 14px;
1059
+ }
1060
+
1061
+ .announcement-body {
1062
+ font-size: 15px;
1063
+ line-height: 1.55;
1064
+ color: var(--text);
1065
+ opacity: 0.92;
1066
+ margin-bottom: 16px;
1067
+ text-align: left;
1068
+ }
1069
+
1070
+ .announcement-highlights {
1071
+ list-style: none;
1072
+ margin: 0 0 20px;
1073
+ padding: 0;
1074
+ text-align: left;
1075
+ display: flex;
1076
+ flex-direction: column;
1077
+ gap: 8px;
1078
+ }
1079
+
1080
+ .announcement-highlights li {
1081
+ position: relative;
1082
+ padding: 8px 12px 8px 34px;
1083
+ background: var(--background);
1084
+ border: 1px solid var(--chrome-border);
1085
+ border-radius: 6px;
1086
+ font-size: 14px;
1087
+ color: var(--text);
1088
+ }
1089
+
1090
+ .announcement-highlights li::before {
1091
+ content: "✦";
1092
+ position: absolute;
1093
+ left: 12px;
1094
+ top: 8px;
1095
+ color: var(--accent);
1096
+ }
1097
+
1098
+ .announcement-footer {
1099
+ display: flex;
1100
+ align-items: center;
1101
+ justify-content: center;
1102
+ gap: 10px;
1103
+ }
1104
+
1105
+ .announcement-cta {
1106
+ flex: 1;
1107
+ padding: 10px 16px;
1108
+ background: var(--accent);
1109
+ color: var(--background);
1110
+ border-radius: 6px;
1111
+ font-weight: 600;
1112
+ font-size: 14px;
1113
+ text-decoration: none;
1114
+ text-align: center;
1115
+ }
1116
+
1117
+ .announcement-cta:hover {
1118
+ filter: brightness(1.08);
1119
+ }
1120
+
1121
+ .announcement-ok {
1122
+ flex: 1;
1123
+ padding: 10px 16px;
1124
+ background: transparent;
1125
+ border: 1px solid var(--chrome-border);
1126
+ border-radius: 6px;
1127
+ color: var(--text);
1128
+ font-weight: 600;
1129
+ font-size: 14px;
1130
+ cursor: pointer;
1131
+ }
1132
+
1133
+ .announcement-ok:hover {
1134
+ border-color: var(--accent);
1135
+ color: var(--accent);
1136
+ }
1137
+
1138
+ @keyframes announcement-fade {
1139
+ from { opacity: 0; }
1140
+ to { opacity: 1; }
1141
+ }
1142
+
1143
+ @keyframes announcement-rise {
1144
+ from { opacity: 0; transform: translateY(12px) scale(0.98); }
1145
+ to { opacity: 1; transform: translateY(0) scale(1); }
1146
+ }
1147
+
1003
1148
  /* =========================================================================
1004
1149
  Quicktask modal
1005
1150
  ========================================================================= */
@@ -4820,6 +4965,59 @@ body.sidebar-pinned .sidebar-tab {
4820
4965
  opacity: 1;
4821
4966
  }
4822
4967
 
4968
+ /* Sidebar announcement banner (evergreen userbase note — see announcement-modal.js) */
4969
+ .announcement-banner {
4970
+ position: relative;
4971
+ flex-basis: 100%;
4972
+ padding: calc(var(--spacing-base) * 1.25);
4973
+ margin-bottom: var(--spacing-base);
4974
+ border: 1px solid color-mix(in srgb, var(--accent) 55%, var(--chrome-border));
4975
+ border-left: 3px solid var(--accent);
4976
+ border-radius: var(--radius, 6px);
4977
+ background: color-mix(in srgb, var(--accent) 6%, var(--chrome));
4978
+ font-size: 11px;
4979
+ line-height: 1.45;
4980
+ }
4981
+
4982
+ .announcement-banner-title {
4983
+ font-weight: 600;
4984
+ color: var(--accent);
4985
+ margin-bottom: 4px;
4986
+ padding-right: 14px; /* clear the ✕ */
4987
+ }
4988
+
4989
+ .announcement-banner-body {
4990
+ color: var(--text-secondary, inherit);
4991
+ }
4992
+
4993
+ .announcement-banner-cta {
4994
+ display: inline-block;
4995
+ margin-top: 6px;
4996
+ color: var(--accent);
4997
+ font-weight: 600;
4998
+ text-decoration: none;
4999
+ }
5000
+
5001
+ .announcement-banner-cta:hover {
5002
+ text-decoration: underline;
5003
+ }
5004
+
5005
+ .announcement-banner-dismiss {
5006
+ position: absolute;
5007
+ top: 4px;
5008
+ right: 6px;
5009
+ border: none;
5010
+ background: none;
5011
+ color: inherit;
5012
+ cursor: pointer;
5013
+ font-size: 11px;
5014
+ opacity: 0.6;
5015
+ }
5016
+
5017
+ .announcement-banner-dismiss:hover {
5018
+ opacity: 1;
5019
+ }
5020
+
4823
5021
  /* Edit-before-send transcript bars (default STT tier) */
4824
5022
  .sidebar-transcript-bar,
4825
5023
  .wb-transcript-bar {
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Announcements — userbase messaging in two channels, one source file.
3
+ *
4
+ * Content is a single JSON file (agentwire/static/announcements.json) edited
5
+ * on `main`. It plays two roles:
6
+ * - Remote source: fetched from raw.githubusercontent on load, so an edit
7
+ * on `main` reaches every user on their next portal open — no upgrade.
8
+ * - Bundled fallback: the same file ships in the package and is served at
9
+ * /static/announcements.json, used when the remote GET fails (offline).
10
+ *
11
+ * Each entry's `placement` picks the channel:
12
+ * - "modal" (default) — big centered splash for the moments that matter.
13
+ * - "banner" — a quiet, persistent strip in the sidebar footer for
14
+ * evergreen notes (a link, a tip, an ask).
15
+ * Both show the newest entry whose id isn't in the shared dismissed set
16
+ * (localStorage `aw-announcements-seen`); dismiss is per-id.
17
+ *
18
+ * The fetch is a single unauthenticated GET with nothing about the user in
19
+ * it — no telemetry. Content fields are rendered as ESCAPED TEXT (the
20
+ * frontend owns all markup), so even though the body comes from a URL there
21
+ * is no injection surface; the CTA url is validated to http(s).
22
+ */
23
+
24
+ const REMOTE_URL = 'https://raw.githubusercontent.com/dotdevdotdev/agentwire-dev/main/agentwire/static/announcements.json';
25
+ const LOCAL_URL = '/static/announcements.json';
26
+ const SEEN_KEY = 'aw-announcements-seen';
27
+ const FETCH_TIMEOUT_MS = 4000;
28
+
29
+ let modalEl = null;
30
+ let escHandler = null;
31
+
32
+ function escapeHtml(s) {
33
+ return String(s).replace(/[&<>"']/g, (c) => (
34
+ { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]
35
+ ));
36
+ }
37
+
38
+ function seenIds() {
39
+ try {
40
+ const raw = localStorage.getItem(SEEN_KEY);
41
+ const arr = raw ? JSON.parse(raw) : [];
42
+ return Array.isArray(arr) ? arr : [];
43
+ } catch {
44
+ return [];
45
+ }
46
+ }
47
+
48
+ function markSeen(id) {
49
+ const ids = seenIds();
50
+ if (!ids.includes(id)) {
51
+ ids.push(id);
52
+ try { localStorage.setItem(SEEN_KEY, JSON.stringify(ids)); } catch { /* ignore */ }
53
+ }
54
+ }
55
+
56
+ async function fetchJson(url) {
57
+ const ctrl = new AbortController();
58
+ const timer = setTimeout(() => ctrl.abort(), FETCH_TIMEOUT_MS);
59
+ try {
60
+ // No credentials, no caching, nothing about the user goes out.
61
+ const resp = await fetch(url, { signal: ctrl.signal, cache: 'no-store', credentials: 'omit' });
62
+ if (!resp.ok) return null;
63
+ return await resp.json();
64
+ } catch {
65
+ return null;
66
+ } finally {
67
+ clearTimeout(timer);
68
+ }
69
+ }
70
+
71
+ /** A valid, safe http(s) URL, or null. */
72
+ function safeUrl(url) {
73
+ try {
74
+ const u = new URL(String(url));
75
+ return (u.protocol === 'https:' || u.protocol === 'http:') ? u.href : null;
76
+ } catch {
77
+ return null;
78
+ }
79
+ }
80
+
81
+ /** Newest (file order) unseen announcement matching `placement` (default "modal"). */
82
+ function pickUnseen(list, placement) {
83
+ const seen = seenIds();
84
+ return list.find((a) => (
85
+ a && typeof a.id === 'string' && a.id
86
+ && (a.placement || 'modal') === placement
87
+ && !seen.includes(a.id)
88
+ )) || null;
89
+ }
90
+
91
+ function renderModal(a) {
92
+ const emoji = a.emoji ? `<div class="announcement-emoji">${escapeHtml(a.emoji)}</div>` : '';
93
+ const date = a.date ? `<div class="announcement-date">${escapeHtml(a.date)}</div>` : '';
94
+ const highlights = Array.isArray(a.highlights) && a.highlights.length
95
+ ? `<ul class="announcement-highlights">${a.highlights
96
+ .map((h) => `<li>${escapeHtml(h)}</li>`).join('')}</ul>`
97
+ : '';
98
+ const ctaUrl = a.cta && safeUrl(a.cta.url);
99
+ const cta = ctaUrl
100
+ ? `<a class="announcement-cta" href="${escapeHtml(ctaUrl)}" target="_blank" rel="noopener noreferrer">${escapeHtml(a.cta.label || 'Learn more')}</a>`
101
+ : '';
102
+ return `<div class="modal-overlay announcement-overlay" id="announcementOverlay">
103
+ <div class="modal announcement-modal" role="dialog" aria-label="Announcement" aria-modal="true">
104
+ <button class="announcement-dismiss" data-action="dismiss" title="Dismiss" aria-label="Dismiss">✕</button>
105
+ ${emoji}
106
+ <h2 class="announcement-title">${escapeHtml(a.title || 'What’s new')}</h2>
107
+ ${date}
108
+ <div class="announcement-body">${escapeHtml(a.body || '')}</div>
109
+ ${highlights}
110
+ <div class="announcement-footer">
111
+ ${cta}
112
+ <button class="announcement-ok" data-action="dismiss">Got it</button>
113
+ </div>
114
+ </div>
115
+ </div>`;
116
+ }
117
+
118
+ function closeModal(id) {
119
+ if (id) markSeen(id);
120
+ if (escHandler) { document.removeEventListener('keydown', escHandler); escHandler = null; }
121
+ modalEl?.remove();
122
+ modalEl = null;
123
+ }
124
+
125
+ function showModal(a) {
126
+ if (modalEl) return;
127
+ const wrapper = document.createElement('div');
128
+ wrapper.innerHTML = renderModal(a);
129
+ modalEl = wrapper.firstElementChild;
130
+ document.body.appendChild(modalEl);
131
+
132
+ modalEl.addEventListener('click', (e) => {
133
+ if (e.target === modalEl || e.target.closest('[data-action="dismiss"]')) {
134
+ closeModal(a.id);
135
+ }
136
+ });
137
+ escHandler = (e) => { if (e.key === 'Escape') closeModal(a.id); };
138
+ document.addEventListener('keydown', escHandler);
139
+ }
140
+
141
+ function renderBanner(a) {
142
+ const slot = document.getElementById('sidebarAnnouncementBanner');
143
+ if (!slot) return;
144
+ const ctaUrl = a.cta && safeUrl(a.cta.url);
145
+ const title = a.emoji ? `${escapeHtml(a.emoji)} ${escapeHtml(a.title || '')}` : escapeHtml(a.title || '');
146
+ const cta = ctaUrl
147
+ ? `<a class="announcement-banner-cta" href="${escapeHtml(ctaUrl)}" target="_blank" rel="noopener noreferrer">${escapeHtml(a.cta.label || 'Learn more')} →</a>`
148
+ : '';
149
+ slot.innerHTML = `<div class="announcement-banner">
150
+ <button class="announcement-banner-dismiss" data-action="dismiss" title="Dismiss" aria-label="Dismiss announcement">✕</button>
151
+ ${title ? `<div class="announcement-banner-title">${title}</div>` : ''}
152
+ ${a.body ? `<div class="announcement-banner-body">${escapeHtml(a.body)}</div>` : ''}
153
+ ${cta}
154
+ </div>`;
155
+ slot.querySelector('[data-action="dismiss"]')?.addEventListener('click', () => {
156
+ markSeen(a.id);
157
+ slot.innerHTML = '';
158
+ });
159
+ }
160
+
161
+ /**
162
+ * Fetch announcements (remote first, bundled fallback) and surface the newest
163
+ * unseen entry per channel: a centered modal and a sidebar-footer banner.
164
+ * Fails silently — an announcement is never worth a broken portal.
165
+ */
166
+ export async function initAnnouncements() {
167
+ try {
168
+ const data = (await fetchJson(REMOTE_URL)) || (await fetchJson(LOCAL_URL));
169
+ const list = Array.isArray(data?.announcements) ? data.announcements : [];
170
+ if (!list.length) return;
171
+ const modal = pickUnseen(list, 'modal');
172
+ if (modal) showModal(modal);
173
+ const banner = pickUnseen(list, 'banner');
174
+ if (banner) renderBanner(banner);
175
+ } catch {
176
+ /* never let an announcement break the desktop */
177
+ }
178
+ }
@@ -32,6 +32,7 @@ import { armDeadKeySuppressor, disarmDeadKeySuppressor } from './dead-key-suppre
32
32
  import { openCommandPalette, isCommandPaletteOpen } from './command-palette.js';
33
33
  import * as browserStt from './voice/browser-stt.js';
34
34
  import { voicePromptWrap } from './voice/prompt.js';
35
+ import { initAnnouncements } from './announcement-modal.js';
35
36
 
36
37
  // State - track open windows
37
38
  const sessionWindows = new Map(); // sessionId -> SessionWindow instance
@@ -251,6 +252,10 @@ async function init() {
251
252
 
252
253
  // Fetch initial data in the background (will emit events to listeners above)
253
254
  desktop.fetchSessions();
255
+
256
+ // Show a userbase announcement if there's a new one (non-blocking,
257
+ // fails silently — never holds up or breaks the desktop).
258
+ initAnnouncements();
254
259
  }
255
260
 
256
261
  /**
@@ -38,6 +38,7 @@
38
38
  <!-- Phase 3: list panel accordion sections mount here -->
39
39
  </div>
40
40
  <div class="sidebar-footer">
41
+ <div class="sidebar-announcement-slot" id="sidebarAnnouncementBanner"></div>
41
42
  <div class="instant-mode-banner" id="instantModeBanner" hidden>
42
43
  <div class="instant-mode-banner-title">⚡ Instant voice mode</div>
43
44
  <div class="instant-mode-banner-body">
@@ -0,0 +1,60 @@
1
+ """The bundled announcements.json must parse and match the modal's schema.
2
+
3
+ It ships in the wheel as the offline fallback AND is the remote source the
4
+ portal fetches from `main`, so a malformed entry would reach every user.
5
+ This guards the shape the frontend (announcement-modal.js) renders.
6
+ """
7
+
8
+ import json
9
+ from pathlib import Path
10
+ from urllib.parse import urlparse
11
+
12
+ import pytest
13
+
14
+ ANNOUNCEMENTS = Path(__file__).resolve().parents[2] / "agentwire" / "static" / "announcements.json"
15
+
16
+
17
+ @pytest.fixture(scope="module")
18
+ def data():
19
+ assert ANNOUNCEMENTS.exists(), f"missing {ANNOUNCEMENTS}"
20
+ return json.loads(ANNOUNCEMENTS.read_text())
21
+
22
+
23
+ def test_top_level_shape(data):
24
+ assert isinstance(data, dict)
25
+ assert isinstance(data.get("announcements"), list)
26
+
27
+
28
+ def test_ids_present_and_unique(data):
29
+ ids = [a["id"] for a in data["announcements"]]
30
+ assert all(isinstance(i, str) and i for i in ids), "every announcement needs a non-empty string id"
31
+ assert len(ids) == len(set(ids)), "announcement ids must be unique (dedup is by id)"
32
+
33
+
34
+ def test_required_and_typed_fields(data):
35
+ for a in data["announcements"]:
36
+ assert isinstance(a.get("title"), str) and a["title"], f"{a.get('id')}: title required"
37
+ assert isinstance(a.get("body"), str) and a["body"], f"{a.get('id')}: body required"
38
+ if "highlights" in a:
39
+ assert isinstance(a["highlights"], list)
40
+ assert all(isinstance(h, str) for h in a["highlights"])
41
+ if "emoji" in a:
42
+ assert isinstance(a["emoji"], str)
43
+ if "date" in a:
44
+ assert isinstance(a["date"], str)
45
+
46
+
47
+ def test_placement_valid(data):
48
+ for a in data["announcements"]:
49
+ placement = a.get("placement", "modal")
50
+ assert placement in ("modal", "banner"), f"{a['id']}: placement must be modal|banner"
51
+
52
+
53
+ def test_cta_is_safe_https(data):
54
+ for a in data["announcements"]:
55
+ cta = a.get("cta")
56
+ if cta is None:
57
+ continue
58
+ assert isinstance(cta.get("label"), str) and cta["label"], f"{a['id']}: cta needs a label"
59
+ scheme = urlparse(cta.get("url", "")).scheme
60
+ assert scheme in ("http", "https"), f"{a['id']}: cta url must be http(s)"
File without changes
File without changes
File without changes