agentwire-dev 1.29.1__tar.gz → 1.29.3__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 (313) hide show
  1. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/CHANGELOG.md +1 -0
  2. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/PKG-INFO +2 -1
  3. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/__init__.py +1 -1
  4. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/config.py +5 -0
  5. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/server.py +69 -21
  6. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/css/desktop.css +105 -0
  7. agentwire_dev-1.29.3/agentwire/static/js/command-palette.js +601 -0
  8. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/desktop-manager.js +14 -0
  9. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/desktop.js +55 -7
  10. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/sidebar/projects-section.js +3 -3
  11. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/templates/desktop.html +1 -1
  12. agentwire_dev-1.29.3/docs/decisions/obsidian-second-brain.md +88 -0
  13. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/INDEX.md +3 -2
  14. agentwire_dev-1.29.3/docs/wiki/tts/stt-self-hosted.md +108 -0
  15. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/pyproject.toml +2 -0
  16. agentwire_dev-1.29.1/agentwire/static/js/quicktask-modal.js +0 -267
  17. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/.github/FUNDING.yml +0 -0
  18. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  19. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  20. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/.github/ISSUE_TEMPLATE/question.md +0 -0
  21. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  22. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/.gitignore +0 -0
  23. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/CLA.md +0 -0
  24. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/CODE_OF_CONDUCT.md +0 -0
  25. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/CONTRIBUTING.md +0 -0
  26. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/Dockerfile.local +0 -0
  27. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/Dockerfile.runpod +0 -0
  28. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/LICENSE +0 -0
  29. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/README.md +0 -0
  30. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/RELEASING.md +0 -0
  31. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/SECURITY.md +0 -0
  32. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/SPONSORS.md +0 -0
  33. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/__main__.py +0 -0
  34. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/agents/__init__.py +0 -0
  35. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/agents/base.py +0 -0
  36. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/agents/tmux.py +0 -0
  37. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/cached_status.py +0 -0
  38. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/channels/__init__.py +0 -0
  39. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/channels/base.py +0 -0
  40. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/channels/email.py +0 -0
  41. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/channels/quo.py +0 -0
  42. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/cli_safety.py +0 -0
  43. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/completion.py +0 -0
  44. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/fetch.py +0 -0
  45. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/handoff/__init__.py +0 -0
  46. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/handoff/git_state.py +0 -0
  47. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/handoff/instructions.py +0 -0
  48. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/handoff/parser.py +0 -0
  49. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/handoff/renderer.py +0 -0
  50. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/handoff/schema.py +0 -0
  51. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/history.py +0 -0
  52. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/hooks/__init__.py +0 -0
  53. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/hooks/agentwire-permission.sh +0 -0
  54. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/hooks/damage-control/__init__.py +0 -0
  55. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/hooks/damage-control/audit_logger.py +0 -0
  56. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/hooks/damage-control/bash-tool-damage-control.py +0 -0
  57. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/hooks/damage-control/edit-tool-damage-control.py +0 -0
  58. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/hooks/damage-control/rules/agentwire.yaml +0 -0
  59. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/hooks/damage-control/rules/aws.yaml +0 -0
  60. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/hooks/damage-control/rules/cloud-hosting.yaml +0 -0
  61. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/hooks/damage-control/rules/containers.yaml +0 -0
  62. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/hooks/damage-control/rules/core.yaml +0 -0
  63. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/hooks/damage-control/rules/databases.yaml +0 -0
  64. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/hooks/damage-control/rules/firebase.yaml +0 -0
  65. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/hooks/damage-control/rules/gcp.yaml +0 -0
  66. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/hooks/damage-control/rules/git.yaml +0 -0
  67. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/hooks/damage-control/rules/gws.yaml +0 -0
  68. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/hooks/damage-control/rules/infrastructure.yaml +0 -0
  69. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/hooks/damage-control/rules/remote.yaml +0 -0
  70. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/hooks/damage-control/write-tool-damage-control.py +0 -0
  71. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/hooks/idle-handler.sh +0 -0
  72. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/listen.py +0 -0
  73. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/locking.py +0 -0
  74. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/mcp_server.py +0 -0
  75. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/missions/__init__.py +0 -0
  76. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/missions/cli.py +0 -0
  77. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/missions/config.py +0 -0
  78. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/missions/dispatcher.py +0 -0
  79. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/missions/eligibility.py +0 -0
  80. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/missions/feedback_router.py +0 -0
  81. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/missions/gc.py +0 -0
  82. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/missions/github.py +0 -0
  83. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/missions/naming.py +0 -0
  84. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/missions/state.py +0 -0
  85. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/network.py +0 -0
  86. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/onboarding.py +0 -0
  87. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/overnight.py +0 -0
  88. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/pane_manager.py +0 -0
  89. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/project_config.py +0 -0
  90. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/projects.py +0 -0
  91. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/prompts/__init__.py +0 -0
  92. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/prompts/init.md +0 -0
  93. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/roles/__init__.py +0 -0
  94. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/roles/agentwire.md +0 -0
  95. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/roles/chatbot.md +0 -0
  96. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/roles/init.md +0 -0
  97. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/roles/notifications.md +0 -0
  98. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/roles/orchestrator.md +0 -0
  99. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/roles/task-runner.md +0 -0
  100. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/roles/voice.md +0 -0
  101. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/roles/worker.md +0 -0
  102. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/safety/__init__.py +0 -0
  103. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/safety/_core.py +0 -0
  104. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/scheduler.py +0 -0
  105. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/search.py +0 -0
  106. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/agentwire-Echo--black.png +0 -0
  107. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/agentwire-Echo--transparent.png +0 -0
  108. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/agentwire-Echo.png +0 -0
  109. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/agentwire-email-banner.png +0 -0
  110. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/agentwire-splash-logo-layers--agentwire-text.png +0 -0
  111. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/agentwire-splash-logo-layers--echo-claw-fg.png +0 -0
  112. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/agentwire-splash-logo-layers--echo.png +0 -0
  113. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/agentwire-splash-logo-layers--full--transparent-top.png +0 -0
  114. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/agentwire-splash-logo-layers--full-black.png +0 -0
  115. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/agentwire-splash-logo-layers--telephone-fg.png +0 -0
  116. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/agentwire-splash-logo-layers--telephone.png +0 -0
  117. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/agentwire-splash-logo-layers--transparent-top.png +0 -0
  118. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/agentwire-splash-logo-layers--transparent.png +0 -0
  119. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/agentwire-splash-logo-layers--tree.png +0 -0
  120. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/agentwire-splash-logo-layers.png +0 -0
  121. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/favicon.png +0 -0
  122. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/machines/android.jpeg +0 -0
  123. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/machines/automaton.jpeg +0 -0
  124. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/machines/bot.jpeg +0 -0
  125. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/machines/cyborg.jpeg +0 -0
  126. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/machines/droid.jpeg +0 -0
  127. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/machines/drone.jpeg +0 -0
  128. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/machines/guardian.jpeg +0 -0
  129. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/machines/mech.jpeg +0 -0
  130. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/machines/probe.jpeg +0 -0
  131. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/machines/robot.jpeg +0 -0
  132. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/machines/sentinel.jpeg +0 -0
  133. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/machines/unit.jpeg +0 -0
  134. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/projects/blob.jpeg +0 -0
  135. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/projects/cloud.jpeg +0 -0
  136. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/projects/crystal.jpeg +0 -0
  137. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/projects/cyclops.jpeg +0 -0
  138. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/projects/flame.jpeg +0 -0
  139. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/projects/fuzzy.jpeg +0 -0
  140. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/projects/horned.jpeg +0 -0
  141. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/projects/moon.jpeg +0 -0
  142. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/projects/slime.jpeg +0 -0
  143. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/projects/star.jpeg +0 -0
  144. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/projects/tentacle.jpeg +0 -0
  145. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/projects/winged.jpeg +0 -0
  146. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/sessions/bear.jpeg +0 -0
  147. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/sessions/cat.jpeg +0 -0
  148. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/sessions/crown.jpeg +0 -0
  149. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/sessions/custom/agentwire-portal.png +0 -0
  150. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/sessions/custom/agentwire-tts.png +0 -0
  151. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/sessions/custom/agentwire.png +0 -0
  152. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/sessions/deer.jpeg +0 -0
  153. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/sessions/drone.jpeg +0 -0
  154. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/sessions/eagle.jpeg +0 -0
  155. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/sessions/fox.jpeg +0 -0
  156. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/sessions/hawk.jpeg +0 -0
  157. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/sessions/horse.jpeg +0 -0
  158. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/sessions/lion.jpeg +0 -0
  159. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/sessions/rabbit.jpeg +0 -0
  160. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/sessions/robot.jpeg +0 -0
  161. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/sessions/tiger.jpeg +0 -0
  162. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/icons/sessions/wolf.jpeg +0 -0
  163. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/.gitkeep +0 -0
  164. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/artifact-window.js +0 -0
  165. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/components/icon-picker.js +0 -0
  166. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/components/list-card.js +0 -0
  167. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/components/type-tag.js +0 -0
  168. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/icon-manager.js +0 -0
  169. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/new-project-modal.js +0 -0
  170. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/notifications-panel.js +0 -0
  171. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/safety-shared.js +0 -0
  172. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/safety-window.js +0 -0
  173. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/session-id.js +0 -0
  174. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/session-window.js +0 -0
  175. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/sidebar/artifacts-section.js +0 -0
  176. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/sidebar/config-section.js +0 -0
  177. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/sidebar/machines-section.js +0 -0
  178. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/sidebar/missions-section.js +0 -0
  179. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/sidebar/safety-section.js +0 -0
  180. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/sidebar/scheduler-section.js +0 -0
  181. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/sidebar/services-section.js +0 -0
  182. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/sidebar/sessions-section.js +0 -0
  183. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/sidebar.js +0 -0
  184. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/terminal-font-prefs.js +0 -0
  185. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/tile-manager.js +0 -0
  186. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/utils/auto-refresh.js +0 -0
  187. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/winbox.bundle.min.js +0 -0
  188. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/static/js/windows/chat-window.js +0 -0
  189. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/stt/__init__.py +0 -0
  190. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/stt/base.py +0 -0
  191. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/stt/server_backend.py +0 -0
  192. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/stt/stt_server.py +0 -0
  193. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/stt/whisperkit.py +0 -0
  194. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tasks.py +0 -0
  195. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/templates/__init__.py +0 -0
  196. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/templates/base.html +0 -0
  197. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/templates/email_notification.html +0 -0
  198. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/templates/handoff/show-the-story.html.j2 +0 -0
  199. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/templates/handoff/theme.css.j2 +0 -0
  200. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/templates/tmux.conf +0 -0
  201. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/templating.py +0 -0
  202. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tooldefs/aws.yaml +0 -0
  203. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tooldefs/docker.yaml +0 -0
  204. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tooldefs/gcp.yaml +0 -0
  205. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tooldefs/gh.yaml +0 -0
  206. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tooldefs/git.yaml +0 -0
  207. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tooldefs/gws.yaml +0 -0
  208. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tooldefs/kubectl.yaml +0 -0
  209. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tooldefs/npm.yaml +0 -0
  210. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tooldefs/terraform.yaml +0 -0
  211. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tooldefs/uv.yaml +0 -0
  212. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tts/__init__.py +0 -0
  213. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tts/base.py +0 -0
  214. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tts/engines/__init__.py +0 -0
  215. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tts/engines/chatterbox.py +0 -0
  216. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tts/engines/kokoro.py +0 -0
  217. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tts/engines/qwen_base.py +0 -0
  218. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tts/engines/qwen_custom.py +0 -0
  219. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tts/engines/qwen_design.py +0 -0
  220. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tts/engines/zonos.py +0 -0
  221. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tts/registry.py +0 -0
  222. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tts/runpod_handler.py +0 -0
  223. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tts_server.py +0 -0
  224. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/tunnels.py +0 -0
  225. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/utils/__init__.py +0 -0
  226. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/utils/chunker.py +0 -0
  227. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/utils/file_io.py +0 -0
  228. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/utils/paths.py +0 -0
  229. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/utils/subprocess.py +0 -0
  230. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/validation.py +0 -0
  231. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/voiceclone.py +0 -0
  232. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/voices/darren.wav +0 -0
  233. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/voices/default.wav +0 -0
  234. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/voices/jessica.wav +0 -0
  235. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/voices/lisa.wav +0 -0
  236. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/voices/may.wav +0 -0
  237. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/agentwire/worktree.py +0 -0
  238. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/logo.png +0 -0
  239. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/architecture.md +0 -0
  240. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/communication/channels.md +0 -0
  241. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/communication/hammerspoon.md +0 -0
  242. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/communication/handoff.md +0 -0
  243. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/concepts.md +0 -0
  244. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/deployment/remote-access.md +0 -0
  245. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/deployment/remote-machines.md +0 -0
  246. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/glossary.md +0 -0
  247. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/integrations/gws-google-workspace-cli.md +0 -0
  248. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/internals/damage-control.md +0 -0
  249. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/internals/portal.md +0 -0
  250. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/internals/shell-escaping.md +0 -0
  251. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/internals/troubleshooting.md +0 -0
  252. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/missions.md +0 -0
  253. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/quickstart.md +0 -0
  254. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/scheduling/scheduled-workloads.md +0 -0
  255. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/sessions/claude-code-auto-mode.md +0 -0
  256. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/sessions/pi.md +0 -0
  257. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/tts/runpod-tts.md +0 -0
  258. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/docs/wiki/tts/tts-self-hosted.md +0 -0
  259. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/requirements-tts.txt +0 -0
  260. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/templates/launchd/dev.agentwire.mission-dispatcher.plist +0 -0
  261. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/templates/launchd/dev.agentwire.mission-feedback-router.plist +0 -0
  262. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/templates/launchd/dev.agentwire.mission-janitor.plist +0 -0
  263. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/conftest.py +0 -0
  264. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/e2e/test_portal_ui.py +0 -0
  265. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/fixtures/sample_agentwire.yml +0 -0
  266. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/fixtures/sample_config.yaml +0 -0
  267. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/fixtures/sample_scheduler.yaml +0 -0
  268. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/integration/test_missions_concurrency.py +0 -0
  269. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/integration/test_missions_lifecycle.py +0 -0
  270. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/integration/test_scheduler_board.py +0 -0
  271. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/integration/test_server_websockets.py +0 -0
  272. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_build_agent_command.py +0 -0
  273. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_channels.py +0 -0
  274. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_cli_commands.py +0 -0
  275. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_cli_output.py +0 -0
  276. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_cli_safety.py +0 -0
  277. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_config.py +0 -0
  278. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_damage_control_hooks.py +0 -0
  279. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_damage_control_sync.py +0 -0
  280. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_file_io.py +0 -0
  281. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_handoff_git_state.py +0 -0
  282. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_handoff_instructions.py +0 -0
  283. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_handoff_parser.py +0 -0
  284. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_handoff_renderer.py +0 -0
  285. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_history.py +0 -0
  286. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_locking.py +0 -0
  287. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_mcp_server.py +0 -0
  288. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_mcp_tools_args.py +0 -0
  289. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_missions_cli.py +0 -0
  290. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_missions_config.py +0 -0
  291. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_missions_dispatcher.py +0 -0
  292. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_missions_eligibility.py +0 -0
  293. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_missions_feedback_router.py +0 -0
  294. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_missions_gc.py +0 -0
  295. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_missions_github.py +0 -0
  296. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_missions_naming.py +0 -0
  297. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_missions_state.py +0 -0
  298. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_overnight_resume_flags.py +0 -0
  299. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_portal_api.py +0 -0
  300. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_project_config.py +0 -0
  301. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_roles.py +0 -0
  302. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_safety_disabled_rules.py +0 -0
  303. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_safety_escape_hatch.py +0 -0
  304. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_safety_kill_switch.py +0 -0
  305. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_safety_mission_worker.py +0 -0
  306. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_scheduler.py +0 -0
  307. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_scheduler_parsing.py +0 -0
  308. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_search.py +0 -0
  309. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_server_async.py +0 -0
  310. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_server_pure.py +0 -0
  311. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_tasks.py +0 -0
  312. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_templating.py +0 -0
  313. {agentwire_dev-1.29.1 → agentwire_dev-1.29.3}/tests/unit/test_worktree.py +0 -0
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
10
10
  ### Removed
