agent-cli 0.95.8__tar.gz → 0.95.9__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 (432) hide show
  1. agent_cli-0.95.9/.github/scripts/update_cask.py +87 -0
  2. {agent_cli-0.95.8 → agent_cli-0.95.9}/.github/workflows/release.yml +25 -0
  3. {agent_cli-0.95.8 → agent_cli-0.95.9}/Casks/agent-cli.rb +2 -2
  4. {agent_cli-0.95.8 → agent_cli-0.95.9}/PKG-INFO +1 -1
  5. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Sources/AgentCLI/AgentCommandRunner.swift +1 -1
  6. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Sources/AgentCLI/BootstrapState.swift +24 -3
  7. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Sources/AgentCLI/Shortcuts.swift +79 -43
  8. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Tests/AgentCLITests/AgentCommandTests.swift +18 -6
  9. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_macos_app.py +33 -16
  10. agent_cli-0.95.9/tests/test_update_cask.py +51 -0
  11. {agent_cli-0.95.8 → agent_cli-0.95.9}/.claude/skills/agent-cli-dev/SKILL.md +0 -0
  12. {agent_cli-0.95.8 → agent_cli-0.95.9}/.claude/skills/agent-cli-dev/examples.md +0 -0
  13. {agent_cli-0.95.8 → agent_cli-0.95.9}/.claude-plugin/README.md +0 -0
  14. {agent_cli-0.95.8 → agent_cli-0.95.9}/.claude-plugin/marketplace.json +0 -0
  15. {agent_cli-0.95.8 → agent_cli-0.95.9}/.claude-plugin/plugin.json +0 -0
  16. {agent_cli-0.95.8 → agent_cli-0.95.9}/.claude-plugin/skills/agent-cli-dev/SKILL.md +0 -0
  17. {agent_cli-0.95.8 → agent_cli-0.95.9}/.claude-plugin/skills/agent-cli-dev/examples.md +0 -0
  18. {agent_cli-0.95.8 → agent_cli-0.95.9}/.cursorrules +0 -0
  19. {agent_cli-0.95.8 → agent_cli-0.95.9}/.dockerignore +0 -0
  20. {agent_cli-0.95.8 → agent_cli-0.95.9}/.env.example +0 -0
  21. {agent_cli-0.95.8 → agent_cli-0.95.9}/.github/logo.svg +0 -0
  22. {agent_cli-0.95.8 → agent_cli-0.95.9}/.github/release-drafter.yml +0 -0
  23. {agent_cli-0.95.8 → agent_cli-0.95.9}/.github/renovate.json +0 -0
  24. {agent_cli-0.95.8 → agent_cli-0.95.9}/.github/scripts/check_extras_sync.py +0 -0
  25. {agent_cli-0.95.8 → agent_cli-0.95.9}/.github/scripts/check_plugin_skill_sync.py +0 -0
  26. {agent_cli-0.95.8 → agent_cli-0.95.9}/.github/scripts/sync_extras.py +0 -0
  27. {agent_cli-0.95.8 → agent_cli-0.95.9}/.github/scripts/sync_requirements.py +0 -0
  28. {agent_cli-0.95.8 → agent_cli-0.95.9}/.github/workflows/automerge.yml +0 -0
  29. {agent_cli-0.95.8 → agent_cli-0.95.9}/.github/workflows/docker.yml +0 -0
  30. {agent_cli-0.95.8 → agent_cli-0.95.9}/.github/workflows/docs.yml +0 -0
  31. {agent_cli-0.95.8 → agent_cli-0.95.9}/.github/workflows/markdown-code-runner.yml +0 -0
  32. {agent_cli-0.95.8 → agent_cli-0.95.9}/.github/workflows/pytest.yml +0 -0
  33. {agent_cli-0.95.8 → agent_cli-0.95.9}/.github/workflows/release-drafter.yml +0 -0
  34. {agent_cli-0.95.8 → agent_cli-0.95.9}/.github/workflows/toc.yaml +0 -0
  35. {agent_cli-0.95.8 → agent_cli-0.95.9}/.gitignore +0 -0
  36. {agent_cli-0.95.8 → agent_cli-0.95.9}/.jscpd.json +0 -0
  37. {agent_cli-0.95.8 → agent_cli-0.95.9}/.pre-commit-config.yaml +0 -0
  38. {agent_cli-0.95.8 → agent_cli-0.95.9}/.prompts/docs-review.md +0 -0
  39. {agent_cli-0.95.8 → agent_cli-0.95.9}/.prompts/pr-review.md +0 -0
  40. {agent_cli-0.95.8 → agent_cli-0.95.9}/CLAUDE.md +0 -0
  41. {agent_cli-0.95.8 → agent_cli-0.95.9}/LICENSE +0 -0
  42. {agent_cli-0.95.8 → agent_cli-0.95.9}/LLAMA_SERVER_USAGE.md +0 -0
  43. {agent_cli-0.95.8 → agent_cli-0.95.9}/README.md +0 -0
  44. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/__init__.py +0 -0
  45. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/__main__.py +0 -0
  46. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/_extras.json +0 -0
  47. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/_requirements/.gitkeep +0 -0
  48. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/_requirements/audio.txt +0 -0
  49. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/_requirements/diarization.txt +0 -0
  50. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/_requirements/faster-whisper.txt +0 -0
  51. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/_requirements/kokoro.txt +0 -0
  52. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/_requirements/llm.txt +0 -0
  53. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/_requirements/memory.txt +0 -0
  54. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/_requirements/mlx-whisper.txt +0 -0
  55. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/_requirements/piper.txt +0 -0
  56. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/_requirements/rag.txt +0 -0
  57. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/_requirements/server.txt +0 -0
  58. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/_requirements/speed.txt +0 -0
  59. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/_requirements/vad.txt +0 -0
  60. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/_requirements/vectordb.txt +0 -0
  61. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/_requirements/whisper-transformers.txt +0 -0
  62. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/_requirements/wyoming.txt +0 -0
  63. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/_tools.py +0 -0
  64. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/agents/__init__.py +0 -0
  65. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/agents/_voice_agent_common.py +0 -0
  66. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/agents/assistant.py +0 -0
  67. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/agents/autocorrect.py +0 -0
  68. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/agents/chat.py +0 -0
  69. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/agents/diarize_live_session.py +0 -0
  70. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/agents/memory/__init__.py +0 -0
  71. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/agents/memory/add.py +0 -0
  72. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/agents/memory/proxy.py +0 -0
  73. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/agents/rag_proxy.py +0 -0
  74. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/agents/speak.py +0 -0
  75. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/agents/speakers.py +0 -0
  76. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/agents/transcribe.py +0 -0
  77. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/agents/transcribe_live.py +0 -0
  78. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/agents/voice_edit.py +0 -0
  79. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/api.py +0 -0
  80. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/cli.py +0 -0
  81. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/config.py +0 -0
  82. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/config_cmd.py +0 -0
  83. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/constants.py +0 -0
  84. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/core/__init__.py +0 -0
  85. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/core/alignment.py +0 -0
  86. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/core/audio.py +0 -0
  87. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/core/audio_format.py +0 -0
  88. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/core/chroma.py +0 -0
  89. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/core/deps.py +0 -0
  90. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/core/diarization.py +0 -0
  91. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/core/openai_proxy.py +0 -0
  92. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/core/process.py +0 -0
  93. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/core/reranker.py +0 -0
  94. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/core/speaker_identity.py +0 -0
  95. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/core/sse.py +0 -0
  96. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/core/transcription_logger.py +0 -0
  97. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/core/utils.py +0 -0
  98. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/core/vad.py +0 -0
  99. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/core/watch.py +0 -0
  100. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/daemon/__init__.py +0 -0
  101. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/daemon/cli.py +0 -0
  102. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/__init__.py +0 -0
  103. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/_branch_name.py +0 -0
  104. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/_config.py +0 -0
  105. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/_output.py +0 -0
  106. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/cleanup.py +0 -0
  107. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/cli.py +0 -0
  108. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/coding_agents/__init__.py +0 -0
  109. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/coding_agents/aider.py +0 -0
  110. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/coding_agents/base.py +0 -0
  111. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/coding_agents/claude.py +0 -0
  112. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/coding_agents/codex.py +0 -0
  113. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/coding_agents/continue_dev.py +0 -0
  114. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/coding_agents/copilot.py +0 -0
  115. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/coding_agents/cursor_agent.py +0 -0
  116. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/coding_agents/gemini.py +0 -0
  117. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/coding_agents/opencode.py +0 -0
  118. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/coding_agents/registry.py +0 -0
  119. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/editors/__init__.py +0 -0
  120. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/editors/base.py +0 -0
  121. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/editors/cursor.py +0 -0
  122. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/editors/emacs.py +0 -0
  123. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/editors/jetbrains.py +0 -0
  124. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/editors/nano.py +0 -0
  125. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/editors/neovim.py +0 -0
  126. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/editors/registry.py +0 -0
  127. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/editors/sublime.py +0 -0
  128. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/editors/vim.py +0 -0
  129. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/editors/vscode.py +0 -0
  130. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/editors/zed.py +0 -0
  131. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/hooks.py +0 -0
  132. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/launch.py +0 -0
  133. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/project.py +0 -0
  134. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/registry.py +0 -0
  135. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/skill/SKILL.md +0 -0
  136. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/skill/examples.md +0 -0
  137. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/terminals/__init__.py +0 -0
  138. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/terminals/apple_terminal.py +0 -0
  139. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/terminals/base.py +0 -0
  140. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/terminals/gnome.py +0 -0
  141. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/terminals/iterm2.py +0 -0
  142. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/terminals/kitty.py +0 -0
  143. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/terminals/registry.py +0 -0
  144. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/terminals/tmux.py +0 -0
  145. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/terminals/warp.py +0 -0
  146. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/terminals/zellij.py +0 -0
  147. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/dev/worktree.py +0 -0
  148. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/docs_gen.py +0 -0
  149. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/example-config.toml +0 -0
  150. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/install/__init__.py +0 -0
  151. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/install/common.py +0 -0
  152. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/install/extras.py +0 -0
  153. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/install/hotkeys.py +0 -0
  154. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/install/launchd.py +0 -0
  155. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/install/service_config.py +0 -0
  156. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/install/services.py +0 -0
  157. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/install/systemd.py +0 -0
  158. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/memory/__init__.py +0 -0
  159. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/memory/_files.py +0 -0
  160. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/memory/_filters.py +0 -0
  161. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/memory/_git.py +0 -0
  162. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/memory/_indexer.py +0 -0
  163. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/memory/_ingest.py +0 -0
  164. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/memory/_persistence.py +0 -0
  165. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/memory/_prompt.py +0 -0
  166. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/memory/_retrieval.py +0 -0
  167. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/memory/_store.py +0 -0
  168. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/memory/_streaming.py +0 -0
  169. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/memory/_tasks.py +0 -0
  170. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/memory/api.py +0 -0
  171. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/memory/client.py +0 -0
  172. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/memory/engine.py +0 -0
  173. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/memory/entities.py +0 -0
  174. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/memory/models.py +0 -0
  175. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/opts.py +0 -0
  176. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/py.typed +0 -0
  177. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/rag/__init__.py +0 -0
  178. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/rag/_indexer.py +0 -0
  179. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/rag/_indexing.py +0 -0
  180. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/rag/_prompt.py +0 -0
  181. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/rag/_retriever.py +0 -0
  182. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/rag/_store.py +0 -0
  183. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/rag/_utils.py +0 -0
  184. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/rag/api.py +0 -0
  185. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/rag/client.py +0 -0
  186. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/rag/engine.py +0 -0
  187. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/rag/models.py +0 -0
  188. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/.runtime/.gitkeep +0 -0
  189. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/__init__.py +0 -0
  190. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/linux-hotkeys/README.md +0 -0
  191. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/linux-hotkeys/toggle-autocorrect.sh +0 -0
  192. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/linux-hotkeys/toggle-transcription.sh +0 -0
  193. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/linux-hotkeys/toggle-voice-edit.sh +0 -0
  194. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/macos-hotkeys/README.md +0 -0
  195. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/macos-hotkeys/skhd-config-example +0 -0
  196. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/macos-hotkeys/toggle-autocorrect.sh +0 -0
  197. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/macos-hotkeys/toggle-transcription.sh +0 -0
  198. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/macos-hotkeys/toggle-voice-edit.sh +0 -0
  199. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/nvidia-asr-server/README.md +0 -0
  200. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/nvidia-asr-server/pyproject.toml +0 -0
  201. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/nvidia-asr-server/server.py +0 -0
  202. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/nvidia-asr-server/shell.nix +0 -0
  203. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/nvidia-asr-server/uv.lock +0 -0
  204. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/run-openwakeword.sh +0 -0
  205. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/setup-linux-hotkeys.sh +0 -0
  206. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/setup-linux.sh +0 -0
  207. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/setup-macos-hotkeys.sh +0 -0
  208. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/setup-macos.sh +0 -0
  209. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/setup-windows.ps1 +0 -0
  210. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/start-all-services-windows.ps1 +0 -0
  211. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/scripts/start-all-services.sh +0 -0
  212. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/__init__.py +0 -0
  213. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/cli.py +0 -0
  214. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/common.py +0 -0
  215. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/model_manager.py +0 -0
  216. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/model_registry.py +0 -0
  217. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/proxy/__init__.py +0 -0
  218. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/proxy/api.py +0 -0
  219. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/streaming.py +0 -0
  220. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/tts/__init__.py +0 -0
  221. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/tts/api.py +0 -0
  222. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/tts/backends/__init__.py +0 -0
  223. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/tts/backends/base.py +0 -0
  224. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/tts/backends/kokoro.py +0 -0
  225. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/tts/backends/piper.py +0 -0
  226. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/tts/model_manager.py +0 -0
  227. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/tts/model_registry.py +0 -0
  228. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/tts/wyoming_handler.py +0 -0
  229. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/whisper/__init__.py +0 -0
  230. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/whisper/api.py +0 -0
  231. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/whisper/backends/__init__.py +0 -0
  232. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/whisper/backends/base.py +0 -0
  233. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/whisper/backends/faster_whisper.py +0 -0
  234. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/whisper/backends/mlx.py +0 -0
  235. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/whisper/backends/transformers.py +0 -0
  236. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/whisper/languages.py +0 -0
  237. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/whisper/model_manager.py +0 -0
  238. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/whisper/model_registry.py +0 -0
  239. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/server/whisper/wyoming_handler.py +0 -0
  240. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/services/__init__.py +0 -0
  241. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/services/_wyoming_utils.py +0 -0
  242. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/services/asr.py +0 -0
  243. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/services/llm.py +0 -0
  244. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/services/tts.py +0 -0
  245. {agent_cli-0.95.8 → agent_cli-0.95.9}/agent_cli/services/wake_word.py +0 -0
  246. {agent_cli-0.95.8 → agent_cli-0.95.9}/docker/docker-compose.yml +0 -0
  247. {agent_cli-0.95.8 → agent_cli-0.95.9}/docker/memory-proxy.Dockerfile +0 -0
  248. {agent_cli-0.95.8 → agent_cli-0.95.9}/docker/rag-proxy.Dockerfile +0 -0
  249. {agent_cli-0.95.8 → agent_cli-0.95.9}/docker/transcribe-proxy.Dockerfile +0 -0
  250. {agent_cli-0.95.8 → agent_cli-0.95.9}/docker/tts.Dockerfile +0 -0
  251. {agent_cli-0.95.8 → agent_cli-0.95.9}/docker/whisper.Dockerfile +0 -0
  252. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/CNAME +0 -0
  253. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/architecture/index.md +0 -0
  254. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/architecture/memory.md +0 -0
  255. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/architecture/rag.md +0 -0
  256. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/assistant.md +0 -0
  257. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/autocorrect.md +0 -0
  258. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/chat.md +0 -0
  259. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/config.md +0 -0
  260. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/daemon.md +0 -0
  261. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/dev.md +0 -0
  262. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/diarize-live-session.md +0 -0
  263. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/index.md +0 -0
  264. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/install-extras.md +0 -0
  265. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/install-hotkeys.md +0 -0
  266. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/install-services.md +0 -0
  267. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/memory.md +0 -0
  268. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/rag-proxy.md +0 -0
  269. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/server/index.md +0 -0
  270. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/server/transcribe-proxy.md +0 -0
  271. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/server/tts.md +0 -0
  272. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/server/whisper.md +0 -0
  273. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/speak.md +0 -0
  274. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/speakers.md +0 -0
  275. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/start-services.md +0 -0
  276. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/transcribe-live.md +0 -0
  277. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/transcribe.md +0 -0
  278. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/commands/voice-edit.md +0 -0
  279. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/configuration.md +0 -0
  280. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/getting-started.md +0 -0
  281. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/iOS_Shortcut_Guide.md +0 -0
  282. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/index.md +0 -0
  283. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/installation/docker.md +0 -0
  284. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/installation/index.md +0 -0
  285. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/installation/linux.md +0 -0
  286. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/installation/macos.md +0 -0
  287. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/installation/nixos.md +0 -0
  288. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/installation/windows.md +0 -0
  289. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/logo-avatar.svg +0 -0
  290. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/logo-clean.svg +0 -0
  291. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/overrides/partials/integrations/analytics/custom.html +0 -0
  292. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/run_markdown_code_runner.py +0 -0
  293. {agent_cli-0.95.8 → agent_cli-0.95.9}/docs/system-integration.md +0 -0
  294. {agent_cli-0.95.8 → agent_cli-0.95.9}/example.agent-cli-config.toml +0 -0
  295. {agent_cli-0.95.8 → agent_cli-0.95.9}/justfile +0 -0
  296. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Package.resolved +0 -0
  297. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Package.swift +0 -0
  298. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/README.md +0 -0
  299. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Resources/AgentCLI.entitlements +0 -0
  300. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Resources/Info.plist +0 -0
  301. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Resources/dmg-background.svg +0 -0
  302. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Sources/AgentCLI/AgentCLIApp.swift +0 -0
  303. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Sources/AgentCLI/AgentCommand.swift +0 -0
  304. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Sources/AgentCLI/AgentRuntime.swift +0 -0
  305. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Sources/AgentCLI/AppDelegate.swift +0 -0
  306. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Sources/AgentCLI/CommandResult.swift +0 -0
  307. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Sources/AgentCLI/ConfigurableHotkeyController.swift +0 -0
  308. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Sources/AgentCLI/FocusedTextTarget.swift +0 -0
  309. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Sources/AgentCLI/LoginItemController.swift +0 -0
  310. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Sources/AgentCLI/MenuBarIcon.swift +0 -0
  311. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Sources/AgentCLI/RecentTranscriptionReader.swift +0 -0
  312. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Sources/AgentCLI/RecordingIndicatorController.swift +0 -0
  313. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Sources/AgentCLI/RecordingSoundSettings.swift +0 -0
  314. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Sources/AgentCLI/RuntimeSettings.swift +0 -0
  315. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Sources/AgentCLI/TranscriptPasteController.swift +0 -0
  316. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Sources/AgentCLI/TranscriptionSettings.swift +0 -0
  317. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Sources/AgentCLI/VoiceLevelOverlay.swift +0 -0
  318. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Tests/AgentCLITests/LoginItemControllerTests.swift +0 -0
  319. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Tests/AgentCLITests/RecentTranscriptionReaderTests.swift +0 -0
  320. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Tests/AgentCLITests/RecordingIndicatorControllerTests.swift +0 -0
  321. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/AgentCLI/Tests/AgentCLITests/ShortcutDefaultsTests.swift +0 -0
  322. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/build-macos-app.sh +0 -0
  323. {agent_cli-0.95.8 → agent_cli-0.95.9}/macos/test-macos-app-e2e.sh +0 -0
  324. {agent_cli-0.95.8 → agent_cli-0.95.9}/pyproject.toml +0 -0
  325. {agent_cli-0.95.8 → agent_cli-0.95.9}/reddit.md +0 -0
  326. {agent_cli-0.95.8 → agent_cli-0.95.9}/shell.nix +0 -0
  327. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/__init__.py +0 -0
  328. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/agents/__init__.py +0 -0
  329. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/agents/test_fix_my_text.py +0 -0
  330. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/agents/test_interactive.py +0 -0
  331. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/agents/test_interactive_extra.py +0 -0
  332. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/agents/test_memory_add.py +0 -0
  333. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/agents/test_speak.py +0 -0
  334. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/agents/test_speak_e2e.py +0 -0
  335. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/agents/test_speakers.py +0 -0
  336. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/agents/test_transcribe.py +0 -0
  337. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/agents/test_transcribe_agent.py +0 -0
  338. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/agents/test_transcribe_e2e.py +0 -0
  339. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/agents/test_transcribe_live.py +0 -0
  340. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/agents/test_transcribe_recovery.py +0 -0
  341. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/agents/test_tts_common.py +0 -0
  342. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/agents/test_tts_common_extra.py +0 -0
  343. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/agents/test_voice_agent_common.py +0 -0
  344. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/agents/test_voice_edit.py +0 -0
  345. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/agents/test_voice_edit_e2e.py +0 -0
  346. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/agents/test_wake_word_assistant.py +0 -0
  347. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/conftest.py +0 -0
  348. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/core/__init__.py +0 -0
  349. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/core/test_audio.py +0 -0
  350. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/core/test_audio_format.py +0 -0
  351. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/core/test_chroma.py +0 -0
  352. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/core/test_sse.py +0 -0
  353. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/core/test_vad.py +0 -0
  354. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/core/test_watch.py +0 -0
  355. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/dev/__init__.py +0 -0
  356. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/dev/test_cleanup.py +0 -0
  357. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/dev/test_cli.py +0 -0
  358. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/dev/test_coding_agents.py +0 -0
  359. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/dev/test_editors.py +0 -0
  360. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/dev/test_hooks.py +0 -0
  361. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/dev/test_launch.py +0 -0
  362. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/dev/test_project.py +0 -0
  363. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/dev/test_terminals.py +0 -0
  364. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/dev/test_verification.py +0 -0
  365. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/dev/test_worktree.py +0 -0
  366. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/install/__init__.py +0 -0
  367. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/install/test_extras.py +0 -0
  368. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/install/test_launchd.py +0 -0
  369. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/memory/__init__.py +0 -0
  370. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/memory/test_api_health.py +0 -0
  371. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/memory/test_api_integration_liveish.py +0 -0
  372. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/memory/test_client.py +0 -0
  373. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/memory/test_engine.py +0 -0
  374. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/memory/test_files.py +0 -0
  375. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/memory/test_filters.py +0 -0
  376. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/memory/test_git_integration.py +0 -0
  377. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/memory/test_indexer.py +0 -0
  378. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/memory/test_memory_integration.py +0 -0
  379. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/memory/test_proxy_passthrough.py +0 -0
  380. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/memory/test_store.py +0 -0
  381. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/memory/test_utils.py +0 -0
  382. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/mocks/__init__.py +0 -0
  383. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/mocks/audio.py +0 -0
  384. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/mocks/llm.py +0 -0
  385. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/mocks/wyoming.py +0 -0
  386. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/rag/__init__.py +0 -0
  387. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/rag/test_api.py +0 -0
  388. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/rag/test_engine.py +0 -0
  389. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/rag/test_history.py +0 -0
  390. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/rag/test_indexer.py +0 -0
  391. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/rag/test_indexing.py +0 -0
  392. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/rag/test_rag_client.py +0 -0
  393. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/rag/test_rag_integration_liveish.py +0 -0
  394. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/rag/test_rag_proxy_passthrough.py +0 -0
  395. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/rag/test_retriever.py +0 -0
  396. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/rag/test_store.py +0 -0
  397. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/rag/test_utils.py +0 -0
  398. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_alignment.py +0 -0
  399. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_api.py +0 -0
  400. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_api_integration.py +0 -0
  401. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_asr.py +0 -0
  402. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_asr_recovery.py +0 -0
  403. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_audio_e2e.py +0 -0
  404. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_cli.py +0 -0
  405. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_config.py +0 -0
  406. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_config_cmd.py +0 -0
  407. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_daemon.py +0 -0
  408. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_diarization.py +0 -0
  409. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_diarize_live_session.py +0 -0
  410. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_docs_gen.py +0 -0
  411. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_env_vars.py +0 -0
  412. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_faster_whisper_backend.py +0 -0
  413. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_json_output.py +0 -0
  414. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_llm.py +0 -0
  415. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_llm_gemini.py +0 -0
  416. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_memory_tools.py +0 -0
  417. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_mlx_backend.py +0 -0
  418. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_process_manager.py +0 -0
  419. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_requires_extras.py +0 -0
  420. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_server_streaming.py +0 -0
  421. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_server_tts.py +0 -0
  422. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_server_whisper.py +0 -0
  423. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_services.py +0 -0
  424. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_speaker_identity.py +0 -0
  425. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_tools.py +0 -0
  426. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_transformers_backend.py +0 -0
  427. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_tts.py +0 -0
  428. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_utils.py +0 -0
  429. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_wake_word.py +0 -0
  430. {agent_cli-0.95.8 → agent_cli-0.95.9}/tests/test_wyoming_utils.py +0 -0
  431. {agent_cli-0.95.8 → agent_cli-0.95.9}/uv.lock +0 -0
  432. {agent_cli-0.95.8 → agent_cli-0.95.9}/zensical.toml +0 -0
