agent-cli 0.95.7__tar.gz → 0.95.8__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 (430) hide show
  1. agent_cli-0.95.8/Casks/agent-cli.rb +29 -0
  2. {agent_cli-0.95.7 → agent_cli-0.95.8}/PKG-INFO +1 -1
  3. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Sources/AgentCLI/AgentCommand.swift +11 -1
  4. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Sources/AgentCLI/AgentCommandRunner.swift +47 -1
  5. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Sources/AgentCLI/BootstrapState.swift +10 -0
  6. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Sources/AgentCLI/RecordingIndicatorController.swift +22 -1
  7. agent_cli-0.95.8/macos/AgentCLI/Sources/AgentCLI/RecordingSoundSettings.swift +54 -0
  8. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Sources/AgentCLI/Shortcuts.swift +90 -12
  9. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Tests/AgentCLITests/AgentCommandTests.swift +26 -0
  10. agent_cli-0.95.8/macos/AgentCLI/Tests/AgentCLITests/RecordingIndicatorControllerTests.swift +55 -0
  11. agent_cli-0.95.8/macos/AgentCLI/Tests/AgentCLITests/ShortcutDefaultsTests.swift +55 -0
  12. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_macos_app.py +44 -9
  13. {agent_cli-0.95.7 → agent_cli-0.95.8}/.claude/skills/agent-cli-dev/SKILL.md +0 -0
  14. {agent_cli-0.95.7 → agent_cli-0.95.8}/.claude/skills/agent-cli-dev/examples.md +0 -0
  15. {agent_cli-0.95.7 → agent_cli-0.95.8}/.claude-plugin/README.md +0 -0
  16. {agent_cli-0.95.7 → agent_cli-0.95.8}/.claude-plugin/marketplace.json +0 -0
  17. {agent_cli-0.95.7 → agent_cli-0.95.8}/.claude-plugin/plugin.json +0 -0
  18. {agent_cli-0.95.7 → agent_cli-0.95.8}/.claude-plugin/skills/agent-cli-dev/SKILL.md +0 -0
  19. {agent_cli-0.95.7 → agent_cli-0.95.8}/.claude-plugin/skills/agent-cli-dev/examples.md +0 -0
  20. {agent_cli-0.95.7 → agent_cli-0.95.8}/.cursorrules +0 -0
  21. {agent_cli-0.95.7 → agent_cli-0.95.8}/.dockerignore +0 -0
  22. {agent_cli-0.95.7 → agent_cli-0.95.8}/.env.example +0 -0
  23. {agent_cli-0.95.7 → agent_cli-0.95.8}/.github/logo.svg +0 -0
  24. {agent_cli-0.95.7 → agent_cli-0.95.8}/.github/release-drafter.yml +0 -0
  25. {agent_cli-0.95.7 → agent_cli-0.95.8}/.github/renovate.json +0 -0
  26. {agent_cli-0.95.7 → agent_cli-0.95.8}/.github/scripts/check_extras_sync.py +0 -0
  27. {agent_cli-0.95.7 → agent_cli-0.95.8}/.github/scripts/check_plugin_skill_sync.py +0 -0
  28. {agent_cli-0.95.7 → agent_cli-0.95.8}/.github/scripts/sync_extras.py +0 -0
  29. {agent_cli-0.95.7 → agent_cli-0.95.8}/.github/scripts/sync_requirements.py +0 -0
  30. {agent_cli-0.95.7 → agent_cli-0.95.8}/.github/workflows/automerge.yml +0 -0
  31. {agent_cli-0.95.7 → agent_cli-0.95.8}/.github/workflows/docker.yml +0 -0
  32. {agent_cli-0.95.7 → agent_cli-0.95.8}/.github/workflows/docs.yml +0 -0
  33. {agent_cli-0.95.7 → agent_cli-0.95.8}/.github/workflows/markdown-code-runner.yml +0 -0
  34. {agent_cli-0.95.7 → agent_cli-0.95.8}/.github/workflows/pytest.yml +0 -0
  35. {agent_cli-0.95.7 → agent_cli-0.95.8}/.github/workflows/release-drafter.yml +0 -0
  36. {agent_cli-0.95.7 → agent_cli-0.95.8}/.github/workflows/release.yml +0 -0
  37. {agent_cli-0.95.7 → agent_cli-0.95.8}/.github/workflows/toc.yaml +0 -0
  38. {agent_cli-0.95.7 → agent_cli-0.95.8}/.gitignore +0 -0
  39. {agent_cli-0.95.7 → agent_cli-0.95.8}/.jscpd.json +0 -0
  40. {agent_cli-0.95.7 → agent_cli-0.95.8}/.pre-commit-config.yaml +0 -0
  41. {agent_cli-0.95.7 → agent_cli-0.95.8}/.prompts/docs-review.md +0 -0
  42. {agent_cli-0.95.7 → agent_cli-0.95.8}/.prompts/pr-review.md +0 -0
  43. {agent_cli-0.95.7 → agent_cli-0.95.8}/CLAUDE.md +0 -0
  44. {agent_cli-0.95.7 → agent_cli-0.95.8}/LICENSE +0 -0
  45. {agent_cli-0.95.7 → agent_cli-0.95.8}/LLAMA_SERVER_USAGE.md +0 -0
  46. {agent_cli-0.95.7 → agent_cli-0.95.8}/README.md +0 -0
  47. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/__init__.py +0 -0
  48. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/__main__.py +0 -0
  49. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/_extras.json +0 -0
  50. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/_requirements/.gitkeep +0 -0
  51. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/_requirements/audio.txt +0 -0
  52. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/_requirements/diarization.txt +0 -0
  53. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/_requirements/faster-whisper.txt +0 -0
  54. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/_requirements/kokoro.txt +0 -0
  55. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/_requirements/llm.txt +0 -0
  56. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/_requirements/memory.txt +0 -0
  57. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/_requirements/mlx-whisper.txt +0 -0
  58. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/_requirements/piper.txt +0 -0
  59. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/_requirements/rag.txt +0 -0
  60. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/_requirements/server.txt +0 -0
  61. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/_requirements/speed.txt +0 -0
  62. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/_requirements/vad.txt +0 -0
  63. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/_requirements/vectordb.txt +0 -0
  64. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/_requirements/whisper-transformers.txt +0 -0
  65. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/_requirements/wyoming.txt +0 -0
  66. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/_tools.py +0 -0
  67. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/agents/__init__.py +0 -0
  68. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/agents/_voice_agent_common.py +0 -0
  69. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/agents/assistant.py +0 -0
  70. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/agents/autocorrect.py +0 -0
  71. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/agents/chat.py +0 -0
  72. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/agents/diarize_live_session.py +0 -0
  73. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/agents/memory/__init__.py +0 -0
  74. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/agents/memory/add.py +0 -0
  75. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/agents/memory/proxy.py +0 -0
  76. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/agents/rag_proxy.py +0 -0
  77. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/agents/speak.py +0 -0
  78. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/agents/speakers.py +0 -0
  79. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/agents/transcribe.py +0 -0
  80. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/agents/transcribe_live.py +0 -0
  81. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/agents/voice_edit.py +0 -0
  82. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/api.py +0 -0
  83. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/cli.py +0 -0
  84. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/config.py +0 -0
  85. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/config_cmd.py +0 -0
  86. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/constants.py +0 -0
  87. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/core/__init__.py +0 -0
  88. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/core/alignment.py +0 -0
  89. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/core/audio.py +0 -0
  90. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/core/audio_format.py +0 -0
  91. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/core/chroma.py +0 -0
  92. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/core/deps.py +0 -0
  93. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/core/diarization.py +0 -0
  94. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/core/openai_proxy.py +0 -0
  95. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/core/process.py +0 -0
  96. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/core/reranker.py +0 -0
  97. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/core/speaker_identity.py +0 -0
  98. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/core/sse.py +0 -0
  99. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/core/transcription_logger.py +0 -0
  100. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/core/utils.py +0 -0
  101. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/core/vad.py +0 -0
  102. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/core/watch.py +0 -0
  103. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/daemon/__init__.py +0 -0
  104. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/daemon/cli.py +0 -0
  105. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/__init__.py +0 -0
  106. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/_branch_name.py +0 -0
  107. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/_config.py +0 -0
  108. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/_output.py +0 -0
  109. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/cleanup.py +0 -0
  110. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/cli.py +0 -0
  111. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/coding_agents/__init__.py +0 -0
  112. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/coding_agents/aider.py +0 -0
  113. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/coding_agents/base.py +0 -0
  114. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/coding_agents/claude.py +0 -0
  115. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/coding_agents/codex.py +0 -0
  116. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/coding_agents/continue_dev.py +0 -0
  117. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/coding_agents/copilot.py +0 -0
  118. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/coding_agents/cursor_agent.py +0 -0
  119. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/coding_agents/gemini.py +0 -0
  120. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/coding_agents/opencode.py +0 -0
  121. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/coding_agents/registry.py +0 -0
  122. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/editors/__init__.py +0 -0
  123. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/editors/base.py +0 -0
  124. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/editors/cursor.py +0 -0
  125. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/editors/emacs.py +0 -0
  126. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/editors/jetbrains.py +0 -0
  127. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/editors/nano.py +0 -0
  128. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/editors/neovim.py +0 -0
  129. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/editors/registry.py +0 -0
  130. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/editors/sublime.py +0 -0
  131. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/editors/vim.py +0 -0
  132. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/editors/vscode.py +0 -0
  133. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/editors/zed.py +0 -0
  134. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/hooks.py +0 -0
  135. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/launch.py +0 -0
  136. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/project.py +0 -0
  137. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/registry.py +0 -0
  138. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/skill/SKILL.md +0 -0
  139. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/skill/examples.md +0 -0
  140. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/terminals/__init__.py +0 -0
  141. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/terminals/apple_terminal.py +0 -0
  142. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/terminals/base.py +0 -0
  143. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/terminals/gnome.py +0 -0
  144. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/terminals/iterm2.py +0 -0
  145. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/terminals/kitty.py +0 -0
  146. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/terminals/registry.py +0 -0
  147. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/terminals/tmux.py +0 -0
  148. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/terminals/warp.py +0 -0
  149. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/terminals/zellij.py +0 -0
  150. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/dev/worktree.py +0 -0
  151. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/docs_gen.py +0 -0
  152. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/example-config.toml +0 -0
  153. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/install/__init__.py +0 -0
  154. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/install/common.py +0 -0
  155. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/install/extras.py +0 -0
  156. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/install/hotkeys.py +0 -0
  157. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/install/launchd.py +0 -0
  158. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/install/service_config.py +0 -0
  159. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/install/services.py +0 -0
  160. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/install/systemd.py +0 -0
  161. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/memory/__init__.py +0 -0
  162. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/memory/_files.py +0 -0
  163. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/memory/_filters.py +0 -0
  164. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/memory/_git.py +0 -0
  165. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/memory/_indexer.py +0 -0
  166. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/memory/_ingest.py +0 -0
  167. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/memory/_persistence.py +0 -0
  168. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/memory/_prompt.py +0 -0
  169. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/memory/_retrieval.py +0 -0
  170. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/memory/_store.py +0 -0
  171. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/memory/_streaming.py +0 -0
  172. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/memory/_tasks.py +0 -0
  173. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/memory/api.py +0 -0
  174. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/memory/client.py +0 -0
  175. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/memory/engine.py +0 -0
  176. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/memory/entities.py +0 -0
  177. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/memory/models.py +0 -0
  178. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/opts.py +0 -0
  179. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/py.typed +0 -0
  180. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/rag/__init__.py +0 -0
  181. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/rag/_indexer.py +0 -0
  182. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/rag/_indexing.py +0 -0
  183. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/rag/_prompt.py +0 -0
  184. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/rag/_retriever.py +0 -0
  185. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/rag/_store.py +0 -0
  186. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/rag/_utils.py +0 -0
  187. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/rag/api.py +0 -0
  188. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/rag/client.py +0 -0
  189. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/rag/engine.py +0 -0
  190. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/rag/models.py +0 -0
  191. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/.runtime/.gitkeep +0 -0
  192. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/__init__.py +0 -0
  193. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/linux-hotkeys/README.md +0 -0
  194. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/linux-hotkeys/toggle-autocorrect.sh +0 -0
  195. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/linux-hotkeys/toggle-transcription.sh +0 -0
  196. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/linux-hotkeys/toggle-voice-edit.sh +0 -0
  197. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/macos-hotkeys/README.md +0 -0
  198. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/macos-hotkeys/skhd-config-example +0 -0
  199. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/macos-hotkeys/toggle-autocorrect.sh +0 -0
  200. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/macos-hotkeys/toggle-transcription.sh +0 -0
  201. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/macos-hotkeys/toggle-voice-edit.sh +0 -0
  202. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/nvidia-asr-server/README.md +0 -0
  203. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/nvidia-asr-server/pyproject.toml +0 -0
  204. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/nvidia-asr-server/server.py +0 -0
  205. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/nvidia-asr-server/shell.nix +0 -0
  206. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/nvidia-asr-server/uv.lock +0 -0
  207. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/run-openwakeword.sh +0 -0
  208. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/setup-linux-hotkeys.sh +0 -0
  209. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/setup-linux.sh +0 -0
  210. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/setup-macos-hotkeys.sh +0 -0
  211. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/setup-macos.sh +0 -0
  212. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/setup-windows.ps1 +0 -0
  213. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/start-all-services-windows.ps1 +0 -0
  214. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/scripts/start-all-services.sh +0 -0
  215. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/__init__.py +0 -0
  216. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/cli.py +0 -0
  217. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/common.py +0 -0
  218. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/model_manager.py +0 -0
  219. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/model_registry.py +0 -0
  220. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/proxy/__init__.py +0 -0
  221. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/proxy/api.py +0 -0
  222. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/streaming.py +0 -0
  223. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/tts/__init__.py +0 -0
  224. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/tts/api.py +0 -0
  225. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/tts/backends/__init__.py +0 -0
  226. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/tts/backends/base.py +0 -0
  227. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/tts/backends/kokoro.py +0 -0
  228. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/tts/backends/piper.py +0 -0
  229. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/tts/model_manager.py +0 -0
  230. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/tts/model_registry.py +0 -0
  231. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/tts/wyoming_handler.py +0 -0
  232. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/whisper/__init__.py +0 -0
  233. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/whisper/api.py +0 -0
  234. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/whisper/backends/__init__.py +0 -0
  235. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/whisper/backends/base.py +0 -0
  236. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/whisper/backends/faster_whisper.py +0 -0
  237. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/whisper/backends/mlx.py +0 -0
  238. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/whisper/backends/transformers.py +0 -0
  239. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/whisper/languages.py +0 -0
  240. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/whisper/model_manager.py +0 -0
  241. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/whisper/model_registry.py +0 -0
  242. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/server/whisper/wyoming_handler.py +0 -0
  243. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/services/__init__.py +0 -0
  244. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/services/_wyoming_utils.py +0 -0
  245. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/services/asr.py +0 -0
  246. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/services/llm.py +0 -0
  247. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/services/tts.py +0 -0
  248. {agent_cli-0.95.7 → agent_cli-0.95.8}/agent_cli/services/wake_word.py +0 -0
  249. {agent_cli-0.95.7 → agent_cli-0.95.8}/docker/docker-compose.yml +0 -0
  250. {agent_cli-0.95.7 → agent_cli-0.95.8}/docker/memory-proxy.Dockerfile +0 -0
  251. {agent_cli-0.95.7 → agent_cli-0.95.8}/docker/rag-proxy.Dockerfile +0 -0
  252. {agent_cli-0.95.7 → agent_cli-0.95.8}/docker/transcribe-proxy.Dockerfile +0 -0
  253. {agent_cli-0.95.7 → agent_cli-0.95.8}/docker/tts.Dockerfile +0 -0
  254. {agent_cli-0.95.7 → agent_cli-0.95.8}/docker/whisper.Dockerfile +0 -0
  255. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/CNAME +0 -0
  256. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/architecture/index.md +0 -0
  257. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/architecture/memory.md +0 -0
  258. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/architecture/rag.md +0 -0
  259. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/assistant.md +0 -0
  260. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/autocorrect.md +0 -0
  261. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/chat.md +0 -0
  262. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/config.md +0 -0
  263. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/daemon.md +0 -0
  264. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/dev.md +0 -0
  265. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/diarize-live-session.md +0 -0
  266. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/index.md +0 -0
  267. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/install-extras.md +0 -0
  268. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/install-hotkeys.md +0 -0
  269. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/install-services.md +0 -0
  270. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/memory.md +0 -0
  271. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/rag-proxy.md +0 -0
  272. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/server/index.md +0 -0
  273. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/server/transcribe-proxy.md +0 -0
  274. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/server/tts.md +0 -0
  275. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/server/whisper.md +0 -0
  276. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/speak.md +0 -0
  277. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/speakers.md +0 -0
  278. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/start-services.md +0 -0
  279. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/transcribe-live.md +0 -0
  280. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/transcribe.md +0 -0
  281. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/commands/voice-edit.md +0 -0
  282. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/configuration.md +0 -0
  283. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/getting-started.md +0 -0
  284. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/iOS_Shortcut_Guide.md +0 -0
  285. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/index.md +0 -0
  286. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/installation/docker.md +0 -0
  287. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/installation/index.md +0 -0
  288. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/installation/linux.md +0 -0
  289. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/installation/macos.md +0 -0
  290. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/installation/nixos.md +0 -0
  291. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/installation/windows.md +0 -0
  292. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/logo-avatar.svg +0 -0
  293. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/logo-clean.svg +0 -0
  294. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/overrides/partials/integrations/analytics/custom.html +0 -0
  295. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/run_markdown_code_runner.py +0 -0
  296. {agent_cli-0.95.7 → agent_cli-0.95.8}/docs/system-integration.md +0 -0
  297. {agent_cli-0.95.7 → agent_cli-0.95.8}/example.agent-cli-config.toml +0 -0
  298. {agent_cli-0.95.7 → agent_cli-0.95.8}/justfile +0 -0
  299. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Package.resolved +0 -0
  300. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Package.swift +0 -0
  301. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/README.md +0 -0
  302. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Resources/AgentCLI.entitlements +0 -0
  303. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Resources/Info.plist +0 -0
  304. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Resources/dmg-background.svg +0 -0
  305. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Sources/AgentCLI/AgentCLIApp.swift +0 -0
  306. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Sources/AgentCLI/AgentRuntime.swift +0 -0
  307. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Sources/AgentCLI/AppDelegate.swift +0 -0
  308. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Sources/AgentCLI/CommandResult.swift +0 -0
  309. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Sources/AgentCLI/ConfigurableHotkeyController.swift +0 -0
  310. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Sources/AgentCLI/FocusedTextTarget.swift +0 -0
  311. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Sources/AgentCLI/LoginItemController.swift +0 -0
  312. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Sources/AgentCLI/MenuBarIcon.swift +0 -0
  313. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Sources/AgentCLI/RecentTranscriptionReader.swift +0 -0
  314. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Sources/AgentCLI/RuntimeSettings.swift +0 -0
  315. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Sources/AgentCLI/TranscriptPasteController.swift +0 -0
  316. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Sources/AgentCLI/TranscriptionSettings.swift +0 -0
  317. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Sources/AgentCLI/VoiceLevelOverlay.swift +0 -0
  318. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Tests/AgentCLITests/LoginItemControllerTests.swift +0 -0
  319. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/AgentCLI/Tests/AgentCLITests/RecentTranscriptionReaderTests.swift +0 -0
  320. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/build-macos-app.sh +0 -0
  321. {agent_cli-0.95.7 → agent_cli-0.95.8}/macos/test-macos-app-e2e.sh +0 -0
  322. {agent_cli-0.95.7 → agent_cli-0.95.8}/pyproject.toml +0 -0
  323. {agent_cli-0.95.7 → agent_cli-0.95.8}/reddit.md +0 -0
  324. {agent_cli-0.95.7 → agent_cli-0.95.8}/shell.nix +0 -0
  325. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/__init__.py +0 -0
  326. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/agents/__init__.py +0 -0
  327. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/agents/test_fix_my_text.py +0 -0
  328. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/agents/test_interactive.py +0 -0
  329. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/agents/test_interactive_extra.py +0 -0
  330. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/agents/test_memory_add.py +0 -0
  331. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/agents/test_speak.py +0 -0
  332. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/agents/test_speak_e2e.py +0 -0
  333. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/agents/test_speakers.py +0 -0
  334. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/agents/test_transcribe.py +0 -0
  335. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/agents/test_transcribe_agent.py +0 -0
  336. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/agents/test_transcribe_e2e.py +0 -0
  337. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/agents/test_transcribe_live.py +0 -0
  338. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/agents/test_transcribe_recovery.py +0 -0
  339. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/agents/test_tts_common.py +0 -0
  340. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/agents/test_tts_common_extra.py +0 -0
  341. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/agents/test_voice_agent_common.py +0 -0
  342. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/agents/test_voice_edit.py +0 -0
  343. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/agents/test_voice_edit_e2e.py +0 -0
  344. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/agents/test_wake_word_assistant.py +0 -0
  345. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/conftest.py +0 -0
  346. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/core/__init__.py +0 -0
  347. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/core/test_audio.py +0 -0
  348. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/core/test_audio_format.py +0 -0
  349. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/core/test_chroma.py +0 -0
  350. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/core/test_sse.py +0 -0
  351. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/core/test_vad.py +0 -0
  352. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/core/test_watch.py +0 -0
  353. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/dev/__init__.py +0 -0
  354. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/dev/test_cleanup.py +0 -0
  355. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/dev/test_cli.py +0 -0
  356. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/dev/test_coding_agents.py +0 -0
  357. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/dev/test_editors.py +0 -0
  358. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/dev/test_hooks.py +0 -0
  359. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/dev/test_launch.py +0 -0
  360. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/dev/test_project.py +0 -0
  361. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/dev/test_terminals.py +0 -0
  362. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/dev/test_verification.py +0 -0
  363. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/dev/test_worktree.py +0 -0
  364. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/install/__init__.py +0 -0
  365. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/install/test_extras.py +0 -0
  366. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/install/test_launchd.py +0 -0
  367. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/memory/__init__.py +0 -0
  368. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/memory/test_api_health.py +0 -0
  369. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/memory/test_api_integration_liveish.py +0 -0
  370. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/memory/test_client.py +0 -0
  371. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/memory/test_engine.py +0 -0
  372. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/memory/test_files.py +0 -0
  373. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/memory/test_filters.py +0 -0
  374. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/memory/test_git_integration.py +0 -0
  375. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/memory/test_indexer.py +0 -0
  376. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/memory/test_memory_integration.py +0 -0
  377. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/memory/test_proxy_passthrough.py +0 -0
  378. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/memory/test_store.py +0 -0
  379. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/memory/test_utils.py +0 -0
  380. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/mocks/__init__.py +0 -0
  381. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/mocks/audio.py +0 -0
  382. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/mocks/llm.py +0 -0
  383. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/mocks/wyoming.py +0 -0
  384. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/rag/__init__.py +0 -0
  385. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/rag/test_api.py +0 -0
  386. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/rag/test_engine.py +0 -0
  387. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/rag/test_history.py +0 -0
  388. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/rag/test_indexer.py +0 -0
  389. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/rag/test_indexing.py +0 -0
  390. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/rag/test_rag_client.py +0 -0
  391. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/rag/test_rag_integration_liveish.py +0 -0
  392. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/rag/test_rag_proxy_passthrough.py +0 -0
  393. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/rag/test_retriever.py +0 -0
  394. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/rag/test_store.py +0 -0
  395. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/rag/test_utils.py +0 -0
  396. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_alignment.py +0 -0
  397. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_api.py +0 -0
  398. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_api_integration.py +0 -0
  399. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_asr.py +0 -0
  400. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_asr_recovery.py +0 -0
  401. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_audio_e2e.py +0 -0
  402. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_cli.py +0 -0
  403. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_config.py +0 -0
  404. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_config_cmd.py +0 -0
  405. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_daemon.py +0 -0
  406. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_diarization.py +0 -0
  407. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_diarize_live_session.py +0 -0
  408. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_docs_gen.py +0 -0
  409. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_env_vars.py +0 -0
  410. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_faster_whisper_backend.py +0 -0
  411. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_json_output.py +0 -0
  412. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_llm.py +0 -0
  413. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_llm_gemini.py +0 -0
  414. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_memory_tools.py +0 -0
  415. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_mlx_backend.py +0 -0
  416. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_process_manager.py +0 -0
  417. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_requires_extras.py +0 -0
  418. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_server_streaming.py +0 -0
  419. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_server_tts.py +0 -0
  420. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_server_whisper.py +0 -0
  421. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_services.py +0 -0
  422. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_speaker_identity.py +0 -0
  423. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_tools.py +0 -0
  424. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_transformers_backend.py +0 -0
  425. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_tts.py +0 -0
  426. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_utils.py +0 -0
  427. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_wake_word.py +0 -0
  428. {agent_cli-0.95.7 → agent_cli-0.95.8}/tests/test_wyoming_utils.py +0 -0
  429. {agent_cli-0.95.7 → agent_cli-0.95.8}/uv.lock +0 -0
  430. {agent_cli-0.95.7 → agent_cli-0.95.8}/zensical.toml +0 -0
