agentwire-dev 1.25.0__tar.gz → 1.27.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 (364) hide show
  1. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/PKG-INFO +1 -1
  2. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/__init__.py +1 -1
  3. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/__main__.py +37 -18
  4. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/cli_safety.py +4 -1
  5. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/config.py +22 -0
  6. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/hooks/damage-control/audit_logger.py +46 -1
  7. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/hooks/damage-control/bash-tool-damage-control.py +185 -17
  8. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/hooks/damage-control/edit-tool-damage-control.py +178 -16
  9. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/hooks/damage-control/write-tool-damage-control.py +178 -16
  10. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/project_config.py +18 -2
  11. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/safety/_core.py +171 -15
  12. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/server.py +117 -0
  13. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/css/desktop.css +812 -166
  14. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/desktop.js +13 -0
  15. agentwire_dev-1.27.0/agentwire/static/js/quicktask-modal.js +257 -0
  16. agentwire_dev-1.27.0/agentwire/static/js/safety-shared.js +164 -0
  17. agentwire_dev-1.27.0/agentwire/static/js/safety-window.js +172 -0
  18. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/session-window.js +40 -4
  19. agentwire_dev-1.27.0/agentwire/static/js/sidebar/config-section.js +63 -0
  20. agentwire_dev-1.27.0/agentwire/static/js/sidebar/safety-section.js +131 -0
  21. agentwire_dev-1.27.0/agentwire/static/js/terminal-font-prefs.js +43 -0
  22. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/templates/desktop.html +3 -0
  23. agentwire_dev-1.27.0/tests/unit/test_safety_disabled_rules.py +36 -0
  24. agentwire_dev-1.27.0/tests/unit/test_safety_escape_hatch.py +39 -0
  25. agentwire_dev-1.27.0/tests/unit/test_safety_kill_switch.py +34 -0
  26. agentwire_dev-1.25.0/agentwire/static/js/sidebar/config-section.js +0 -20
  27. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/.github/FUNDING.yml +0 -0
  28. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  29. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  30. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/.github/ISSUE_TEMPLATE/question.md +0 -0
  31. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  32. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/.gitignore +0 -0
  33. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/CHANGELOG.md +0 -0
  34. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/CLA.md +0 -0
  35. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/CODE_OF_CONDUCT.md +0 -0
  36. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/CONTRIBUTING.md +0 -0
  37. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/Dockerfile.local +0 -0
  38. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/Dockerfile.runpod +0 -0
  39. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/LICENSE +0 -0
  40. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/README.md +0 -0
  41. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/RELEASING.md +0 -0
  42. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/SECURITY.md +0 -0
  43. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/SPONSORS.md +0 -0
  44. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/agents/__init__.py +0 -0
  45. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/agents/base.py +0 -0
  46. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/agents/tmux.py +0 -0
  47. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/bridges/__init__.py +0 -0
  48. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/bridges/telegram.py +0 -0
  49. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/cached_status.py +0 -0
  50. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/channels/__init__.py +0 -0
  51. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/channels/_template.py +0 -0
  52. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/channels/base.py +0 -0
  53. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/channels/discord.py +0 -0
  54. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/channels/email.py +0 -0
  55. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/channels/quo.py +0 -0
  56. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/channels/slack.py +0 -0
  57. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/channels/sms.py +0 -0
  58. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/channels/telegram.py +0 -0
  59. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/channels/webhook.py +0 -0
  60. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/completion.py +0 -0
  61. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/fetch.py +0 -0
  62. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/handoff/__init__.py +0 -0
  63. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/handoff/git_state.py +0 -0
  64. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/handoff/instructions.py +0 -0
  65. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/handoff/parser.py +0 -0
  66. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/handoff/renderer.py +0 -0
  67. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/handoff/schema.py +0 -0
  68. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/history.py +0 -0
  69. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/hooks/__init__.py +0 -0
  70. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/hooks/agentwire-permission.sh +0 -0
  71. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/hooks/damage-control/__init__.py +0 -0
  72. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/hooks/damage-control/rules/agentwire.yaml +0 -0
  73. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/hooks/damage-control/rules/aws.yaml +0 -0
  74. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/hooks/damage-control/rules/cloud-hosting.yaml +0 -0
  75. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/hooks/damage-control/rules/containers.yaml +0 -0
  76. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/hooks/damage-control/rules/core.yaml +0 -0
  77. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/hooks/damage-control/rules/databases.yaml +0 -0
  78. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/hooks/damage-control/rules/firebase.yaml +0 -0
  79. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/hooks/damage-control/rules/gcp.yaml +0 -0
  80. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/hooks/damage-control/rules/git.yaml +0 -0
  81. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/hooks/damage-control/rules/gws.yaml +0 -0
  82. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/hooks/damage-control/rules/infrastructure.yaml +0 -0
  83. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/hooks/damage-control/rules/remote.yaml +0 -0
  84. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/hooks/idle-handler.sh +0 -0
  85. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/listen.py +0 -0
  86. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/locking.py +0 -0
  87. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/mcp_server.py +0 -0
  88. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/network.py +0 -0
  89. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/onboarding.py +0 -0
  90. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/overnight.py +0 -0
  91. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/pane_manager.py +0 -0
  92. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/projects.py +0 -0
  93. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/prompts/__init__.py +0 -0
  94. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/prompts/init.md +0 -0
  95. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/repl/__init__.py +0 -0
  96. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/repl/app.py +0 -0
  97. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/repl/commands.py +0 -0
  98. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/repl/context.py +0 -0
  99. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/repl/mentions.py +0 -0
  100. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/repl/persistence.py +0 -0
  101. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/repl/state.py +0 -0
  102. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/repl/textual_app.py +0 -0
  103. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/repl/views/__init__.py +0 -0
  104. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/repl/views/fanout.py +0 -0
  105. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/roles/__init__.py +0 -0
  106. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/roles/agentwire.md +0 -0
  107. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/roles/channel-admin.md +0 -0
  108. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/roles/chatbot.md +0 -0
  109. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/roles/discord-dm.md +0 -0
  110. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/roles/init.md +0 -0
  111. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/roles/notifications.md +0 -0
  112. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/roles/orchestrator.md +0 -0
  113. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/roles/slack-dm.md +0 -0
  114. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/roles/task-runner.md +0 -0
  115. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/roles/voice.md +0 -0
  116. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/roles/worker.md +0 -0
  117. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/safety/__init__.py +0 -0
  118. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/scheduler.py +0 -0
  119. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/sdk/__init__.py +0 -0
  120. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/sdk/capabilities.py +0 -0
  121. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/sdk/client.py +0 -0
  122. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/sdk/damage_control.py +0 -0
  123. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/sdk/errors.py +0 -0
  124. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/sdk/events.py +0 -0
  125. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/sdk/render.py +0 -0
  126. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/sdk/sinks/__init__.py +0 -0
  127. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/sdk/sinks/base.py +0 -0
  128. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/sdk/sinks/textual.py +0 -0
  129. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/sdk/state.py +0 -0
  130. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/search.py +0 -0
  131. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/agentwire-Echo--black.png +0 -0
  132. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/agentwire-Echo--transparent.png +0 -0
  133. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/agentwire-Echo.png +0 -0
  134. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/agentwire-email-banner.png +0 -0
  135. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/agentwire-splash-logo-layers--agentwire-text.png +0 -0
  136. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/agentwire-splash-logo-layers--echo-claw-fg.png +0 -0
  137. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/agentwire-splash-logo-layers--echo.png +0 -0
  138. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/agentwire-splash-logo-layers--full--transparent-top.png +0 -0
  139. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/agentwire-splash-logo-layers--full-black.png +0 -0
  140. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/agentwire-splash-logo-layers--telephone-fg.png +0 -0
  141. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/agentwire-splash-logo-layers--telephone.png +0 -0
  142. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/agentwire-splash-logo-layers--transparent-top.png +0 -0
  143. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/agentwire-splash-logo-layers--transparent.png +0 -0
  144. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/agentwire-splash-logo-layers--tree.png +0 -0
  145. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/agentwire-splash-logo-layers.png +0 -0
  146. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/favicon.png +0 -0
  147. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/machines/android.jpeg +0 -0
  148. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/machines/automaton.jpeg +0 -0
  149. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/machines/bot.jpeg +0 -0
  150. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/machines/cyborg.jpeg +0 -0
  151. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/machines/droid.jpeg +0 -0
  152. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/machines/drone.jpeg +0 -0
  153. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/machines/guardian.jpeg +0 -0
  154. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/machines/mech.jpeg +0 -0
  155. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/machines/probe.jpeg +0 -0
  156. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/machines/robot.jpeg +0 -0
  157. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/machines/sentinel.jpeg +0 -0
  158. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/machines/unit.jpeg +0 -0
  159. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/projects/blob.jpeg +0 -0
  160. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/projects/cloud.jpeg +0 -0
  161. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/projects/crystal.jpeg +0 -0
  162. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/projects/cyclops.jpeg +0 -0
  163. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/projects/flame.jpeg +0 -0
  164. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/projects/fuzzy.jpeg +0 -0
  165. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/projects/horned.jpeg +0 -0
  166. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/projects/moon.jpeg +0 -0
  167. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/projects/slime.jpeg +0 -0
  168. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/projects/star.jpeg +0 -0
  169. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/projects/tentacle.jpeg +0 -0
  170. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/projects/winged.jpeg +0 -0
  171. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/sessions/bear.jpeg +0 -0
  172. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/sessions/cat.jpeg +0 -0
  173. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/sessions/crown.jpeg +0 -0
  174. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/sessions/custom/agentwire-portal.png +0 -0
  175. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/sessions/custom/agentwire-tts.png +0 -0
  176. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/sessions/custom/agentwire.png +0 -0
  177. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/sessions/deer.jpeg +0 -0
  178. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/sessions/drone.jpeg +0 -0
  179. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/sessions/eagle.jpeg +0 -0
  180. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/sessions/fox.jpeg +0 -0
  181. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/sessions/hawk.jpeg +0 -0
  182. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/sessions/horse.jpeg +0 -0
  183. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/sessions/lion.jpeg +0 -0
  184. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/sessions/rabbit.jpeg +0 -0
  185. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/sessions/robot.jpeg +0 -0
  186. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/sessions/tiger.jpeg +0 -0
  187. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/icons/sessions/wolf.jpeg +0 -0
  188. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/.gitkeep +0 -0
  189. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/artifact-window.js +0 -0
  190. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/components/icon-picker.js +0 -0
  191. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/components/list-card.js +0 -0
  192. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/components/type-tag.js +0 -0
  193. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/desktop-manager.js +0 -0
  194. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/icon-manager.js +0 -0
  195. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/notifications-panel.js +0 -0
  196. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/sidebar/artifacts-section.js +0 -0
  197. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/sidebar/machines-section.js +0 -0
  198. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/sidebar/projects-section.js +0 -0
  199. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/sidebar/scheduler-section.js +0 -0
  200. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/sidebar/sdk-sessions-section.js +0 -0
  201. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/sidebar/services-section.js +0 -0
  202. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/sidebar/sessions-section.js +0 -0
  203. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/sidebar/socials-section.js +0 -0
  204. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/sidebar/workflows-section.js +0 -0
  205. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/sidebar.js +0 -0
  206. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/tile-manager.js +0 -0
  207. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/utils/auto-refresh.js +0 -0
  208. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/winbox.bundle.min.js +0 -0
  209. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/windows/chat-window.js +0 -0
  210. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/windows/sdk-watch-window.js +0 -0
  211. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/static/js/windows/workflow-window.js +0 -0
  212. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/stt/__init__.py +0 -0
  213. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/stt/base.py +0 -0
  214. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/stt/server_backend.py +0 -0
  215. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/stt/stt_server.py +0 -0
  216. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/stt/whisperkit.py +0 -0
  217. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tasks.py +0 -0
  218. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/templates/__init__.py +0 -0
  219. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/templates/base.html +0 -0
  220. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/templates/email_notification.html +0 -0
  221. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/templates/handoff/show-the-story.html.j2 +0 -0
  222. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/templates/handoff/theme.css.j2 +0 -0
  223. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/templates/tmux.conf +0 -0
  224. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/templating.py +0 -0
  225. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tooldefs/aws.yaml +0 -0
  226. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tooldefs/docker.yaml +0 -0
  227. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tooldefs/gcp.yaml +0 -0
  228. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tooldefs/gh.yaml +0 -0
  229. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tooldefs/git.yaml +0 -0
  230. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tooldefs/gws.yaml +0 -0
  231. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tooldefs/kubectl.yaml +0 -0
  232. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tooldefs/npm.yaml +0 -0
  233. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tooldefs/terraform.yaml +0 -0
  234. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tooldefs/uv.yaml +0 -0
  235. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tts/__init__.py +0 -0
  236. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tts/base.py +0 -0
  237. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tts/engines/__init__.py +0 -0
  238. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tts/engines/chatterbox.py +0 -0
  239. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tts/engines/kokoro.py +0 -0
  240. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tts/engines/qwen_base.py +0 -0
  241. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tts/engines/qwen_custom.py +0 -0
  242. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tts/engines/qwen_design.py +0 -0
  243. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tts/engines/zonos.py +0 -0
  244. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tts/registry.py +0 -0
  245. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tts/runpod_handler.py +0 -0
  246. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tts_server.py +0 -0
  247. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/tunnels.py +0 -0
  248. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/utils/__init__.py +0 -0
  249. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/utils/chunker.py +0 -0
  250. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/utils/file_io.py +0 -0
  251. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/utils/paths.py +0 -0
  252. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/utils/subprocess.py +0 -0
  253. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/validation.py +0 -0
  254. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/voiceclone.py +0 -0
  255. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/voices/darren.wav +0 -0
  256. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/voices/default.wav +0 -0
  257. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/voices/jessica.wav +0 -0
  258. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/voices/lisa.wav +0 -0
  259. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/voices/may.wav +0 -0
  260. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/workflows/__init__.py +0 -0
  261. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/workflows/cli.py +0 -0
  262. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/workflows/context.py +0 -0
  263. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/workflows/definitions.py +0 -0
  264. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/workflows/node.py +0 -0
  265. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/workflows/outputs.py +0 -0
  266. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/workflows/pi_runner.py +0 -0
  267. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/workflows/runner.py +0 -0
  268. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/workflows/runners/__init__.py +0 -0
  269. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/workflows/runners/anthropic.py +0 -0
  270. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/workflows/runners/human_gate.py +0 -0
  271. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/workflows/runners/pi.py +0 -0
  272. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/workflows/storage.py +0 -0
  273. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/agentwire/worktree.py +0 -0
  274. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/logo.png +0 -0
  275. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/INDEX.md +0 -0
  276. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/architecture.md +0 -0
  277. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/communication/channels.md +0 -0
  278. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/communication/hammerspoon.md +0 -0
  279. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/communication/handoff.md +0 -0
  280. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/concepts.md +0 -0
  281. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/deployment/remote-access.md +0 -0
  282. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/deployment/remote-machines.md +0 -0
  283. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/glossary.md +0 -0
  284. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/integrations/gws-google-workspace-cli.md +0 -0
  285. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/internals/damage-control.md +0 -0
  286. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/internals/portal.md +0 -0
  287. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/internals/shell-escaping.md +0 -0
  288. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/internals/troubleshooting.md +0 -0
  289. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/quickstart.md +0 -0
  290. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/scheduling/scheduled-workloads.md +0 -0
  291. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/scheduling/workflows.md +0 -0
  292. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/sessions/claude-code-auto-mode.md +0 -0
  293. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/sessions/pi.md +0 -0
  294. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/sessions/repl-tui.md +0 -0
  295. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/tts/runpod-tts.md +0 -0
  296. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/docs/wiki/tts/tts-self-hosted.md +0 -0
  297. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/pyproject.toml +0 -0
  298. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/requirements-tts.txt +0 -0
  299. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/conftest.py +0 -0
  300. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/e2e/test_portal_ui.py +0 -0
  301. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/fixtures/sample_agentwire.yml +0 -0
  302. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/fixtures/sample_config.yaml +0 -0
  303. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/fixtures/sample_scheduler.yaml +0 -0
  304. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/integration/test_anthropic_runner_live.py +0 -0
  305. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/integration/test_channels_cli.py +0 -0
  306. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/integration/test_scheduler_board.py +0 -0
  307. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/integration/test_server_websockets.py +0 -0
  308. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/snapshot/__snapshots__/test_repl_snapshots/test_empty_boot_snapshot.raw +0 -0
  309. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/snapshot/apps/repl_empty.py +0 -0
  310. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/snapshot/test_repl_snapshots.py +0 -0
  311. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_anthropic_capabilities.py +0 -0
  312. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_anthropic_classify.py +0 -0
  313. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_anthropic_events.py +0 -0
  314. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_build_agent_command.py +0 -0
  315. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_channels.py +0 -0
  316. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_cli_commands.py +0 -0
  317. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_cli_output.py +0 -0
  318. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_cli_safety.py +0 -0
  319. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_config.py +0 -0
  320. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_damage_control_hooks.py +0 -0
  321. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_damage_control_sync.py +0 -0
  322. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_file_io.py +0 -0
  323. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_handoff_git_state.py +0 -0
  324. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_handoff_instructions.py +0 -0
  325. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_handoff_parser.py +0 -0
  326. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_handoff_renderer.py +0 -0
  327. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_history.py +0 -0
  328. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_human_gate_runner.py +0 -0
  329. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_locking.py +0 -0
  330. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_mcp_server.py +0 -0
  331. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_mcp_tools_args.py +0 -0
  332. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_overnight_resume_flags.py +0 -0
  333. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_pi_runner.py +0 -0
  334. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_portal_api.py +0 -0
  335. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_project_config.py +0 -0
  336. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_repl_commands.py +0 -0
  337. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_repl_context.py +0 -0
  338. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_repl_damage_control.py +0 -0
  339. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_repl_fanout.py +0 -0
  340. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_repl_mentions.py +0 -0
  341. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_repl_persistence.py +0 -0
  342. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_repl_sdk.py +0 -0
  343. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_repl_sink_wrap.py +0 -0
  344. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_repl_tail.py +0 -0
  345. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_repl_textual_app.py +0 -0
  346. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_roles.py +0 -0
  347. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_runner_on_event.py +0 -0
  348. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_runner_override.py +0 -0
  349. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_runners_registry.py +0 -0
  350. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_scheduler.py +0 -0
  351. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_scheduler_parsing.py +0 -0
  352. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_scheduler_workflow_dispatch.py +0 -0
  353. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_sdk_session_types.py +0 -0
  354. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_search.py +0 -0
  355. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_server_async.py +0 -0
  356. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_server_pure.py +0 -0
  357. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_server_sdk_watch.py +0 -0
  358. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_server_workflow_history.py +0 -0
  359. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_tasks.py +0 -0
  360. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_templating.py +0 -0
  361. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_workflow_cli.py +0 -0
  362. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_workflow_storage.py +0 -0
  363. {agentwire_dev-1.25.0 → agentwire_dev-1.27.0}/tests/unit/test_workflows.py +0 -0
  364. {agentwire_dev-1.25.0 → agentwire_dev-1.27.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.25.0
3
+ Version: 1.27.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.25.0"
3
+ __version__ = "1.27.0"
@@ -3650,6 +3650,34 @@ def cmd_new(args) -> int:
3650
3650
 
3651
3651
  # Local session
3652
3652
  # Resolve path
3653
+ base_branch = getattr(args, 'base', 'main') or 'main'
3654
+ pull_first = getattr(args, 'pull_first', True)
3655
+
3656
+ def _spawn_worktree(project_path: Path, session_path: Path) -> tuple[bool, str | None]:
3657
+ """Fetch origin/<base> if requested, then create worktree starting at that ref."""
3658
+ worktree_commit: str | None = None
3659
+ if pull_first:
3660
+ fetch = subprocess.run(
3661
+ ["git", "fetch", "origin", base_branch],
3662
+ cwd=project_path,
3663
+ capture_output=True,
3664
+ text=True,
3665
+ )
3666
+ if fetch.returncode != 0:
3667
+ stderr = (fetch.stderr or fetch.stdout or "").strip()
3668
+ return False, f"git fetch origin {base_branch} failed: {stderr}"
3669
+ worktree_commit = f"origin/{base_branch}"
3670
+ ok = ensure_worktree(
3671
+ project_path,
3672
+ branch,
3673
+ session_path,
3674
+ auto_create_branch=auto_create_branch,
3675
+ commit=worktree_commit,
3676
+ )
3677
+ if not ok:
3678
+ return False, f"Failed to create worktree for branch '{branch}' in {project_path}"
3679
+ return True, None
3680
+
3653
3681
  if path and branch and worktrees_enabled:
3654
3682
  # Path + branch: use provided path as main repo, create worktree from it
3655
3683
  project_path = Path(path).expanduser().resolve()
@@ -3659,15 +3687,9 @@ def cmd_new(args) -> int:
3659
3687
  if not session_path.exists():
3660
3688
  if not project_path.exists():
3661
3689
  return _output_result(False, json_mode, f"Project path does not exist: {project_path}")
3662
-
3663
- success = ensure_worktree(
3664
- project_path,
3665
- branch,
3666
- session_path,
3667
- auto_create_branch=auto_create_branch,
3668
- )
3669
- if not success:
3670
- return _output_result(False, json_mode, f"Failed to create worktree for branch '{branch}' in {project_path}")
3690
+ ok, err = _spawn_worktree(project_path, session_path)
3691
+ if not ok:
3692
+ return _output_result(False, json_mode, err or "worktree creation failed")
3671
3693
  elif path:
3672
3694
  session_path = Path(path).expanduser().resolve()
3673
3695
  elif branch and worktrees_enabled:
@@ -3679,15 +3701,9 @@ def cmd_new(args) -> int:
3679
3701
  if not session_path.exists():
3680
3702
  if not project_path.exists():
3681
3703
  return _output_result(False, json_mode, f"Project path does not exist: {project_path}")
3682
-
3683
- success = ensure_worktree(
3684
- project_path,
3685
- branch,
3686
- session_path,
3687
- auto_create_branch=auto_create_branch,
3688
- )
3689
- if not success:
3690
- return _output_result(False, json_mode, f"Failed to create worktree for branch '{branch}' in {project_path}")
3704
+ ok, err = _spawn_worktree(project_path, session_path)
3705
+ if not ok:
3706
+ return _output_result(False, json_mode, err or "worktree creation failed")
3691
3707
  else:
3692
3708
  # Simple session: ~/projects/project/
3693
3709
  session_path = projects_dir / project
@@ -10552,6 +10568,9 @@ def main() -> int:
10552
10568
  new_parser.add_argument("--model", help="Model override (e.g., haiku, sonnet, opus)")
10553
10569
  new_parser.add_argument("--persist", action="store_true", help="Write --type/--roles to .agentwire.yml (default: session-level override only)")
10554
10570
  new_parser.add_argument("--env", action="append", metavar="KEY=VAL", help="Inject env var via `tmux set-environment` (repeatable, keeps secrets out of `ps`)")
10571
+ new_parser.add_argument("--base", default="main", help="For worktree sessions: base branch to fork the new branch from (default: main)")
10572
+ new_parser.add_argument("--pull-first", dest="pull_first", action="store_true", default=True, help="For worktree sessions: fetch origin/<base> before branching (default)")
10573
+ new_parser.add_argument("--no-pull-first", dest="pull_first", action="store_false", help="Skip the fetch — branch from the local copy of <base> as-is")
10555
10574
  new_parser.add_argument("--json", action="store_true", help="Output as JSON")
10556
10575
  new_parser.set_defaults(func=cmd_new)
10557
10576
 
@@ -190,7 +190,10 @@ def query_audit_logs(
190
190
  if today:
191
191
  log_files = [LOGS_DIR / f"{datetime.now().strftime('%Y-%m-%d')}.jsonl"]
192
192
  else:
193
- log_files = sorted(LOGS_DIR.glob("*.jsonl"), reverse=True)
193
+ # Sort chronologically (oldest first) so that within the merged list,
194
+ # entries are strictly in time order. Callers that want newest-first
195
+ # (e.g. the portal Safety section) reverse on their end after slicing.
196
+ log_files = sorted(LOGS_DIR.glob("*.jsonl"))
194
197
 
195
198
  for log_file in log_files:
196
199
  if not log_file.exists():
@@ -267,6 +267,14 @@ class OvernightConfig:
267
267
  self.live_state_file = _expand_path(self.live_state_file) or self.live_state_file
268
268
 
269
269
 
270
+ @dataclass
271
+ class SafetyConfig:
272
+ """Global damage-control safety knobs."""
273
+
274
+ enabled: bool = True
275
+ disabled_rules: list[str] = field(default_factory=list)
276
+
277
+
270
278
  @dataclass
271
279
  class Config:
272
280
  """Root configuration for AgentWire."""
@@ -285,6 +293,7 @@ class Config:
285
293
  repl: ReplConfig = field(default_factory=ReplConfig)
286
294
  scheduler: SchedulerConfig = field(default_factory=SchedulerConfig)
287
295
  overnight: OvernightConfig = field(default_factory=OvernightConfig)
296
+ safety: SafetyConfig = field(default_factory=SafetyConfig)
288
297
  channels: dict = field(default_factory=dict)
289
298
 
290
299
 
@@ -508,6 +517,18 @@ def _dict_to_config(data: dict) -> Config:
508
517
  theme_overrides = {}
509
518
  repl = ReplConfig(theme={str(k): str(v) for k, v in theme_overrides.items()})
510
519
 
520
+ # Safety (damage-control kill switch + disabled rules)
521
+ safety_data = data.get("safety", {}) or {}
522
+ if not isinstance(safety_data, dict):
523
+ safety_data = {}
524
+ disabled_rules_raw = safety_data.get("disabled_rules", []) or []
525
+ if not isinstance(disabled_rules_raw, list):
526
+ disabled_rules_raw = []
527
+ safety = SafetyConfig(
528
+ enabled=bool(safety_data.get("enabled", True)),
529
+ disabled_rules=[str(r) for r in disabled_rules_raw if r],
530
+ )
531
+
511
532
  return Config(
512
533
  server=server,
513
534
  projects=projects,
@@ -523,6 +544,7 @@ def _dict_to_config(data: dict) -> Config:
523
544
  overnight=overnight,
524
545
  channels=channel_configs,
525
546
  repl=repl,
547
+ safety=safety,
526
548
  )
527
549
 
528
550
 
@@ -56,6 +56,9 @@ def log_entry(
56
56
  blocked_by: Optional[str] = None,
57
57
  user_approved: Optional[bool] = None,
58
58
  pattern_matched: Optional[str] = None,
59
+ rule_id: Optional[str] = None,
60
+ escape_reason: Optional[str] = None,
61
+ cwd: Optional[str] = None,
59
62
  ) -> None:
60
63
  """
61
64
  Write a log entry to the audit log.
@@ -63,11 +66,15 @@ def log_entry(
63
66
  Args:
64
67
  tool: Tool name (Bash, Edit, Write)
65
68
  command: Command or path that was checked
66
- decision: "blocked", "asked", or "allowed"
69
+ decision: "blocked", "asked", "allowed", "allowed_by_escape", or "allowed_by_disabled"
67
70
  blocked_by: Reason/pattern that triggered block
68
71
  user_approved: Whether user approved (for ask patterns)
69
72
  pattern_matched: The regex pattern that matched
73
+ rule_id: Stable identifier of the matched rule (when applicable)
74
+ escape_reason: Reason supplied via "# allow:" escape hatch (when applicable)
75
+ cwd: Working directory where the command would have run
70
76
  """
77
+ import os
71
78
  context = get_session_context()
72
79
 
73
80
  entry = {
@@ -80,6 +87,9 @@ def log_entry(
80
87
  "blocked_by": blocked_by,
81
88
  "user_approved": user_approved,
82
89
  "pattern_matched": pattern_matched,
90
+ "rule_id": rule_id,
91
+ "escape_reason": escape_reason,
92
+ "cwd": cwd or os.environ.get("PWD") or os.getcwd(),
83
93
  }
84
94
 
85
95
  log_file = get_log_file()
@@ -94,6 +104,7 @@ def log_blocked(
94
104
  command: str,
95
105
  reason: str,
96
106
  pattern: Optional[str] = None,
107
+ rule_id: Optional[str] = None,
97
108
  ) -> None:
98
109
  """
99
110
  Log a blocked operation.
@@ -103,6 +114,7 @@ def log_blocked(
103
114
  command: Command or path that was blocked
104
115
  reason: Human-readable reason for block
105
116
  pattern: The regex pattern that matched
117
+ rule_id: Stable identifier of the matched rule
106
118
  """
107
119
  log_entry(
108
120
  tool=tool,
@@ -110,6 +122,39 @@ def log_blocked(
110
122
  decision="blocked",
111
123
  blocked_by=reason,
112
124
  pattern_matched=pattern,
125
+ rule_id=rule_id,
126
+ )
127
+
128
+
129
+ def log_escape(
130
+ tool: str,
131
+ command: str,
132
+ escape_reason: str,
133
+ ) -> None:
134
+ """
135
+ Log a command that was allowed through the ``# allow: <reason>`` escape hatch.
136
+ """
137
+ log_entry(
138
+ tool=tool,
139
+ command=command,
140
+ decision="allowed_by_escape",
141
+ blocked_by=f"Escape hatch: {escape_reason}",
142
+ escape_reason=escape_reason,
143
+ )
144
+
145
+
146
+ def log_disabled(
147
+ tool: str,
148
+ command: str,
149
+ ) -> None:
150
+ """
151
+ Log a command that was allowed because the safety system is disabled.
152
+ """
153
+ log_entry(
154
+ tool=tool,
155
+ command=command,
156
+ decision="allowed_by_disabled",
157
+ blocked_by="safety disabled",
113
158
  )
114
159
 
115
160
 
@@ -24,11 +24,13 @@ from pathlib import Path
24
24
 
25
25
  # audit_logger lives next to this script
26
26
  try:
27
- from audit_logger import log_allowed, log_asked, log_blocked
27
+ from audit_logger import log_allowed, log_asked, log_blocked, log_disabled, log_escape
28
28
  except ImportError:
29
29
  def log_allowed(*args, **kwargs): pass
30
30
  def log_asked(*args, **kwargs): pass
31
31
  def log_blocked(*args, **kwargs): pass
32
+ def log_disabled(*args, **kwargs): pass
33
+ def log_escape(*args, **kwargs): pass
32
34
 
33
35
 
34
36
  # === BEGIN GENERATED FROM agentwire/safety/_core.py ===
@@ -408,11 +410,42 @@ def load_write_patterns_from_tooldefs(tooldefs_dir: Optional[Path]) -> List[Dict
408
410
  return patterns
409
411
 
410
412
 
413
+ _RULE_ID_SLUG_RE = re.compile(r"[^a-z0-9]+")
414
+
415
+
416
+ def _slug_for_rule(text: str, max_len: int = 60) -> str:
417
+ """Lowercase, ASCII, kebab-case slug suitable for rule IDs."""
418
+ s = _RULE_ID_SLUG_RE.sub("-", (text or "").lower()).strip("-")
419
+ return s[:max_len] or "rule"
420
+
421
+
422
+ def _assign_rule_id(pattern_obj: Dict[str, Any], file_stem: str, taken: set) -> str:
423
+ """Generate (or honor) an ID for a bash pattern. Mutates pattern_obj in place."""
424
+ existing = pattern_obj.get("id")
425
+ if isinstance(existing, str) and existing.strip():
426
+ pattern_obj["id"] = existing.strip()
427
+ taken.add(pattern_obj["id"])
428
+ return pattern_obj["id"]
429
+ slug = _slug_for_rule(pattern_obj.get("reason", "rule"))
430
+ candidate = f"{file_stem}.{slug}"
431
+ n = 2
432
+ while candidate in taken:
433
+ candidate = f"{file_stem}.{slug}-{n}"
434
+ n += 1
435
+ pattern_obj["id"] = candidate
436
+ taken.add(candidate)
437
+ return candidate
438
+
439
+
411
440
  def load_config(
412
441
  rules_dir: Path,
413
442
  tooldefs_dir: Optional[Path] = None,
414
443
  ) -> Dict[str, Any]:
415
- """Load and merge all rule YAMLs in ``rules_dir`` plus tooldef ask-patterns."""
444
+ """Load and merge all rule YAMLs in ``rules_dir`` plus tooldef ask-patterns.
445
+
446
+ Bash patterns get a stable ``id`` field (``"<file>.<slug-of-reason>"``) so
447
+ they can be referenced by the ``safety.disabled_rules`` config.
448
+ """
416
449
  merged: Dict[str, Any] = {
417
450
  "bashToolPatterns": [],
418
451
  "zeroAccessPaths": [],
@@ -422,22 +455,110 @@ def load_config(
422
455
  }
423
456
  if not yaml or not rules_dir.exists():
424
457
  return merged
458
+ taken_ids: set = set()
425
459
  yaml_files = sorted(rules_dir.glob("*.yaml"))
426
460
  for rules_file in yaml_files:
427
461
  try:
428
462
  with open(rules_file, "r") as f:
429
463
  data = yaml.safe_load(f) or {}
430
464
  for key in merged:
431
- merged[key].extend(data.get(key, []))
465
+ items = data.get(key, []) or []
466
+ if key == "bashToolPatterns":
467
+ for it in items:
468
+ if isinstance(it, dict):
469
+ _assign_rule_id(it, rules_file.stem, taken_ids)
470
+ it.setdefault("source", rules_file.stem)
471
+ merged[key].extend(items)
432
472
  except Exception:
433
473
  continue
434
474
  if tooldefs_dir is not None:
435
- merged["bashToolPatterns"].extend(
436
- load_write_patterns_from_tooldefs(tooldefs_dir)
437
- )
475
+ tooldef_patterns = load_write_patterns_from_tooldefs(tooldefs_dir)
476
+ for it in tooldef_patterns:
477
+ _assign_rule_id(it, "tooldef", taken_ids)
478
+ it.setdefault("source", "tooldef")
479
+ merged["bashToolPatterns"].extend(tooldef_patterns)
438
480
  return merged
439
481
 
440
482
 
483
+ def load_safety_config(
484
+ global_config_path: Optional[Path] = None,
485
+ cwd: Optional[str] = None,
486
+ ) -> Dict[str, Any]:
487
+ """Resolve the effective ``safety`` block from global + nearest project config.
488
+
489
+ Returns ``{enabled: bool, disabled_rules: list[str]}``. Project ``.agentwire.yml``
490
+ overrides global; ``disabled_rules`` are merged (set-union).
491
+ """
492
+ enabled = True
493
+ disabled_rules: List[str] = []
494
+ project_enabled: Optional[bool] = None
495
+ if not yaml:
496
+ return {"enabled": enabled, "disabled_rules": disabled_rules}
497
+
498
+ if global_config_path is None:
499
+ global_config_path = Path.home() / ".agentwire" / "config.yaml"
500
+ try:
501
+ if global_config_path.exists():
502
+ with open(global_config_path, "r") as f:
503
+ data = yaml.safe_load(f) or {}
504
+ safety = data.get("safety", {})
505
+ if isinstance(safety, dict):
506
+ if "enabled" in safety:
507
+ enabled = bool(safety["enabled"])
508
+ rules = safety.get("disabled_rules", [])
509
+ if isinstance(rules, list):
510
+ disabled_rules.extend(str(r) for r in rules if r)
511
+ except Exception:
512
+ pass
513
+
514
+ if cwd is None:
515
+ cwd = os.environ.get("PWD", os.getcwd())
516
+ current = os.path.abspath(cwd)
517
+ while True:
518
+ candidate = os.path.join(current, ".agentwire.yml")
519
+ if os.path.isfile(candidate):
520
+ try:
521
+ with open(candidate, "r") as f:
522
+ pdata = yaml.safe_load(f) or {}
523
+ psafety = pdata.get("safety", {})
524
+ if isinstance(psafety, dict):
525
+ if "enabled" in psafety and psafety["enabled"] is not None:
526
+ project_enabled = bool(psafety["enabled"])
527
+ prules = psafety.get("disabled_rules", [])
528
+ if isinstance(prules, list):
529
+ disabled_rules.extend(str(r) for r in prules if r)
530
+ except Exception:
531
+ pass
532
+ break
533
+ parent = os.path.dirname(current)
534
+ if parent == current:
535
+ break
536
+ current = parent
537
+
538
+ if project_enabled is not None:
539
+ enabled = project_enabled
540
+
541
+ return {"enabled": enabled, "disabled_rules": sorted(set(disabled_rules))}
542
+
543
+
544
+ _ESCAPE_HATCH_RE = re.compile(r"#\s*allow:[ \t]*([^\n]+)", re.IGNORECASE)
545
+
546
+
547
+ def detect_escape_hatch(command: str) -> Optional[str]:
548
+ """Return the reason if ``command`` contains a ``# allow: <reason>`` marker.
549
+
550
+ Non-empty reason required; matches the rest of the comment line so the
551
+ marker works on multi-line / chained commands too.
552
+ """
553
+ if not command:
554
+ return None
555
+ m = _ESCAPE_HATCH_RE.search(command)
556
+ if not m:
557
+ return None
558
+ reason = m.group(1).strip()
559
+ return reason or None
560
+
561
+
441
562
  # ============================================================================
442
563
  # DECISION LADDERS
443
564
  # ============================================================================
@@ -446,27 +567,57 @@ def load_config(
446
567
  def check_command(command: str, config: Dict[str, Any]) -> Dict[str, Any]:
447
568
  """Decide whether a bash command should be allowed/blocked/asked.
448
569
 
449
- Returns ``{decision, reason, pattern, command}``.
570
+ Returns ``{decision, reason, pattern, command}`` plus optional ``id``,
571
+ ``escape_reason``, ``escape``, ``disabled``.
450
572
 
451
573
  Order:
452
- 1. Hard-blocked bash patterns (no ``bypassable`` flag) → BLOCK
453
- 2. Ask patternsASK
454
- 3. Bypassable bash patterns check allowlist for required operation
455
- 4. zeroAccessPaths → check allowlist with ``read`` permission
456
- 5. readOnlyPathsmatch against READ_ONLY_BLOCKED operation patterns
457
- 6. noDeletePathsmatch against NO_DELETE_BLOCKED patterns
574
+ 0. Escape hatch (``# allow: <reason>``) → ALLOW (escape=True)
575
+ 1. Kill switch (``config["safety"]["enabled"] is False``) ALLOW (disabled=True)
576
+ 2. Hard-blocked bash patterns (skip if ``id`` in ``disabled_rules``)
577
+ 3. Ask patterns
578
+ 4. Bypassable bash patterns check allowlist for required operation
579
+ 5. zeroAccessPathscheck allowlist with ``read`` permission
580
+ 6. readOnlyPaths → match against READ_ONLY_BLOCKED operation patterns
581
+ 7. noDeletePaths → match against NO_DELETE_BLOCKED patterns
458
582
  """
583
+ safety_cfg = config.get("safety", {}) if isinstance(config.get("safety"), dict) else {}
584
+ disabled_rules = set(safety_cfg.get("disabled_rules", []) or [])
585
+ is_enabled = safety_cfg.get("enabled", True)
586
+
587
+ escape_reason = detect_escape_hatch(command)
588
+ if escape_reason:
589
+ return {
590
+ "decision": "allow",
591
+ "reason": f"Escape hatch: {escape_reason}",
592
+ "pattern": None,
593
+ "command": command,
594
+ "escape": True,
595
+ "escape_reason": escape_reason,
596
+ }
597
+
598
+ if is_enabled is False:
599
+ return {
600
+ "decision": "allow",
601
+ "reason": "safety disabled",
602
+ "pattern": None,
603
+ "command": command,
604
+ "disabled": True,
605
+ }
606
+
459
607
  bash_patterns = config.get("bashToolPatterns", [])
460
608
  zero_access = config.get("zeroAccessPaths", [])
461
609
  read_only = config.get("readOnlyPaths", [])
462
610
  no_delete = config.get("noDeletePaths", [])
463
611
  allowed = load_allowed_paths(config)
464
612
 
465
- bypassable_matches: List[Tuple[str, str]] = []
613
+ bypassable_matches: List[Tuple[str, str, Optional[str]]] = []
466
614
 
467
615
  for pattern_obj in bash_patterns:
468
616
  if not isinstance(pattern_obj, dict):
469
617
  continue
618
+ rule_id = pattern_obj.get("id")
619
+ if rule_id and rule_id in disabled_rules:
620
+ continue
470
621
  pattern = pattern_obj.get("pattern", "")
471
622
  reason = pattern_obj.get("reason", "Matched pattern")
472
623
  should_ask = pattern_obj.get("ask", False)
@@ -479,20 +630,22 @@ def check_command(command: str, config: Dict[str, Any]) -> Dict[str, Any]:
479
630
  "reason": reason,
480
631
  "pattern": pattern,
481
632
  "command": command,
633
+ "id": rule_id,
482
634
  }
483
635
  elif bypassable:
484
- bypassable_matches.append((pattern, reason))
636
+ bypassable_matches.append((pattern, reason, rule_id))
485
637
  else:
486
638
  return {
487
639
  "decision": "block",
488
640
  "reason": reason,
489
641
  "pattern": pattern,
490
642
  "command": command,
643
+ "id": rule_id,
491
644
  }
492
645
  except re.error:
493
646
  continue
494
647
 
495
- for pattern, reason in bypassable_matches:
648
+ for pattern, reason, rule_id in bypassable_matches:
496
649
  operation = _infer_operation_from_reason(reason)
497
650
  if not is_command_path_allowed(command, allowed, operation):
498
651
  return {
@@ -500,6 +653,7 @@ def check_command(command: str, config: Dict[str, Any]) -> Dict[str, Any]:
500
653
  "reason": reason,
501
654
  "pattern": pattern,
502
655
  "command": command,
656
+ "id": rule_id,
503
657
  }
504
658
 
505
659
  for path in zero_access:
@@ -548,6 +702,10 @@ def check_command(command: str, config: Dict[str, Any]) -> Dict[str, Any]:
548
702
 
549
703
  def check_path(file_path: str, config: Dict[str, Any]) -> Tuple[bool, str]:
550
704
  """File-path-only check used by edit/write hooks. Returns ``(blocked, reason)``."""
705
+ safety_cfg = config.get("safety", {}) if isinstance(config.get("safety"), dict) else {}
706
+ if safety_cfg.get("enabled", True) is False:
707
+ return False, ""
708
+
551
709
  allowed = load_allowed_paths(config)
552
710
 
553
711
  if is_path_allowed_for_op(file_path, allowed, "edit"):
@@ -591,6 +749,7 @@ def _resolve_tooldefs_dir():
591
749
 
592
750
  def main() -> None:
593
751
  config = load_config(_resolve_rules_dir(), _resolve_tooldefs_dir())
752
+ config["safety"] = load_safety_config()
594
753
 
595
754
  try:
596
755
  input_data = json.load(sys.stdin)
@@ -623,7 +782,10 @@ def main() -> None:
623
782
  reason = result["reason"]
624
783
 
625
784
  if decision == "block":
626
- log_blocked("Bash", command, reason)
785
+ try:
786
+ log_blocked("Bash", command, reason, pattern=result.get("pattern"), rule_id=result.get("id"))
787
+ except TypeError:
788
+ log_blocked("Bash", command, reason)
627
789
  print(f"SECURITY: Blocked: {reason}", file=sys.stderr)
628
790
  print(f"Command: {command[:100]}{'...' if len(command) > 100 else ''}", file=sys.stderr)
629
791
  sys.exit(2)
@@ -638,6 +800,12 @@ def main() -> None:
638
800
  }
639
801
  print(json.dumps(output))
640
802
  sys.exit(0)
803
+ elif result.get("escape"):
804
+ log_escape("Bash", command, result.get("escape_reason") or "")
805
+ sys.exit(0)
806
+ elif result.get("disabled"):
807
+ log_disabled("Bash", command)
808
+ sys.exit(0)
641
809
  else:
642
810
  log_allowed("Bash", command, user_approved=False)
643
811
  sys.exit(0)