@@ -0,0 +1,87 @@
1
+ """Update the Agent CLI Homebrew cask version and checksum."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import re
7
+ from pathlib import Path
8
+
9
+ VERSION_RE = re.compile(r'^(?P<indent>\s*)version "[^"]+"$')
10
+ SHA256_RE = re.compile(r'^(?P<indent>\s*)sha256 "[0-9a-f]{64}"$')
11
+
12
+
13
+ def _validate_sha256(value: str) -> str:
14
+ if not re.fullmatch(r"[0-9a-f]{64}", value):
15
+ msg = "sha256 must be 64 lowercase hexadecimal characters"
16
+ raise ValueError(msg)
17
+ return value
18
+
19
+
20
+ def _validate_version(value: str) -> str:
21
+ value = value.removeprefix("v")
22
+ if not re.fullmatch(r"\d+(?:\.\d+)*(?:[-,._A-Za-z0-9]+)?", value):
23
+ msg = f"unsupported cask version: {value}"
24
+ raise ValueError(msg)
25
+ return value
26
+
27
+
28
+ def update_cask_text(text: str, *, version: str, sha256: str) -> str:
29
+ """Replace the single version and sha256 stanzas in a cask."""
30
+ version = _validate_version(version)
31
+ sha256 = _validate_sha256(sha256)
32
+
33
+ version_count = 0
34
+ sha256_count = 0
35
+ lines: list[str] = []
36
+ for source_line in text.splitlines(keepends=True):
37
+ newline = "\n" if source_line.endswith("\n") else ""
38
+ content = source_line.removesuffix("\n")
39
+
40
+ if match := VERSION_RE.match(content):
41
+ output_line = f'{match.group("indent")}version "{version}"{newline}'
42
+ version_count += 1
43
+ elif match := SHA256_RE.match(content):
44
+ output_line = f'{match.group("indent")}sha256 "{sha256}"{newline}'
45
+ sha256_count += 1
46
+ else:
47
+ output_line = source_line
48
+ lines.append(output_line)
49
+
50
+ if version_count != 1:
51
+ msg = f"expected exactly one version stanza, found {version_count}"
52
+ raise ValueError(msg)
53
+ if sha256_count != 1:
54
+ msg = f"expected exactly one sha256 stanza, found {sha256_count}"
55
+ raise ValueError(msg)
56
+
57
+ return "".join(lines)
58
+
59
+
60
+ def update_cask_file(path: Path, *, version: str, sha256: str) -> None:
61
+ """Update a cask file in place."""
62
+ path.write_text(
63
+ update_cask_text(path.read_text(), version=version, sha256=sha256),
64
+ encoding="utf-8",
65
+ )
66
+
67
+
68
+ def main() -> None:
69
+ """Run the command-line cask updater."""
70
+ parser = argparse.ArgumentParser(description=__doc__)
71
+ parser.add_argument(
72
+ "--cask",
73
+ type=Path,
74
+ default=Path("Casks/agent-cli.rb"),
75
+ help="Path to the cask file to update.",
76
+ )
77
+ parser.add_argument(
78
+ "--version", required=True, help="Release version, with or without v prefix."
79
+ )
80
+ parser.add_argument("--sha256", required=True, help="SHA-256 checksum for the release DMG.")
81
+ args = parser.parse_args()
82
+
83
+ update_cask_file(args.cask, version=args.version, sha256=args.sha256)
84
+
85
+
86
+ if __name__ == "__main__":
87
+ main()
@@ -64,3 +64,28 @@ jobs:
64
64
  GH_TOKEN: ${{ github.token }}
65
65
  TAG_NAME: ${{ github.event.release.tag_name }}
66
66
  run: gh release upload "$TAG_NAME" dist/macos/AgentCLI.dmg --clobber
67
+ - name: Update Homebrew cask
68
+ env:
69
+ TAG_NAME: ${{ github.event.release.tag_name }}
70
+ run: |
71
+ VERSION="${TAG_NAME#v}"
72
+ SHA256=$(shasum -a 256 dist/macos/AgentCLI.dmg | awk '{ print $1 }')
73
+
74
+ git fetch origin main
75
+ git switch --force-create cask-update origin/main
76
+
77
+ python3 .github/scripts/update_cask.py \
78
+ --version "$VERSION" \
79
+ --sha256 "$SHA256"
80
+
81
+ if git diff --quiet -- Casks/agent-cli.rb; then
82
+ echo "Casks/agent-cli.rb is already up to date."
83
+ exit 0
84
+ fi
85
+
86
+ git config user.name "github-actions[bot]"
87
+ git config user.email "github-actions[bot]@users.noreply.github.com"
88
+ git add Casks/agent-cli.rb
89
+ git commit -m "Update AgentCLI cask to ${TAG_NAME}"
90
+ git pull --rebase origin main
91
+ git push origin HEAD:main
@@ -1,6 +1,6 @@
1
1
  cask "agent-cli" do
2
- version "0.95.7"
3
- sha256 "9db4a8d9f44765e1197d687a46e4cde041ada2d5284e6a22324c706d2a40848e"
2
+ version "0.95.8"
3
+ sha256 "60273504f3c4bea181db64033790e0290bf1b53b86a1386afa3d41216a172029"
4
4
 
5
5
  url "https://github.com/basnijholt/agent-cli/releases/download/v#{version}/AgentCLI.dmg"
6
6
  name "Agent CLI"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-cli
3
- Version: 0.95.8
3
+ Version: 0.95.9
4
4
  Summary: A suite of AI-powered command-line tools for text correction, audio transcription, and voice assistance.
5
5
  Project-URL: Homepage, https://github.com/basnijholt/agent-cli
6
6
  Author-email: Bas Nijholt <bas@nijho.lt>
@@ -161,7 +161,7 @@ final class AgentCommandRunner: ObservableObject {
161
161
  self.stopBootstrapAnimationTimer()
162
162
  return
163
163
  }
164
- self.bootstrapAnimationTick = (self.bootstrapAnimationTick + 1) % 3
164
+ self.bootstrapAnimationTick = (self.bootstrapAnimationTick + 1) % 4
165
165
  if let startedAt = self.bootstrapPhaseStartedAt {
166
166
  self.bootstrapElapsedSeconds = max(0, Int(Date().timeIntervalSince(startedAt)))
167
167
  }
@@ -45,10 +45,31 @@ enum BootstrapPhase: Equatable {
45
45
 
46
46
  func statusMessage(animationTick: Int, elapsedSeconds: Int) -> String {
47
47
  switch self {
48
+ case .checkingRuntime, .installingRuntime, .installingVoiceService, .waitingForVoiceService, .warmingWhisperModel:
49
+ let spinnerFrames = ["◐", "◓", "◑", "◒"]
50
+ let spinner = spinnerFrames[animationTick % spinnerFrames.count]
51
+ let minutes = elapsedSeconds / 60
52
+ let seconds = elapsedSeconds % 60
53
+ let elapsedTime = String(format: "%02d:%02d", minutes, seconds)
54
+ return "\(animatedStatusMessage) \(spinner) (\(elapsedTime))"
55
+ case .idle, .failed:
56
+ return statusMessage
57
+ }
58
+ }
59
+
60
+ private var animatedStatusMessage: String {
61
+ switch self {
62
+ case .checkingRuntime:
63
+ return "Checking CLI runtime"
64
+ case .installingRuntime:
65
+ return "Installing CLI runtime"
66
+ case .installingVoiceService:
67
+ return "Installing voice service"
48
68
  case .waitingForVoiceService:
49
- let periodCount = (animationTick % 3) + 1
50
- return "Waiting for voice service\(String(repeating: ".", count: periodCount)) (\(elapsedSeconds)s)"
51
- case .idle, .checkingRuntime, .installingRuntime, .installingVoiceService, .warmingWhisperModel, .failed:
69
+ return "Waiting for voice service"
70
+ case .warmingWhisperModel:
71
+ return "Warming Whisper model"
72
+ case .idle, .failed:
52
73
  return statusMessage
53
74
  }
54
75
  }
@@ -20,15 +20,34 @@ extension KeyboardShortcuts.Name {
20
20
  )
21
21
  }
22
22
 
23
- enum AppShortcutDefaults {
24
- static let toggleTranscription = ShortcutStorage.shortcut(
23
+ enum ToggleTranscriptionDefault {
24
+ static let shortcut = FunctionShortcutPersistence.rawShortcut(
25
25
  carbonKeyCode: kVK_Space,
26
26
  carbonModifiers: kEventKeyModifierFnMask
27
27
  )
28
+
29
+ static func set() {
30
+ FunctionShortcutPersistence.set(shortcut, for: .toggleTranscription)
31
+ }
32
+
33
+ static func seedIfNeeded() {
34
+ guard !userDefaultsContainsShortcut else {
35
+ return
36
+ }
37
+ set()
38
+ }
39
+
40
+ private static var userDefaultsContainsShortcut: Bool {
41
+ UserDefaults.standard.object(forKey: userDefaultsKey) != nil
42
+ }
43
+
44
+ private static var userDefaultsKey: String {
45
+ "KeyboardShortcuts_\(KeyboardShortcuts.Name.toggleTranscription.rawValue)"
46
+ }
28
47
  }
29
48
 
30
- enum ShortcutStorage {
31
- static func shortcut(carbonKeyCode: Int, carbonModifiers: Int = 0) -> KeyboardShortcuts.Shortcut {
49
+ enum FunctionShortcutPersistence {
50
+ static func rawShortcut(carbonKeyCode: Int, carbonModifiers: Int) -> KeyboardShortcuts.Shortcut {
32
51
  // KeyboardShortcuts' public initializer normalizes away Fn, but Codable preserves raw Carbon modifiers.
33
52
  let shortcutJSON = """