@@ -0,0 +1,29 @@
1
+ cask "agent-cli" do
2
+ version "0.95.7"
3
+ sha256 "9db4a8d9f44765e1197d687a46e4cde041ada2d5284e6a22324c706d2a40848e"
4
+
5
+ url "https://github.com/basnijholt/agent-cli/releases/download/v#{version}/AgentCLI.dmg"
6
+ name "Agent CLI"
7
+ desc "Local-first AI voice and text tools with menu bar integration"
8
+ homepage "https://github.com/basnijholt/agent-cli"
9
+
10
+ livecheck do
11
+ url :url
12
+ strategy :github_latest
13
+ end
14
+
15
+ depends_on arch: :arm64
16
+ depends_on macos: :ventura
17
+
18
+ app "AgentCLI.app"
19
+
20
+ uninstall launchctl: "com.agent_cli.whisper",
21
+ quit: "lt.nijho.agent-cli.menubar"
22
+
23
+ zap trash: [
24
+ "~/Library/Application Support/AgentCLI",
25
+ "~/Library/LaunchAgents/com.agent_cli.whisper.plist",
26
+ "~/Library/Logs/agent-cli-whisper",
27
+ "~/Library/Preferences/lt.nijho.agent-cli.menubar.plist",
28
+ ]
29
+ end
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-cli
3
- Version: 0.95.7
3
+ Version: 0.95.8
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>
@@ -1,5 +1,15 @@
1
1
  import Foundation