11
11
 
12
12
  - **Workflow engine** — entire `agentwire/workflows/` package (DAG runner, definitions, storage, pi runner, CLI), the `agentwire workflow` CLI subcommand, 5 MCP tools (`workflow_list/validate/run/history/show`), 3 portal endpoints (`/api/workflows/list|runs|runs/{id}`), the Workflows sidebar section + WorkflowWindow + ~230 lines of CSS, the scheduler's `workflow:` dispatch branch (`SchedulerTask.workflow`/`inputs` fields, `_dispatch_workflow_task`, `_render_workflow_inputs`, `_parse_workflow_summary`, `_workflow_failure_state`, validation block), 9 workflow test files plus the workflow-specific cases in `test_scheduler.py`, the `agentwire-workflows` skill, `docs/wiki/scheduling/workflows.md`, and ~120 dirs of historical runs under `~/.agentwire/workflows/`. The user's actual recurring automations all live as scheduler ensure tasks (`task:`); the engine was unused in practice and the empty sidebar surface was just noise. Scheduler is now ensure-only.
13
+ - **On-hold mission docs** — retroactive accounting for the seven on-hold files left behind by #153 and wholesale-deleted in commit `2425847` (2026-05-13) as part of the GitHub-issues-as-SSOT migration: `docs/missions/OBJECTIVE.md` (folded into README + website), `docs/missions/pi-harness-overview.md` (roadmap superseded — phases shipped or moved to research wiki), `docs/missions/pi-workflow-advanced.md` (on-hold-awaiting-usage stance has no scoped plan to track), `docs/missions/pi-workflow-ui.md` (visible portion shipped; speculative remainder unscoped), `docs/missions/later/multi-channel-bus.md` (premise actively rejected — wire surface is now outbound-only), `docs/missions/later/personal-replica.md` (speculative ideation, not a plan), `docs/missions/later/ralph-loop-use-cases.md` (brainstorm artifact). Closes [#154](https://github.com/dotdevdotdev/agentwire-dev/issues/154).
13
14
  - **Inbound channel surface** — entire Telegram bridge (`agentwire/bridges/telegram.py`), Discord channel (`agentwire/channels/discord.py`), Slack channel (`agentwire/channels/slack.py`), Twilio SMS (`agentwire/channels/sms.py`), Webhook (`agentwire/channels/webhook.py`), outbound-Telegram (`agentwire/channels/telegram.py`), channel scaffolding template (`agentwire/channels/_template.py`), all `agentwire {telegram,discord,slack,sms,webhook}` CLI command groups, the `agentwire reply` command, MCP tools `discord_status` / `slack_status` / `sms_send` / `webhook_send`, the portal sidebar "socials" section, the `ServiceChannel` / `MessageQueueManager` / `QueuedMessage` / `compose_session_config` / `inject_instructions` / session-helper plumbing in `channels/base.py`, the TTS/STT primitives on the channel base class, the auto-injected `discord-dm` / `slack-dm` / `channel-admin` roles, the `OutputConfig.notify` task field plus its `_handle_task_notification` dispatcher (voice / alert / webhook / email / command), the doctor's Telegram bridge check, and the `aiogram` optional dep. Wire surface is now outbound-only: **email** (Resend) and **quo** (OpenPhone SMS) remain. Inbound user input flows through the portal. Security review traced the cut: Telegram bridge was secure (refuse-to-start on empty allowlist + silent default-deny), Discord/Slack fail-open on empty allowlist + unauthenticated channel `@mention`; rather than fix the gaps, the whole inbound surface comes out to keep the wire posture outbound-only.