34
53
  {"carbonKeyCode":\(carbonKeyCode),"carbonModifiers":\(carbonModifiers)}
@@ -43,42 +62,23 @@ enum ShortcutStorage {
43
62
  return shortcut
44
63
  }
45
64
 
46
- static func setShortcut(_ shortcut: KeyboardShortcuts.Shortcut?, for name: KeyboardShortcuts.Name) {
47
- guard let shortcut else {
48
- KeyboardShortcuts.setShortcut(nil, for: name)
49
- UserDefaults.standard.set(false, forKey: userDefaultsKey(for: name))
50
- postShortcutChange(for: name)
51
- return
52
- }
53
-
54
- guard shortcut.carbonModifiers & kEventKeyModifierFnMask != 0 else {
55
- KeyboardShortcuts.setShortcut(shortcut, for: name)
56
- return
57
- }
58
-
65
+ static func set(_ shortcut: KeyboardShortcuts.Shortcut, for name: KeyboardShortcuts.Name) {
59
66
  KeyboardShortcuts.setShortcut(nil, for: name)
60
67
  guard let encoded = try? JSONEncoder().encode(shortcut),
61
68
  let encodedString = String(data: encoded, encoding: .utf8) else {
62
69
  return
63
70
  }
64
71
  UserDefaults.standard.set(encodedString, forKey: userDefaultsKey(for: name))
65
- postShortcutChange(for: name)
66
- }
67
-
68
- static func userDefaultsContains(name: KeyboardShortcuts.Name) -> Bool {
69
- UserDefaults.standard.object(forKey: userDefaultsKey(for: name)) != nil
70
72
  }
71
73
 
72
74
  private static func userDefaultsKey(for name: KeyboardShortcuts.Name) -> String {
73
75
  "KeyboardShortcuts_\(name.rawValue)"
74
76
  }
77
+ }
75
78
 