2
2
 
3
+ private extension String {
4
+ var isVisiblyBlank: Bool {
5
+ unicodeScalars.allSatisfy { scalar in
6
+ CharacterSet.whitespacesAndNewlines.contains(scalar)
7
+ || scalar.properties.generalCategory == .format
8
+ || scalar.properties.generalCategory == .control
9
+ }
10
+ }
11
+ }
12
+
3
13
  struct AgentCommand {
4
14
  let identifier: String
5
15
  let title: String
@@ -40,7 +50,7 @@ struct AgentCommand {
40
50
  guard appliesTranscriptionExtraInstructions else { return arguments }
41
51
 
42
52
  let trimmedInstructions = extraInstructions?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
43
- guard !trimmedInstructions.isEmpty else { return arguments }
53
+ guard !trimmedInstructions.isVisiblyBlank else { return arguments }
44
54
 
45
55
  return arguments + ["--extra-instructions", trimmedInstructions]
46
56
  }
@@ -29,9 +29,13 @@ final class AgentCommandRunner: ObservableObject {
29
29
  @Published private(set) var isRecording = false
30
30
  @Published private(set) var bootstrapPhase: BootstrapPhase = .idle
31
31
  @Published private var activeCommandCount = 0
32
+ @Published private var bootstrapAnimationTick = 0
33
+ @Published private var bootstrapElapsedSeconds = 0
32
34
  private var recordingIndicator = RecordingIndicatorController()
33
35
  private let pasteController: TranscriptPasteController
34
36
  private let bootstrap: AgentBootstrap
37
+ private var bootstrapAnimationTimer: Timer?
38
+ private var bootstrapPhaseStartedAt: Date?
35
39
  private var pendingStopRecordingCommands: Set<String> = []
36
40
  private var holdTranscriptionState: HoldTranscriptionState = .idle
37
41
  private var holdToTranscribePasteTarget: FocusedTextTarget?
@@ -47,7 +51,10 @@ final class AgentCommandRunner: ObservableObject {
47
51
  return "Recording"
48
52
  }
49
53
  if bootstrapPhase.isPreparing {
50
- return bootstrapPhase.statusMessage
54
+ return bootstrapPhase.statusMessage(
55
+ animationTick: bootstrapAnimationTick,
56
+ elapsedSeconds: bootstrapElapsedSeconds
57
+ )
51
58
  }
52
59
  if holdTranscriptionState.isFinishing {
53
60
  return "Transcribing..."
@@ -122,7 +129,19 @@ final class AgentCommandRunner: ObservableObject {
122
129
  }
123
130
 
124
131
  private func reportBootstrapPhase(_ phase: BootstrapPhase) {
132
+ let wasPreparing = bootstrapPhase.isPreparing
133
+ let phaseChanged = bootstrapPhase != phase
125
134
  bootstrapPhase = phase
135
+ if phase.isPreparing {
136
+ if !wasPreparing || phaseChanged {
137
+ bootstrapAnimationTick = 0
138
+ bootstrapElapsedSeconds = 0
139
+ bootstrapPhaseStartedAt = Date()
140
+ }
141
+ startBootstrapAnimationTimer()
142
+ } else {
143
+ stopBootstrapAnimationTimer()
144
+ }
126
145
  }
127
146
 
128
147
  private func makeBootstrapProgressReporter() -> AgentBootstrapProgress {
@@ -133,6 +152,33 @@ final class AgentCommandRunner: ObservableObject {
133
152
  }
134
153
  }
135
154
 
155
+ private func startBootstrapAnimationTimer() {
156
+ guard bootstrapAnimationTimer == nil else { return }
157
+ let timer = Timer(timeInterval: 0.8, repeats: true) { [weak self] _ in
158
+ Task { @MainActor in
159
+ guard let self else { return }
160
+ guard self.bootstrapPhase.isPreparing else {
161
+ self.stopBootstrapAnimationTimer()
162
+ return
163
+ }
164
+ self.bootstrapAnimationTick = (self.bootstrapAnimationTick + 1) % 3
165
+ if let startedAt = self.bootstrapPhaseStartedAt {
166
+ self.bootstrapElapsedSeconds = max(0, Int(Date().timeIntervalSince(startedAt)))
167
+ }
168
+ }
169
+ }
170
+ RunLoop.main.add(timer, forMode: .common)
171
+ bootstrapAnimationTimer = timer
172
+ }
173
+
174
+ private func stopBootstrapAnimationTimer() {
175
+ bootstrapAnimationTimer?.invalidate()
176
+ bootstrapAnimationTimer = nil
177
+ bootstrapAnimationTick = 0
178
+ bootstrapElapsedSeconds = 0
179
+ bootstrapPhaseStartedAt = nil
180
+ }
181
+
136
182
  @discardableResult
137
183
  func beginHoldToTranscribe() -> Bool {
138
184
  guard holdTranscriptionState == .idle else {
@@ -42,6 +42,16 @@ enum BootstrapPhase: Equatable {
42
42
  return "Voice service warm-up failed"
43
43
  }
44
44
  }
45
+
46
+ func statusMessage(animationTick: Int, elapsedSeconds: Int) -> String {
47
+ switch self {
48
+ 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:
52
+ return statusMessage
53
+ }
54
+ }
45
55
  }
46
56
 
47
57
  typealias AgentBootstrapProgress = (BootstrapPhase) -> Void
@@ -3,6 +3,16 @@ import Foundation
3
3
  final class RecordingIndicatorController {
4
4
  private var recordingCommandCount = 0
5
5
  private var activeRecordingCommands: [String: Int] = [:]
6
+ private let defaults: UserDefaults
7
+ private let audioCuePlayer: RecordingCuePlaying
8
+
9
+ init(
10
+ defaults: UserDefaults = .standard,
11
+ audioCuePlayer: RecordingCuePlaying = NativeRecordingCuePlayer.shared
12
+ ) {
13
+ self.defaults = defaults
14
+ self.audioCuePlayer = audioCuePlayer
15
+ }
6
16
 
7
17
  var isRecording: Bool {
8
18
  recordingCommandCount > 0
@@ -13,12 +23,17 @@ final class RecordingIndicatorController {
13
23
  }
14
24
 
15
25
  func begin(for command: AgentCommand) {
26
+ let wasRecording = isRecording
16
27
  activeRecordingCommands[command.identifier, default: 0] += 1
17
28
  recordingCommandCount += 1
29
+ if !wasRecording {
30
+ play(.startedRecording)
31
+ }
18
32
  VoiceLevelOverlayController.shared.show()
19
33
  }
20
34
 
21
35
  func end(for command: AgentCommand) {
36
+ let wasRecording = isRecording
22
37
  let activeCommandCount = max(0, activeRecordingCommands[command.identifier, default: 0] - 1)
23
38
  if activeCommandCount > 0 {
24
39
  activeRecordingCommands[command.identifier] = activeCommandCount
@@ -26,8 +41,14 @@ final class RecordingIndicatorController {
26
41
  activeRecordingCommands.removeValue(forKey: command.identifier)
27
42
  }
28
43
  recordingCommandCount = max(0, recordingCommandCount - 1)
29
- if !isRecording {
44
+ if wasRecording && !isRecording {
45
+ play(.finishedRecording)
30
46
  VoiceLevelOverlayController.shared.hide()
31
47
  }
32
48
  }
49
+
50
+ private func play(_ event: RecordingSoundEvent) {
51
+ guard RecordingSoundSettings.isEnabled(defaults: defaults) else { return }
52
+ audioCuePlayer.play(event)
53
+ }
33
54
  }
@@ -0,0 +1,54 @@
1
+ import AppKit
2
+ import Foundation
3
+
4
+ enum RecordingSoundSettings {
5
+ static let enabledKey = "recordingNotificationSoundsEnabled"
6
+
7
+ static func isEnabled(defaults: UserDefaults = .standard) -> Bool {
8
+ defaults.bool(forKey: enabledKey)
9
+ }
10
+ }
11
+
12
+ enum RecordingSoundEvent: Hashable {
13
+ case startedRecording
14
+ case finishedRecording
15
+
16
+ var cueName: NSSound.Name {
17
+ switch self {
18
+ case .startedRecording:
19
+ return NSSound.Name("Frog")
20
+ case .finishedRecording:
21
+ return NSSound.Name("Funk")
22
+ }
23
+ }
24
+ }
25
+
26
+ protocol RecordingCuePlaying: AnyObject {
27
+ func play(_ event: RecordingSoundEvent)
28
+ }
29
+
30
+ final class NativeRecordingCuePlayer: RecordingCuePlaying {
31
+ static let shared = NativeRecordingCuePlayer()
32
+
33
+ private var sounds: [RecordingSoundEvent: NSSound] = [:]
34
+
35
+ private init() {}
36
+
37
+ func play(_ event: RecordingSoundEvent) {
38
+ guard let sound = sound(for: event) else { return }
39
+ sound.stop()
40
+ sound.currentTime = 0
41
+ sound.play()
42
+ }
43
+
44
+ private func sound(for event: RecordingSoundEvent) -> NSSound? {
45
+ if let sound = sounds[event] {
46
+ return sound
47
+ }
48
+ guard let sound = NSSound(named: event.cueName) else {
49
+ return nil
50
+ }
51
+ sounds[event] = sound
52
+ return sound
53
+ }
54
+ }
@@ -5,10 +5,7 @@ import KeyboardShortcuts
5
5
  import SwiftUI
6
6
 
7
7
  extension KeyboardShortcuts.Name {
8
- static let toggleTranscription = Self(
9
- "toggleTranscription",
10
- default: KeyboardShortcuts.Shortcut(carbonKeyCode: kVK_Space, carbonModifiers: kEventKeyModifierFnMask)
11
- )
8
+ static let toggleTranscription = Self("toggleTranscription")
12
9
  static let holdToTranscribe = Self(
13
10
  "holdToTranscribe",
14
11
  default: KeyboardShortcuts.Shortcut(.function)
@@ -23,6 +20,68 @@ extension KeyboardShortcuts.Name {
23
20
  )
24
21
  }
25
22
 
23
+ enum AppShortcutDefaults {
24
+ static let toggleTranscription = ShortcutStorage.shortcut(
25
+ carbonKeyCode: kVK_Space,
26
+ carbonModifiers: kEventKeyModifierFnMask
27
+ )
28
+ }
29
+
30
+ enum ShortcutStorage {
31
+ static func shortcut(carbonKeyCode: Int, carbonModifiers: Int = 0) -> KeyboardShortcuts.Shortcut {
32
+ // KeyboardShortcuts' public initializer normalizes away Fn, but Codable preserves raw Carbon modifiers.
33
+ let shortcutJSON = """
34
+ {"carbonKeyCode":\(carbonKeyCode),"carbonModifiers":\(carbonModifiers)}
35
+ """
36
+ guard let data = shortcutJSON.data(using: .utf8),
37
+ let shortcut = try? JSONDecoder().decode(KeyboardShortcuts.Shortcut.self, from: data) else {
38
+ return KeyboardShortcuts.Shortcut(
39
+ carbonKeyCode: carbonKeyCode,
40
+ carbonModifiers: carbonModifiers
41
+ )
42
+ }
43
+ return shortcut
44
+ }
45
+
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
+
59
+ KeyboardShortcuts.setShortcut(nil, for: name)
60
+ guard let encoded = try? JSONEncoder().encode(shortcut),
61
+ let encodedString = String(data: encoded, encoding: .utf8) else {
62
+ return
63
+ }
64
+ 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
+ }
71
+
72
+ private static func userDefaultsKey(for name: KeyboardShortcuts.Name) -> String {
73
+ "KeyboardShortcuts_\(name.rawValue)"
74
+ }
75
+
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
+ )
82
+ }
83
+ }
84
+
26
85
  final class ShortcutRecordingState {
27
86
  static let shared = ShortcutRecordingState()
28
87
 
@@ -64,8 +123,8 @@ final class ShortcutSummaryState: ObservableObject {
64
123
  }
65
124
 
66
125
  func resetDefaults() {
126
+ ShortcutStorage.setShortcut(AppShortcutDefaults.toggleTranscription, for: .toggleTranscription)
67
127
  KeyboardShortcuts.reset(
68
- .toggleTranscription,
69
128
  .holdToTranscribe,
70
129
  .autocorrect,
71
130
  .voiceEdit
@@ -118,7 +177,7 @@ private enum ShortcutDisplay {
118
177
  if event.modifierFlags.contains(.function) {
119
178
  carbonModifiers |= kEventKeyModifierFnMask
120
179
  }
121
- return KeyboardShortcuts.Shortcut(
180
+ return ShortcutStorage.shortcut(
122
181
  carbonKeyCode: shortcut.carbonKeyCode,
123
182
  carbonModifiers: carbonModifiers
124
183
  )
@@ -154,13 +213,19 @@ enum ShortcutDefaultsMigrator {
154
213
  migrateDefault(
155
214
  name: .toggleTranscription,
156
215
  from: KeyboardShortcuts.Shortcut(.r, modifiers: [.command, .shift]),
157
- to: KeyboardShortcuts.Shortcut(carbonKeyCode: kVK_Space, carbonModifiers: kEventKeyModifierFnMask)
216
+ to: AppShortcutDefaults.toggleTranscription
217
+ )
218
+ migrateDefault(
219
+ name: .toggleTranscription,
220
+ from: KeyboardShortcuts.Shortcut(.space),
221
+ to: AppShortcutDefaults.toggleTranscription
158
222
  )
159
223
  migrateDefault(
160
224
  name: .holdToTranscribe,
161
225
  from: KeyboardShortcuts.Shortcut(.space, modifiers: [.control, .option]),
162
226
  to: KeyboardShortcuts.Shortcut(.function)
163
227
  )
228
+ seedDefault(name: .toggleTranscription, shortcut: AppShortcutDefaults.toggleTranscription)
164
229
  }
165
230
 
166
231
  private static func migrateDefault(
@@ -171,7 +236,17 @@ enum ShortcutDefaultsMigrator {
171
236
  guard KeyboardShortcuts.getShortcut(for: name) == oldShortcut else {
172
237
  return
173
238
  }
174
- KeyboardShortcuts.setShortcut(newShortcut, for: name)
239
+ ShortcutStorage.setShortcut(newShortcut, for: name)
240
+ }
241
+
242
+ private static func seedDefault(
243
+ name: KeyboardShortcuts.Name,
244
+ shortcut: KeyboardShortcuts.Shortcut
245
+ ) {
246
+ guard !ShortcutStorage.userDefaultsContains(name: name) else {
247
+ return
248
+ }
249
+ ShortcutStorage.setShortcut(shortcut, for: name)
175
250
  }
176
251
  }
177
252
 
@@ -179,6 +254,8 @@ struct SettingsView: View {
179
254
  @ObservedObject private var loginItemController = LoginItemController.shared
180
255
  @AppStorage(RuntimeSettings.useUserInstalledAgentCLIKey)
181
256
  private var useUserInstalledAgentCLI = false
257
+ @AppStorage(RecordingSoundSettings.enabledKey)
258
+ private var recordingSoundsEnabled = false
182
259
  @AppStorage(TranscriptionSettings.transcriptionExtraInstructionsKey)
183
260
  private var transcriptionExtraInstructions = ""
184
261
  @State private var shortcutRevision = 0
@@ -202,10 +279,11 @@ struct SettingsView: View {
202
279
  }
203
280
 
204
281
  Toggle("Use User-Installed agent-cli", isOn: $useUserInstalledAgentCLI)
282
+ Toggle("Play Recording Sounds", isOn: $recordingSoundsEnabled)
205
283
  } header: {
206
284
  Text("General")
207
285
  } footer: {
208
- Text("Runs the agent-cli found on PATH with your normal config instead of the app's private bundled-uv runtime.")
286
+ Text("Runs the agent-cli found on PATH with your normal config instead of the app's private bundled-uv runtime. Recording sounds use Frog when recording starts and Funk when recording ends.")
209
287
  }
210
288
 
211
289
  Section {
@@ -358,7 +436,7 @@ final class ShortcutRecorderButton: NSButton {
358
436
  stopRecording()
359
437
  case kVK_Delete, kVK_ForwardDelete:
360
438
  pendingFunctionShortcut = false
361
- KeyboardShortcuts.setShortcut(nil, for: shortcutName)
439
+ ShortcutStorage.setShortcut(nil, for: shortcutName)
362
440
  stopRecording()
363
441
  case kVK_Function:
364
442
  handleFunctionKeyChange(event)
@@ -368,7 +446,7 @@ final class ShortcutRecorderButton: NSButton {
368
446
  NSSound.beep()
369
447
  return
370
448
  }
371
- KeyboardShortcuts.setShortcut(shortcut, for: shortcutName)
449
+ ShortcutStorage.setShortcut(shortcut, for: shortcutName)
372
450
  stopRecording()
373
451
  }
374
452
  }
@@ -390,7 +468,7 @@ final class ShortcutRecorderButton: NSButton {
390
468
 
391
469
  private func captureBareFunctionShortcut() {
392
470
  pendingFunctionShortcut = false
393
- KeyboardShortcuts.setShortcut(KeyboardShortcuts.Shortcut(.function), for: shortcutName)
471
+ ShortcutStorage.setShortcut(KeyboardShortcuts.Shortcut(.function), for: shortcutName)
394
472
  stopRecording()
395
473
  }
396
474
 
@@ -41,6 +41,13 @@ final class AgentCommandTests: XCTestCase {
41
41
  )
42
42
  }
43
43
 
44
+ func testVisuallyBlankExtraInstructionsAreIgnored() {
45
+ XCTAssertEqual(
46
+ AgentCommand.toggleTranscription.resolvedArguments(extraInstructions: "\u{2060}\u{FEFF}"),
47
+ AgentCommand.toggleTranscription.arguments
48
+ )
49
+ }
50
+
44
51
  func testExtraInstructionsOnlyApplyToTranscription() {
45
52
  XCTAssertEqual(
46
53
  AgentCommand.autocorrect.resolvedArguments(extraInstructions: "Remember Bas."),
@@ -140,6 +147,25 @@ final class AgentCommandTests: XCTestCase {
140
147
 
141
148
  XCTAssertEqual(recorder.calls, [.init(requirement: .transcriptionModel, force: false)])
142
149
  }
150
+
151
+ func testWaitingForVoiceServiceStatusAnimatesEllipsis() {
152
+ XCTAssertEqual(
153
+ BootstrapPhase.waitingForVoiceService.statusMessage(animationTick: 0, elapsedSeconds: 0),
154
+ "Waiting for voice service. (0s)"
155
+ )
156
+ XCTAssertEqual(
157
+ BootstrapPhase.waitingForVoiceService.statusMessage(animationTick: 1, elapsedSeconds: 12),
158
+ "Waiting for voice service.. (12s)"
159
+ )
160
+ XCTAssertEqual(
161
+ BootstrapPhase.waitingForVoiceService.statusMessage(animationTick: 2, elapsedSeconds: 123),
162
+ "Waiting for voice service... (123s)"
163
+ )
164
+ XCTAssertEqual(
165
+ BootstrapPhase.waitingForVoiceService.statusMessage(animationTick: 3, elapsedSeconds: 4),
166
+ "Waiting for voice service. (4s)"
167
+ )
168
+ }
143
169
  }
144
170
 
145
171
  private struct BootstrapCall: Equatable {
@@ -0,0 +1,55 @@
1
+ #if canImport(XCTest)
2
+ import XCTest
3
+ @testable import AgentCLI
4
+
5
+ final class RecordingIndicatorControllerTests: XCTestCase {
6
+ func testRecordingSoundsAreDisabledByDefault() {
7
+ let defaults = UserDefaults(suiteName: "AgentCLITests.recording-sounds-default")!
8
+ defaults.removePersistentDomain(forName: "AgentCLITests.recording-sounds-default")
9
+ let player = RecordingCuePlayerSpy()
10
+ let controller = RecordingIndicatorController(defaults: defaults, audioCuePlayer: player)
11
+
12
+ controller.begin(for: .toggleTranscription)
13
+ controller.end(for: .toggleTranscription)
14
+
15
+ XCTAssertEqual(player.events, [])
16
+ }
17
+
18
+ func testRecordingSoundsPlayStartAndFinishWhenEnabled() {
19
+ let defaults = UserDefaults(suiteName: "AgentCLITests.recording-sounds-enabled")!
20
+ defaults.removePersistentDomain(forName: "AgentCLITests.recording-sounds-enabled")
21
+ defaults.set(true, forKey: RecordingSoundSettings.enabledKey)
22
+ let player = RecordingCuePlayerSpy()
23
+ let controller = RecordingIndicatorController(defaults: defaults, audioCuePlayer: player)
24
+
25
+ controller.begin(for: .toggleTranscription)
26
+ controller.end(for: .toggleTranscription)
27
+
28
+ XCTAssertEqual(player.events, [.startedRecording, .finishedRecording])
29
+ }
30
+
31
+ func testFinishSoundPlaysOnlyWhenAllRecordingCommandsHaveEnded() {
32
+ let defaults = UserDefaults(suiteName: "AgentCLITests.recording-sounds-nested")!
33
+ defaults.removePersistentDomain(forName: "AgentCLITests.recording-sounds-nested")
34
+ defaults.set(true, forKey: RecordingSoundSettings.enabledKey)
35
+ let player = RecordingCuePlayerSpy()
36
+ let controller = RecordingIndicatorController(defaults: defaults, audioCuePlayer: player)
37
+
38
+ controller.begin(for: .toggleTranscription)
39
+ controller.begin(for: .voiceEdit)
40
+ controller.end(for: .toggleTranscription)
41
+ XCTAssertEqual(player.events, [.startedRecording])
42
+
43
+ controller.end(for: .voiceEdit)
44
+ XCTAssertEqual(player.events, [.startedRecording, .finishedRecording])
45
+ }
46
+ }
47
+
48
+ private final class RecordingCuePlayerSpy: RecordingCuePlaying {
49
+ private(set) var events: [RecordingSoundEvent] = []
50
+
51
+ func play(_ event: RecordingSoundEvent) {
52
+ events.append(event)
53
+ }
54
+ }
55
+ #endif
@@ -0,0 +1,55 @@
1
+ #if canImport(XCTest)
2
+ import Carbon.HIToolbox
3
+ import KeyboardShortcuts
4
+ import XCTest
5
+ @testable import AgentCLI
6
+
7
+ final class ShortcutDefaultsTests: XCTestCase {
8
+ override func setUp() {
9
+ super.setUp()
10
+ clearShortcutDefaults()
11
+ }
12
+
13
+ override func tearDown() {
14
+ clearShortcutDefaults()
15
+ super.tearDown()
16
+ }
17
+
18
+ func testMigratesPlainSpaceToggleShortcutToFunctionSpace() {
19
+ KeyboardShortcuts.setShortcut(
20
+ KeyboardShortcuts.Shortcut(.space),
21
+ for: .toggleTranscription
22
+ )
23
+
24
+ ShortcutDefaultsMigrator.migrate()
25
+
26
+ let shortcut = KeyboardShortcuts.getShortcut(for: .toggleTranscription)
27
+ XCTAssertEqual(shortcut?.carbonKeyCode, kVK_Space)
28
+ XCTAssertEqual((shortcut?.carbonModifiers ?? 0) & kEventKeyModifierFnMask, kEventKeyModifierFnMask)
29
+ }
30
+
31
+ func testResetDefaultsRestoresFunctionSpaceToggleShortcut() {
32
+ KeyboardShortcuts.setShortcut(
33
+ KeyboardShortcuts.Shortcut(.space),
34
+ for: .toggleTranscription
35
+ )
36
+
37
+ ShortcutSummaryState.shared.resetDefaults()
38
+
39
+ let shortcut = KeyboardShortcuts.getShortcut(for: .toggleTranscription)
40
+ XCTAssertEqual(shortcut?.carbonKeyCode, kVK_Space)
41
+ XCTAssertEqual((shortcut?.carbonModifiers ?? 0) & kEventKeyModifierFnMask, kEventKeyModifierFnMask)
42
+ }
43
+
44
+ private func clearShortcutDefaults() {
45
+ for name in [
46
+ "toggleTranscription",
47
+ "holdToTranscribe",
48
+ "autocorrect",
49
+ "voiceEdit",
50
+ ] {
51
+ UserDefaults.standard.removeObject(forKey: "KeyboardShortcuts_\(name)")
52
+ }
53
+ }
54
+ }
55
+ #endif