14
15
  - **Anthropic SDK surface** — entire `agentwire/sdk/` package, `agentwire/repl/` (Textual REPL), `agentwire/workflows/runners/{anthropic,human_gate}.py`, `sdk-bypass` / `sdk-prompted` / `sdk-restricted` session types, `sdk-watch` portal window + sidebar section, `--runner` workflow CLI override, and the `claude-agent-sdk` dependency. Anthropic moved Agent SDK + `claude -p` usage out of the monthly subscription tier on 2026-05-13 (now API-billed); the in-tree consumers were too expensive to keep running. The `pi` workflow runner is now the only runner. For Anthropic-quality scheduled work, use a `claude-bypass` tmux session via `.agentwire.yml` + scheduler. Mission [#184](https://github.com/dotdevdotdev/agentwire-dev/issues/184). Findings captured in `~/.agentwire/wiki/` (anthropic-agent-sdk, anthropic-runner-findings, textual-repl-retrospective, workflow-runner-choice, claude-code-print-mode).
15
16
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentwire-dev
3
- Version: 1.29.1
3
+ Version: 1.29.3
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
@@ -686,6 +686,7 @@ Classifier: Topic :: Software Development :: User Interfaces
686
686
  Requires-Python: >=3.10
687
687
  Requires-Dist: aiohttp-jinja2>=1.6
688
688
  Requires-Dist: aiohttp>=3.9.0
689
+ Requires-Dist: av>=12.0.0
689
690
  Requires-Dist: jinja2>=3.1.0
690
691
  Requires-Dist: markdown>=3.5
691
692
  Requires-Dist: mcp>=1.2.0
@@ -1,3 +1,3 @@
1
1
  """AgentWire - Multi-session voice web interface for AI coding agents."""
2
2
 
3
- __version__ = "1.29.1"
3
+ __version__ = "1.29.3"
@@ -109,6 +109,10 @@ class STTConfig:
109
109
 
110
110
  url: str | None = None # STT server URL (e.g., http://localhost:8100)
111
111
  timeout: int = 30
112
+ # Milliseconds of silence to prepend to the decoded audio before sending
113
+ # to the STT backend. Default 0 — moonshine doesn't need it. Set to ~300
114
+ # if your backend (e.g. older faster-whisper builds) clips the first syllable.
115
+ silence_prepend_ms: int = 0
112
116
 
113
117
 
114
118
  @dataclass
@@ -406,6 +410,7 @@ def _dict_to_config(data: dict) -> Config:
406
410
  stt = STTConfig(
407
411
  url=stt_data.get("url"),
408
412
  timeout=stt_data.get("timeout", 30),
413
+ silence_prepend_ms=int(stt_data.get("silence_prepend_ms", 0)),
409
414
  )
410
415
 
411
416
  # Agent
@@ -3283,7 +3283,13 @@ projects:
3283
3283
  return web.json_response({"error": str(e)}, status=500)
3284
3284
 
3285
3285
  async def handle_transcribe(self, request: web.Request) -> web.Response:
3286
- """Transcribe audio to text."""
3286
+ """Transcribe audio to text.
3287
+
3288
+ Decodes WebM/Opus uploads in-process via PyAV (no ffmpeg subprocess
3289
+ startup) and resamples to 16 kHz mono PCM16 — the canonical input
3290
+ shape for Whisper- and Moonshine-class models. Optionally prepends a
3291
+ configurable amount of silence (``stt.silence_prepend_ms``, default 0).
3292
+ """
3287
3293
  try:
3288
3294
  reader = await request.multipart()
3289
3295
  audio_field = await reader.next()
@@ -3291,46 +3297,88 @@ projects:
3291
3297
  if audio_field is None:
3292
3298
  return web.json_response({"error": "No audio data"})
3293
3299
 
3294
- # Read audio data
3295
3300
  audio_data = await audio_field.read()
3296
-
3297
3301
  if not audio_data:
3298
3302
  return web.json_response({"error": "Empty audio data"})
3299
3303
 
3300
- # Save webm to temp file
3301
- with tempfile.NamedTemporaryFile(suffix=".webm", delete=False) as f:
3302
- f.write(audio_data)
3303
- webm_path = f.name
3304
+ silence_ms = int(getattr(self.config.stt, "silence_prepend_ms", 0) or 0)
3304
3305
 
3305
- # Convert webm to wav (16kHz mono for Whisper)
3306
- wav_path = webm_path.replace(".webm", ".wav")
3307
3306
  try:
3308
- logger.info("Converting webm to wav: %s -> %s", webm_path, wav_path)
3309
- proc = await asyncio.create_subprocess_exec(
3310
- "ffmpeg", "-i", webm_path,
3311
- "-ar", "16000", "-ac", "1", "-y", wav_path,
3312
- stdout=asyncio.subprocess.DEVNULL,
3313
- stderr=asyncio.subprocess.DEVNULL,
3307
+ wav_data = await asyncio.get_event_loop().run_in_executor(
3308
+ None,
3309
+ self._decode_audio_to_wav,
3310
+ audio_data,
3311
+ silence_ms,
3314
3312
  )
3315
- await proc.wait()
3313
+ except Exception as e:
3314
+ logger.error("Failed to decode audio: %s", e)
3315
+ return web.json_response({"error": "Audio conversion failed"})
3316
3316
 
3317
- if proc.returncode != 0 or not Path(wav_path).exists():
3318
- logger.error("Failed to convert webm to wav (ffmpeg returned %d)", proc.returncode)
3319
- return web.json_response({"error": "Audio conversion failed"})
3317
+ with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as f:
3318
+ f.write(wav_data)
3319
+ wav_path = f.name
3320
3320
 
3321
- # Transcribe the wav file
3321
+ try:
3322
3322
  logger.info("Transcribing %s via %s backend", wav_path, type(self.stt).__name__)
3323
3323
  text = await self.stt.transcribe(Path(wav_path))
3324
3324
  logger.info("Transcription result: %s", text)
3325
3325
  return web.json_response({"text": text})
3326
3326
  finally:
3327
- Path(webm_path).unlink(missing_ok=True)
3328
3327
  Path(wav_path).unlink(missing_ok=True)
3329
3328
 
3330
3329
  except Exception as e:
3331
3330
  logger.error(f"Transcription failed: {e}")
3332
3331
  return web.json_response({"error": str(e)})
3333
3332
 
3333
+ @staticmethod
3334
+ def _decode_audio_to_wav(audio_data: bytes, silence_prepend_ms: int = 0) -> bytes:
3335
+ """Decode arbitrary input audio (WebM/Opus, MP3, M4A, …) to 16 kHz mono PCM16 WAV.
3336
+
3337
+ Replaces the previous ``ffmpeg -i in.webm out.wav`` subprocess. Subprocess
3338
+ cold-start was 100–300 ms before any actual decoding; PyAV uses libav
3339
+ bindings in-process so the only cost is the decoding itself.
3340
+ """
3341
+ import io
3342
+ import wave
3343
+
3344
+ import av # PyAV — declared in pyproject.toml `dependencies`
3345
+
3346
+ target_rate = 16000
3347
+
3348
+ with av.open(io.BytesIO(audio_data), mode="r") as container:
3349
+ if not container.streams.audio:
3350
+ raise RuntimeError("Input contains no audio stream")
3351
+
3352
+ resampler = av.AudioResampler(format="s16", layout="mono", rate=target_rate)
3353
+ pcm_chunks: list[bytes] = []
3354
+
3355
+ def _frame_bytes(f) -> bytes:
3356
+ # AudioFrame.planes[0] may include SIMD alignment padding; slice
3357
+ # to the exact PCM length (samples × channels × bytes_per_sample).
3358
+ bytes_per_sample = f.format.bytes # 2 for s16
3359
+ channels = len(f.layout.channels) # 1 for mono
3360
+ size = f.samples * channels * bytes_per_sample
3361
+ return bytes(f.planes[0])[:size]
3362
+
3363
+ for frame in container.decode(audio=0):
3364
+ for resampled in resampler.resample(frame):
3365
+ pcm_chunks.append(_frame_bytes(resampled))
3366
+ for resampled in resampler.resample(None):
3367
+ pcm_chunks.append(_frame_bytes(resampled))
3368
+
3369
+ if silence_prepend_ms > 0:
3370
+ silence_samples = int(target_rate * silence_prepend_ms / 1000)
3371
+ pcm_chunks.insert(0, b"\x00\x00" * silence_samples)
3372
+
3373
+ pcm_data = b"".join(pcm_chunks)
3374
+ buf = io.BytesIO()
3375
+ with wave.open(buf, "wb") as wav:
3376
+ wav.setnchannels(1)
3377
+ wav.setsampwidth(2) # 16-bit
3378
+ wav.setframerate(target_rate)
3379
+ wav.writeframes(pcm_data)
3380
+ return buf.getvalue()
3381
+
3334
3382
  async def handle_upload(self, request: web.Request) -> web.Response:
3335
3383
  """Upload an image file for attachment to messages."""
3336
3384
  try:
@@ -1162,6 +1162,111 @@ body {
1162
1162
  text-align: center;
1163
1163
  }
1164
1164
 
1165
+ /* =========================================================================
1166
+ Command palette (Cmd/Ctrl+K)
1167
+ ========================================================================= */
1168
+
1169
+ .cmdk-overlay {
1170
+ align-items: flex-start;
1171
+ padding-top: 12vh;
1172
+ }
1173
+
1174
+ .command-palette {
1175
+ width: 560px;
1176
+ max-width: 92vw;
1177
+ display: flex;
1178
+ flex-direction: column;
1179
+ overflow: hidden;
1180
+ }
1181
+
1182
+ .cmdk-search {
1183
+ display: flex;
1184
+ align-items: center;
1185
+ gap: 10px;
1186
+ padding: 12px 16px;
1187
+ border-bottom: 1px solid var(--chrome-border);
1188
+ }
1189
+
1190
+ .cmdk-search-icon {
1191
+ color: var(--text-muted);
1192
+ font-size: 16px;
1193
+ }
1194
+
1195
+ .cmdk-input {
1196
+ flex: 1;
1197
+ background: transparent;
1198
+ border: none;
1199
+ outline: none;
1200
+ color: var(--text);
1201
+ font-size: 16px;
1202
+ font-family: inherit;
1203
+ }
1204
+
1205
+ .cmdk-input::placeholder {
1206
+ color: var(--text-muted);
1207
+ }
1208
+
1209
+ .cmdk-body {
1210
+ padding: 8px;
1211
+ max-height: 50vh;
1212
+ overflow-y: auto;
1213
+ }
1214
+
1215
+ /* Form drill-ins reuse the quicktask form styling. */
1216
+ .cmdk-body .quicktask-form {
1217
+ padding: 8px 8px 4px;
1218
+ }
1219
+
1220
+ .cmdk-item {
1221
+ display: flex;
1222
+ align-items: center;
1223
+ gap: 12px;
1224
+ padding: 10px 12px;
1225
+ border-radius: 6px;
1226
+ cursor: pointer;
1227
+ font-size: 14px;
1228
+ color: var(--text);
1229
+ }
1230
+
1231
+ .cmdk-item-selected {
1232
+ background: var(--accent);
1233
+ color: var(--background);
1234
+ }
1235
+
1236
+ .cmdk-item-icon {
1237
+ width: 18px;
1238
+ text-align: center;
1239
+ opacity: 0.85;
1240
+ }
1241
+
1242
+ .cmdk-item-label {
1243
+ flex: 1;
1244
+ }
1245
+
1246
+ .cmdk-item-sub {
1247
+ font-size: 12px;
1248
+ color: var(--text-muted);
1249
+ }
1250
+
1251
+ .cmdk-item-selected .cmdk-item-sub {
1252
+ color: var(--background);
1253
+ opacity: 0.8;
1254
+ }
1255
+
1256
+ .cmdk-empty {
1257
+ padding: 20px 12px;
1258
+ text-align: center;
1259
+ color: var(--text-muted);
1260
+ font-size: 14px;
1261
+ }
1262
+
1263
+ .cmdk-footer {
1264
+ padding: 8px 16px;
1265
+ border-top: 1px solid var(--chrome-border);
1266
+ font-size: 12px;
1267
+ color: var(--text-muted);
1268
+ }
1269
+
1165
1270
  .sidebar-quicktask {
1166
1271
  background: transparent;
1167
1272
  border: none;