76
- private static func postShortcutChange(for name: KeyboardShortcuts.Name) {
77
- NotificationCenter.default.post(
78
- name: Notification.Name("KeyboardShortcuts_shortcutByNameDidChange"),
79
- object: nil,
80
- userInfo: ["name": name]
81
- )
79
+ private extension KeyboardShortcuts.Shortcut {
80
+ var usesFunctionModifier: Bool {
81
+ carbonModifiers & kEventKeyModifierFnMask != 0
82
82
  }
83
83
  }
84
84
 
@@ -123,7 +123,7 @@ final class ShortcutSummaryState: ObservableObject {
123
123
  }
124
124
 
125
125
  func resetDefaults() {
126
- ShortcutStorage.setShortcut(AppShortcutDefaults.toggleTranscription, for: .toggleTranscription)
126
+ ToggleTranscriptionDefault.set()
127
127
  KeyboardShortcuts.reset(
128
128
  .holdToTranscribe,
129
129
  .autocorrect,
@@ -174,15 +174,37 @@ private enum ShortcutDisplay {
174
174
  }
175
175
 
176
176
  var carbonModifiers = shortcut.carbonModifiers
177
- if event.modifierFlags.contains(.function) {
177
+ if event.modifierFlags.contains(.function),
178
+ shouldTreatFunctionFlagAsModifier(for: shortcut.carbonKeyCode) {
178
179
  carbonModifiers |= kEventKeyModifierFnMask
179
180
  }
180
- return ShortcutStorage.shortcut(
181
+
182
+ guard carbonModifiers & kEventKeyModifierFnMask != 0 else {
183
+ return KeyboardShortcuts.Shortcut(
184
+ carbonKeyCode: shortcut.carbonKeyCode,
185
+ carbonModifiers: carbonModifiers
186
+ )
187
+ }
188
+
189
+ return FunctionShortcutPersistence.rawShortcut(
181
190
  carbonKeyCode: shortcut.carbonKeyCode,
182
191
  carbonModifiers: carbonModifiers
183
192
  )
184
193
  }
185
194
 
195
+ private static func shouldTreatFunctionFlagAsModifier(for carbonKeyCode: Int) -> Bool {
196
+ !isFunctionRowKey(carbonKeyCode)
197
+ }
198
+
199
+ private static func isFunctionRowKey(_ carbonKeyCode: Int) -> Bool {
200
+ switch carbonKeyCode {
201
+ case kVK_F1...kVK_F20:
202
+ return true
203
+ default:
204
+ return false
205
+ }
206
+ }
207
+
186
208
  private static func label(for shortcut: KeyboardShortcuts.Shortcut, fallback: String) -> String {
187
209
  if shortcut.carbonKeyCode == kVK_Function, shortcut.carbonModifiers == 0 {
188
210
  return "Fn"
@@ -213,19 +235,19 @@ enum ShortcutDefaultsMigrator {
213
235
  migrateDefault(
214
236
  name: .toggleTranscription,
215
237
  from: KeyboardShortcuts.Shortcut(.r, modifiers: [.command, .shift]),
216
- to: AppShortcutDefaults.toggleTranscription
238
+ to: ToggleTranscriptionDefault.shortcut
217
239
  )
218
240
  migrateDefault(
219
241
  name: .toggleTranscription,
220
242
  from: KeyboardShortcuts.Shortcut(.space),
221
- to: AppShortcutDefaults.toggleTranscription
243
+ to: ToggleTranscriptionDefault.shortcut
222
244
  )
223
245
  migrateDefault(
224
246
  name: .holdToTranscribe,
225
247
  from: KeyboardShortcuts.Shortcut(.space, modifiers: [.control, .option]),
226
248
  to: KeyboardShortcuts.Shortcut(.function)
227
249
  )
228
- seedDefault(name: .toggleTranscription, shortcut: AppShortcutDefaults.toggleTranscription)
250
+ ToggleTranscriptionDefault.seedIfNeeded()
229
251
  }
230
252
 
231
253
  private static func migrateDefault(
@@ -236,17 +258,19 @@ enum ShortcutDefaultsMigrator {
236
258
  guard KeyboardShortcuts.getShortcut(for: name) == oldShortcut else {
237
259
  return
238
260
  }
239
- ShortcutStorage.setShortcut(newShortcut, for: name)
261
+ setShortcut(newShortcut, for: name)
240
262
  }
241
263
 
242
- private static func seedDefault(
243
- name: KeyboardShortcuts.Name,
244
- shortcut: KeyboardShortcuts.Shortcut
264
+ private static func setShortcut(
265
+ _ shortcut: KeyboardShortcuts.Shortcut,
266
+ for name: KeyboardShortcuts.Name
245
267
  ) {
246
- guard !ShortcutStorage.userDefaultsContains(name: name) else {
268
+ guard name == .toggleTranscription,
269
+ shortcut == ToggleTranscriptionDefault.shortcut else {
270
+ KeyboardShortcuts.setShortcut(shortcut, for: name)
247
271
  return
248
272
  }
249
- ShortcutStorage.setShortcut(shortcut, for: name)
273
+ ToggleTranscriptionDefault.set()
250
274
  }
251
275
  }
252
276
 
@@ -436,7 +460,7 @@ final class ShortcutRecorderButton: NSButton {
436
460
  stopRecording()
437
461
  case kVK_Delete, kVK_ForwardDelete:
438
462
  pendingFunctionShortcut = false
439
- ShortcutStorage.setShortcut(nil, for: shortcutName)
463
+ KeyboardShortcuts.setShortcut(nil, for: shortcutName)
440
464
  stopRecording()
441
465
  case kVK_Function:
442
466
  handleFunctionKeyChange(event)
@@ -446,7 +470,15 @@ final class ShortcutRecorderButton: NSButton {
446
470
  NSSound.beep()
447
471
  return
448
472
  }
449
- ShortcutStorage.setShortcut(shortcut, for: shortcutName)
473
+ if shortcut.usesFunctionModifier {
474
+ guard supportsFunctionChord(shortcutName) else {
475
+ NSSound.beep()
476
+ return
477
+ }
478
+ FunctionShortcutPersistence.set(shortcut, for: shortcutName)
479
+ } else {
480
+ KeyboardShortcuts.setShortcut(shortcut, for: shortcutName)
481
+ }
450
482
  stopRecording()
451
483
  }
452
484
  }
@@ -468,10 +500,14 @@ final class ShortcutRecorderButton: NSButton {
468
500
 
469
501
  private func captureBareFunctionShortcut() {
470
502
  pendingFunctionShortcut = false
471
- ShortcutStorage.setShortcut(KeyboardShortcuts.Shortcut(.function), for: shortcutName)
503
+ KeyboardShortcuts.setShortcut(KeyboardShortcuts.Shortcut(.function), for: shortcutName)
472
504
  stopRecording()
473
505
  }
474
506
 
507
+ private func supportsFunctionChord(_ name: KeyboardShortcuts.Name) -> Bool {
508
+ name == .toggleTranscription || name == .holdToTranscribe
509
+ }
510
+
475
511
  private func stopRecording() {
476
512
  if let eventMonitor {
477
513
  NSEvent.removeMonitor(eventMonitor)
@@ -148,22 +148,34 @@ final class AgentCommandTests: XCTestCase {
148
148
  XCTAssertEqual(recorder.calls, [.init(requirement: .transcriptionModel, force: false)])
149
149
  }
150
150
 
151
- func testWaitingForVoiceServiceStatusAnimatesEllipsis() {
151
+ func testPreparingStatusShowsFixedWidthSpinnerAndElapsedTime() {
152
+ XCTAssertEqual(
153
+ BootstrapPhase.checkingRuntime.statusMessage(animationTick: 0, elapsedSeconds: 0),
154
+ "Checking CLI runtime ◐ (00:00)"
155
+ )
156
+ XCTAssertEqual(
157
+ BootstrapPhase.installingRuntime.statusMessage(animationTick: 1, elapsedSeconds: 12),
158
+ "Installing CLI runtime ◓ (00:12)"
159
+ )
160
+ XCTAssertEqual(
161
+ BootstrapPhase.installingVoiceService.statusMessage(animationTick: 2, elapsedSeconds: 123),
162
+ "Installing voice service ◑ (02:03)"
163
+ )
152
164
  XCTAssertEqual(
153
165
  BootstrapPhase.waitingForVoiceService.statusMessage(animationTick: 0, elapsedSeconds: 0),
154
- "Waiting for voice service. (0s)"
166
+ "Waiting for voice service (00:00)"
155
167
  )
156
168
  XCTAssertEqual(
157
169
  BootstrapPhase.waitingForVoiceService.statusMessage(animationTick: 1, elapsedSeconds: 12),
158
- "Waiting for voice service.. (12s)"
170
+ "Waiting for voice service (00:12)"
159
171
  )
160
172
  XCTAssertEqual(
161
173
  BootstrapPhase.waitingForVoiceService.statusMessage(animationTick: 2, elapsedSeconds: 123),
162
- "Waiting for voice service... (123s)"
174
+ "Waiting for voice service (02:03)"
163
175
  )
164
176
  XCTAssertEqual(
165
- BootstrapPhase.waitingForVoiceService.statusMessage(animationTick: 3, elapsedSeconds: 4),
166
- "Waiting for voice service. (4s)"
177
+ BootstrapPhase.warmingWhisperModel.statusMessage(animationTick: 3, elapsedSeconds: 4),
178
+ "Warming Whisper model (00:04)"
167
179
  )
168
180
  }
169
181
  }
@@ -531,19 +531,22 @@ def test_macos_app_keeps_preparing_status_visible_during_command_bootstrap() ->
531
531
  assert 'statusMessage == "Preparing voice service..."' not in source
532
532
 
533
533
 
534
- def test_macos_app_animates_waiting_for_voice_service_status() -> None:
535
- """The waiting status should visibly indicate that setup is still progressing."""
534
+ def test_macos_app_animates_all_preparing_statuses_with_fixed_width_timer() -> None:
535
+ """Every setup phase should show stable-width progress without shifting the timer."""
536
536
  source = swift_source()
537
537
 
538
538
  assert "statusMessage(animationTick: Int, elapsedSeconds: Int)" in source
539
- assert "let periodCount = (animationTick % 3) + 1" in source
539
+ assert '["◐", "◓", "◑", "◒"]' in source
540
+ assert 'String(format: "%02d:%02d", minutes, seconds)' in source
541
+ assert '"\\(animatedStatusMessage) \\(spinner) (\\(elapsedTime))"' in source
540
542
  assert (
541
- '"Waiting for voice service\\(String(repeating: ".", count: periodCount)) '
542
- '(\\(elapsedSeconds)s)"' in source
543
+ "case .checkingRuntime, .installingRuntime, .installingVoiceService, .waitingForVoiceService, .warmingWhisperModel:"
544
+ in source
543
545
  )
544
546
  assert "bootstrapAnimationTimer" in source
545
547
  assert "bootstrapPhaseStartedAt" in source
546
548
  assert "bootstrapElapsedSeconds" in source
549
+ assert "bootstrapAnimationTick = (self.bootstrapAnimationTick + 1) % 4" in source
547
550
  assert "RunLoop.main.add(timer, forMode: .common)" in source
548
551
  assert "bootstrapPhase.statusMessage(" in source
549
552
  assert "animationTick: bootstrapAnimationTick" in source
@@ -586,7 +589,8 @@ def test_macos_app_defaults_clipboard_transcription_to_fn_space() -> None:
586
589
  source = swift_source()
587
590
 
588
591
  assert "kEventKeyModifierFnMask" in source
589
- assert "static let toggleTranscription = ShortcutStorage.shortcut(" in source
592
+ assert "enum ToggleTranscriptionDefault" in source
593
+ assert "static let shortcut = FunctionShortcutPersistence.rawShortcut(" in source
590
594
  assert "carbonKeyCode: kVK_Space" in source
591
595
  assert "carbonModifiers: kEventKeyModifierFnMask" in source
592
596
  assert "event.modifierFlags.contains(.function)" in source
@@ -596,15 +600,17 @@ def test_macos_app_defaults_clipboard_transcription_to_fn_space() -> None:
596
600
 
597
601
 
598
602
  def test_macos_app_persists_fn_space_without_keyboardshortcuts_normalization() -> None:
599
- """KeyboardShortcuts' public Shortcut initializer drops Fn, so app storage must preserve it."""
603
+ """Fn shortcuts should bypass KeyboardShortcuts normalization only where the app can dispatch them."""
600
604
  source = swift_source()
601
605
 
602
- assert "enum ShortcutStorage" in source
606
+ assert "enum ToggleTranscriptionDefault" in source
607
+ assert "enum ShortcutStorage" not in source
603
608
  assert "JSONEncoder().encode(shortcut)" in source
604
609
  assert "JSONDecoder().decode(KeyboardShortcuts.Shortcut.self" in source
605
610
  assert '"KeyboardShortcuts_\\(name.rawValue)"' in source
606
- assert "ShortcutStorage.setShortcut(AppShortcutDefaults.toggleTranscription" in source
607
- assert "static let toggleTranscription = ShortcutStorage.shortcut(" in source
611
+ assert "ToggleTranscriptionDefault.set()" in source
612
+ assert "FunctionShortcutPersistence.set(shortcut, for: shortcutName)" in source
613
+ assert "ShortcutStorage.setShortcut(" not in source
608
614
 
609
615
 
610
616
  def test_macos_app_uses_fn_aware_event_tap_for_transcription_shortcuts() -> None:
@@ -667,15 +673,12 @@ def test_macos_app_migrates_old_default_shortcuts_to_fn_defaults() -> None:
667
673
  assert "migrateDefault(" in source
668
674
  assert "from: KeyboardShortcuts.Shortcut(.r, modifiers: [.command, .shift])" in source
669
675
  assert "from: KeyboardShortcuts.Shortcut(.space)" in source
670
- assert "to: AppShortcutDefaults.toggleTranscription" in source
671
- assert (
672
- "seedDefault(name: .toggleTranscription, shortcut: AppShortcutDefaults.toggleTranscription)"
673
- in source
674
- )
676
+ assert "to: ToggleTranscriptionDefault.shortcut" in source
677
+ assert "ToggleTranscriptionDefault.seedIfNeeded()" in source
675
678
  assert "from: KeyboardShortcuts.Shortcut(.space, modifiers: [.control, .option])" in source
676
679
  assert "to: KeyboardShortcuts.Shortcut(.function)" in source
677
680
  assert "KeyboardShortcuts.getShortcut(for: name) == oldShortcut" in source
678
- assert "ShortcutStorage.setShortcut(newShortcut, for: name)" in source
681
+ assert "setShortcut(newShortcut, for: name)" in source
679
682
 
680
683
 
681
684
  def test_macos_app_pastes_hold_transcription_into_focused_field() -> None:
@@ -941,6 +944,20 @@ def test_macos_app_records_fn_chords_before_bare_fn() -> None:
941
944
  assert "captureBareFunctionShortcut()" in source
942
945
  assert "event.modifierFlags.contains(.function)" in source
943
946
  assert "case kVK_Function:" in source
947
+ assert "shortcut.usesFunctionModifier" in source
948
+ assert "supportsFunctionChord(shortcutName)" in source
949
+ assert "FunctionShortcutPersistence.set(shortcut, for: shortcutName)" in source
950
+ assert "KeyboardShortcuts.setShortcut(shortcut, for: shortcutName)" in source
951
+
952
+
953
+ def test_macos_app_does_not_record_function_row_keys_as_fn_chords() -> None:
954
+ """F1/F2 key events can carry .function in modifierFlags but should remain plain keys."""
955
+ source = swift_source()
956
+
957
+ assert "shouldTreatFunctionFlagAsModifier(for: shortcut.carbonKeyCode)" in source
958
+ assert "isFunctionRowKey(" in source
959
+ assert "case kVK_F1...kVK_F20:" in source
960
+ assert "!isFunctionRowKey(carbonKeyCode)" in source
944
961
 
945
962
 
946
963
  def test_macos_app_shows_actual_persisted_shortcuts_and_can_reset_them() -> None:
@@ -0,0 +1,51 @@
1
+ """Tests for the release cask updater."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import importlib.util
6
+ from pathlib import Path
7
+
8
+ import pytest
9
+
10
+ SCRIPT_PATH = Path(__file__).parents[1] / ".github" / "scripts" / "update_cask.py"
11
+ spec = importlib.util.spec_from_file_location("update_cask", SCRIPT_PATH)
12
+ assert spec is not None
13
+ assert spec.loader is not None
14
+ update_cask = importlib.util.module_from_spec(spec)
15
+ spec.loader.exec_module(update_cask)
16
+ update_cask_text = update_cask.update_cask_text
17
+
18
+
19
+ CASK = """cask "agent-cli" do
20
+ version "0.95.7"
21
+ sha256 "9db4a8d9f44765e1197d687a46e4cde041ada2d5284e6a22324c706d2a40848e"
22
+
23
+ url "https://github.com/basnijholt/agent-cli/releases/download/v#{version}/AgentCLI.dmg"
24
+ end
25
+ """
26
+
27
+
28
+ def test_update_cask_text_replaces_version_and_sha256() -> None:
29
+ updated = update_cask_text(
30
+ CASK,
31
+ version="v0.95.8",
32
+ sha256="60273504f3c4bea181db64033790e0290bf1b53b86a1386afa3d41216a172029",
33
+ )
34
+
35
+ assert ' version "0.95.8"' in updated
36
+ assert ' sha256 "60273504f3c4bea181db64033790e0290bf1b53b86a1386afa3d41216a172029"' in updated
37
+ assert "v#{version}" in updated
38
+
39
+
40
+ def test_update_cask_text_rejects_invalid_sha256() -> None:
41
+ with pytest.raises(ValueError, match="sha256"):
42
+ update_cask_text(CASK, version="0.95.8", sha256="bad")
43
+
44
+
45
+ def test_update_cask_text_requires_one_version_stanza() -> None:
46
+ with pytest.raises(ValueError, match="expected exactly one version"):
47
+ update_cask_text(
48
+ CASK.replace(' version "0.95.7"\n', ""),
49
+ version="0.95.8",
50
+ sha256="60273504f3c4bea181db64033790e0290bf1b53b86a1386afa3d41216a172029",
51
+ )
File without changes
File without changes
File without changes
File without changes